@sabaiway/agent-workflow-kit 1.37.1 → 1.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,119 @@ Semantically versioned ([semver](https://semver.org)), newest first. The `versio
4
4
  is the current release. `upgrade` mode reads a project's `docs/ai/.workflow-version` and applies
5
5
  every `migrations/<version>-<slug>.md` newer than it, in semver order.
6
6
 
7
+ ## 1.39.0 — Fold boundaries: commit-anchored segments, the diff-size cap, the green-baseline receipt, no-repro-no-fold, and gate telemetry (AD-048)
8
+
9
+ A **feature** release (deployment-lineage head stays `1.3.0` — no migration; engine/memory/bridges
10
+ untouched). AD-047's own execution loop field-proved the next gap twice: the ledger hard-capped a
11
+ MULTIPHASE plan at 3 rounds total (11 real council rounds across 4 commit boundaries went
12
+ unrecordable, their late fixable-bugs unbindable), and custody obligations spanning the whole plan
13
+ forced a waiver for every later-phase edit of an earlier-bound test file (4 of 5 recorded
14
+ overrides). One structural move fixes both and gives the three most-replicated fold-boundary
15
+ effects in the review literature real teeth: **the SEGMENT**.
16
+
17
+ - **The segment (review-ledger schema v4)** — every new record carries `base` = the commit the
18
+ dirty tree sits on (`git rev-parse HEAD`; null on an unborn branch); a segment = (activity,
19
+ loop, base). Round numbering, `REVIEW_CAP`/`HARD_MAX` (values unchanged — scope corrected),
20
+ every writer tooth, and `--check` operate **per segment**; a segment closes ONLY through a
21
+ gated commit, so a round-counter reset is **earned, never declared**. The field-proven
22
+ 11-round/4-base shape records completely while round 4 within one segment stays refused.
23
+ `--status` groups rounds by segment; v1..v3 records stay readable and never enter one (the
24
+ failure reason names the schema upgrade).
25
+ - **The diff-size cap (D4, writer tooth)** — `recordRound` refuses a round whose changed source
26
+ surface exceeds `AW_REVIEW_DIFF_CAP` (default 400 new-side lines; fail-closed parser) without a
27
+ recorded segment-scoped **`size-cap`** override carrying the EXACT sanctioned magnitude (it dies
28
+ at the next commit — a grown surface needs a fresh recorded sanction). Counted classes are
29
+ pinned: assessable + unsupported SOURCE lines count (excluding TS would gift a bypass); tests
30
+ and out-of-domain never count; pure deletions are free. The computation lives in the NEW
31
+ NEUTRAL `tools/changed-surface.mjs` — one home shared with the coverage domain (the runner and
32
+ the writer can never drift; the writer never imports the runner).
33
+ - **The green-baseline receipt (D5)** — `run-gates --record` mints a v4 **`gate-run`** record via
34
+ the ledger's NEW sole-writer API `recordGateRun` (the runner never opens the ledger itself):
35
+ the FULL declaration + exactly what ran + the tree fingerprint BEFORE and AFTER the run; a red
36
+ run records honestly; a failed record is its own loud **exit 7**. `recordRound` then refuses
37
+ without a **quality-green** gate-run at the current fingerprint — gates-before-review is
38
+ computed, not remembered: a subset that omits a declared non-process gate (any `--only` run
39
+ short of the full quality set) or a tree-changed run never satisfies, while the kit's own
40
+ `--check` loop gates (a CLOSED whole-command classification — compound lines and suffix-named
41
+ tools never match) legitimately fail mid-loop and never block — omitting THOSE is fine. The velocity tier
42
+ auto-approves only the exact no-`--record` form. Revert-first beyond this ships as protocol +
43
+ telemetry visibility — stated plainly, never pretend-teeth.
44
+ - **No-repro-no-fold (D6)** — a blocking finding of the previous segment round may not VANISH
45
+ unclassified: present means present-AS-BLOCKING (a severity downgrade does not survive), a
46
+ pending `escalate` never clears, and the new v4 triage class **`refuted`** is the honest
47
+ phantom lane (mandatory grounds in `note`; it also resolves in `decideStop` — additive rows
48
+ beside the untouched truth table — so an honestly refuted phantom minted at the hard-max round
49
+ can never wedge a segment). Minors stay exempt. Every fixable-bug fold therefore binds its
50
+ red→green `testId` at the round it folded — late binding on multiphase plans restored.
51
+ - **Segment-scoped fold custody (D7, fold ledger v3)** — run and observed-red records carry
52
+ `base`; bound testIds, receipts, custody chains, and tamper all filter to the current segment.
53
+ A committed phase's custody obligations **close with its commit** — the cross-phase churn class
54
+ that forced 4 of BUGFREE-1's 5 overrides is dead (regression-pinned); a receipt never crosses a
55
+ commit boundary, so a cross-segment fold still takes the recorded `red-proof` lane (the stated
56
+ residual).
57
+ - **Gate telemetry (D8)** — `review-ledger --telemetry`: read-only COUNTS across all loops and
58
+ both ledgers (rounds/segments, finding origins, classification distribution incl. `refuted`,
59
+ per-backend verdicts + divergence rounds, override usage by scope, gate-run quality-green and
60
+ red-results-by-gate, fold runs, observed-red receipts, quarantined probes). Counts only —
61
+ which gates earn their keep stays the maintainer's judgment. Never combined with `--check`.
62
+ - Bound-test probes now pass the pattern in the `=`-joined `--test-name-pattern=` form — a test
63
+ name beginning with `-`/`--` no longer parses as a node option and silently selects no test
64
+ (the pattern-half sibling of AD-047's dash-spawn fix; found live by this release's own `--red`
65
+ loop).
66
+ - Surfaces in lockstep: both mode-refs + `gates.md` (the runner's claim is now "writes nothing
67
+ BY DEFAULT"), README rows, catalog one-liners, the procedures advisor (run `run-gates --record`
68
+ BEFORE recording a round; per-segment wording), velocity notes; the surface test pins every
69
+ token.
70
+
71
+ Dogfooded live on its own three-segment execution loop (the AD-047 precedent): the cap fired on
72
+ the plan's own 792-line Phase-1 surface (exact re-sanctions recorded), the quality-green receipt
73
+ was consumed by the D5 tooth at the very first segment-2 round, and segment closure was exercised
74
+ end-to-end at each phase commit.
75
+
76
+ ## 1.38.0 — Honest red→green: observed-red receipts, flaky quarantine, content custody, and the oracle-tamper guard (AD-047)
77
+
78
+ A **feature** release (deployment-lineage head stays `1.3.0` — no migration; engine/memory/bridges
79
+ untouched). AD-046 verified each bound test is resolvable and green — this release closes its one
80
+ named hole: **nothing proved the test ever FAILED before the fix**. A test written green beside the
81
+ fix ("fix theater") passed every shipped check. Now the gate demands the whole honest sequence:
82
+ red observed → fix folded → green observed — with the test's bytes in custody in between.
83
+
84
+ - **Observed-red receipts** — a new runner verb, `fold-completeness-run.mjs --red "<testId>"`,
85
+ observes a test on the REAL pre-fold tree: failing on N/N runs → it mints a receipt (testId,
86
+ rerun counts, the test file's sha-256, fingerprint) into the fold ledger (schema **v2**: records
87
+ carry a kind, `run` | `red-probe`; v1 records stay readable, a v1 record as the loop's latest run
88
+ fails with a re-run reason). Observed-green / unresolvable / mixed / timed-out are DISTINGUISHED
89
+ refusals — nothing is written. A test that cannot even load pre-fold is authored with a dynamic
90
+ `import()` (the refusal says so).
91
+ - **The N/N verdict algebra** — every probe side runs `AW_FOLD_RERUNS` times (default 3): RED and
92
+ GREEN are strict N/N verdicts; anything mixed or timed out is **QUARANTINE** — never converted,
93
+ no override lane (a flaky pin proves nothing — replace the test). Probes gain the kit's first
94
+ spawn timeout (`AW_FOLD_PROBE_TIMEOUT_S`, default 120, per RUN, probes only); both knobs go
95
+ through one fail-closed positive-integer parser.
96
+ - **Content custody** — the gate requires, per bound testId: the receipt, the receipt PRECEDING the
97
+ loop's latest run (a post-hoc red proves nothing), N/N-green probes, and that the green test is
98
+ **byte-identical** to the test seen failing (per-FILE hash custody; appending the next fold's red
99
+ test re-attests its file without ceremony). Probes always spawn the safe resolver's canonical
100
+ absolute path — a leading-dash or OS-resolved traversal path would execute a different file than
101
+ the hashed one.
102
+ - **Oracle-tamper guard + recorded overrides** — the runner records a tamper surface over the
103
+ tracked diff (test-classified paths + bound-testId file halves at HEAD, by hunk old-side
104
+ polarity; pure additions and new test files never trip it; parsing is config/platform-proof).
105
+ The gate fails closed on a tampered file without a recorded **`oracle-change`** override; a
106
+ **`red-proof`** override waives receipt+custody for exactly one testId (the loud escape for a
107
+ genuinely unestablishable red). Overrides are a new review-ledger record kind (schema **v3**;
108
+ v1/v2 records stay valid; exact per-scope payloads), written only by
109
+ `review-ledger-write override --json '…'` with the standard teeth plus a strict
110
+ single-in-flight-loop rule. **Never silent: every waiver is a durable, auditable ledger entry.**
111
+ - **Honest limits (stated):** insertion-only weakening inside a pre-existing test body,
112
+ expectation artifacts outside test files (snapshots/goldens), and weakening an already-green
113
+ test behind a newer same-file receipt (characterization-pinned) remain in the stated
114
+ self-discipline residual class; ledgers stay forgeable — this is a self-discipline mechanism,
115
+ not a security boundary. No mutation testing ships (still shelved); the checker still fails
116
+ closed on any mutation data.
117
+ - Dogfooded live on its own development loop: ten pre-fix receipts, six council-found bugs folded
118
+ strictly red→fix→green, and the guard's own refusals caught one premature fix mid-plan.
119
+
7
120
  ## 1.37.1 — Fix: the fold-completeness probe on Node 18/20 counted pattern-filtered SKIP lines as executed tests
8
121
 
9
122
  A **patch** release (one product fix + its pinned fixtures; no other change). On Node 18/20 —
package/README.md CHANGED
@@ -228,7 +228,7 @@ file), or run the guarded `/agent-workflow-kit uninstall`.
228
228
  | `/agent-workflow-kit upgrade` | existing deployment | reads `docs/ai/.workflow-version`, shows the changelog diff, preserves your authored memory, applies migrations, re-stamps — then prints a **read-only** one-line backend-status line (what's set up vs missing); refreshes the already-placed bridges from the kit's bundled copies (never installs a new one — set one up with `/agent-workflow-kit setup`) |
229
229
  | `/agent-workflow-kit help` | any time | **read-only command index** — every command, grouped (Inspect / Configure / Orchestrate / Lifecycle) and tagged read-only / writer / guarded. The discoverable entry point, and where any unrecognized invocation lands (always read-only — a garbage invocation never writes). Never writes, never commits, never runs a subscription CLI. |
230
230
  | `/agent-workflow-kit backends` | any time | **read-only** check of the optional execution-backends (the `codex` / `agy` bridges): what's set up vs missing and the next step. Never writes, never commits, never runs a subscription CLI (credentials = marker-file presence, not a live login). |
231
- | `/agent-workflow-kit gates` | any time | **project gate runner** — runs the verification commands **your project itself declares** in `docs/ai/gates.json` (seeded at deploy; hand-editable `{ id, title, cmd }` entries, each `cmd` one bash line) as one batch: a per-gate **PASS/FAIL table** + one machine-readable summary line, exit 0 iff all green; a failing gate's own output is shown verbatim; `--only <id>` re-runs one. Honest distinct outcomes for a missing / empty / malformed declaration — never a silent green. The runner writes nothing and never commits; it executes only your own declared commands (a batching convenience, not a sandbox). |
231
+ | `/agent-workflow-kit gates` | any time | **project gate runner** — runs the verification commands **your project itself declares** in `docs/ai/gates.json` (seeded at deploy; hand-editable `{ id, title, cmd }` entries, each `cmd` one bash line) as one batch: a per-gate **PASS/FAIL table** + one machine-readable summary line, exit 0 iff all green; a failing gate's own output is shown verbatim; `--only <id>` re-runs one. Honest distinct outcomes for a missing / empty / malformed declaration — never a silent green. The runner writes nothing **by default** and never commits — opt-in `--record` mints ONE `gate-run` record into the review ledger **via the ledger's sole writer** (the segment's green-baseline receipt: full declaration + what ran + pre/post tree fingerprints; a red run records honestly; a failed record is its own loud exit 7); it executes only your own declared commands (a batching convenience, not a sandbox). The velocity tier auto-approves only the exact no-`--record` form — the recording run stays explicit. |
232
232
  | `/agent-workflow-kit setup [backend]` | opt-in, any time | **link-only** auto-setup of a bridge: places the bundled bridge skill (only into an absent / empty / managed dir — never overwrites an unmanaged one) + links its wrappers onto `PATH` via managed symlinks (idempotent; refuses to clobber a non-symlink; try `--dry-run` to preview). The binary install + the one-time subscription login stay **manual**: it prints the exact **login** command and points the binary install at each bridge's `setup/README.md`. POSIX wrappers — on Windows use WSL. Never commits, never runs a subscription CLI. |
233
233
  | `/agent-workflow-kit status` | any time | **read-only** single view of **versions + deployment + settings + bridges**: which members (kit / memory / engine / the two bridges) are installed and at what version (with an honest "installed on this machine" note when one is behind) and — in a project — what's deployed (`docs/ai`, the version stamps, and the **visibility**: visible / hidden / unclear), plus your settings (orchestration recipes, attribution, velocity) and the bridges' readiness. The two version axes (package number vs deployment-structure head) stay decoupled. Never writes, never commits, never runs a subscription CLI. |
234
234
  | `/agent-workflow-kit recipes` | any time | **read-only** orchestration advisor: presents four named recipes for composing the bridges into plan → execute → review — **Solo / Reviewed / Council / Delegated** — plans + recommends one for your environment (degrading with a stated reason when a backend isn't ready), and offers the choice. The orchestrator runs it via the bridge skills and **always commits**; the kit never executes a recipe, never runs a subscription CLI, never commits. |
@@ -236,8 +236,8 @@ file), or run the guarded `/agent-workflow-kit uninstall`.
236
236
  | `/agent-workflow-kit set-recipe` | any time | **config writer** for `docs/ai/orchestration.json`: tell the agent your preference in plain language and it maps it to explicit `--set <activity>.<slot>=<recipe>` / `--unset` ops; the kit validates, **previews by default**, and writes only on `--write` (deployment-gated, atomic, symlink/TOCTOU-safe), resolving the effective recipe vs live readiness. Writes **only** that file — **never runs a backend, never commits**; hand-editing stays fully supported. |
237
237
  | `/agent-workflow-kit review-state` | any time | **read-only review-receipt checker** — makes "reviewed ≠ shipped" detectable: the bridge review wrappers append a receipt per successful review (into a file inside the git dir — never committable); this checks that every backend your configured `plan-execution.review` recipe names holds a **fresh, grounded receipt for the current uncommitted tree** (any later edit moves the fingerprint and stales the receipt; a review continuation never re-attests a folded tree). `--check` gives a gate exit code to declare in `docs/ai/gates.json` **by hand or via the consent-gated seeder** (preview → your explicit yes; never without consent). Never writes, never commits, never runs a subscription CLI; it spawns read-only `git` queries to fingerprint the tree — and `git commit --no-verify` stays possible (discipline, not a sandbox). |
238
238
  | `/agent-workflow-kit grounding` | any time | **grounded-review facts assembler** — mechanizes populating `agy-review --facts @f`: slices your entry-point's **Hard Constraints** section verbatim (exactly one match, else a loud stop) and/or a plan's decision-bearing sections (`## Approach` + `## Verification` required, `## Decisions (locked)` when present; duplicates stop), under the same byte budget the agy wrapper enforces (minus `--reserve-bytes` for the artifact share), with a loud tail-trim on overflow. Prints to stdout; `--out` writes **one scratch file only** (gitignored / outside the repo — a tracked or not-ignored in-repo path is refused). Never commits, never runs a subscription CLI. |
239
- | `/agent-workflow-kit review-ledger` | any time | **review-round ledger** — turns the review-loop stop rule into a **computed** signal: record each plan-execution review round + its triage into a JSONL ledger inside the git dir (never committable), and read the stop decision (`converged > resolved-residual > triage-required > continue`) from the records — never from a remembered rule. `--status` replaces the hand-composed per-round tally; `--check` is a fail-closed gate exit code for `docs/ai/gates.json` (by hand or via the consent-gated seeder). A `fixable-bug` triage **requires its red→green `testId`** (schema v2; older records stay valid on read). The writer refuses a round past the hard-max, while a triage is pending, or without a grounded review receipt. Honest residual: records are forgeable — self-discipline, not a security boundary. Never commits, never runs a subscription CLI. |
240
- | `/agent-workflow-kit fold-completeness` | any time | **fold-completeness gate** — attests the review loop's folded fixes against the changed code: the runner executes your suite ONCE under `NODE_V8_COVERAGE`, checks every changed executable line is **executed** and every bound `testId` resolves + starts GREEN, and appends one result record bound to BOTH the tree fingerprint AND the sorted testId set (either moving stales it re-run after the last edit); the separate read-only checker (`--status` / `--check`) turns the record into a fail-closed gate. Honest residuals: coverage proves **execution, not assertion** (the per-fold proof stays the red→green `testId` discipline), and records are forgeable — self-discipline, not a security boundary. v1 scope is JS/V8: changed TS/JSX fails closed, docs/config changes are listed but never block, and **no mutation testing ships**. Wire the gate by hand — the consent-gated seeder deliberately does not offer it yet (JS-only hold). Never commits, never runs a subscription CLI. |
239
+ | `/agent-workflow-kit review-ledger` | any time | **review-round ledger** — turns the review-loop stop rule into a **computed** signal: record each plan-execution review round, its triage, and any recorded **overrides** (`oracle-change` lifts named tampered test files; `red-proof` waives the observed-red proof for exactly one `testId`; v4 adds **`size-cap`** — the exact sanctioned magnitude for a surface over the diff cap, segment-scoped — all loud, durable, auditable waivers, never silent) into a JSONL ledger inside the git dir (never committable), and read the stop decision (`converged > resolved-residual > triage-required > continue`) from the records — never from a remembered rule. **Since v4 every record carries `base` = the HEAD commit and the whole loop is SEGMENT-scoped (AD-048):** round numbering, the caps, and every tooth reset ONLY at a gated commit — a multiphase plan records fully while round 4 within one segment stays refused; `gate-run` records (minted by `gates --record`) make gates-before-review a computed precondition; the triage class **`refuted`** is the honest phantom-finding lane (grounds mandatory); `--telemetry` renders counts-only gate-efficacy data across all loops and both ledgers. `--status` replaces the hand-composed per-round tally; `--check` is a fail-closed gate exit code for `docs/ai/gates.json` (by hand or via the consent-gated seeder). A `fixable-bug` triage **requires its red→green `testId`** (v1..v3 records stay valid on read — old records never enter a segment). The writer refuses a round (past the hard-max, while a triage is pending, or lacking a grounded review receipt) and refuses an override outside its single in-flight loop. Honest residual: records are forgeable — self-discipline, not a security boundary. Never commits, never runs a subscription CLI. |
240
+ | `/agent-workflow-kit fold-completeness` | any time | **fold-completeness gate** — attests the review loop's folded fixes were proven the HONEST way (no fix theater): the runner executes your suite ONCE under `NODE_V8_COVERAGE`, checks every changed executable line is **executed**, probes every bound `testId` N times (`AW_FOLD_RERUNS`), records content hashes, and scans the test surface for tamper; the `--red` verb observes a test FAILING on the pre-fold tree **BEFORE the fix**and mints an **observed-red receipt**. The read-only checker (`--status` / `--check`) then requires, per bound test: the receipt, receipt-precedes-run order, N/N-green probes, and content **custody** (the green test is byte-identical to the one seen failing) — the receipt+custody half waivable for exactly one `testId` by a recorded `red-proof` override; mixed/timed-out probes are QUARANTINE (never converted, no override); **v3 records carry `base` and the proof is segment-scoped (AD-048)** — a committed phase's custody obligations close with its commit, and a receipt never crosses a commit boundary; tampered pre-existing test files fail closed unless covered by a recorded `oracle-change` override. Honest residuals: coverage proves **execution, not assertion**, and records are forgeable — self-discipline, not a security boundary. v1 scope is JS/V8 (pluggable via `AW_FOLD_BOUND_CMD`): changed TS/JSX fails closed, docs/config changes are listed but never block, and **no mutation testing ships**. Wire the gate by hand — the consent-gated seeder deliberately does not offer it yet (JS-only hold). Never commits, never runs a subscription CLI. |
241
241
  | `/agent-workflow-kit uninstall` | opt-in, any time | **guarded teardown** — the inverse of `init` / `setup`. Removes only what's **provably ours** (managed skill dirs + bridge wrappers; in a project, the hidden-mode git-ignore block it added + the pre-commit hook it installed); **never deletes** your `docs/ai` / `AGENTS.md` (prints the exact `rm` to run by hand) or your `.claude/settings.json` (prints an **edit** — remove the attribution key, review any velocity `permissions.*` — never an `rm`). Always `--dry-run` first; preflight-then-mutate; never commits. |
242
242
  | `/agent-workflow-kit velocity` | Claude Code · opt-in | **onboarding velocity profile** — seeds a fixed, audited **read-only** allowlist into `.claude/settings.json` so routine read-only commands stop idling on approval prompts while you're away; opt-in `acceptEdits`; plus a **read-only advisory** of likely project gate commands to add by hand. Writes **only** `.claude/settings.json` — **never** allowlists commit/push/publish, never writes `settings.local.json`, never commits. A seeded entry is a **trust posture, not a sandbox** (a runtime residual remains at the settings level — its guard ships as the opt-in `hook` command); a direct commit/push/publish still asks. `--dry-run` first. |
243
243
  | `/agent-workflow-kit agents` | Claude Code · opt-in | **cheap-lane subagents** — places bundled subagent definitions (`.claude/agents/`) pinned to a **cheap model** (haiku, low effort, read-only tools) for mechanical work: extraction sweeps, changelog fact-skeletons, gate-failure triage. Judgment, review, and real code stay on your main lane — these vehicles only extract and draft, and their output is verified. Preview by default (`--apply` writes); an existing customized file is **preserved, never overwritten**; never touches `settings*.json`, never commits. |
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: agent-workflow-kit
3
3
  description: Deploy or upgrade a portable AI-agent memory-and-workflow system in any project. Use when the user wants to bootstrap `docs/ai/` + an entry-point `AGENTS.md` (+ `CLAUDE.md` alias) + cap/archive/index enforcement in a new or existing repo, set up the Memory Map and session protocols, install the docs-rotation pre-commit hook, or run `/agent-workflow-kit` / `/agent-workflow-kit upgrade`. Triggers on phrases like "set up the memory system", "deploy the AI workflow here", "bootstrap docs/ai", "upgrade the workflow".
4
4
  disable-model-invocation: true
5
5
  metadata:
6
- version: '1.37.1'
6
+ version: '1.39.0'
7
7
  ---
8
8
 
9
9
  # agent-workflow-kit
package/capability.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "schema": 1,
4
4
  "name": "agent-workflow-kit",
5
5
  "kind": "composition-root",
6
- "version": "1.37.1",
6
+ "version": "1.39.0",
7
7
  "provides": [],
8
8
  "roles": {},
9
9
  "detect": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sabaiway/agent-workflow-kit",
3
- "version": "1.37.1",
3
+ "version": "1.39.0",
4
4
  "description": "Portable, cross-agent memory & workflow for AI coding agents — Claude Code, Codex, Cursor, Devin Desktop. One command deploys an AGENTS.md entry point + docs/ai context with cap/archive/index enforcement into any repo.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -1,11 +1,15 @@
1
1
  ### Mode: fold-completeness
2
2
 
3
- The FOLD-COMPLETENESS gate (M3a / AD-046, DEBT-TEST-COMPLETENESS) — the sibling of the review-round ledger: the ledger computes WHEN the plan-execution review loop stops; this tool pair verifies that the tests the loop's folds bind to ACTUALLY pin the changed code. One recorded coverage run proves (a) every changed executable line is executed by the suite and (b) every `fixable-bug` bound testId resolves and starts GREEN; a read-only checker turns the recorded result into a gate exit code.
3
+ The FOLD-COMPLETENESS gate (M3a / AD-046, honest red→green BUGFREE-1 / AD-047) — the sibling of the review-round ledger: the ledger computes WHEN the plan-execution review loop stops; this tool pair verifies that the tests the loop's folds bind to ACTUALLY pin the changed code, and that each bound test was SEEN FAILING before its fix (no fix theater). One recorded run proves (a) every changed executable line is executed by the suite and (b) every `fixable-bug` bound testId is N/N green with an observed-red receipt behind it; a read-only checker turns the recorded evidence into a gate exit code. **Since schema v3 (BUGFREE-2 / AD-048, D7) every record carries `base` and the whole proof is SEGMENT-scoped** — bound testIds, receipts, custody chains, and tamper obligations all filter to (loop, `base` = the current HEAD): a committed phase's custody obligations **close with its commit** (editing a custody file in a LATER segment no longer re-demands the closed segment's proof — the cross-phase churn class is dead), while a fold whose red was observed in a PREVIOUS segment still needs the `red-proof` lane (a receipt never crosses a commit boundary — the stated residual). Pre-v3 records never enter a segment; a dirty loop holding only pre-v3 records fails with a reason naming the schema upgrade.
4
+
5
+ **The fold-time order (the operational contract — red is observed BEFORE the fix):** classify the fixable-bug with its testId → write the failing test → `--red "<testId>"` observes it FAIL on the real pre-fold tree and mints the receipt → fold the fix → the normal run observes green → `--check`. Folding first is not recoverable without reverting the fix to re-observe red — observe red when it actually happens.
4
6
 
5
7
  **Two tools — the read/run split:**
6
8
 
7
- 1. **Runner** — `node ${CLAUDE_SKILL_DIR}/tools/fold-completeness-run.mjs [--suite "<cmd>"] [--cwd <dir>]` — the SOLE tree-toucher and the SOLE result writer. One run over the in-flight plan-execution loop's dirty tree: resolve the loop (the single in-flight plan stem — 0 or >1 plans is a typed refusal), classify the changed surface by a CLOSED extension rule (assessable JS / unsupported TS-JSX / out-of-domain), run the suite ONCE under `NODE_V8_COVERAGE` (the coverage dir lives OUTSIDE the work tree — no repo artifacts), map every changed executable line to covered/uncovered from the V8 report itself, probe each bound testId once (shell-free spawn) for resolvability + a green baseline, and append ONE machine-only record — bound to BOTH the tree fingerprint AND the sorted `fixable-bug` testId set — to `<git dir>/agent-workflow-fold-completeness.jsonl` (never committable by construction; `AW_FOLD_RESULTS` overrides).
8
- 2. **Read-only checker** — `node ${CLAUDE_SKILL_DIR}/tools/fold-completeness.mjs [--check | --status | --json]` — never runs tests, never touches the tree, never imports the runner (an import-split test pins the structural split). `--status` (default) is the human report; **`--check` is the gate exit code — the normative exit contract lives in the CHECKER's tool header (the single home — do not re-enumerate it elsewhere)**; `--json` is the structured state + decision.
9
+ 1. **Runner** — `node ${CLAUDE_SKILL_DIR}/tools/fold-completeness-run.mjs [--suite "<cmd>"] [--cwd <dir>]`, plus the red verb `--red "<test-file>#<test-name-pattern>"` — the SOLE tree-toucher and the SOLE result writer. The default run, over the in-flight plan-execution loop's dirty tree: resolve the loop (the single in-flight plan stem — 0 or >1 plans is a typed refusal), classify the changed surface by a CLOSED extension rule (assessable JS / unsupported TS-JSX / out-of-domain), run the suite ONCE under `NODE_V8_COVERAGE` (the coverage dir lives OUTSIDE the work tree — no repo artifacts), map every changed executable line to covered/uncovered from the V8 report itself, probe each bound testId N times (`AW_FOLD_RERUNS`, default 3; a shell-free spawn of the resolver's canonical path; each run under its own per-run `AW_FOLD_PROBE_TIMEOUT_S`, default 120 — probes only, never the suite) recording rerun counts + the test file's content hash (custody), and append ONE machine-only v3 run record — segment-framed (`base`) and bound to BOTH the tree fingerprint AND the segment's sorted `fixable-bug` testId set — to `<git dir>/agent-workflow-fold-completeness.jsonl` (never committable by construction; `AW_FOLD_RESULTS` overrides). **`--red` observes a testId on the CURRENT (pre-fold) tree**: failing on N/N runs → it appends the observed-red receipt (testId, counts, content hash, fingerprint); observed-green / unresolvable / mixed / timed-out are DISTINGUISHED typed refusals and nothing is written. The verdict algebra is strict N/N: RED = N/N fail, GREEN = N/N pass, anything mixed or timed out is **QUARANTINE** — it never converts and has NO override lane (a flaky pin proves nothing — replace the test). A test that cannot even LOAD pre-fold (it imports an export the fix introduces) is authored with a dynamic `import()` so it loads and fails pre-fold.
10
+ 2. **Read-only checker** — `node ${CLAUDE_SKILL_DIR}/tools/fold-completeness.mjs [--check | --status | --json]` — never runs tests, never touches the tree, never imports the runner (an import-split test pins the structural split). Per bound testId (of the CURRENT segment) the gate requires: an N/N-green probe, an observed-red receipt in this segment, that receipt PRECEDING the loop's latest run in ledger order (a post-hoc red proves nothing — a late receipt forces one fresh run), and content **custody** — the run's recorded test-file hash equals the latest custody-eligible receipt hash on that file (eligible = the receipt's own testId is bound AND it precedes the run), so the test that is green now is byte-identical to a test that provably failed; any edit after the receipt requires re-observing red, and appending the NEXT fold's red test to the same file re-attests it without ceremony. `--status` (default) is the human report; **`--check` is the gate exit code — the normative exit contract lives in the CHECKER's tool header (the single home — do not re-enumerate it elsewhere)**; `--json` is the structured state + decision.
11
+
12
+ **The oracle-tamper guard + the recorded override lanes (review-ledger schema v3).** The runner also records a **tamper surface** over the tracked working-vs-HEAD diff — the union of test-classified paths and the bound-testId file halves, restricted to files existing at HEAD — classified by hunk line polarity: any removed/modified line (or a deleted file) is TAMPER; pure additions and brand-new test files never trip it. Note two edges: a **rename** reads as delete+add under the pinned `--no-renames` diff, so renaming a test file trips the guard (record the override or split the rename from the fix); and a run record written by a **pre-tamper runner** (no recorded surface) fails the gate with a re-run reason — after an upgrade, one fresh run refreshes the evidence. The gate fails closed on any tampered file not named by a recorded **`oracle-change`** override (`review-ledger-write override --json '{"loop":…,"round":…,"scope":"oracle-change","files":[…],"reason":…}'` — a durable, auditable ledger entry, never a silent waiver; one override covers the named files for the rest of the loop). The second lane, scope **`red-proof`**, names ONE testId whose red is genuinely unestablishable pre-fold (or whose custody file was legitimately edited post-fix) and waives the receipt + custody proof for exactly that testId — never the N/N-green requirement, never QUARANTINE. Overrides are loop + payload scoped, minted only inside the single in-flight loop.
9
13
 
10
14
  **Wire the gate BY HAND, once, BEFORE the round's runner run.** The candidate line for your own `docs/ai/gates.json`: `{ "id": "fold-completeness", "title": "Fold-completeness — every changed executable line executed by tests (M3a)", "cmd": "node \"<path-to-this-skill>/tools/fold-completeness.mjs\" --check" }` — the path your project reaches the kit by, kept inside the escaped quotes so a path with spaces survives. Wiring comes FIRST because where `docs/ai` is tracked, the gate-file edit itself moves the tree fingerprint — wiring after a run stales the record you just wrote. The consent-gated seeder does NOT offer this entry yet — a deliberate v1 hold: the signal is JS/V8-only, and offering it to a project whose source the runner cannot assess would seed a gate that can only fail closed; seeder offering arrives with a language-aware verification profile.
11
15
 
@@ -1,8 +1,8 @@
1
1
  ### Mode: gates
2
2
 
3
- The **generic project gate runner** — it batches the project's OWN declared verification commands into one run. The runner itself **writes nothing, never commits, and never runs a subscription CLI**; what it EXECUTES is the project's own declaration, with the caller's privileges (trust posture: a batching convenience over commands the project already runs by hand — **not a sandbox**).
3
+ The **generic project gate runner** — it batches the project's OWN declared verification commands into one run. The runner itself **writes nothing by default, never commits, and never runs a subscription CLI** — opt-in **`--record`** (BUGFREE-2 / AD-048) mints ONE `gate-run` record into the review ledger **via the ledger's sole writer** (`recordGateRun`; the runner never opens the ledger itself): the D5 green-baseline receipt — the FULL declaration + exactly what ran (a `--only` subset records honestly as a subset) + the tree fingerprint before/after the run; a red run records honestly; a failed record is its own loud exit 7, and it needs a single in-flight plan; what it EXECUTES is the project's own declaration, with the caller's privileges (trust posture: a batching convenience over commands the project already runs by hand — **not a sandbox**).
4
4
 
5
- Run `node ${CLAUDE_SKILL_DIR}/tools/run-gates.mjs [--cwd <project>] [--only <id>]…`:
5
+ Run `node ${CLAUDE_SKILL_DIR}/tools/run-gates.mjs [--cwd <project>] [--only <id>]… [--record]`:
6
6
 
7
7
  1. **Reads `docs/ai/gates.json`** (strict JSON, hand-editable; seeded from `references/templates/gates.json`). Each gate is `{ id, title, cmd }` — `id` a unique kebab handle, `cmd` **ONE bash command line** (brace/glob expansion works; a host without bash gets a loud preflight error, exit 6 — never a silent reinterpretation under another shell). The declaration names **WHAT to check, never who executes it** — the schema has no lane/model/routing fields and rejects unknown keys loudly.
8
8
  2. **Runs each gate from the project root** and prints a per-gate **PASS/FAIL table** plus **one machine-readable summary line** as the last line (`[run-gates] status=… gates=… passed=… failed=… failed_ids=…`). A failing gate's own output is preserved **verbatim** (triage without re-running); a green gate's output is not echoed; gates after a failure still run. **Exit 0 iff all selected gates are green.**
@@ -10,10 +10,12 @@ Run `node ${CLAUDE_SKILL_DIR}/tools/run-gates.mjs [--cwd <project>] [--only <id>
10
10
 
11
11
  The declaration is **seeded at bootstrap** (the template loop, `${CLAUDE_SKILL_DIR}/references/modes/bootstrap.md` step 6) and **ensured-if-missing on upgrade** from THIS kit's own template twin (`${CLAUDE_SKILL_DIR}/references/modes/upgrade.md` step 3) — independent of the installed memory substrate's age; an existing file is always **preserved byte-for-byte**. It is deliberately **not** a delegation-required memory asset: gates are optional, and absence is an honest runner outcome, not a deployment failure.
12
12
 
13
+ **The velocity `--kit-tools` tier auto-approves ONLY the exact no-`--record` invocation** (AD-040/AD-048): `--record` is a ledger WRITE and stays an explicit, prompted run — never seeded into an allowlist.
14
+
13
15
  Declared gates can also be **auto-approved** (no permission prompt on a byte-exact invocation from the project root) via the opt-in PreToolUse hook — `${CLAUDE_SKILL_DIR}/references/modes/hook.md`: the SAME declaration, a second consumer; editing gates.json needs no re-wiring.
14
16
 
15
17
  **Candidate line — the review-receipt gate (opt-in, never auto-seeded; AD-021).** Projects that configure a reviewed/council `plan-execution.review` recipe can declare the AD-038 review-state check as one more gate — the exact candidate `{ id, title, cmd }` line and its contract live under `${CLAUDE_SKILL_DIR}/references/modes/review-state.md` (step 3). The template `gates.json` stays EMPTY; adding the line is the maintainer's explicit consent — by hand, or through the consent-gated seeder below (AD-042).
16
18
 
17
19
  **Consent-gated seeding — a separate WRITER CLI, not part of the runner (AD-042).** Bootstrap recon already records the project's own daily commands; the seeder turns them into a preview of `{ id, title, cmd }` entries. Protocol: run `node ${CLAUDE_SKILL_DIR}/tools/seed-gates.mjs --cwd <project>` (dry-run by default — prints the derived entries and **writes NOTHING**; declining leaves the file byte-identical), show the user the EXACT entries (`AskUserQuestion` preview where supported, prose otherwise), and only on an explicit yes run it again with `--apply [--only <id>]…` — it **appends exactly the consented entries** (append-only: existing entries are never modified or removed; an id collision is refused loudly; a malformed declaration is never written over). Only terminating verification commands are offered (test / lint / type-check / build — never dev/watch/serve, never a formatter write-mode, never a release/publish/deploy script), commands are package-manager-aware, and the review-state candidate above is included automatically when the project's orchestration config declares reviewed/council on `plan-execution.review`. **Disclose before the yes** (the preview prints it): once the approval hook is wired, it auto-approves byte-exact declared gate commands — seeding and hook wiring are two separate consents.
18
20
 
19
- **Invariants:** the runner writes nothing · never commits · never runs a subscription CLI · executes only the project's OWN declared commands (never a kit-invented one) · the bash contract fails loud, never reinterprets · the seeder is a separate consent-per-run CLI — preview-first, append-only, never pre-approved by any velocity tier.
21
+ **Invariants:** the runner writes nothing by default (`--record` delegates its ONE ledger write to the review-ledger sole writer, `recordGateRun` — the runner itself never opens the ledger) · never commits · never runs a subscription CLI · executes only the project's OWN declared commands (never a kit-invented one) · the bash contract fails loud, never reinterprets · the seeder is a separate consent-per-run CLI — preview-first, append-only, never pre-approved by any velocity tier.
@@ -2,26 +2,31 @@
2
2
 
3
3
  The review-round **LEDGER** (DEBT-REVIEW-CAP / AD-045) — it turns the prose review-loop crossover-stop (`planning.md` §9 "cap ≤2 / crossover-stop / fold-at-altitude"; `procedures.md` "{round N · finding-origin tally · per-backend verdict} … computed signal, not a remembered rule") into a **COMPUTED** signal. The orchestrator records **one round per review round** to a JSONL ledger **inside the git dir** (`<git dir>/agent-workflow-review-ledger.jsonl` — never committable by construction; `AW_REVIEW_LEDGER` overrides), and a read-only checker computes the stop decision from the recorded rounds + triage classifications, never from a remembered rule. It is the read-only sibling of `review-state` (presence vs convergence are distinct axes) — the read module **never imports the writer** (an import-split test pins it).
4
4
 
5
+ **The SEGMENT (schema v4, BUGFREE-2 / AD-048).** Every v4 record carries `base` = the commit the dirty tree sits on (`git rev-parse HEAD`; `null` on an unborn branch). A **segment** = (activity, loop, base) — the review loop's real domain, the uncommitted change set over one base commit. **Round numbering (1..n), the review cap, the hard-max ceiling, every writer tooth, and `--check` all operate per segment**; the loop id (the plan stem) is unchanged — a plan is a sequence of segments. A segment closes ONLY through a gated commit (the gate matrix admits a commit only from a converged/resolved segment), so a round-counter reset is **earned, never declared**; an amend/rebase mid-loop orphans the segment's rounds — correct, the reviewed tree no longer exists. Pre-v4 records never enter a segment (readable history; the checker's failure reason names the schema upgrade when only old records exist).
6
+
5
7
  **Two tools — the read/write split (Decision 3):**
6
8
 
7
9
  1. **Read-only checker** — `node ${CLAUDE_SKILL_DIR}/tools/review-ledger.mjs [--check | --status | --json]`:
8
- - `--status` (default) → the human report: resolved `plan-execution.review` recipe, plan-in-flight, per-round tally with `findings[]`, per-backend counts + verdict, the `decideStop` verdict. **This printed render REPLACES the remembered per-round `{round N · finding-origin tally · per-backend verdict}` emission** — run it each round instead of composing the tally by hand.
9
- - **`--check`** → the gate exit code. The **normative exit contract lives in the tool header** (the single home — do not re-enumerate it). It enforces the **plan-execution (code) loop** (the loop that produces the committable artifact), filtered to `activity==="plan-execution"` AND the in-flight plan's filename stem: exit 0 for solo / no plan in flight / a clean tree / a non-git cwd / a `converged` or `resolved-residual` loop; exit 1 for a dirty non-converged loop (`triage-required`, `continue`, or **no round/receipt recorded at all** — a dirty active plan with an empty/stale ledger is a FAILURE, not a fail-open pass), more than one plan in flight (ambiguous loop id), a recorded 0/0 coexisting with a non-ship receipt verdict, or a non-degraded recorded backend missing its receipt. **Fail-CLOSED** on a detector failure — the only detector-independent green is an EXPLICIT configured solo.
10
+ - `--status` (default) → the human report: resolved `plan-execution.review` recipe, plan-in-flight, per-round tally with `findings[]` **grouped by segment** (the current segment marked), per-backend counts + verdict, gate-run postures, the `decideStop` verdict. **This printed render REPLACES the remembered per-round `{round N · finding-origin tally · per-backend verdict}` emission** — run it each round instead of composing the tally by hand.
11
+ - **`--check`** → the gate exit code. The **normative exit contract lives in the tool header** (the single home — do not re-enumerate it). It enforces the **plan-execution (code) loop** (the loop that produces the committable artifact), filtered to the current SEGMENT — `activity==="plan-execution"` AND the in-flight plan's filename stem AND `base===git rev-parse HEAD`: exit 0 for solo / no plan in flight / a clean tree / a non-git cwd / a `converged` or `resolved-residual` loop; exit 1 for a dirty non-converged loop (`triage-required`, `continue`, or **no round/receipt recorded at all** — a dirty active plan with an empty/stale ledger is a FAILURE, not a fail-open pass), more than one plan in flight (ambiguous loop id), a recorded 0/0 coexisting with a non-ship receipt verdict, or a non-degraded recorded backend missing its receipt. **Fail-CLOSED** on a detector failure — the only detector-independent green is an EXPLICIT configured solo.
10
12
  - `--json` → the structured state + decision.
13
+ - **`--telemetry`** → read-only COUNTS across ALL loops and BOTH ledgers (never combined with the other flags — a mixed-mode gate cmd would silently pass): rounds/segments per loop, finding-origin totals, classification distribution (incl. `refuted`), per-backend verdict + divergence-round counts, override usage by scope, gate-run counts (quality-green / red results by gate id), fold runs, observed-red receipts, quarantined probes. Counts only — which gates earn their keep stays the maintainer's judgment.
11
14
 
12
- 2. **Writer** — `node ${CLAUDE_SKILL_DIR}/tools/review-ledger-write.mjs record|classify --json '<payload>'` (the SOLE writer, over the shared `atomic-write` core):
13
- - `record` appends one round — `{ loop, round, origins, backends, findings }` (activity defaults to `plan-execution`). **The teeth (Decision 5):** it REFUSES (typed STOP) to append a round WHILE `decideStop` on the existing records is `triage-required` (an UNCLASSIFIED surviving blocking finding at/after the cap), and refuses ANY round beyond the **hard-max ceiling of 3** unconditionally. **Integrity binding (Decision 7):** each NON-degraded backend needs a grounded **code** receipt (from `codex-review code` / `agy-review code --facts @f`) for the current tree — a round cannot be recorded for a tree no bridge reviewed.
14
- - `classify` appends one triage — each surviving blocking finding classified `fixable-bug` / `inherent-layer-residual` / `escalate`. **A `fixable-bug` REQUIRES a `testId`** (M2/AD-046, schema v2) — the red→green test that pins the fold, formatted `<test-file>#<test-name-pattern>` (a `#` separator, both halves non-empty; no file-suffix rule); `inherent-layer-residual` / `escalate` may omit it. The writer validates the FORMAT only. **This is what BREAKS the deadlock:** once every surviving blocking finding is classified, `record` permits the next round (a `fixable-bug` classification lets the fix round run — no deadlock).
15
+ 2. **Writer** — `node ${CLAUDE_SKILL_DIR}/tools/review-ledger-write.mjs record|classify|override --json '<payload>'` (the SOLE writer, over the shared `atomic-write` core):
16
+ - `record` appends one round — `{ loop, round, origins, backends, findings }` (activity defaults to `plan-execution`). **The teeth (Decision 5 + AD-048, all per SEGMENT):** it REFUSES (typed STOP) to append a round WHILE `decideStop` on the segment's records is `triage-required` (an UNCLASSIFIED surviving blocking finding at/after the cap); refuses ANY round beyond the **hard-max ceiling of 3 within one segment** unconditionally (the counter reopens only at the next gated commit); refuses while a blocking finding of the segment's previous round **VANISHED unclassified** (present means present-as-blocking — a downgrade to minor does not survive; a pending `escalate` never clears; `refuted` is the honest phantom lane); refuses while the changed source surface exceeds the **diff-size cap** (`AW_REVIEW_DIFF_CAP`, default 400 new-side lines of assessable + unsupported SOURCE — tests and out-of-domain never count, pure deletions are free) without a recorded segment `size-cap` override; and refuses without a **quality-green gate-run** at the current fingerprint (`run-gates --record` — gates-before-review is computed, not remembered; a `--only` subset or a tree-changed run never satisfies; red PROCESS gates — the kit's own `--check` loop gates — never block). **Integrity binding (Decision 7):** each NON-degraded backend needs a grounded **code** receipt (from `codex-review code` / `agy-review code --facts @f`) for the current tree — a round cannot be recorded for a tree no bridge reviewed.
17
+ - `classify` appends one triage — each surviving blocking finding of a SEGMENT round classified `fixable-bug` / `inherent-layer-residual` / `escalate` / **`refuted`** (v4 — the honest lane for a phantom finding, refuted against code: a MANDATORY non-empty `note` cites the grounds; never silently dropped, never folded). **A `fixable-bug` REQUIRES a `testId`** (M2/AD-046, schema v2) — the red→green test that pins the fold, formatted `<test-file>#<test-name-pattern>` (a `#` separator, both halves non-empty; no file-suffix rule); `inherent-layer-residual` / `escalate` may omit it. The writer validates the FORMAT only. **This is what BREAKS the deadlock:** once every surviving blocking finding is classified, `record` permits the next round (a `fixable-bug` classification lets the fix round run — no deadlock).
18
+ - `override` appends one override record (schema v3, BUGFREE-1/AD-047) — the LOUD, durable waiver the **fold-completeness** gate consumes, `{ loop, round, scope, reason }` plus the per-scope payload (EXACT — a stray key is refused): scope **`oracle-change`** → `files[]`, the repo-relative pre-existing test files whose tamper flag it lifts (a fix diff that deliberately rewrote test expectations); scope **`red-proof`** → `testId`, the ONE bound test whose observed-red receipt + custody it waives (a red genuinely unestablishable pre-fold, or a custody file legitimately edited post-fix); scope **`size-cap`** (v4) → `sanctionedLines`, the EXACT changed-surface magnitude the waiver sanctions — **segment-scoped** (it dies at the next commit; a grown surface needs a fresh recorded sanction). Teeth: schema validation, fail-closed ledger read, round-sequence integrity, and the loop must be the SINGLE in-flight plan. QUARANTINE (a flaky/timed-out probe) has NO override lane. Overrides never enter `decideStop` — the two v3 scopes are fold-completeness inputs; `size-cap` is a writer-tooth input.
19
+ - **`gate-run` records (v4, kind `gate-run`)** are minted by `run-gates --record` through the writer's `recordGateRun` API (the runner never opens the ledger itself) — the D5 green-baseline receipt: the FULL declaration + exactly what ran + the tree fingerprint BEFORE and AFTER the run, segment-framed with NO round number, minted only inside the single in-flight loop. A red run records honestly (telemetry fuel); **quality-green** (every declared NON-process gate green, tree unchanged under the run) is judged at read time. Revert-first beyond this is not mechanically observable at this layer — it ships as protocol + telemetry visibility (consecutive red gate-runs), stated plainly.
15
20
 
16
21
  **The computed stop (`decideStop`, precedence `converged > resolved-residual > triage-required > continue`).** Machine fields only (counts, `class`, `accepted`, `fingerprint`), never free-text:
17
22
  - **converged** — every recipe-named backend present, **non-degraded, at 0 blockers + 0 majors** in the latest round, at the current tree fingerprint. **"Surviving blocking finding" = a blocker OR a major** (a minor never forces triage).
18
- - **resolved-residual** — at/after the cap (or a recurrence auto-trip), every surviving blocking finding classified `inherent-layer-residual` (document + raise to an acceptance criterion → NEVER folded again) OR `escalate` with `accepted:true`, and the triage's own fingerprint equals the current tree (a doc edit after the triage → a fresh round).
23
+ - **resolved-residual** — at/after the cap (or a recurrence auto-trip), every surviving blocking finding classified `inherent-layer-residual` (document + raise to an acceptance criterion → NEVER folded again), **`refuted`** (grounds recorded — without this arm an honestly refuted phantom minted at the hard-max round would wedge the segment), OR `escalate` with `accepted:true`, and the triage's own fingerprint equals the current tree (a doc edit after the triage → a fresh round).
19
24
  - **triage-required** (the writer HARD STOP) — a surviving blocking finding is UNCLASSIFIED at/after the cap, or a blocking finding recurred in ≥2 rounds still unclassified (even under the cap). `fixable-bug` → fold ONCE, re-review; `escalate` needs an accepted maintainer outcome.
20
25
  - **continue** — the catch-all: under the cap, or a classified-but-not-resolved loop (fold the `fixable-bug` / obtain the `escalate` outcome, then a fresh round).
21
26
 
22
27
  **"Every named backend" = "every NON-degraded named backend" (Decision 4).** A backend recorded `degraded:true` (agy is Issue-001-degraded on large diffs) is EXCLUDED from the 0/0 convergence requirement AND from the receipt cross-check (it ran no real review, mints no receipt), but is RECORDED (verdict `degraded`, a required `reason`) — it can never FAKE convergence. A recipe-named backend with NO entry is `missing` (≠ degraded) and BLOCKS convergence. Because the `degraded` mark is self-reported, `--check` surfaces every degraded backend loudly.
23
28
 
24
- **Wire `--check` as a gate by hand OR via the explicit-consent seeder — never without consent.** The candidate line for your own `docs/ai/gates.json`: `{ "id": "review-ledger", "title": "Review-round ledger: the in-flight loop is converged or accepted-residual", "cmd": "node <path-to-this-skill>/tools/review-ledger.mjs --check" }` — the path your project reaches the kit by, QUOTED. The consent-gated seeder offers exactly this entry ONLY when `docs/ai/orchestration.json` declares `reviewed`/`council` on `plan-execution.review`.
29
+ **Wire `--check` as a gate by hand OR via the explicit-consent seeder — never without consent.** The candidate line for your own `docs/ai/gates.json`: `{ "id": "review-ledger", "title": "Review-round ledger: the in-flight loop is converged or resolved-residual", "cmd": "node <path-to-this-skill>/tools/review-ledger.mjs --check" }` — the path your project reaches the kit by, QUOTED. The consent-gated seeder offers exactly this entry ONLY when `docs/ai/orchestration.json` declares `reviewed`/`council` on `plan-execution.review`.
25
30
 
26
31
  **Human residual (stated, accepted — like `review-state`'s):** the ledger attests a review occurred and its ship-class is consistent; it does NOT prove the recorded COUNTS are truthful, nor that a self-reported `degraded:true` is real (`git commit --no-verify`, ledger-file editing, and forged counts remain possible). The ledger lives in the git dir (never committable) — a self-discipline mechanism against silent process drift, not a security boundary.
27
32
 
@@ -23,7 +23,7 @@ Run `node ${CLAUDE_SKILL_DIR}/tools/velocity-profile.mjs [--dry-run | --apply] [
23
23
  - `node ${CLAUDE_SKILL_DIR}/tools/review-state.mjs --check` (wildcard)
24
24
  - `node ${CLAUDE_SKILL_DIR}/tools/manifest/validate.mjs --strict <skill-dir>` (wildcard)
25
25
  - `node ${CLAUDE_SKILL_DIR}/tools/release-scan.mjs <path>` (wildcard)
26
- - `node ${CLAUDE_SKILL_DIR}/tools/run-gates.mjs --cwd ${PROJECT_ROOT}` — **EXACT byte-string only**, and honestly **project-exec, not read-only**: it runs YOUR declared `docs/ai/gates.json` commands — the same trust boundary the opt-in hook grants byte-exact per-cmd. A wildcard would be BROADER than that boundary (`--cwd <dir>` executes another project's declared gates), so the bare cwd-defaulting form, any other `--cwd`, and `--only` forms all still prompt.
26
+ - `node ${CLAUDE_SKILL_DIR}/tools/run-gates.mjs --cwd ${PROJECT_ROOT}` — **EXACT byte-string only**, and honestly **project-exec, not read-only**: it runs YOUR declared `docs/ai/gates.json` commands — the same trust boundary the opt-in hook grants byte-exact per-cmd. A wildcard would be BROADER than that boundary (`--cwd <dir>` executes another project's declared gates), so the bare cwd-defaulting form, any other `--cwd`, `--only`, and **`--record`** forms all still prompt (`--record` WRITES a gate-run record into the review ledger — a recording run is never auto-approved, AD-048).
27
27
  - Writer previews, **exact arg-free dry-run byte-strings only** (for these three writers the arg-free default IS the preview): `node ${CLAUDE_SKILL_DIR}/tools/velocity-profile.mjs` · `node ${CLAUDE_SKILL_DIR}/tools/cheap-agents.mjs` · `node ${CLAUDE_SKILL_DIR}/tools/gate-hook.mjs` — every `--apply`/`--write`/`--yes` still prompts, always.
28
28
 
29
29
  Honesty notes: tier entries get **NO PreToolUse-hook residual coverage** — the opt-in hook's residual ask-net guards only the seeded read-only CORE prefixes, so the tier rides the same settings-level residual posture as the core (redirection / command substitution are not inspectable at the settings layer; see the residual notice). A skill or project path that cannot survive UNQUOTED in a byte-exact rule (spaces, metacharacters, non-POSIX) **STOPs the tier up front with a clear error** — nothing is seeded. Anything you want covered beyond the tier — such paths, this repo's own relative-path spellings, other tools — stays a **BY-HAND add** to your settings, with the path your project actually reaches the kit by. Pre-existing `node …` allow entries that do NOT match the seeded tier byte-forms stay flagged by the advisory for hand review.