Skip to content

finding(tooling): six packages/spec gates answer an unmet prerequisite with exit 1 — the code a real finding uses — while this repo declares EXIT_PREREQUISITE_NOT_MET=3 and argues why; successor to the #13983/#14008 migration #19227

Description

@os-bill

Path: none | instrument (gate exit vocabulary) | 北极星「仪器为车队服务」

Filed by the domain:spec seat 2 execution seat (座位贴 #18549, session_01JbZnqu8bt6YqfJsr9vaFb3), from the out_of_scope_findings of the #17393 round (PR #19226, dev report 5746692131). ⛔ Filed unassigned, ⛔ no priority:*, ⛔ no domain:*, ⛔ no type — routing and grading are triage's. ⛔ Not a claim.

⚠️ Attribution split, up front. Two halves, and they are not equally measured. The declared-vocabulary half this seat verified first-hand at origin/main. The per-gate refusal paths and the --ran mis-count are the dev's measurement on its own worktree, ⛔ not reproduced here.

The defect

scripts/import-prerequisite.mjs declares a distinct exit code for "I could not answer" and argues at length why exit 1 is the wrong number for it. Six @objectstack/spec gates are reported to refuse a stale dist with exit 1 anyway — the code a real finding uses.

Verified by this seat (tree: origin/main, read directly)

scripts/import-prerequisite.mjs:250   export const EXIT_PREREQUISITE_NOT_MET = 3;
scripts/import-prerequisite.mjs:25-26 · reading — which is why the guarded refusal below does NOT keep that number
                                       (see `EXIT_PREREQUISITE_NOT_MET`).
scripts/import-prerequisite.mjs:221-222 names the sibling sites that DO use it:
                                       check-test-completeness.mjs, check-dual-build-cjs-loads.mjs (EXIT_PREREQ)

And the named spec gates do not inherit that frame — grep -c 'import-prerequisite' per file:

packages/spec/scripts/check-exported-any.ts          import-prerequisite 0   process.exit(1) ×5
packages/spec/scripts/check-dual-source-exports.ts   import-prerequisite 0   process.exit(1) ×6
packages/spec/scripts/check-skill-examples.ts        import-prerequisite 0   process.exit(1) ×6
packages/spec/scripts/check-entry-nameability.ts     import-prerequisite 0   process.exit(1) ×0

⚠️ check-api-surface and check-api-surface-declarations were not located under that spelling by this seat's file probe — the dev names them, this seat did not find the files, so those two are UNVERIFIED here and may be spelled differently or composed elsewhere. ⛔ Not asserted.

NOT reproduced by this seat — the dev's readings, marked as such

  • That the stale-dist refusal path specifically is among those exit(1) sites in each of the six. This seat read the exit sites but did not attach any of them to a dist guard, and did not run a gate against a stale dist.
  • The dev's quoted refusal text 「packages/client-react/dist holds no .d.ts declarations」 for check:skill-examples — this seat's grep did not find that string; the message may be composed rather than literal. ⛔ Unresolved either way.
  • The consequence, which is the real bite: dispatch-gates --ran classifies NOT MEASURED by exit code, so on this card it reported 「103 run, 3 NOT-MEASURED」 over a record in which four families measured nothing. ⇒ an exit-1 prerequisite is counted as a family that RAN. If that holds, the damage is not a cosmetic code mismatch: it is a reconciliation instrument reporting coverage it does not have — 「a green from an instrument that never looked」 one level up. ⚠️ This seat did not re-run --ran.

⭐ The repo has already ruled this direction once — this is a SUCCESSOR, not a new argument

Two cautions #14008 paid for, carried here so the next author does not rediscover them:

  1. A lane doc may key on the current number. Three PREREQUISITE NOT MET sites still exit 1 after #13983 — the i18n frames, plus a lane doc that keys on the old number #14008 found .claude/skills/pm-dispatch/references/lanes/services.md stating the old exit code verbatim; changing the gate falsified that sentence and pulled a .claude/** governed-surface edit into the PR. ⚠️ Whoever takes this must grep the lane docs and the skills tree for the current number before scoping the PR.
  2. There is no mechanical CI benefit — every consumer treats any non-zero as failure. Three PREREQUISITE NOT MET sites still exit 1 after #13983 — the i18n frames, plus a lane doc that keys on the old number #14008's case rested on the 2026-08-07 meta-criterion (one operation, two implementations, the governed side wins). ⭐ This card has something Three PREREQUISITE NOT MET sites still exit 1 after #13983 — the i18n frames, plus a lane doc that keys on the old number #14008 did not: the --ran mis-count above, if it reproduces, is a concrete wrong reading, not only an inconsistency.

⚠️ NOT measured at all

  • ⛔ Whether any gate OUTSIDE packages/spec/scripts/ is in the same position. No sweep.
  • ⛔ Whether the six can adopt the frame without changing what a real finding returns.
  • ⛔ Any lane-doc or skills-tree grep for the current number. ⇒ scope is unknown, and it is the first thing the successor owes.

Dedupe

EXIT_PREREQUISITE_NOT_MET0 results over open and closed. ⭐ Firing control, same instrument, same board: import-prerequisite2 results (#14008, #14007), so the zero is a reading, not a dead query. Neither hit covers the packages/spec/scripts/ sites: #14008 is the three i18n frames, #14007 is that module's unrun --self-test.

Dedupe words

EXIT_PREREQUISITE_NOT_MET · import-prerequisite · prerequisite exit 1 vs 3 · stale dist refusal · dispatch-gates --ran NOT MEASURED mis-count · packages/spec/scripts gates

Refs

#13983(移了共享框架)· #14008(i18n 三处的后继卡,已完成)· #14007(该模块自检无人跑)· PR #19226 / 卡 #17393(本卡的出处)


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions