@sabaiway/agent-workflow-kit 2.1.0 → 3.1.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 +94 -1
- package/README.md +7 -5
- package/SKILL.md +16 -8
- package/bin/install.mjs +11 -2
- package/bridges/antigravity-cli-bridge/SKILL.md +8 -1
- package/bridges/antigravity-cli-bridge/bin/agy-review-honesty.test.mjs +163 -0
- package/bridges/antigravity-cli-bridge/bin/agy-review-model-screen.test.mjs +76 -0
- package/bridges/antigravity-cli-bridge/bin/agy-review.sh +80 -15
- package/bridges/antigravity-cli-bridge/bin/agy-review.test.mjs +171 -22
- package/bridges/antigravity-cli-bridge/bin/agy.test.mjs +59 -41
- package/bridges/antigravity-cli-bridge/capability.json +3 -2
- package/bridges/codex-cli-bridge/SKILL.md +8 -1
- package/bridges/codex-cli-bridge/bin/codex-exec.test.mjs +67 -22
- package/bridges/codex-cli-bridge/bin/codex-review-honesty.test.mjs +156 -0
- package/bridges/codex-cli-bridge/bin/codex-review.sh +71 -10
- package/bridges/codex-cli-bridge/bin/codex-review.test.mjs +158 -27
- package/bridges/codex-cli-bridge/capability.json +3 -2
- package/capability.json +1 -1
- package/migrations/3.0.0-hardened-core-loop.md +44 -0
- package/migrations/README.md +1 -1
- package/package.json +2 -2
- package/references/hooks/gate-approve.mjs +1 -1
- package/references/modes/bootstrap.md +3 -3
- package/references/modes/commit-guard.md +19 -0
- package/references/modes/core-evidence.md +15 -0
- package/references/modes/coverage-check.md +12 -0
- package/references/modes/doc-parity.md +7 -6
- package/references/modes/gates.md +7 -6
- package/references/modes/grounding.md +1 -2
- package/references/modes/hook.md +1 -1
- package/references/modes/recommendations.md +1 -0
- package/references/modes/review-state.md +3 -3
- package/references/modes/upgrade.md +6 -6
- package/references/modes/velocity.md +2 -2
- package/references/modes/worktrees.md +120 -0
- package/references/scripts/archive-decisions.mjs +3 -3
- package/references/scripts/archive-decisions.test.mjs +5 -5
- package/references/scripts/check-docs-size-cli.test.mjs +41 -0
- package/references/scripts/check-docs-size.mjs +46 -29
- package/references/scripts/install-git-hooks-repo-exec.test.mjs +82 -0
- package/references/scripts/install-git-hooks.mjs +90 -18
- package/references/scripts/install-git-hooks.test.mjs +102 -0
- package/references/scripts/migrate-gates-branches.test.mjs +157 -0
- package/references/scripts/migrate-gates.mjs +395 -0
- package/references/scripts/migrate-gates.test.mjs +284 -0
- package/references/templates/agent_rules.md +2 -2
- package/tools/ack-write.mjs +1 -1
- package/tools/atomic-write.mjs +2 -2
- package/tools/autonomy-config.mjs +1 -1
- package/tools/autonomy-doctor.mjs +2 -2
- package/tools/autonomy-write.mjs +1 -1
- package/tools/bridge-settings-read.mjs +1 -1
- package/tools/bridge-settings.mjs +1 -1
- package/tools/changed-surface.mjs +16 -77
- package/tools/cheap-agents.mjs +2 -2
- package/tools/commands.mjs +26 -10
- package/tools/commit-guard.mjs +167 -0
- package/tools/core-evidence.mjs +914 -0
- package/tools/coverage-check.mjs +260 -0
- package/tools/delegation.mjs +1 -1
- package/tools/detect-backends.mjs +3 -3
- package/tools/doc-parity.mjs +11 -27
- package/tools/engine-source.mjs +1 -1
- package/tools/family-members.mjs +1 -1
- package/tools/family-registry.mjs +1 -1
- package/tools/fs-safe.mjs +1 -1
- package/tools/gate-hook.mjs +1 -1
- package/tools/{seed-gates.mjs → gates-init.mjs} +58 -52
- package/tools/grounding.mjs +19 -96
- package/tools/hide-footprint.mjs +1 -1
- package/tools/inject-methodology.mjs +72 -41
- package/tools/known-footprint.mjs +1 -1
- package/tools/labels.mjs +1 -1
- package/tools/lcov.mjs +6 -10
- package/tools/lens-region.mjs +1 -1
- package/tools/manifest/validate.mjs +19 -0
- package/tools/migrate-adr-store.mjs +5 -5
- package/tools/orchestration-config.mjs +1 -1
- package/tools/orchestration-write.mjs +1 -1
- package/tools/presentation.mjs +1 -1
- package/tools/procedures.mjs +3 -3
- package/tools/recipes.mjs +62 -11
- package/tools/recommendations.mjs +97 -14
- package/tools/release-scan.mjs +10 -3
- package/tools/renderers.mjs +1 -1
- package/tools/review-state.mjs +291 -343
- package/tools/run-gates.mjs +216 -92
- package/tools/sandbox-masks.mjs +14 -14
- package/tools/semver-lite.mjs +1 -1
- package/tools/set-autonomy.mjs +1 -1
- package/tools/set-recipe.mjs +2 -2
- package/tools/setup-backends.mjs +1 -1
- package/tools/surface.mjs +1 -1
- package/tools/uninstall.mjs +1 -1
- package/tools/velocity-profile.mjs +9 -9
- package/tools/view-model.mjs +1 -1
- package/tools/worktrees.mjs +2292 -0
- package/references/modes/fold-completeness.md +0 -30
- package/references/modes/review-ledger.md +0 -34
- package/references/templates/verification-profile.json +0 -10
- package/tools/fold-completeness-run.mjs +0 -1120
- package/tools/fold-completeness.mjs +0 -672
- package/tools/review-ledger-core.mjs +0 -428
- package/tools/review-ledger-write.mjs +0 -647
- package/tools/review-ledger.mjs +0 -630
- package/tools/sarif.mjs +0 -52
- package/tools/verification-profile.mjs +0 -219
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
### Mode: fold-completeness
|
|
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. **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
|
-
|
|
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
|
-
|
|
7
|
-
**Two tools — the read/run split:**
|
|
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 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.
|
|
15
|
-
|
|
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.
|
|
17
|
-
|
|
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.
|
|
19
|
-
|
|
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.
|
|
21
|
-
|
|
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).
|
|
23
|
-
|
|
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.
|
|
25
|
-
|
|
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).
|
|
27
|
-
|
|
28
|
-
**Honest residuals (stated, accepted — exactly like review-state's / review-ledger's):** coverage proves EXECUTION, not assertion — an executed-but-unasserted line still reads covered; the per-fold proof remains the M2 discipline (a `fixable-bug` testId written red→green, probed green here), the coverage run is the whole-surface prefilter; the result records, testIds, and ledgers are forgeable (`git commit --no-verify`, file editing) — a self-discipline mechanism against silent process drift, NOT a security boundary.
|
|
29
|
-
|
|
30
|
-
**Invariants:** the checker is read-only · never commits · never runs a subscription CLI · spawns read-only `git` queries only · the SOLE tree-toucher + result writer is `fold-completeness-run.mjs`, which the checker NEVER imports (read/run split, import-split test) · the runner's only writes land OUTSIDE the work tree (the coverage temp dir + the git-dir result ledger) — the tree fingerprint is byte-identical before and after a run.
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
### Mode: review-ledger
|
|
2
|
-
|
|
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
|
-
|
|
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
|
-
|
|
7
|
-
**Two tools — the read/write split (Decision 3):**
|
|
8
|
-
|
|
9
|
-
1. **Read-only checker** — `node ${CLAUDE_SKILL_DIR}/tools/review-ledger.mjs [--check | --status | --json]`:
|
|
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.
|
|
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.
|
|
14
|
-
|
|
15
|
-
2. **Writer** — `node ${CLAUDE_SKILL_DIR}/tools/review-ledger-write.mjs record|classify|override|batch --json '<payload>'` (the SOLE writer, over the shared `atomic-write` core):
|
|
16
|
-
- `record` appends one round — `{ loop, round, origins, backends, findings }` (activity defaults to `plan-execution`). **The teeth (Decision 5 + AD-048, all per SEGMENT):** it REFUSES (typed STOP) to append a round WHILE `decideStop` on the segment's records is `triage-required` (an UNCLASSIFIED surviving blocking finding at/after the cap); refuses ANY round beyond the **hard-max ceiling of 3 within one segment** unconditionally (the counter reopens only at the next gated commit); refuses while a blocking finding of the segment's previous round **VANISHED unclassified** (present means present-as-blocking — a downgrade to minor does not survive; a pending `escalate` never clears; `refuted` is the honest phantom lane); refuses while the changed source surface exceeds the **diff-size cap** (`AW_REVIEW_DIFF_CAP`, default 400 new-side lines of assessable + unsupported SOURCE — tests and out-of-domain never count, pure deletions are free) without a recorded segment `size-cap` override; and refuses without a **quality-green gate-run** at the current fingerprint (`run-gates --record` — gates-before-review is computed, not remembered; a `--only` subset or a tree-changed run never satisfies; red PROCESS gates — the kit's own `--check` loop gates — never block). **Integrity binding (Decision 7):** each NON-degraded backend needs an **attesting** code receipt for the current tree — a round cannot be recorded for a tree no bridge really reviewed. *Attesting* is the SHARED predicate (`review-ledger-core`) that `review-state` and the round cross-check read too, so the gates can never disagree about what counts: a fresh `code` receipt at the current fingerprint that is **grounded** AND carries an explicit **`probe:false`**. A `probe:true` receipt never attests (a probe review runs with the quality guards off), and a **malformed or ABSENT** marker is rejected fail-closed — silence is not a declaration, so a receipt from a pre-marker bridge no longer counts (refresh it: `npx @sabaiway/agent-workflow-kit@latest init`). Each exclusion states its own reason, because the recoveries differ. **`--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.
|
|
20
|
-
- **`batch`** applies an ordered list of `record` / `classify` / `override` operations in ONE invocation — the prompt-economy lane for a records stage (WRITER-BURST-BATCH: one writer call, not one per op). The payload is `{ operations: [ { verb, …that verb's payload } ] }` (a `record` op may carry `fromReceipts: true`); every op rides the SAME per-verb teeth (no forked validator), so N batched ops are record-equivalent to the same N single invocations. **Two passes:** the whole envelope is validated STRUCTURALLY first with ZERO writes (a malformed envelope stops before any op runs), then ops apply sequentially and **fail-fast** on the first typed STOP — the ops already applied stay recorded (append-only, no rollback) and the STOP names the failing op index + the applied count; **resume by re-running the REMAINING ops**.
|
|
21
|
-
|
|
22
|
-
**The computed stop (`decideStop`, precedence `converged > resolved-residual > triage-required > continue`).** Machine fields only (counts, `class`, `accepted`, `fingerprint`), never free-text:
|
|
23
|
-
- **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).
|
|
24
|
-
- **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).
|
|
25
|
-
- **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.
|
|
26
|
-
- **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).
|
|
27
|
-
|
|
28
|
-
**"Every named backend" = "every NON-degraded named backend" (Decision 4).** A backend recorded `degraded:true` (agy is Issue-001-degraded on large diffs) is EXCLUDED from the 0/0 convergence requirement AND from the receipt cross-check (it ran no real review, mints no receipt), but is RECORDED (verdict `degraded`, a required `reason`) — it can never FAKE convergence. A recipe-named backend with NO entry is `missing` (≠ degraded) and BLOCKS convergence. Because the `degraded` mark is self-reported, `--check` surfaces every degraded backend loudly.
|
|
29
|
-
|
|
30
|
-
**Wire `--check` as a gate by hand OR via the explicit-consent seeder — never without consent.** The candidate line for your own `docs/ai/gates.json`: `{ "id": "review-ledger", "title": "Review-round ledger: the in-flight loop is converged or resolved-residual", "cmd": "node <path-to-this-skill>/tools/review-ledger.mjs --check" }` — the path your project reaches the kit by, QUOTED. The consent-gated seeder offers exactly this entry ONLY when `docs/ai/orchestration.json` declares `reviewed`/`council` on `plan-execution.review`.
|
|
31
|
-
|
|
32
|
-
**Human residual (stated, accepted — like `review-state`'s):** the ledger attests a review occurred and its ship-class is consistent; it does NOT prove the recorded COUNTS are truthful, nor that a self-reported `degraded:true` is real (`git commit --no-verify`, ledger-file editing, and forged counts remain possible). The ledger lives in the git dir (never committable) — a self-discipline mechanism against silent process drift, not a security boundary.
|
|
33
|
-
|
|
34
|
-
**Invariants:** the read module is read-only · never commits · never runs a subscription CLI · spawns read-only `git` queries only · the SOLE writer is `review-ledger-write.mjs`, which the read module NEVER imports (structural read/write split, import-split test) · `hardMax` is a writer-only ceiling, never a `decideStop` input.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_README": "Optional per-project VERIFICATION PROFILE for the fold-completeness gate (the language-independence contract). DELETE this file to reproduce the exact default behaviour (V8 line coverage + node:test TAP on stdout) — an absent profile is fully supported. Present, it GENERALIZES three inputs so a consumer on another language/runner can drive the same gate: (1) coverage.kind is \"v8\" (default) or \"lcov\" — with lcov, set coverage.lcovPath to where your suite leaves an LCOV file; (2) singleTest.argv is the shell-free command template for probing ONE test (placeholders {file} and {pattern} are required; a file-based resultFormat also requires {resultPath}), and singleTest.resultFormat is \"tap-stdout\" (default), \"tap-file\", or \"junit-xml\"; (3) findings.sarifPath (optional) points at a SARIF file for advisory-only findings (never gate-blocking). The suite COMMAND is NOT declared here — it stays your docs/ai/gates.json unit-tests gate (so the fold run and the gate share command-identity). Every DECLARED path (coverage.lcovPath, findings.sarifPath) MUST be gitignored or outside the repo (a symlink is refused): an in-tree, non-ignored file the suite writes would move the review fingerprint. Env knobs still override (AW_FOLD_SUITE_CMD / AW_FOLD_BOUND_CMD / AW_FOLD_RESULTS). Strict JSON — no comments.",
|
|
3
|
-
"schema": 1,
|
|
4
|
-
"coverage": { "kind": "v8" },
|
|
5
|
-
"singleTest": {
|
|
6
|
-
"argv": ["node", "--test", "--test-reporter", "tap", "--test-name-pattern={pattern}", "{file}"],
|
|
7
|
-
"resultFormat": "tap-stdout"
|
|
8
|
-
},
|
|
9
|
-
"findings": {}
|
|
10
|
-
}
|