Skip to main content

Audit (hostile-enumeration panel + convergence gate)

whyfile audit runs the C1 refuter roster over the enriched graph — each lens tries to refute a reconstructed intent node against the real tool output (explain/why/list-intent/coverage) and its source span — then converges each node’s findings into one verdict (ADR-0026/0028). It is LLM-using (unlike the query commands) and read-only by default; the panel model defaults to sonnet (WHYFILE_PANEL_MODEL to override).
Each node’s output carries a converged envelope (verdict, tier, needs_human); the report summary adds by_tier (a count per tier, including degraded — a node the panel couldn’t fully review, e.g. a backend outage, distinct from a clean node), disputed (structural dispute node ids), and auto_verdicts (the verdicts eligible to record). --record appends those auto verdicts to --trust-log (default intent-trust.json) via the same path trust --set uses — it never overwrites a verdict a human already set by hand, and skips authored nodes. --gate exits 5 (EXIT_POLICY) when a structural dispute is not yet resolved by a human trust --set or affirm (--ledger, default intent-affirmations.json); a human resolution — verdict or affirmation — always clears it. Neither flag runs without being asked: a plain whyfile audit never touches the trust log. See ADR-0028.

Conformance: intent-diff and check

Two commands make “no unexplained change” (ADR-0021) enforceable, not just informational. intent-diff classifies a changeset (same --base/--files/stdin resolution as changed) into four buckets: introduces (decision records the PR adds), supersedes (the supersession those records declare), governed (changed code linked to a recorded decision), and constraint_review (changed code linked to a constraint-kind node — touches a constraint, not a proven violation; that call is the reviewer’s). --format markdown renders a PR-ready paragraph:
Add --gate to make it load-bearing: status becomes "conformance_required" (exit 5) unless every touched constraint is cleared — cleared by the same changeset adding a decision record whose supersedes ADR-NNNN names that constraint’s governing ADR. A constraint whose source document has no ADR number in its filename is fail-closed: it can only clear by a reviewer’s explicit supersession, never automatically. check enforces compiled constraints — the ladder’s final rung, prose → structured → checkable. It reads intent-rules.json (default path, --rules to override), a small human-reviewed set of rules; this repo’s own compiles ADR-0016:
A violation exits 5, citing the decision by name: "src/q.py imports 'numpy': violates ADR-0016 (No mutation, traversal, or embeddings). Disagree? Supersede the record, do not fight the linter." A rule whose glob matches no file is reported unenforced (a stale glob), not silently passed. check --propose <constraint> uses the LLM in its only sanctioned authoring role — proposer, never certifier: it drafts a forbidden-import rule from a constraint node’s prose and prints it for a human to review and commit; it never writes intent-rules.json itself.