LearnNewsExamplesServices
Frontmatter
id13595
titlelint-skill-manifest: no-base run gives false-green (byte-delta gates silently skipped)
stateClosed
labels
ai
assigneesneo-opus-ada
createdAtJun 20, 2026, 7:06 AM
updatedAtJun 20, 2026, 7:57 AM
githubUrlhttps://github.com/neomjs/neo/issues/13595
authorneo-opus-ada
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 20, 2026, 7:57 AM

lint-skill-manifest: no-base run gives false-green (byte-delta gates silently skipped)

neo-opus-ada
neo-opus-ada commented on Jun 20, 2026, 7:06 AM

Context

ai/scripts/lint/lint-skill-manifest.mjs gives a FALSE-GREEN when run without --base. Hit twice during PR #13588 (the reviewer-contract skill edits): local npm run ai:lint-skill-manifest printed [lint-skill-manifest] OK, but the per-file + net byte-delta gates were never evaluated, so a +672 net (and a per-file overflow) only surfaced in CI, which runs --base origin/dev.

The Problem

lint() guards BOTH byte-delta checks behind if (base) {...} (lint-skill-manifest.mjs:1119, :1232) — checkOversizedWorkflowMaps (per-file ≤250) and checkSkillMarkdownNetDelta (net ≤250). Without --base those are silently skipped, yet main() still prints a bare [lint-skill-manifest] OK (:1280). An agent editing a .agents/skills/**/references/*.md workflow-map runs the local script, sees OK, assumes the ≤250 budgets passed — then CI fails on the delta. Cost: a false-green → push → CI-catch round-trip per occurrence, recurring across every agent that edits skill substrate.

The Fix

When options.base is absent, the success output must NOT read as budget-passing — it should name that the byte-delta gates were skipped, e.g.:

[lint-skill-manifest] OK (structural checks only — byte-delta gates skipped; run with --base origin/dev, as CI does, to check the <=250 per-file + net skill-Markdown growth budgets)

Acceptance Criteria

  • A no---base run does NOT print a bare OK that reads as a full pass; it names the skipped byte-delta gates and the --base origin/dev form.
  • A --base run is unchanged (bare OK on full pass).

Out of Scope

  • Auto-defaulting --base to origin/dev (could break a fresh clone without the ref fetched); a clear notice is the minimal safe fix.

Evidence

PR #13588 cycle-1/cycle-2: the local no-base lint read green while Euclid's --base CI caught the +672 net (and separately a multi-line [skill-growth-justified] token that the [^\]\n]+ regex silently rejected). Captured in agent memory feedback_skill_substrate_edit_byte_budget.

Release classification

post-release (developer-experience / lint tooling). Boardless.

Origin Session ID: abe80be3-6235-4a9e-99bc-b14659ba806a