Proposal (rationale)
F-063, from the WI-090 canary: the CLI parses check [path] [tier], so node .ai/rungs.mjs check full through the pinned npm launcher looks for a repository at ./full and exits 1 with “no gates
registered — is this a rungs repo?”. The ejected runner parses check [tier], so the same command
after ejection runs the full tier. The ejected README documents check [tier], and a consumer who
quotes it before ejecting gets a wrong answer that looks like a broken install.
Decision
accepted — 2026-09-06, at the user’s request to tackle F-059 to F-063. One grammar on both
surfaces: check [path] [tier], where a lone positional that is not an existing directory and carries
no path separator is the tier. Flags keep working.
Plan
Requirements
- CLI:
check fullfrom inside a repository runs the full tier;check <dir> fulland--fullare unchanged;check nonsensereports an unknown tier, never “no gates registered”. - Ejected runner:
check full,check . fullandcheck <its own root> fullall run the full tier; a path that is not the repository it lives in is refused with a message, exit 1. - The ejected README and runner usage say
check [path] [tier].
Impacts
src/cli.ts(case 'check'),src/ejected-runner.ts,src/lifecycle.ts(ejected README),test/core.test.js,test/package.test.js(the ambiguous form joins the journey).
Approach
Shared rule: a first positional is a path if it names an existing directory or contains a path
separator; otherwise it is the tier. Alternative — tier only by flag on both surfaces — rejected:
it would break every consumer’s check full in CI workflows the ci module already emitted.
Acceptance criteria / tests
- Core test: in a fresh tracked scaffold,
check fullexits 0 and prints the full tier;check nonsenseexits 1 withunknown tier; aftereject,node .ai/rungs.mjs check . fullandcheck fullboth run the full tier andcheck <elsewhere> fullis refused. - Packed journey:
check fullfrom the consumer directory through the installed candidate passes beside the existingcheck <dir> full. - Serial suite and
rungs checkpass.
Out of scope
- Any other CLI grammar; nothing else deferred.
Execution
Branch feature/WI-094-check-tier-positional from 497c079f, 2026-09-06. As planned, with one
detail the plan left open: the ejected runner refuses a path that is not its own repository rather
than re-rooting, since it has no other repository’s frozen tables to run. The packed journey’s new
runs sit after its ledger arithmetic, because a successful check appends rows and the first
placement broke the “both runs recorded” count — moved, not weakened.
Review
node --test --test-name-pattern '^check takes the same' test/core.test.js: 1/1 (2026-09-06) — CLIcheck <dir> full,check full,check . fullrun the full tier,check nonsenseexits 1 withunknown tier "nonsense"and no “no gates registered”; aftereject, the launcher runs the full tier forcheck full,check . full,check <root> fulland--full, refuses another directory with exit 1, and reports an unknown tier.- Packed journey alone: 1/1 in 42 s with the lone-tier and unknown-tier forms through the installed candidate (2026-09-06).
- Serial suite
NODE_OPTIONS=--max-old-space-size=2048 node --test --test-concurrency=1 test/*.test.js: 154 tests, 151 pass, 0 fail, 3 skipped, 166 s.node src/cli.ts check: 31 pass.