@sabaiway/agent-workflow-kit 1.38.0 → 1.40.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 +108 -0
- package/README.md +6 -5
- package/SKILL.md +7 -3
- package/capability.json +1 -1
- package/package.json +1 -1
- package/references/modes/bootstrap.md +1 -1
- package/references/modes/doc-parity.md +18 -0
- package/references/modes/fold-completeness.md +10 -6
- package/references/modes/gates.md +5 -3
- package/references/modes/grounding.md +4 -3
- package/references/modes/review-ledger.md +10 -6
- package/references/modes/review-state.md +1 -0
- package/references/modes/upgrade.md +3 -1
- package/references/modes/velocity.md +1 -1
- package/references/scripts/archive-decisions.mjs +39 -2
- package/references/scripts/archive-decisions.test.mjs +118 -1
- package/references/scripts/check-docs-size.mjs +50 -24
- package/references/scripts/check-docs-size.test.mjs +73 -1
- package/references/templates/agent_rules.md +1 -0
- package/references/templates/verification-profile.json +10 -0
- package/tools/changed-surface.mjs +294 -0
- package/tools/commands.mjs +10 -3
- package/tools/doc-parity.mjs +139 -0
- package/tools/fold-completeness-run.mjs +518 -252
- package/tools/fold-completeness.mjs +184 -66
- package/tools/grounding.mjs +92 -5
- package/tools/lcov.mjs +127 -0
- package/tools/procedures.mjs +1 -1
- package/tools/review-ledger-write.mjs +253 -50
- package/tools/review-ledger.mjs +382 -53
- package/tools/review-state.mjs +69 -3
- package/tools/run-gates.mjs +101 -11
- package/tools/sarif.mjs +52 -0
- package/tools/verification-profile.mjs +219 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,114 @@ 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.40.0 — Universal verification profile + session-loop economics (a)–(h) (BUGFREE-3, AD-049)
|
|
8
|
+
|
|
9
|
+
A **feature** release (deployment-lineage head stays `1.3.0` — no migration; co-released with
|
|
10
|
+
`@sabaiway/agent-workflow-memory` 1.12.0; engine/bridges untouched). BUGFREE-3 closes two residuals
|
|
11
|
+
AD-046/AD-048 left open: the fold-completeness signal was **JS/V8-only** (coverage read solely from
|
|
12
|
+
`NODE_V8_COVERAGE`, the single-test probe parsed node:test TAP from stdout — no consumer on another
|
|
13
|
+
runner could use the gate), and the BUGFREE-2 retro left **eight kit-level cycle-costs** unfolded.
|
|
14
|
+
|
|
15
|
+
- **Verification profile** — a new, optional, versionable `docs/ai/verification-profile.json`
|
|
16
|
+
(`schema:1`; memory-canon template + kit mirror + a read-core kit tool) declares WHERE the suite
|
|
17
|
+
leaves coverage (`coverage.kind ∈ {v8,lcov}` + `lcovPath`), the single-test template
|
|
18
|
+
(`resultFormat ∈ {tap-stdout,tap-file,junit-xml}`), and an optional SARIF findings path. Env knobs
|
|
19
|
+
override; an **absent profile reproduces today's V8 + node:test behaviour exactly**. Every declared
|
|
20
|
+
path is realpath-guarded gitignored/out-of-tree. LCOV branches at `readCoverage` (the V8 path is
|
|
21
|
+
byte-unchanged); the single-test strategy preserves `resolvable = matched>0` across every format;
|
|
22
|
+
SARIF is advisory, never on the blocking path.
|
|
23
|
+
- **(a) one suite run per fingerprint** — fold RESULT schema v3→v4 carries suite-execution evidence,
|
|
24
|
+
and `run-gates --record` **credits** the `unit-tests` gate from it instead of re-spawning (strictly
|
|
25
|
+
fingerprint-bound + tree-unchanged + command-identity + exit-0; no "recent enough" cache).
|
|
26
|
+
**(c) same-segment re-attest** — a recorded `reattest` receipt anchors custody at a new file hash
|
|
27
|
+
for a green-only test append without fabricating a red-observe (the honest replacement for
|
|
28
|
+
mis-using `red-proof`). **(f) `--preflight`** — the cheap set only, actions routed by kind, no
|
|
29
|
+
suite/probe spawn.
|
|
30
|
+
- **(b) doc-parity** — a new read-only lint + mode: a closed, live-imported registry pins each
|
|
31
|
+
mode-contract doc token to its code constant (caps, schema versions, the ledger vocabulary),
|
|
32
|
+
fail-closed on drift. **(d) `review-state --await`** — block until every recipe-named backend has
|
|
33
|
+
a fresh grounded receipt for the current tree (receipts-not-pgrep; deadline-first, bounded sleep).
|
|
34
|
+
**(e) `grounding --ledger-summary`** — a loop/base-scoped review-ledger digest for `--facts`,
|
|
35
|
+
fail-closed on an unreadable/malformed ledger. **(g) `record --from-receipts`** — draft
|
|
36
|
+
`backends[]` from the current-fingerprint receipts; an explicit non-degraded row is a loud STOP.
|
|
37
|
+
- **(h) a rotation regenerates `docs/ai/index.md`** (the memory-canon `archive-decisions.mjs` reuses
|
|
38
|
+
the root-parameterized `check-docs-size.mjs --write-index --report`) — so an ADR rotation never
|
|
39
|
+
leaves the index stale mid-release-matrix; **dogfooded on this very release** (AD-049's rotation
|
|
40
|
+
regenerated the index automatically, zero mid-matrix trip).
|
|
41
|
+
|
|
42
|
+
**Stated residual (Option A).** The (a) credit rides `NODE_V8_COVERAGE`, an observable env var — a
|
|
43
|
+
test reading it could flip; bounded (fails-under-coverage caught by exit-0), documented, and tested.
|
|
44
|
+
The clean closure (Node ≥22 + `--test-reporter=lcov`) is queued.
|
|
45
|
+
|
|
46
|
+
## 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)
|
|
47
|
+
|
|
48
|
+
A **feature** release (deployment-lineage head stays `1.3.0` — no migration; engine/memory/bridges
|
|
49
|
+
untouched). AD-047's own execution loop field-proved the next gap twice: the ledger hard-capped a
|
|
50
|
+
MULTIPHASE plan at 3 rounds total (11 real council rounds across 4 commit boundaries went
|
|
51
|
+
unrecordable, their late fixable-bugs unbindable), and custody obligations spanning the whole plan
|
|
52
|
+
forced a waiver for every later-phase edit of an earlier-bound test file (4 of 5 recorded
|
|
53
|
+
overrides). One structural move fixes both and gives the three most-replicated fold-boundary
|
|
54
|
+
effects in the review literature real teeth: **the SEGMENT**.
|
|
55
|
+
|
|
56
|
+
- **The segment (review-ledger schema v4)** — every new record carries `base` = the commit the
|
|
57
|
+
dirty tree sits on (`git rev-parse HEAD`; null on an unborn branch); a segment = (activity,
|
|
58
|
+
loop, base). Round numbering, `REVIEW_CAP`/`HARD_MAX` (values unchanged — scope corrected),
|
|
59
|
+
every writer tooth, and `--check` operate **per segment**; a segment closes ONLY through a
|
|
60
|
+
gated commit, so a round-counter reset is **earned, never declared**. The field-proven
|
|
61
|
+
11-round/4-base shape records completely while round 4 within one segment stays refused.
|
|
62
|
+
`--status` groups rounds by segment; v1..v3 records stay readable and never enter one (the
|
|
63
|
+
failure reason names the schema upgrade).
|
|
64
|
+
- **The diff-size cap (D4, writer tooth)** — `recordRound` refuses a round whose changed source
|
|
65
|
+
surface exceeds `AW_REVIEW_DIFF_CAP` (default 400 new-side lines; fail-closed parser) without a
|
|
66
|
+
recorded segment-scoped **`size-cap`** override carrying the EXACT sanctioned magnitude (it dies
|
|
67
|
+
at the next commit — a grown surface needs a fresh recorded sanction). Counted classes are
|
|
68
|
+
pinned: assessable + unsupported SOURCE lines count (excluding TS would gift a bypass); tests
|
|
69
|
+
and out-of-domain never count; pure deletions are free. The computation lives in the NEW
|
|
70
|
+
NEUTRAL `tools/changed-surface.mjs` — one home shared with the coverage domain (the runner and
|
|
71
|
+
the writer can never drift; the writer never imports the runner).
|
|
72
|
+
- **The green-baseline receipt (D5)** — `run-gates --record` mints a v4 **`gate-run`** record via
|
|
73
|
+
the ledger's NEW sole-writer API `recordGateRun` (the runner never opens the ledger itself):
|
|
74
|
+
the FULL declaration + exactly what ran + the tree fingerprint BEFORE and AFTER the run; a red
|
|
75
|
+
run records honestly; a failed record is its own loud **exit 7**. `recordRound` then refuses
|
|
76
|
+
without a **quality-green** gate-run at the current fingerprint — gates-before-review is
|
|
77
|
+
computed, not remembered: a subset that omits a declared non-process gate (any `--only` run
|
|
78
|
+
short of the full quality set) or a tree-changed run never satisfies, while the kit's own
|
|
79
|
+
`--check` loop gates (a CLOSED whole-command classification — compound lines and suffix-named
|
|
80
|
+
tools never match) legitimately fail mid-loop and never block — omitting THOSE is fine. The velocity tier
|
|
81
|
+
auto-approves only the exact no-`--record` form. Revert-first beyond this ships as protocol +
|
|
82
|
+
telemetry visibility — stated plainly, never pretend-teeth.
|
|
83
|
+
- **No-repro-no-fold (D6)** — a blocking finding of the previous segment round may not VANISH
|
|
84
|
+
unclassified: present means present-AS-BLOCKING (a severity downgrade does not survive), a
|
|
85
|
+
pending `escalate` never clears, and the new v4 triage class **`refuted`** is the honest
|
|
86
|
+
phantom lane (mandatory grounds in `note`; it also resolves in `decideStop` — additive rows
|
|
87
|
+
beside the untouched truth table — so an honestly refuted phantom minted at the hard-max round
|
|
88
|
+
can never wedge a segment). Minors stay exempt. Every fixable-bug fold therefore binds its
|
|
89
|
+
red→green `testId` at the round it folded — late binding on multiphase plans restored.
|
|
90
|
+
- **Segment-scoped fold custody (D7, fold ledger v3)** — run and observed-red records carry
|
|
91
|
+
`base`; bound testIds, receipts, custody chains, and tamper all filter to the current segment.
|
|
92
|
+
A committed phase's custody obligations **close with its commit** — the cross-phase churn class
|
|
93
|
+
that forced 4 of BUGFREE-1's 5 overrides is dead (regression-pinned); a receipt never crosses a
|
|
94
|
+
commit boundary, so a cross-segment fold still takes the recorded `red-proof` lane (the stated
|
|
95
|
+
residual).
|
|
96
|
+
- **Gate telemetry (D8)** — `review-ledger --telemetry`: read-only COUNTS across all loops and
|
|
97
|
+
both ledgers (rounds/segments, finding origins, classification distribution incl. `refuted`,
|
|
98
|
+
per-backend verdicts + divergence rounds, override usage by scope, gate-run quality-green and
|
|
99
|
+
red-results-by-gate, fold runs, observed-red receipts, quarantined probes). Counts only —
|
|
100
|
+
which gates earn their keep stays the maintainer's judgment. Never combined with `--check`.
|
|
101
|
+
- Bound-test probes now pass the pattern in the `=`-joined `--test-name-pattern=` form — a test
|
|
102
|
+
name beginning with `-`/`--` no longer parses as a node option and silently selects no test
|
|
103
|
+
(the pattern-half sibling of AD-047's dash-spawn fix; found live by this release's own `--red`
|
|
104
|
+
loop).
|
|
105
|
+
- Surfaces in lockstep: both mode-refs + `gates.md` (the runner's claim is now "writes nothing
|
|
106
|
+
BY DEFAULT"), README rows, catalog one-liners, the procedures advisor (run `run-gates --record`
|
|
107
|
+
BEFORE recording a round; per-segment wording), velocity notes; the surface test pins every
|
|
108
|
+
token.
|
|
109
|
+
|
|
110
|
+
Dogfooded live on its own three-segment execution loop (the AD-047 precedent): the cap fired on
|
|
111
|
+
the plan's own 792-line Phase-1 surface (exact re-sanctions recorded), the quality-green receipt
|
|
112
|
+
was consumed by the D5 tooth at the very first segment-2 round, and segment closure was exercised
|
|
113
|
+
end-to-end at each phase commit.
|
|
114
|
+
|
|
7
115
|
## 1.38.0 — Honest red→green: observed-red receipts, flaky quarantine, content custody, and the oracle-tamper guard (AD-047)
|
|
8
116
|
|
|
9
117
|
A **feature** release (deployment-lineage head stays `1.3.0` — no migration; engine/memory/bridges
|
package/README.md
CHANGED
|
@@ -228,16 +228,17 @@ 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. |
|
|
235
235
|
| `/agent-workflow-kit procedures <activity>` | any time | **read-only** activity-procedures advisor: prints a named activity's ordered steps (`plan-authoring` / `plan-execution`) read **live** from the engine, plus the **resolved recipe per slot** from your `docs/ai/orchestration.json` (agent-writable via `set-recipe`, or hand-edited) + backend readiness (default Reviewed when a backend is ready, Council on request, slot-aware incl. Delegated) — and, for every dispatched backend, the **full driving contract at the point of use** (exact copy-pasteable invocation, grounding levers like agy's `--facts`/`--decided`, the round-2 `--continue` delta, guarded passthrough), verbatim from the bridge manifests (drift-guarded; each wrapper's `--help` prints the same). `--override <slot>=<recipe>` adjusts one slot per run. Composes with `recipes`; never writes, never commits, never runs a subscription CLI. |
|
|
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
|
-
| `/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
|
-
| `/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, and any recorded **overrides** (
|
|
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); 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. |
|
|
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). `--await [--timeout <s>]` (AD-049) BLOCKS until every recipe-named backend has receipted the current tree — the durable completion signal is the receipt, never a process event — so you wait for the bridges instead of hand-polling. 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
|
+
| `/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. `--ledger-summary` (AD-049) appends a COMPUTED review-ledger digest for the single in-flight segment (rounds · origins · classifications · verdicts · overrides — unrelated loops excluded), so the reviewer sees the loop's own history without hand-copying. 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, 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; `record --from-receipts` (AD-049) DRAFTS the `backends[]` from the current-fingerprint receipts (verdict per backend, counts from the supplied findings) instead of hand-composing them — a recipe-named backend with no receipt is a loud stop; `--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
|
+
| `/agent-workflow-kit doc-parity` | any time | **read-only doc-parity lint** (AD-049) — kills the doc-drift class where a mode-contract doc silently lags a code constant (a `--check` doc still reading `300` after the diff cap moved to `400`): a **closed, exported registry** binds each live constant (review caps, schema versions, and the ledger's own class/scope vocabulary) to the exact token its `references/modes/*.md` contract must carry, and asserts the CURRENT value renders into every bound file — a drifted doc, an unreadable file, or an absent token **fails closed**. The values are sourced from the live imports (never re-typed), so the lint can't itself go stale; adding a binding is adding a checked entry (closed-world, edit-safe). `--check` is a gate exit code for `docs/ai/gates.json`. Never writes, never commits, never runs a subscription CLI. |
|
|
241
242
|
| `/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
243
|
| `/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
244
|
| `/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.
|
|
6
|
+
version: '1.40.0'
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# agent-workflow-kit
|
|
@@ -22,8 +22,8 @@ This kit is the **composition root** of the `agent-workflow` family. The memory
|
|
|
22
22
|
when it is present and healthy, and otherwise uses its **own bundled copy** (`references/`,
|
|
23
23
|
`migrations/`) — so the existing one-command install keeps working with **no new dependency on the
|
|
24
24
|
memory substrate**. (The methodology slot is a separate axis: its fragment is read **live from the
|
|
25
|
-
installed `agent-workflow-engine`**, which `npx @sabaiway/agent-workflow-kit@latest init` installs
|
|
26
|
-
|
|
25
|
+
installed `agent-workflow-engine`**, which `npx @sabaiway/agent-workflow-kit@latest init` installs;
|
|
26
|
+
see `${CLAUDE_SKILL_DIR}/references/shared/composition-handoff.md`.)
|
|
27
27
|
`init` also **refreshes the installed memory substrate** (best-effort — a miss is a loud DEGRADED
|
|
28
28
|
success: warn + the exact recovery command + exit 0, never silent, never the engine's hard STOP;
|
|
29
29
|
`--no-memory` skips it), so a returning `init` leaves **no stale core member**. The
|
|
@@ -163,6 +163,10 @@ writer — read `${CLAUDE_SKILL_DIR}/references/modes/review-ledger.md` before a
|
|
|
163
163
|
|
|
164
164
|
writer — read `${CLAUDE_SKILL_DIR}/references/modes/fold-completeness.md` before acting.
|
|
165
165
|
|
|
166
|
+
### Mode: doc-parity
|
|
167
|
+
|
|
168
|
+
read-only — read `${CLAUDE_SKILL_DIR}/references/modes/doc-parity.md` before acting.
|
|
169
|
+
|
|
166
170
|
---
|
|
167
171
|
|
|
168
172
|
## References
|
package/capability.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sabaiway/agent-workflow-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.40.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",
|
|
@@ -18,7 +18,7 @@ Requires: ${CLAUDE_SKILL_DIR}/references/shared/report-footer.md · ${CLAUDE_SKI
|
|
|
18
18
|
3. **Choose conversational language — answered in the step-2 batch.** Which language should the agent *talk to them* in — questions, explanations, summaries, status updates? Offer the language they're already writing in as the default. Carry the answer into the `{{COMM_LANGUAGE}}` slot of the *Communication language* block when `AGENTS.md` is created (step 5). See [Communication contract](${CLAUDE_SKILL_DIR}/references/contracts.md#communication-contract). This sets the **dialogue** language only — never the files.
|
|
19
19
|
4. **Choose agent attribution — answered in the step-2 batch.** May the agent attribute work to itself / to AI — `Co-Authored-By` trailers, "Generated with …" footers, "AI"/agent/model mentions in code, comments, commit messages, PR titles/bodies, or docs? **Default to `off`** (no agent/AI mention anywhere) unless they opt in — people are routinely surprised to find an AI listed as a repo contributor. Carry the answer into the `{{AGENT_ATTRIBUTION}}` slot of the *Attribution* block when `AGENTS.md` is created (step 5). **If `off` and the project uses Claude Code**, also set `"includeCoAuthoredBy": false` in the project's `.claude/settings.json` (create it if absent) — the trailer is added by the harness, so a doc directive alone won't stop it. See [Attribution contract](${CLAUDE_SKILL_DIR}/references/contracts.md#attribution-contract).
|
|
20
20
|
5. **Entry-point doc.** If `AGENTS.md` / `CLAUDE.md` already exist (step-1 recon), do **not** overwrite — show the user and ask whether to merge or replace. Otherwise create `AGENTS.md` (the cross-agent standard — Codex / Cursor / Devin Desktop / Copilot read it natively) from `${CLAUDE_SKILL_DIR}/references/templates/AGENTS.md`, and symlink `CLAUDE.md -> AGENTS.md` (`ln -s AGENTS.md CLAUDE.md`) for Claude Code — single source, no duplication. For nested context, add a subdir `AGENTS.md` (+ a `CLAUDE.md` symlink beside it for Claude Code).
|
|
21
|
-
6. **Deploy `docs/ai/`.** Create every `docs/ai/` file + `pages/` from `${CLAUDE_SKILL_DIR}/references/templates/` (the template loop deploys each non-`AGENTS.md` template — the `.md` docs **and** the
|
|
21
|
+
6. **Deploy `docs/ai/`.** Create every `docs/ai/` file + `pages/` from `${CLAUDE_SKILL_DIR}/references/templates/` (the template loop deploys each non-`AGENTS.md` template — the `.md` docs **and** the three seeded, user-editable strict-JSON configs: **`docs/ai/orchestration.json`** (the per-project recipe defaults the `procedures` advisor reads), **`docs/ai/gates.json`** (the project's gate declaration — an empty list to fill with its own verification commands, consumed by `${CLAUDE_SKILL_DIR}/references/modes/gates.md`), and **`docs/ai/verification-profile.json`** (the OPTIONAL fold-completeness verification profile — its seeded default reproduces the composition root's V8 + node:test behaviour, so a project deletes it to fall back to exactly that, or edits it for another language/runner)). Keep each `.md` file's frontmatter (`type / lastUpdated / scope / staleAfter / owner / maxLines`); the `.json` seeds carry no frontmatter (the docs cap-validator globs `*.md` only, so they are inherently skipped).
|
|
22
22
|
7. **Fill templates** per the table below.
|
|
23
23
|
8. **Install enforcement (Node projects).** Copy `${CLAUDE_SKILL_DIR}/references/scripts/*.mjs` (+ `*.test.mjs`) into the project's `scripts/`. They self-configure (project name from `package.json`, hierarchical/on-demand sections auto-discovered). **If the project has no Node runtime** (step-1 recon), skip this step and the hook in step 9 — follow the cap/archive/index policy manually, or port the scripts to the project's language.
|
|
24
24
|
9. **Wire / hide** per visibility (see [Visibility contract](${CLAUDE_SKILL_DIR}/references/contracts.md#visibility-contract)). Install the pre-commit hook (Node projects): `node scripts/install-git-hooks.mjs`. If the installer reports a pre-existing non-marker hook, stop and ask the user to merge it manually rather than overwriting.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
### Mode: doc-parity
|
|
2
|
+
|
|
3
|
+
The DOC-PARITY lint (BUGFREE-3 / AD-049, session-economics item (b)) — the deterministic doc-drift killer. A recurring class of review churn came from a mode-contract doc silently lagging a code constant (a `--check` doc still reading "300" after the diff cap moved to 400, caught only in a later review round). This read-only tool closes that class mechanically: a **closed, exported registry** ties each live code constant to the exact token its `references/modes/*.md` contract must carry, and asserts the CURRENT value renders into every bound file.
|
|
4
|
+
|
|
5
|
+
**Run** — `node ${CLAUDE_SKILL_DIR}/tools/doc-parity.mjs [--check | --json]`:
|
|
6
|
+
- default → the per-binding report (each `constant → file` marked ✓/✗).
|
|
7
|
+
- **`--check`** → the gate exit code (0 consistent, 1 drift). Declare it as a project gate by hand in `docs/ai/gates.json`.
|
|
8
|
+
- `--json` → the structured result.
|
|
9
|
+
|
|
10
|
+
**What it checks (the closed registry).** The numeric/version tokens are IMPORTED live from the tools — never re-typed in the lint — so the registry itself can never go stale:
|
|
11
|
+
- `references/modes/review-ledger.md` carries `SCHEMA_VERSION` (schema v4), `HARD_MAX` (the hard-max ceiling of 3), `DEFAULT_DIFF_CAP` (the default 400 diff cap), `REVIEW_CAP` (cap ≤2), and the ledger vocabulary sourced from the schema's own `V4_CLASSES` / `V4_OVERRIDE_SCOPES` Sets plus the `gate-run` kind (`size-cap`, `refuted`, `gate-run`, `red-proof`, `oracle-change`, `fixable-bug`, `inherent-layer-residual`, `escalate`);
|
|
12
|
+
- `references/modes/fold-completeness.md` carries `RESULT_SCHEMA_VERSION` (fold RESULT schema v4).
|
|
13
|
+
|
|
14
|
+
**Why the modes/*.md docs and NOT the tool HELP strings.** Every tool's HELP INTERPOLATES the same constant (`the ${DEFAULT_DIFF_CAP}-line diff cap`), so it can never drift from the code — there is nothing to check there. The hand-authored contract prose in `references/modes/*.md` is the surface that DOES drift, so that is exactly what this lint pins. Change a constant and the current-value token stops appearing in the lagging doc → the gate fails, forcing the doc update **in the same edit as the code** (the §2.6 "contract docs change in the same edit as code" rule, mechanized).
|
|
15
|
+
|
|
16
|
+
**Edit-safe (the closed-world discipline).** Adding a binding ADDS a checked entry; it never widens a blocklist. A token that stops appearing, a bound file that cannot be read, or an unknown binding all FAIL CLOSED — never a silent pass.
|
|
17
|
+
|
|
18
|
+
**Invariants:** read-only · never writes · never commits · never runs a subscription CLI · spawns nothing · the value source is the live imported constant (and the schema's exported vocab Sets), never a re-typed literal.
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
### Mode: fold-completeness
|
|
2
2
|
|
|
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.
|
|
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. **Since schema v4 (BUGFREE-3 / AD-049)** a run record additionally carries the **suite-execution evidence** ((a): `cmd` + exit + pre/post fingerprints — so `run-gates --record` can CREDIT the `unit-tests` gate instead of re-spawning it), and a new record kind **`reattest`** joins `run`/`red-probe` ((c): an operator-minted, recorded custody re-attestation — see the runner's `--reattest`). A placed pre-v4 checker rejects a v4 record outright (the version-skew guard); v1/v2/v3 rules are untouched.
|
|
4
4
|
|
|
5
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.
|
|
6
6
|
|
|
7
7
|
**Two tools — the read/run split:**
|
|
8
8
|
|
|
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
|
|
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 the gate requires: an N/N-green probe, an observed-red receipt in this
|
|
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 verification PROFILE — language independence (BUGFREE-3 / AD-049).** An OPTIONAL per-project `docs/ai/verification-profile.json` (seeded by the memory bootstrap; a memory-canon template with a kit mirror) generalizes the fold signal beyond JS/V8 so a consumer on another language/runner drives the SAME gate. It declares three inputs — **`coverage.kind`** `"v8"` (default) or `"lcov"` (+ `lcovPath`: your suite leaves an LCOV file there, parsed by a dependency-free reader — the diff-cover pattern); **`singleTest`** an argv template (`{file}`/`{pattern}`, plus `{resultPath}` for a file-based format) + `resultFormat` `"tap-stdout"` (default) / `"tap-file"` / `"junit-xml"` (the "0 tests matched" → unresolvable guard holds for EVERY format — a zero-match is never read green); and an optional **`findings.sarifPath`** for ADVISORY findings (`--findings` prints them — never recorded, never gate-blocking; a malformed SARIF fails the advisory read loudly but leaves `--check` unaffected). An ABSENT profile reproduces today's exact behaviour (V8 + node:test TAP on stdout); env knobs (`AW_FOLD_SUITE_CMD`/`AW_FOLD_BOUND_CMD`) still override. Every DECLARED path (`lcovPath`, `sarifPath`) MUST be gitignored or outside the repo (a symlink is refused) — else the suite writing there would move the review fingerprint. The suite COMMAND is NOT a profile field: it stays the `gates.json` `unit-tests` cmd (command-identity — the (a) credit).
|
|
13
|
+
|
|
14
|
+
**The operator verbs (recorded, self-discipline — never auto-detection):** besides `--red`, the runner offers **`--reattest "<testId>"`** ((c)): re-anchor a bound test FILE's custody at its CURRENT bytes after a GREEN-ONLY append — the honest replacement for a `red-proof` waiver (there is no red to observe); it never converts a red baseline or waives the observed-red proof, and the guard still fails closed on any un-reattested change. **`--preflight`** ((f)): the CHEAP half — from the git diff + ledgers (seconds, no suite run, no probe, no coverage) it prints the overrides/re-attests to RECORD BEFORE the expensive pass, routed by kind (`oracle-change` for a tampered file, `--reattest` for a green-only custody delta, `--red`/`red-proof` for a bound testId with no observed-red receipt). **`--findings`**: the SARIF advisory above.
|
|
11
15
|
|
|
12
16
|
**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.
|
|
13
17
|
|
|
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
|
|
18
|
+
**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 hold: the language-aware verification profile now EXISTS (BUGFREE-3 / AD-049 — coverage via LCOV, single-test via TAP-file/JUnit-XML), so the JS/V8-only blocker is lifted, but consumer-seeding of this gate is a SEPARATE follow-up the profile merely unblocks.
|
|
15
19
|
|
|
16
20
|
**Run-then-check usage (each plan-execution round):** run the runner AFTER the round's LAST edit — any later tree edit (a source fix, a doc touch, a gate-file tweak) moves the fingerprint and requires a re-run — then the wired `--check` attests it. Staleness is by BOTH bindings: a tree edit moves the fingerprint, and a new `fixable-bug` triage moves the bound-testId set — either makes the previous record STALE, so a green check always attests the CURRENT tree against the CURRENT fold set.
|
|
17
21
|
|
|
18
|
-
**Suite + bound-test commands:** the suite command defaults to the `unit-tests` gate `cmd` in the project's `docs/ai/gates.json`; absent that, `--suite "<cmd>"` (or `AW_FOLD_SUITE_CMD`) is REQUIRED — refused loudly otherwise. Bound-test probes default to the `node --test --test-name-pattern` shape over the testId halves (`<test-file>#<test-name-pattern>`); a consumer on another runner sets `AW_FOLD_BOUND_CMD` — a JSON ARRAY of argv strings with `{file}` / `{pattern}`
|
|
22
|
+
**Suite + bound-test commands:** the suite command defaults to the `unit-tests` gate `cmd` in the project's `docs/ai/gates.json`; absent that, `--suite "<cmd>"` (or `AW_FOLD_SUITE_CMD`) is REQUIRED — refused loudly otherwise. Bound-test probes default to the `node --test --test-name-pattern` shape over the testId halves (`<test-file>#<test-name-pattern>`); a consumer on another runner sets the profile's `singleTest.argv` (or the `AW_FOLD_BOUND_CMD` env override, which wins) — a JSON ARRAY of argv strings with `{file}` / `{pattern}` substitution (plus `{resultPath}` for a file-based `resultFormat`), spawned WITHOUT a shell (testId content never reaches a shell). Coverage comes from V8 by default, or from an LCOV file the suite writes (`coverage.kind:"lcov"` + `lcovPath`) — either source feeds the same uncovered-changed decision. Note: the suite's own child processes must inherit `NODE_V8_COVERAGE` for their lines to count (node child spawns inherit it by default; a test runner that scrubs its child env needs consumer configuration).
|
|
19
23
|
|
|
20
|
-
**v1 scope (stated):** assessable = `.mjs` / `.cjs` / `.js`, excluding test files (`*.test.*` / `*.spec.*`); changed `.ts` / `.tsx` / `.jsx` / `.mts` / `.cts` files are recorded as unsupported and FAIL the gate CLOSED — the signal never vouches for JS-family source it cannot assess; everything else (docs/config the suite does not execute) is recorded out-of-domain and LOUDLY listed, never gate-blocking. Executability is
|
|
24
|
+
**v1 scope (stated):** assessable = `.mjs` / `.cjs` / `.js`, excluding test files (`*.test.*` / `*.spec.*`); changed `.ts` / `.tsx` / `.jsx` / `.mts` / `.cts` files are recorded as unsupported and FAIL the gate CLOSED — the signal never vouches for JS-family source it cannot assess; everything else (docs/config the suite does not execute) is recorded out-of-domain and LOUDLY listed, never gate-blocking. Executability is coverage-derived (V8 by default, or LCOV via the profile): a changed assessable file entirely absent from the coverage report is RED at file level ("never imported" must not read as "nothing executable"). The LANGUAGE-INDEPENDENCE contract (BUGFREE-3) generalizes the coverage source + single-test result format without changing this closed JS assessable rule — a consumer whose suite emits LCOV + JUnit-XML drives the same gate.
|
|
21
25
|
|
|
22
26
|
**Mutation is NOT shipped (v1).** The result record carries a reserved, always-empty `mutation` shape; the shipped runner performs NO mutation and never modifies a source file, and the checker FAILS CLOSED on a record carrying ANY mutation data (such a record was not produced by this runner version). The researched mutation half was shelved: a bounded operator set tests local expression boundaries, not the cross-module interactions that produce real fold bugs, and it is not language-independent. The `AW_FOLD_MUTANTS_MAX` / `AW_FOLD_HUNK_MUTANTS_MAX` / `AW_FOLD_TIME_BUDGET_S` budgets are parsed and recorded but inert in v1 (reserved).
|
|
23
27
|
|
|
@@ -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
|
|
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,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
The **grounded-review facts assembler** (AD-038) — an ungrounded `agy` review GUESSES, and while the grounding contract is mechanized (`agy-review code --facts @f`), populating the facts file was a manual chore. This mode emits the two **mechanical** halves of a facts payload; the orchestrator still owns any judgment-bearing additions. **Catalogued honestly as a WRITER** — `--out <path>` writes one file — with the invariant: `--out` accepts **only gitignored / out-of-repo scratch destinations** and REFUSES a tracked path AND an in-repo not-ignored path (a new untracked file would itself move the review fingerprint the facts are about to ground); **stdout is the default**. It never commits and never runs a subscription CLI.
|
|
4
4
|
|
|
5
|
-
Run `node ${CLAUDE_SKILL_DIR}/tools/grounding.mjs [--constraints] [--plan <path>] [--reserve-bytes <n>] [--out <path>]`:
|
|
5
|
+
Run `node ${CLAUDE_SKILL_DIR}/tools/grounding.mjs [--constraints] [--plan <path>] [--ledger-summary] [--reserve-bytes <n>] [--out <path>]`:
|
|
6
6
|
|
|
7
7
|
1. **`--constraints`** — slice the root `AGENTS.md` **Hard Constraints** section, verbatim and whole (exactly ONE matching heading; zero or several is a loud STOP, never a guess — the marker-slot discipline).
|
|
8
8
|
2. **`--plan <path>`** — extract the plan's decision-bearing canonical sections, verbatim + whole: `## Approach` (REQUIRED — its "What we are NOT doing" text rides inside; it is not a heading in canon) and `## Verification` (REQUIRED — STOP if missing), plus `## Decisions (locked)` when present (the optional engine §7 heading); a DUPLICATE heading is always a STOP.
|
|
9
|
-
3.
|
|
10
|
-
4.
|
|
9
|
+
3. **`--ledger-summary`** (BUGFREE-3 / AD-049) — append a COMPUTED review-ledger digest for the SINGLE in-flight `plan-execution` segment: the round/origin/classification/verdict/override counts (filtered to that loop + base — unrelated loops excluded) plus a terse per-round render. "Computed, not remembered" facts — the reviewer sees the loop's own history without the orchestrator hand-copying it. A loud STOP unless exactly one plan is in flight; read-only (the ledger is never written here).
|
|
10
|
+
4. **Byte budget** — the output honors the same `AGY_MAX_PROMPT_BYTES` contract the agy wrapper enforces (override may only tighten; the OS argv ceiling is rejected), MINUS **`--reserve-bytes <n>`** — the artifact share the caller expects `agy-review` to add around these facts. Overflow is trimmed tail-first with a loud in-band marker + stderr report — never a silent cut.
|
|
11
|
+
5. Feed the result to the wrapper: `agy-review code --facts @<out>`. The `procedures` advisor renders this invocation as a concrete pre-step whenever the resolved review dispatch includes agy — populated with the in-flight plan path when exactly one plan is in flight.
|
|
11
12
|
|
|
12
13
|
**Invariants:** writer (writes at most the ONE `--out` scratch file — gitignored / out-of-repo only) · never commits · never runs a subscription CLI · verbatim slices only (assembly is mechanical; facts judgment stays with the orchestrator).
|
|
@@ -2,21 +2,25 @@
|
|
|
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[]
|
|
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
|
|
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
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):
|
|
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
|
|
14
|
-
- `classify` appends one triage — each surviving blocking finding classified `fixable-bug` / `inherent-layer-residual` / `escalate
|
|
15
|
-
- `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). 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` —
|
|
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. **`--from-receipts`** (BUGFREE-3 / AD-049) DRAFTS the `backends[]` from those receipts instead of hand-composing them: each recipe-named backend's verdict comes from its fresh grounded code receipt and its counts are computed from the supplied `findings` (`origins` / `findings` stay explicit input); a recipe-named backend with no receipt is a LOUD stop — the draft never invents one (supply it explicitly as a degraded backend if the bridge really is down).
|
|
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.
|
|
16
20
|
|
|
17
21
|
**The computed stop (`decideStop`, precedence `converged > resolved-residual > triage-required > continue`).** Machine fields only (counts, `class`, `accepted`, `fingerprint`), never free-text:
|
|
18
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).
|
|
19
|
-
- **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).
|
|
20
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.
|
|
21
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).
|
|
22
26
|
|
|
@@ -7,6 +7,7 @@ Run `node ${CLAUDE_SKILL_DIR}/tools/review-state.mjs [--check] [--json]`:
|
|
|
7
7
|
1. Plain run → the human report: resolved recipe + source, plan-in-flight, tree fingerprint, per-backend receipt state (current / stale / ungrounded / missing) with verdict + grounding + timestamp.
|
|
8
8
|
2. **`--check`** → the gate exit code. The **normative exit contract lives in the tool header** (the single home — do not re-enumerate it elsewhere): exit 0 for a solo-resolved recipe (configured, or degraded there — no ready reviewer), no plan in flight (the `docs/plans` naming convention: `queue.md` and `EXECUTE-`/`FEEDBACK-`-prefixed or `PROMPT`/`prompt`/`handoff`-carrying names are scratch), a clean tree, a non-git cwd, or every recipe-named backend receipted **current + grounded**; exit 1 when a backend is missing, **stale** (ANY edit after its review moves the fingerprint), or grounded:false under reviewed/council. **Presence, not unanimity:** verdict adjudication (ship/revise, the divergence crossover) stays orchestrator judgment — the gate only proves the configured backends really reviewed THIS tree. Plan/diff receipts and continuations (`agy-review --continue`) are **informational-only**: after a fold, only a **fresh grounded re-run** (`codex-review code`; `agy-review code --facts @f`) restores green.
|
|
9
9
|
3. **Wire it as a gate by hand OR via the explicit-consent seeder — never without consent (AD-021/AD-042).** The candidate line for your own `docs/ai/gates.json`: `{ "id": "review-state", "title": "Review receipts current for the uncommitted tree", "cmd": "node <path-to-this-skill>/tools/review-state.mjs --check" }` — with the path your project actually reaches the kit by, QUOTED so a path with spaces survives, executable from the project root. The consent-gated seeder (`${CLAUDE_SKILL_DIR}/references/modes/gates.md`, consent-seed section) offers exactly this entry — path resolved and quoted — ONLY when your `docs/ai/orchestration.json` declares `reviewed`/`council` on `plan-execution.review` (the slot this checker enforces); it writes nothing without your explicit yes. Once declared, the opt-in `${CLAUDE_SKILL_DIR}/references/modes/hook.md` auto-approves it like any other declared gate.
|
|
10
|
+
4. **`--await [--timeout <s>]`** (BUGFREE-3 / AD-049) → BLOCK until every recipe-named backend has a fresh grounded code receipt for the current tree (i.e. until `--check` would PASS), or the bounded timeout elapses (a loud exit 1; default 900s). Run it after dispatching the review bridges to WAIT for their receipts to land instead of hand-polling a pid: the durable completion signal is the **receipt**, never a process event (a harness "completed" notification fires early; a bridge's output late-flushes). It waits for ALL recipe-named backends — review-state has no durable degraded-backend source before a round is recorded, so awaiting a backend you KNOW is degraded is your call (don't `--await` it). Still read-only (it only re-reads state); solo / no-plan / clean-tree resolve instantly.
|
|
10
11
|
|
|
11
12
|
**Human residual (stated, accepted):** `git commit --no-verify` and receipt-file deletion/forgery remain possible — this is a self-discipline mechanism against silent process drift, not a security boundary.
|
|
12
13
|
|
|
@@ -22,6 +22,8 @@ Requires: ${CLAUDE_SKILL_DIR}/references/shared/report-footer.md · ${CLAUDE_SKI
|
|
|
22
22
|
|
|
23
23
|
**Gate-declaration ensure (seed-if-missing) — stamp-independent, same gate, BEFORE the equal-head short-circuit.** Ensure `docs/ai/gates.json` exists: **create it from `${CLAUDE_SKILL_DIR}/references/templates/gates.json` if missing** — the kit's OWN template twin, so this works even when the installed memory substrate predates the gates feature (a stale memory never silently loses it); **an existing file is preserved byte-for-byte** (a project's declared gate matrix is authored content — never clobbered, never refreshed in place; unlike the orchestration `_README` there is no note-refresh here). Report it in the step 4 / step 8 success report (*seeded* / *already present*). Like the config ensure, this reaches an equal-head deployment without a lineage-head bump or a migration file (a `.json`, inherently outside the docs cap-validator).
|
|
24
24
|
|
|
25
|
+
**Verification-profile ensure (seed-if-missing) — stamp-independent, same gate, BEFORE the equal-head short-circuit.** Ensure `docs/ai/verification-profile.json` exists: **create it from `${CLAUDE_SKILL_DIR}/references/templates/verification-profile.json` if missing** (the kit's OWN template twin, so the fallback/stale-memory path still gains the OPTIONAL fold-completeness profile); **an existing file is preserved byte-for-byte** (a project may have edited it for its language/runner). An ABSENT profile reproduces the default V8 + node:test behaviour, so this ensure only ADDS the opt-in default. Report it in the step 4 / step 8 report (*seeded* / *already present*). Like the config + gate ensures, no lineage-head bump or migration file (a `.json`, outside the docs cap-validator).
|
|
26
|
+
|
|
25
27
|
**Enforcement-script ensure (seed-if-missing) — stamp-independent, same gate, BEFORE the equal-head short-circuit.** A deployment older than the ADR-cascade feature has no `scripts/archive-decisions.mjs`, and an equal-head exit would otherwise never deliver it. Ensure the pair exists in the project's `scripts/`: **copy `archive-decisions.mjs` + `archive-decisions.test.mjs` from `${CLAUDE_SKILL_DIR}/references/scripts/` if missing** (the kit's own fallback copies — byte-identical to the memory canon by the mirror guard); **an existing file is preserved, never overwritten** (drift repair belongs to a lineage migration, not this ensure). The deployed pre-commit hook gains the `archive-decisions.mjs --check` line only when the hook itself is next refreshed (re-run `node scripts/install-git-hooks.mjs` after the ensure and it will refuse a non-marker hook as always); an OLD hook without the line stays consistent-safe — the decisions gate is simply not enforced yet, never a broken hook. Skip this ensure on a No-Node project (the scripts are Node enforcement). Report it in the step 4 / step 8 success report (*added* / *already present*).
|
|
26
28
|
|
|
27
29
|
**Placed-bridge refresh — stamp-independent, same gate, BEFORE the equal-head short-circuit.** Run
|
|
@@ -52,7 +54,7 @@ Requires: ${CLAUDE_SKILL_DIR}/references/shared/report-footer.md · ${CLAUDE_SKI
|
|
|
52
54
|
**NEVER writes** it (the file lives outside every kit tree — D2), so an unknown/retired key is
|
|
53
55
|
flagged + preserved, never edited. Runs on **every** upgrade; exit 0 covers every outcome.
|
|
54
56
|
4. **Equal-head exit — a real successful-exit report, not a bare stop.** If the stamp **equals** the head, the lineage is up to date — but step 3 (the stamp-independent reconciles) ran first and may have changed things, so this is a proper exit report, not a no-op:
|
|
55
|
-
- **Report step 3's outcome in plain language** — for **each** pointer (workflow-methodology and orchestration-recipes) whether it was *added*, was *already present* (nothing changed), or was *skipped because the entry point is over its line limit* (the cap-refusal soft-skip from step 3, with its reason); whether the `docs/ai/orchestration.json` config was *seeded* (created from the template), had its onboarding note *refreshed*, was *already current*, or carried a *customized note that was preserved* (a user edit is never clobbered); whether the `docs/ai/gates.json` gate declaration was *seeded* or was *already present* (preserved byte-for-byte); whether the enforcement-script ensure *added* the `archive-decisions` pair to `scripts/` or found it *already present*; the **placed-bridge refresh** outcome — paste the tool's per-bridge lines verbatim (they are already plain: *refreshed* / *already current* / *skipped — not placed* / *could not refresh* + recovery); the **agent-rules lens** outcome (*refreshed* / *already current* / *custom edit preserved + note* / *file absent* / *engine too old* / *over the line cap*); the **bridge-settings reconcile** outcome (paste the tool's line verbatim); and, for a hidden deployment, whether the hidden-mode footprint was *moved to project-local*, was *already project-local* (nothing changed), or needed a question (ambiguous visibility / a leftover machine-wide block). Plain wording only — never the reconcile/slot/anchor/marker terms (the never-leak-kit-internals Gotcha — `${CLAUDE_SKILL_DIR}/references/shared/deploy-tail.md`).
|
|
57
|
+
- **Report step 3's outcome in plain language** — for **each** pointer (workflow-methodology and orchestration-recipes) whether it was *added*, was *already present* (nothing changed), or was *skipped because the entry point is over its line limit* (the cap-refusal soft-skip from step 3, with its reason); whether the `docs/ai/orchestration.json` config was *seeded* (created from the template), had its onboarding note *refreshed*, was *already current*, or carried a *customized note that was preserved* (a user edit is never clobbered); whether the `docs/ai/gates.json` gate declaration was *seeded* or was *already present* (preserved byte-for-byte); whether the `docs/ai/verification-profile.json` profile was *seeded* or was *already present* (preserved byte-for-byte); whether the enforcement-script ensure *added* the `archive-decisions` pair to `scripts/` or found it *already present*; the **placed-bridge refresh** outcome — paste the tool's per-bridge lines verbatim (they are already plain: *refreshed* / *already current* / *skipped — not placed* / *could not refresh* + recovery); the **agent-rules lens** outcome (*refreshed* / *already current* / *custom edit preserved + note* / *file absent* / *engine too old* / *over the line cap*); the **bridge-settings reconcile** outcome (paste the tool's line verbatim); and, for a hidden deployment, whether the hidden-mode footprint was *moved to project-local*, was *already project-local* (nothing changed), or needed a question (ambiguous visibility / a leftover machine-wide block). Plain wording only — never the reconcile/slot/anchor/marker terms (the never-leak-kit-internals Gotcha — `${CLAUDE_SKILL_DIR}/references/shared/deploy-tail.md`).
|
|
56
58
|
- **Never surface the structure number on this exit.** Whatever step 3 did, do **not** recite the `docs/ai` structure version, the internal versioning vocabulary, or the two-axes note here — the number is inert on an equal-head exit; it belongs to *Version disclosure* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md` (shown at the never-downgrade STOP, the explicit status view, or on an explicit ask). Frame the success itself per the final bullet: if step 3 changed anything, say **what changed** in plain human terms; only a pure zero-diff no-op is *settings already current — no update needed*.
|
|
57
59
|
- **Print the report footer** in the canonical order (version block → one-line backend-status line → welcome mat — the shared contracts in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`; rendered from the helpers, same host-can't-run skip-with-reason). The welcome mat closes on **one** caveat-aware next step (a behind member first, else `setup` / `recipes` / `velocity` / `agents` / `hook`).
|
|
58
60
|
- **Then ask before committing — never auto-commit.** If step 3 added the slot (or anything else changed), report it and ask. If step 3 was a pure zero-diff no-op and nothing else changed, give the plain **settings already current — no update needed** message (the *Success state* contract in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`) and still print the read-only version block (installed package versions) + backend line — but **no `docs/ai` structure version and no two-axes note** (nothing changed, so the number is inert here).
|
|
@@ -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`,
|
|
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.
|