@sabaiway/agent-workflow-kit 1.49.0 → 2.0.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 +71 -0
- package/SKILL.md +1 -1
- package/bridges/antigravity-cli-bridge/SKILL.md +9 -1
- package/bridges/antigravity-cli-bridge/bin/agy-review.sh +22 -9
- package/bridges/antigravity-cli-bridge/bin/agy-review.test.mjs +173 -2
- package/bridges/antigravity-cli-bridge/bin/agy.test.mjs +76 -0
- package/bridges/antigravity-cli-bridge/capability.json +160 -2
- package/bridges/codex-cli-bridge/SKILL.md +8 -1
- package/bridges/codex-cli-bridge/bin/codex-exec.test.mjs +133 -0
- package/bridges/codex-cli-bridge/bin/codex-review.sh +22 -9
- package/bridges/codex-cli-bridge/bin/codex-review.test.mjs +165 -2
- package/bridges/codex-cli-bridge/capability.json +118 -2
- package/capability.json +1 -1
- package/package.json +1 -1
- package/references/modes/review-ledger.md +1 -1
- package/references/modes/review-state.md +2 -2
- package/tools/detect-backends.mjs +2 -2
- package/tools/manifest/schema.md +62 -0
- package/tools/manifest/validate.mjs +327 -0
- package/tools/review-ledger-core.mjs +74 -0
- package/tools/review-ledger-write.mjs +19 -10
- package/tools/review-ledger.mjs +21 -12
- package/tools/review-state.mjs +89 -28
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"schema": 1,
|
|
4
4
|
"name": "codex-cli-bridge",
|
|
5
5
|
"kind": "execution-backend",
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.8.0",
|
|
7
7
|
"provides": ["execute", "review"],
|
|
8
8
|
"roles": {
|
|
9
9
|
"execute": {
|
|
@@ -42,10 +42,126 @@
|
|
|
42
42
|
],
|
|
43
43
|
"grounding": "automatic — the wrapper precomputes the full working-tree change set (repo map, status, diffs, untracked contents) and codex auto-merges the root AGENTS.md; no grounding flags",
|
|
44
44
|
"continue": [],
|
|
45
|
-
"receipt": "side effect — a successful review appends one JSON receipt line to <git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides): fingerprint = sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff + untracked-not-ignored contents — the review-payload domain; never-committable untracked paths — character/block devices, FIFOs, sockets — are excluded from the domain entirely, untracked symlinks/directories ride as name-only notes) in code mode, the artifact-file sha256 in plan mode; verdict parsed from the mandated literal verdict line (schema mode: the verdict field); always fresh:true (one-shot) + grounded:true (native AGENTS.md auto-merge, factsHash null); a write failure warns, never fails the review"
|
|
45
|
+
"receipt": "side effect — a successful review appends one JSON receipt line to <git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides): fingerprint = sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff + untracked-not-ignored contents — the review-payload domain; never-committable untracked paths — character/block devices, FIFOs, sockets — are excluded from the domain entirely, untracked symlinks/directories ride as name-only notes) in code mode, the artifact-file sha256 in plan mode; verdict parsed from the mandated literal verdict line (schema mode: the verdict field); always fresh:true (one-shot) + grounded:true (native AGENTS.md auto-merge, factsHash null); probe = whether the run relaxed the quality guards (CODEX_PROBE=1), written on EVERY receipt so it self-declares — the kit's review-state gate rejects a probe-marked receipt (a probe review never attests) and equally rejects an unmarked one (silence is not a declaration); a write failure warns, never fails the review"
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
|
+
"modeCatalog": [
|
|
50
|
+
{
|
|
51
|
+
"key": "exec",
|
|
52
|
+
"kind": "primary",
|
|
53
|
+
"role": "execute",
|
|
54
|
+
"purpose": "Execute a bounded plan in a sandboxed workspace and hand back a diff to review.",
|
|
55
|
+
"whenToUse": [
|
|
56
|
+
"a bounded sub-task whose acceptance criteria are already pinned",
|
|
57
|
+
"work you will review and commit yourself — the backend never commits"
|
|
58
|
+
],
|
|
59
|
+
"whenNotTo": [
|
|
60
|
+
"work whose design is still open — decide it first, then delegate",
|
|
61
|
+
"anything you cannot check: the diff is advisory until you review it"
|
|
62
|
+
],
|
|
63
|
+
"invocationRefs": [
|
|
64
|
+
{ "contractField": "invocations", "index": 0 },
|
|
65
|
+
{ "contractField": "invocations", "index": 1 }
|
|
66
|
+
],
|
|
67
|
+
"operands": [
|
|
68
|
+
{ "slot": "<plan-file|->", "required": true, "description": "the plan or instruction file, or - to read it from stdin" },
|
|
69
|
+
{ "slot": "<extra codex flags...>", "required": false, "description": "extra codex flags, filtered by the guarded passthrough tiers" }
|
|
70
|
+
],
|
|
71
|
+
"guardrails": [
|
|
72
|
+
{ "value": "runs under codex's OWN OS sandbox (workspace-write)", "enforcement": "enforced", "condition": "it cannot nest inside another sandbox — the FS turns read-only; route it outside on the OBSERVED failure", "source": "capability.json roles.execute.contract.notes" },
|
|
73
|
+
{ "value": "the guarded passthrough blocks model / sandbox / approval overrides", "enforcement": "enforced", "source": "bin/codex-exec.sh" },
|
|
74
|
+
{ "value": "hard wall-clock cap CODEX_HARD_TIMEOUT (built-in default 3600s)", "enforcement": "enforced", "condition": "only while timeout(1)/gtimeout is on PATH — otherwise the wrapper warns and runs uncapped", "source": "capability.json settings.CODEX_HARD_TIMEOUT" }
|
|
75
|
+
],
|
|
76
|
+
"customHooks": ["CODEX_PROBE"]
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"key": "exec.resume-last",
|
|
80
|
+
"kind": "continuation",
|
|
81
|
+
"role": "execute",
|
|
82
|
+
"purpose": "Continue the most recent codex-exec session with a follow-up instruction.",
|
|
83
|
+
"whenToUse": ["a small delta on work the same session already holds in context"],
|
|
84
|
+
"whenNotTo": ["a fresh task — a stale session carries stale assumptions"],
|
|
85
|
+
"invocationRefs": [{ "contractField": "continue", "index": 0 }],
|
|
86
|
+
"operands": [
|
|
87
|
+
{ "slot": "<plan-file|->", "required": true, "description": "the follow-up instruction file, or - to read it from stdin" }
|
|
88
|
+
],
|
|
89
|
+
"customHooks": ["CODEX_PROBE"]
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"key": "exec.resume",
|
|
93
|
+
"kind": "continuation",
|
|
94
|
+
"role": "execute",
|
|
95
|
+
"purpose": "Continue a NAMED codex-exec session by the session id it printed.",
|
|
96
|
+
"whenToUse": ["resuming a specific earlier session after other runs happened in between"],
|
|
97
|
+
"invocationRefs": [{ "contractField": "continue", "index": 1 }],
|
|
98
|
+
"operands": [
|
|
99
|
+
{ "slot": "<session-id>", "required": true, "description": "the session id the original run printed on stderr" },
|
|
100
|
+
{ "slot": "<plan-file|->", "required": true, "description": "the follow-up instruction file, or - to read it from stdin" }
|
|
101
|
+
],
|
|
102
|
+
"customHooks": ["CODEX_PROBE"]
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"key": "review.plan",
|
|
106
|
+
"kind": "primary",
|
|
107
|
+
"role": "review",
|
|
108
|
+
"submode": "plan",
|
|
109
|
+
"purpose": "Critique an implementation plan before any of its code exists.",
|
|
110
|
+
"whenToUse": [
|
|
111
|
+
"a plan draft heading into its review council",
|
|
112
|
+
"checking whether a cold executor could really run the plan"
|
|
113
|
+
],
|
|
114
|
+
"whenNotTo": ["a working-tree change set — that is review.code"],
|
|
115
|
+
"invocationRefs": [{ "contractField": "invocations", "index": 0 }],
|
|
116
|
+
"operands": [
|
|
117
|
+
{ "slot": "<plan-file>", "required": true, "description": "the plan file under review" }
|
|
118
|
+
],
|
|
119
|
+
"guardrails": [
|
|
120
|
+
{ "value": "read-only sandbox — codex cannot edit, create or delete a file", "enforcement": "enforced", "source": "bin/codex-review.sh" },
|
|
121
|
+
{ "value": "runs on the pinned frontier model at max effort", "enforcement": "enforced", "condition": "unless CODEX_PROBE=1 relaxes the guard for a throwaway probe", "source": "bin/codex-review.sh" },
|
|
122
|
+
{ "value": "a successful review appends one receipt line the review-state gate reads", "enforcement": "enforced", "condition": "a receipt write failure warns and the review still succeeds — the tree then reads un-receipted", "source": "capability.json roles.review.contract.receipt" }
|
|
123
|
+
],
|
|
124
|
+
"customHooks": ["CODEX_PROBE"]
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"key": "review.code",
|
|
128
|
+
"kind": "primary",
|
|
129
|
+
"role": "review",
|
|
130
|
+
"submode": "code",
|
|
131
|
+
"purpose": "Review the uncommitted working-tree change set, precomputed in full for codex.",
|
|
132
|
+
"whenToUse": [
|
|
133
|
+
"a finished segment heading into its review round",
|
|
134
|
+
"a second opinion on real code before the commit ask"
|
|
135
|
+
],
|
|
136
|
+
"whenNotTo": ["a clean tree — the wrapper exits before spending a run"],
|
|
137
|
+
"invocationRefs": [{ "contractField": "invocations", "index": 1 }],
|
|
138
|
+
"operands": [
|
|
139
|
+
{ "slot": "[extra focus...]", "required": false, "description": "extra focus words appended to the review directive" }
|
|
140
|
+
],
|
|
141
|
+
"guardrails": [
|
|
142
|
+
{ "value": "read-only sandbox — codex cannot edit, create or delete a file", "enforcement": "enforced", "source": "bin/codex-review.sh" },
|
|
143
|
+
{ "value": "an oversized change set rides via a git-dir temp file, never truncated", "enforcement": "enforced", "source": "bin/codex-review.sh" },
|
|
144
|
+
{ "value": "a successful review appends one receipt line the review-state gate reads", "enforcement": "enforced", "condition": "a receipt write failure warns and the review still succeeds — the tree then reads un-receipted", "source": "capability.json roles.review.contract.receipt" }
|
|
145
|
+
],
|
|
146
|
+
"customHooks": ["CODEX_PROBE"]
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"key": "CODEX_PROBE",
|
|
150
|
+
"kind": "env-hook",
|
|
151
|
+
"parents": ["exec", "exec.resume-last", "exec.resume", "review.plan", "review.code"],
|
|
152
|
+
"purpose": "Relax the quality guards for a THROWAWAY probe run.",
|
|
153
|
+
"whenToUse": [
|
|
154
|
+
"a probe whose answer cannot depend on model or effort",
|
|
155
|
+
"checking that the wrapper plumbing works at all"
|
|
156
|
+
],
|
|
157
|
+
"whenNotTo": ["any run whose output informs what ships — a probe never attests"],
|
|
158
|
+
"descriptor": "CODEX_PROBE=1 codex-review code",
|
|
159
|
+
"guardrails": [
|
|
160
|
+
{ "value": "a probe review mints a probe-marked receipt the review-state gate rejects", "enforcement": "enforced", "source": "agent-workflow-kit tools/review-state.mjs" },
|
|
161
|
+
{ "value": "on codex-exec it also relaxes the passthrough to the probeRelaxed tier", "enforcement": "enforced", "source": "bin/codex-exec.sh" }
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
],
|
|
49
165
|
"settings": [
|
|
50
166
|
{
|
|
51
167
|
"key": "CODEX_SERVICE_TIER",
|
package/capability.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sabaiway/agent-workflow-kit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.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",
|
|
@@ -13,7 +13,7 @@ The review-round **LEDGER** (DEBT-REVIEW-CAP / AD-045) — it turns the prose re
|
|
|
13
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
14
|
|
|
15
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
|
|
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
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
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
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.
|
|
@@ -4,8 +4,8 @@ Read-only **review-receipt checker** (AD-038) — it makes *"reviewed ≠ shippe
|
|
|
4
4
|
|
|
5
5
|
Run `node ${CLAUDE_SKILL_DIR}/tools/review-state.mjs [--check] [--json]`:
|
|
6
6
|
|
|
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
|
-
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** — **or degraded-exempt**: the current segment's latest **review-ledger** round records that backend `degraded:true` at the current tree fingerprint, with ≥1 non-degraded recipe-named backend present + grounded and the ledger reading clean (AD-050; a corrupt ledger DENIES the exemption fail-closed but never fails an otherwise-satisfied tree — the tool header is the single home). Exit 1 when a backend is missing, **stale** (ANY edit after its review moves the fingerprint), or grounded:false under reviewed/council, and is not degraded-exempt. **Presence, not unanimity:** verdict adjudication (ship/revise, the divergence crossover) stays orchestrator judgment — the gate only proves the configured backends really reviewed THIS tree (a recorded degrade counts as "reviewed", never as "converged" — that stays `review-ledger`'s job). 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.
|
|
7
|
+
1. Plain run → the human report: resolved recipe + source, plan-in-flight, tree fingerprint, per-backend receipt state (current / stale / ungrounded / probe / rejected / missing) with verdict + grounding + timestamp.
|
|
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** — **or degraded-exempt**: the current segment's latest **review-ledger** round records that backend `degraded:true` at the current tree fingerprint, with ≥1 non-degraded recipe-named backend present + grounded and the ledger reading clean (AD-050; a corrupt ledger DENIES the exemption fail-closed but never fails an otherwise-satisfied tree — the tool header is the single home). Exit 1 when a backend is missing, **stale** (ANY edit after its review moves the fingerprint), or grounded:false under reviewed/council, and is not degraded-exempt. **Presence, not unanimity:** verdict adjudication (ship/revise, the divergence crossover) stays orchestrator judgment — the gate only proves the configured backends really reviewed THIS tree (a recorded degrade counts as "reviewed", never as "converged" — that stays `review-ledger`'s job). 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. **Probe receipts never attest either:** a `CODEX_PROBE=1` / `AGY_PROBE=1` review runs with the frontier-model/max-effort guard OFF, so the wrapper stamps `probe:true` and this checker excludes it — a backend whose only current receipts are probes fails with its own stated reason, distinct from stale. The filter is **per receipt**, so a real review at the same fingerprint still satisfies. **Silence is not a declaration:** a marker-aware wrapper writes `probe` on **every** successful review — `true` or `false` — so the receipt states the fact itself, and a **malformed** *or* **absent** marker is rejected **fail-closed** and stated in the check line, never silently dropped. This is deliberately **not** keyed on the wrapper version: the version bumps in a different release phase than the marker lands, so a version floor would reject the very receipts the current wrappers write — and it could only ever proxy a fact the receipt already carries. Accepted cost: a pre-marker receipt stops satisfying — re-run the review with a marker-aware bridge. Honest bound: receipts are **not authenticated** (a forger could write `probe:false` as easily as any other field) — like the rest of the receipt this is a self-discipline mechanism, not a security boundary.
|
|
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
10
|
4. **`--await [--timeout <s>]`** (BUGFREE-3 / AD-049) → BLOCK until every recipe-named backend is SATISFIED 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 until each backend has a fresh grounded receipt **OR is degraded-exempt**: once a current-tree degrade is recorded in the review-ledger, `--await` stops waiting for that backend and returns READY (AD-050 — it inherits the `--check` exemption via the shared decision), so you no longer hand-`--await` around a known degrade. Still read-only (it only re-reads state, now the ledger too); solo / no-plan / clean-tree resolve instantly.
|
|
11
11
|
|
|
@@ -91,7 +91,7 @@ const RAW_BACKENDS = [
|
|
|
91
91
|
],
|
|
92
92
|
grounding: 'automatic — the wrapper precomputes the full working-tree change set (repo map, status, diffs, untracked contents) and codex auto-merges the root AGENTS.md; no grounding flags',
|
|
93
93
|
continue: [],
|
|
94
|
-
receipt: 'side effect — a successful review appends one JSON receipt line to <git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides): fingerprint = sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff + untracked-not-ignored contents — the review-payload domain; never-committable untracked paths — character/block devices, FIFOs, sockets — are excluded from the domain entirely, untracked symlinks/directories ride as name-only notes) in code mode, the artifact-file sha256 in plan mode; verdict parsed from the mandated literal verdict line (schema mode: the verdict field); always fresh:true (one-shot) + grounded:true (native AGENTS.md auto-merge, factsHash null); a write failure warns, never fails the review',
|
|
94
|
+
receipt: 'side effect — a successful review appends one JSON receipt line to <git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides): fingerprint = sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff + untracked-not-ignored contents — the review-payload domain; never-committable untracked paths — character/block devices, FIFOs, sockets — are excluded from the domain entirely, untracked symlinks/directories ride as name-only notes) in code mode, the artifact-file sha256 in plan mode; verdict parsed from the mandated literal verdict line (schema mode: the verdict field); always fresh:true (one-shot) + grounded:true (native AGENTS.md auto-merge, factsHash null); probe = whether the run relaxed the quality guards (CODEX_PROBE=1), written on EVERY receipt so it self-declares — the kit\'s review-state gate rejects a probe-marked receipt (a probe review never attests) and equally rejects an unmarked one (silence is not a declaration); a write failure warns, never fails the review',
|
|
95
95
|
},
|
|
96
96
|
},
|
|
97
97
|
bin: 'codex',
|
|
@@ -124,7 +124,7 @@ const RAW_BACKENDS = [
|
|
|
124
124
|
'agy-review --continue [--decided @f] [--focus "…"]',
|
|
125
125
|
'agy-review --conversation <id> [--decided @f] [--focus "…"]',
|
|
126
126
|
],
|
|
127
|
-
receipt: "side effect — a successful review appends one JSON receipt line to <git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides; plan/diff outside a git tree: warn + skip unless overridden): fingerprint = sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff + untracked-not-ignored contents — the review-payload domain; never-committable untracked paths — character/block devices, FIFOs, sockets — are excluded from the domain entirely, untracked symlinks/directories ride as name-only notes) in code mode, the artifact-file sha256 in plan/diff mode; verdict recorded verbatim from the mandated '### Verdict' section (SHIP / SHIP WITH NITS / REWORK); grounded = whether a NON-EMPTY --facts payload was supplied (an empty payload records grounded:false — fail-closed, the state gate rejects it), factsHash = sha256 of the facts payload; a continuation receipt is fresh:false (informational-only — it cannot attest the folded tree); a write failure warns, never fails the review",
|
|
127
|
+
receipt: "side effect — a successful review appends one JSON receipt line to <git dir>/agent-workflow-review-receipts.jsonl (AW_REVIEW_RECEIPTS overrides; plan/diff outside a git tree: warn + skip unless overridden): fingerprint = sha256 over the canonical uncommitted-state payload (staged diff + unstaged diff + untracked-not-ignored contents — the review-payload domain; never-committable untracked paths — character/block devices, FIFOs, sockets — are excluded from the domain entirely, untracked symlinks/directories ride as name-only notes) in code mode, the artifact-file sha256 in plan/diff mode; verdict recorded verbatim from the mandated '### Verdict' section (SHIP / SHIP WITH NITS / REWORK); grounded = whether a NON-EMPTY --facts payload was supplied (an empty payload records grounded:false — fail-closed, the state gate rejects it), factsHash = sha256 of the facts payload; a continuation receipt is fresh:false (informational-only — it cannot attest the folded tree); probe = whether the run relaxed the quality guards (AGY_PROBE=1), written on EVERY receipt so it self-declares — the kit's review-state gate rejects a probe-marked receipt (a probe review never attests) and equally rejects an unmarked one (silence is not a declaration); a write failure warns, never fails the review",
|
|
128
128
|
notes: [
|
|
129
129
|
'pre-dispatch host-diff: before the FIRST dispatch of this bridge, diff its declared networkHosts against the live sandbox allow-list — a missing host is surfaced to the maintainer BEFORE dispatching, never fired into a known prompt',
|
|
130
130
|
],
|
package/tools/manifest/schema.md
CHANGED
|
@@ -20,6 +20,7 @@ expansion), never via the shell. The validator is [`validate.mjs`](./validate.mj
|
|
|
20
20
|
| `settings` | array | no | the bridge's **settings-file surface** (typed; see *Settings*). Unlike `contract`, a malformed entry **fails** `--strict`. |
|
|
21
21
|
| `networkHosts` | string[] | no | the backend CLI's **observed egress host families** (see *Network hosts*). A malformed list **fails** `--strict`. |
|
|
22
22
|
| `writableDirs` | object[] | no | the backend CLI's **writable state-dir declarations** — `{env, default}` entries (see *Writable dirs*). A malformed list **fails** `--strict`. |
|
|
23
|
+
| `modeCatalog` | object[] | no | the bridge's **user-facing operating modes** — what each mode is FOR and when to reach for it (see *Mode catalog*). A malformed block **fails** `--strict`. |
|
|
23
24
|
| `install` / `uninstall` | object | no | `install.npm` is a package name, not a path |
|
|
24
25
|
| `cost` / `quota` / `provenance` | misc | no | informational |
|
|
25
26
|
| `available` | boolean | no | `false` = a declared-but-not-installed stub; skips fs/version checks |
|
|
@@ -128,6 +129,67 @@ declared path is only the **default under no override**. Rules:
|
|
|
128
129
|
`sandbox.filesystem.allowWrite` or any other filesystem allowance — the entries feed the
|
|
129
130
|
sandbox-lane discoverability item (session/host sandbox config is hand-applied territory).
|
|
130
131
|
|
|
132
|
+
## Mode catalog (BRIDGE-MODES-CATALOG)
|
|
133
|
+
|
|
134
|
+
`modeCatalog` answers the question the `contract` block deliberately does not: **what modes does
|
|
135
|
+
this bridge offer, and what is each one FOR?** The `contract` is the internal DRIVING contract (how
|
|
136
|
+
a dispatching agent invokes a role); the catalog is the **user-facing discovery surface**. They are
|
|
137
|
+
related, never nested: a catalog entry backed by a contract **composes by reference** and never
|
|
138
|
+
restates a descriptor.
|
|
139
|
+
|
|
140
|
+
**Additive-optional.** The schema stays `1`. An absent block is **valid** — a bridge released before
|
|
141
|
+
the catalog keeps validating, and the mode renders a stated *"no catalog — this bridge predates it"*
|
|
142
|
+
line rather than `invalid-manifest` or an empty silent list. A **present** block is typed-validated
|
|
143
|
+
like `settings`: the renderer prints these strings verbatim and builds invocation forms from the
|
|
144
|
+
refs, so a malformed entry would render a lying discovery surface.
|
|
145
|
+
|
|
146
|
+
**Currency claim (honest scope):** the catalog tracks the **documented wrapper mode set** — never
|
|
147
|
+
"the CLI's modes". Upstream CLI evolution enters through a bridge release, where the source-level
|
|
148
|
+
drift tests fail loudly until the catalog is updated. Nothing here ever probes a live CLI.
|
|
149
|
+
|
|
150
|
+
An **array** of entries (an object would silently dedupe keys under `JSON.parse`). Each entry:
|
|
151
|
+
|
|
152
|
+
- `key` (string, required) — a **unique bare token** (`exec`, `review.plan`, `exec.resume-last`).
|
|
153
|
+
For an `env-hook` the key **IS** its env-var name, so it must be UPPER_SNAKE_CASE.
|
|
154
|
+
- `kind` (string, required) — the closed taxonomy:
|
|
155
|
+
- `primary` — a mode you drive directly (`codex exec`, `agy-review code`, the raw `agy-run`).
|
|
156
|
+
- `continuation` — resumes a mode already in flight (`--resume-last`, `--continue`).
|
|
157
|
+
- `env-hook` — an env var that MODIFIES named modes (`CODEX_PROBE`). It names `parents[]`, never
|
|
158
|
+
a role: an env var is not a capability, and a fake role would corrupt the recipe planner.
|
|
159
|
+
- `role` (string) — required on `primary`/`continuation`, must be a declared key of `roles`;
|
|
160
|
+
**forbidden** on an `env-hook`.
|
|
161
|
+
- `parents` (string[]) — required and non-empty on an `env-hook`, resolving to catalog keys (never
|
|
162
|
+
itself); **forbidden** elsewhere.
|
|
163
|
+
- `submode` (string) — the **explicit** binding to the wrapper's parser mode arm. Present exactly
|
|
164
|
+
when the entry is a `primary` **and** its role declares `modes[]`; must be one of them. The
|
|
165
|
+
bridge drift tests set-equal these against the wrapper's REAL arms — the binding is never parsed
|
|
166
|
+
back out of the key.
|
|
167
|
+
- `purpose` (string, required) — one line: what the mode is for.
|
|
168
|
+
- `whenToUse` (string[], required, non-empty) / `whenNotTo` (string[], optional) — the reach-for-it
|
|
169
|
+
and reach-for-something-else signals.
|
|
170
|
+
- `invocationRefs` (object[]) — **composition by reference**: `{contractField, index}` into
|
|
171
|
+
`roles[<role>].contract.invocations` / `.continue`. Required (non-empty) on a contract-backed
|
|
172
|
+
entry; every ref must resolve, and a contract invocation is claimed by **at most one** entry.
|
|
173
|
+
- `descriptor` (string) — the literal invocation form. Allowed **only** where no contract exists (a
|
|
174
|
+
contract-free primary such as a raw-prompt mode, or an env-hook): for those the catalog IS
|
|
175
|
+
canonical — the stated exception to no-duplication.
|
|
176
|
+
- `operands` (object[], optional) — `{slot, required, description}`. Typed **catalog data**, never
|
|
177
|
+
parsed out of contract strings. Each `slot` is unique within the entry and must really appear in
|
|
178
|
+
one of the entry's rendered invocation forms — the render labels an unfilled form a **template**
|
|
179
|
+
and names each required operand, so a slot with nowhere to go would be a lie.
|
|
180
|
+
- `guardrails` (object[], optional) — `{value, enforcement, condition?, source}`. `enforcement` is
|
|
181
|
+
`enforced` **only** for an OS-/code-enforced fact; where the guarantee has a runtime bound, the
|
|
182
|
+
`condition` carries it (e.g. a hard timeout is enforced *only when `timeout(1)`/`gtimeout` is on
|
|
183
|
+
PATH*). Anything a prompt merely asks for renders `advisory`. `source` names where the fact lives.
|
|
184
|
+
- `customHooks` (string[], optional) — this mode's escape hatches, as catalog keys. Each is either
|
|
185
|
+
an **env-hook that really lists this mode in its `parents[]`** (a hook can never lie about a mode
|
|
186
|
+
it does not target), or the entry's **own key** — the raw-mode carve-out: a contract-free primary
|
|
187
|
+
IS its own escape, so it references itself rather than repeating one it does not have.
|
|
188
|
+
|
|
189
|
+
Every string the renderer prints (`purpose`, `whenToUse`/`whenNotTo` items, `descriptor`, operand
|
|
190
|
+
`description`, guardrail `value`/`condition`/`source`) is ONE line of at most **200** characters
|
|
191
|
+
with no control characters — the surface is a terminal-width list and a pasted form.
|
|
192
|
+
|
|
131
193
|
## Path-field rules (Windows-safe, traversal-safe)
|
|
132
194
|
|
|
133
195
|
These rules govern the **repo/project-relative path fields** enumerated below (`source`,
|