Skip to main content

Skip docs navigation
manual page/ ADRs

ADR-0143 — Path-agnostic check: the entire CLI contract

Context

  1. The check engine is already pure. Every rule in the checks contract operates on parsed records with filesystem access injected as predicates; only the command plumbing resolves workspaces, stores, and repo roots. The purity boundary the codebase already enforces is the product boundary this decision draws.
  2. Every other verb lost its subject. With the store retired (ADR-0141) and promotion retired (ADR-0142), the launch spine, evidence capture, gate, scaffolds, seeding, staleness reconcile, board/status projections, and store management have nothing to operate on.
  3. Reinforcement posture. ADR-0140 Decision 2: the CLI's one job is the deterministic honesty floor — the facts a lazy or dishonest reviewer cannot fake (coverage-complete, command-matches, pass-needs-evidence, ref-resolves) plus the single-artifact lint, at zero model cost.

Decision

  1. The surface. suspec check <artifact> [--spec <path>] [--task <path>] and suspec check --contract (the checks contract as JSON). Nothing else — no other command, no interactive mode, no dashboard. Level: enforced (suspec-cli).

  2. Path-agnostic, always. The CLI reads exactly the files it is handed by full path. It never resolves a store, a config, a repo root, or a workspace tree. The exceptions are three reference checks — C009, C015, and C010 (Decision 4) — each of which resolves one level of sibling directory relative to the passed artifact and never walks a tree or touches a store. The primary artifact's kind is read from its own frontmatter; companions are always explicit flags. Level: enforced (suspec-cli).

  3. A missing required companion blocks. --spec is required for every review; --task is required iff the review's frontmatter names a task: (a task-less 1:1 review reconciles spec-keyed, against the spec's full requirement set) — a --task passed but not referenced is refused as a wiring mistake, never silently ignored. A review checked without a companion it needs exits blocking (2) naming the missing flag — the honesty floor never degrades silently into a shallower check. Level: enforced (suspec-cli).

  4. Reference checks resolve artifact-relative. C009 (source refs) and C015 (citation anchors) resolve against the passed artifact's own directory — sources.md is the spec's sibling — never against a workspace root. C010 (change-plan preserves:/SPEC-id#AC-NNN refs) is the narrow exception to Decision 2's no-siblings-scan rule: it resolves SPEC-id#AC-NNN by scanning the plan's own directory for sibling */spec.md files, one level beside the plan, never a tree walk. Level: enforced (suspec-cli).

  5. C017 leaves the adopter contract. The orphaned-reference scan presumes a governed tree to walk; catalog hygiene is the catalog repo's own concern (narrows ADR-0097; C016's check and hard-error severity stand untouched — the gate-path/reconcile-path split it was framed against narrows per Decision 7, same as C013/C020). Level: convention.

  6. Contract 0.16.0. checks/checks.yaml (canon) and the CLI's contract table move together in one logical change; the sibling-canon drift guard stays the enforcement. Level: enforced (drift-guard test + CI).

  7. Exit codes are the API. 0 clean · 1 warning · 2 blocking; --json stays the structured face. Severity previously expressed as "blocks at the gate face" is expressed as blocking severity at check time — the human owns what blocks a merge (narrows ADR-0097 (C016's gate-path-vs-reconcile-path split), ADR-0129, and ADR-0128: the checks and their hard severities stand; the gate face they referenced retires). Level: enforced (suspec-cli).

  8. Family consequences. corpus-mcp adapts this surface only — path-explicit tools, shell-out posture unchanged. The suspec show <task|spec|review|checks> --json read family ADR-0085 grew as "the loader surface the MCP needs" — and ADR-0110 confirms shipped (suspec show spec) — retires with the rest of the multi-verb surface; only ADR-0085's shell-out, never-import-core architecture survives (narrows ADR-0085 and ADR-0110; see Upheld). The agents emit Codex emitter retires; the committed Codex projections become hand-maintained (narrows ADR-0098: the universal AGENTS.md discipline stands; the emitter and its sync guard retire). Level: convention.

Superseded and narrowed decisions

Superseded:

  • ADR-0136 — the launcher boundary loses its subject: there is no launcher, no worktree orchestration, no prompt generation, no run record.
  • ADR-0084 — the prepare verbs (pull, promote, scaffolds) retire with their subjects.
  • ADR-0107 and ADR-0130 — the staleness reconcile ran inside review/check --staleness; both verbs retire. Staleness stays a review concern the reviewer owns by reading the diff.

Narrowed:

  • ADR-0077 — reconcile-only, markdown-only, verdict-free, facts-not-verdicts (D8): all stand, sharpened — the harness of composable parts collapses to the one composable part that earned its keep. The multi-verb surface retires.
  • ADR-0097, ADR-0128, ADR-0129 — per Decisions 5 and 7.
  • ADR-0098 — per Decision 8.
  • ADR-0085 and ADR-0110 — per Decision 8: the suspec show … --json read family ADR-0085 grew (shipped per ADR-0110's suspec show spec) retires with the multi-verb surface; ADR-0085's shell-out, never-import-core architecture is what actually survives (see Upheld). ADR-0110's Scope and Coverage sub-decisions stand; its Pins sub-decision (reviewed-sha:
    • evidence-hash:, written by suspec stamp) retires with the staleness machinery it served — ADR-0107/ADR-0130 (Superseded, above) — Decision 1's exhaustive surface ("nothing else — no other command") leaves no stamp command to write it.

Upheld: ADR-0085 (shell-out, never import-core architecture only — its read-family growth narrows, above), ADR-0063 (levels as stated), ADR-0079/ADR-0083 (the surviving checks' semantics).

Alternatives considered

AlternativeWhy rejected
Positional multi-file with role pairing (suspec check review.md spec.md task.md)Pairing inference between positionals is hidden resolution — the exact organ this decision removes; explicit flags are deterministic and self-documenting.
Keep a path-agnostic scaffold verbSkills carry the artifact shapes; an agent writes files natively. A scaffold verb is surface without subject.
Keep --staleness (git-backed advisory)It resolves a repo root and reads git — both banned by Decision 2; the reviewer reads the diff.
Warn (exit 1) on a review checked without companionsSilently downgrades the floor's strongest checks (C012/C013/C020 simply don't run); a floor that degrades quietly is not a floor.

Consequences

  • Positive: the CLI becomes a pure function over files it is handed — trivially testable, trivially portable, no location opinions; the drift guard keeps canon and implementation honest; the check is runnable by hand, in CI, or through MCP identically.
  • Negative: no tool lists, resumes, or manages work in flight — by design, that capability left with the store; anyone wanting it composes it from their own harness.
  • Neutral: contract 0.16.0 is a breaking bump consumed only by the repo family (nothing external pins 0.15.0).

Status

Accepted (2026-07-10). Supersedes ADR-0136, ADR-0084, ADR-0107, ADR-0130; narrows ADR-0077, ADR-0097, ADR-0128, ADR-0129, ADR-0098, ADR-0085 (its read-family growth only — the shell-out architecture is upheld), ADR-0110; upholds ADR-0085 (shell-out, never-import-core architecture), ADR-0063, ADR-0079/ADR-0083 (the surviving checks' semantics). Part of the ADR-0140 re-founding.

Propagation

  • docs/adrs/README.md — ledger row + disposition flips (0136, 0084, 0107, 0130, 0077, 0097, 0128, 0129, 0098, 0085, 0110).
  • Canon: checks/checks.yaml → 0.16.0 (C009/C015 re-scope wording, C017 removal); docs/reference/cli.md (two-invocation rewrite), docs/reference/checks.md, checks/README.md, docs/10-integrations.md.
  • corpus-cli: the surgery — 19 command retirements, store/gate/launch/Tui/Workspace cull, explicit-path review checking, contract bump, test rebuild, gates green.
  • corpus-mcp: path-pass-through realign + fixture regeneration against the rebuilt CLI.
  • corpus-agents: drop the retired verbs from agent bodies; retire the codex-sync guard; freeze .codex/ as hand-maintained.

Need a starting point? Install the skills