@sabaiway/agent-workflow-kit 5.4.0 → 5.6.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +1 -0
  3. package/SKILL.md +5 -1
  4. package/bridges/antigravity-cli-bridge/SKILL.md +1 -1
  5. package/bridges/antigravity-cli-bridge/bin/agy-review.sh +1 -1
  6. package/bridges/antigravity-cli-bridge/capability.json +1 -1
  7. package/bridges/codex-cli-bridge/SKILL.md +51 -4
  8. package/bridges/codex-cli-bridge/bin/codex-exec.sh +616 -24
  9. package/bridges/codex-cli-bridge/bin/codex-exec.test.mjs +700 -1
  10. package/bridges/codex-cli-bridge/bin/codex-review.sh +1 -1
  11. package/bridges/codex-cli-bridge/capability.json +15 -10
  12. package/capability.json +1 -1
  13. package/package.json +1 -1
  14. package/references/modes/dispatch.md +29 -0
  15. package/references/modes/gates.md +6 -3
  16. package/references/modes/procedures.md +2 -0
  17. package/references/modes/receipt-deadline.md +3 -3
  18. package/references/modes/recommendations.md +1 -1
  19. package/references/modes/velocity.md +1 -0
  20. package/tools/commands.mjs +7 -0
  21. package/tools/core-evidence.mjs +37 -3
  22. package/tools/detect-backends.mjs +5 -4
  23. package/tools/dispatch-record.mjs +10 -3
  24. package/tools/dispatch-store.mjs +392 -0
  25. package/tools/dispatch.mjs +1779 -0
  26. package/tools/doc-parity.mjs +10 -2
  27. package/tools/exec-producer.mjs +483 -0
  28. package/tools/exec-receipt.mjs +263 -0
  29. package/tools/flow-check-cores.mjs +253 -0
  30. package/tools/flow-check-git-lane.mjs +56 -0
  31. package/tools/flow-check-rungs.mjs +330 -0
  32. package/tools/flow-check.mjs +23 -611
  33. package/tools/flow-store.mjs +111 -462
  34. package/tools/gates-declaration.mjs +13 -1
  35. package/tools/gates-init.mjs +134 -22
  36. package/tools/procedures.mjs +64 -5
  37. package/tools/receipt-deadline.mjs +25 -3
  38. package/tools/recommendations.mjs +108 -7
  39. package/tools/release-scan.mjs +33 -0
  40. package/tools/source-size-check.mjs +320 -0
  41. package/tools/source-size-config.mjs +244 -0
  42. package/tools/source-size-core.mjs +53 -0
  43. package/tools/source-size-gate-cmd.mjs +55 -0
  44. package/tools/source-size-judge.mjs +114 -0
  45. package/tools/source-size-refusal.mjs +70 -0
  46. package/tools/source-size-report.mjs +254 -0
  47. package/tools/source-size-scope.mjs +145 -0
  48. package/tools/store-append.mjs +444 -0
  49. package/tools/velocity-profile.mjs +24 -3
package/CHANGELOG.md CHANGED
@@ -4,6 +4,136 @@ 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
+ ## 5.6.0 — a source-size practice your project declares, and a record that is debt rather than permission (AD-091; engine 2.1.0)
8
+
9
+ **A big module is expensive long before anyone calls it a problem, and nothing in the kit ever said
10
+ so.** This release adds the practice: a checker your project declares scope for, a cap it can hold
11
+ you to, and — for the files already over it — a recorded baseline that can shrink for free but can
12
+ only GROW with a written reason. Nothing is guessed and nothing is imposed: a project that declares
13
+ no scope gets no cap, and the one manual step is a scope file you author from the starter template
14
+ the tool prints — its `roots`/`extensions` placeholders are deliberately invalid until you replace
15
+ them. With a valid, judgeable scope, `--adopt` then mints the record and attempts the gate
16
+ declaration, reporting the second half if it is refused.
17
+
18
+ - **`source-size-check.mjs` — the checker, and it refuses rather than assumes.** In scope is what
19
+ you DECLARE: git-tracked files under your roots, with your extensions, minus your excluded
20
+ prefixes. New files stay within 400 lines and 1000 bytes per line by default (both overridable,
21
+ because a multi-KB single line hides from a line count). There is no default root list, no default
22
+ file-type list and no content sniffing — a fixed extension list would silently exempt every
23
+ language it forgot. Run it with no config and it tells you the exact path to author and prints a
24
+ template; the placeholders in that template are rejected by the validator until you replace them,
25
+ so the printed starting point can never be pasted into a scope that matches nothing and passes.
26
+ - **A recorded size is DEBT, not permission — that is the whole design.** Adopting on a real
27
+ codebase records today's oversized files instead of demanding a refactor you did not plan. From
28
+ then on the record only moves under rules: it may not grow without `--reason "<text>"` (recorded
29
+ verbatim in the entry it raised), it may not sit ABOVE what the tree now measures (a stale record
30
+ is headroom nobody earned, so the checker tells you to tighten it), and it disappears when the
31
+ file finally comes back under the cap. A record whose file is GONE is an error — that is what
32
+ makes a split or a rename visible rather than silent. **Every declared root also carries a line
33
+ budget**, so splitting 3000 lines across six modules buys exactly zero headroom.
34
+ - **Every ratchet refusal hands you the next step, and it is a step this build can actually
35
+ perform.** Shrunk below the record? You get the regenerator command exactly as it should be pasted
36
+ — no reason asked, because shrinking is progress. Growing something? You get the same command as a
37
+ template with the reason placeholder and a plain statement that it is required: the tool cannot
38
+ invent your reason. On a project path that would not survive quoting, no command is printed at all
39
+ — the file, the actual, the allowed and the manual lane are stated instead, because a rendered
40
+ command that runs somewhere else is worse than none. Inputs the checker cannot judge at all — a
41
+ malformed config, a failed git enumeration — exit 2 stating what is unusable, with no rendered
42
+ recovery command.
43
+ - **Adoption is one consented line.** `--adopt --reason "<text>"` records the baseline AND declares
44
+ the gate in `docs/ai/gates.json` in a single step, is idempotent once adopted, and reports exactly
45
+ what it did and did not do if the declaration is refused. Existing projects meet it as a
46
+ Recommendations item at upgrade; new ones meet it the same way on their first upgrade.
47
+ - **The practice arrives BEFORE the code, not after it.** The plan-authoring and plan-execution
48
+ procedure renders now print your declared caps, your recorded debt and the reason the caps exist;
49
+ the checker's green line says the same thing on the enforced path. The point is a layout decided
50
+ while a plan is written, with the gate as the backstop rather than the teacher. A project that
51
+ declares no practice gets no invented
52
+ limits: the render's declared-practice block stays empty and `gates-init` offers no candidate. The
53
+ canon rule it does still print is conditional by construction — no declared cap, no limit to
54
+ state.
55
+ - **The gate declaration learned where to place things.** A consented non-checker gate is now written
56
+ BEFORE a trailing canonical coverage checker instead of after it, which is what makes adopting on a
57
+ final-capable declaration work at all; entries you already declared are never reordered. The fill's
58
+ result gained `placed`, and `appended` remains as an alias of it.
59
+ - **Scope, counting and the gate matcher live in a pure read core**, so the surfaces that ask about
60
+ the practice — the advisor, the gate declaration, the procedure render — never reach the writer.
61
+ Counting is pinned by literal fixtures: LF, and the CR of a CRLF, never count; a file with no final
62
+ newline still counts its last line.
63
+ - **Housekeeping shipped alongside:** `flow-check.mjs` became a 254-line facade over two pure
64
+ decision modules and a git-I/O leaf (the decision cores and the evidence rungs, plus the git lane
65
+ that is deliberately the only one allowed to spawn `git`) with its behaviour and its declared gate
66
+ command unchanged — the first tranche of the cleanup this practice arms, and the first proof that
67
+ the record notices a split.
68
+
69
+ ## 5.5.0 — delegating a sub-task stops being a feeling and becomes a record (AD-090; codex-cli-bridge 3.5.0, antigravity-cli-bridge 5.1.1)
70
+
71
+ **"How much does handing this off actually buy?" had no answer, because nothing wrote the answer
72
+ down.** A delegated task went out, something came back, and whether it was worth it was a judgement
73
+ made from memory. This release gives the handoff an **identity**, a **deadline** and an
74
+ **accounting**: the wrapper that runs your delegate now claims its work before spending anything and
75
+ publishes what it can prove afterwards, and the kit absorbs that into an append-only ledger you can
76
+ read back per task class. The number it reports is deliberately hard to fake and easy to refuse — it
77
+ would rather print INELIGIBLE with a reason than a figure it cannot stand behind.
78
+
79
+ - **A delegated run now has a name, and the name is claimed BEFORE the money is spent.** Pass
80
+ `codex-exec --nonce <n>` and the wrapper writes a reservation beside the ledger, atomically and
81
+ no-clobber, before it starts the CLI: a second dispatch on the same nonce refuses while it is still
82
+ free to refuse. At exit the reservation is replaced by the finished receipt, and the ORDER is the
83
+ guarantee — the delegate's report is published first, the receipt last, so anything that has
84
+ arrived always has a complete report behind it. A run that cannot publish exits nonzero and says
85
+ the tree is dirtied rather than leaving you to discover it. **An invocation without `--nonce` is
86
+ byte-for-byte what it always was**: no reservation, no receipt, no extra process.
87
+ - **Five new verbs on `dispatch` — four that write, one that only reads — and none of them invents a
88
+ second rulebook.** `open` puts a thread on the record with every mint-time field copied from the
89
+ task brief's own header; `await` waits for that one dispatch to answer; `return` absorbs the
90
+ wrapper's receipt; `fold` is the acceptance; and `degrade` closes a thread that never earned one,
91
+ on the record and with its reason. The ledger's
92
+ existing preflight stays the single legality door — the four WRITER verbs assemble a record and
93
+ pass its refusals through in the store's own words, while `await` writes nothing at all.
94
+ - **`dispatch await` waits, and a wait that ends without an answer authorizes nothing.** Only the
95
+ FINISHED receipt satisfies it; a run still holding the nonce means keep waiting; an artifact from a
96
+ neighbouring feature refuses rather than pretending to answer. The bound is the deadline recorded
97
+ when the thread opened — not a fresh timer per wait — so `--timeout` defaults to the time actually
98
+ remaining, and while nothing has arrived and the dispatch is still inside its deadline one reaching
99
+ past it is refused rather than quietly shortened; a terminal receipt already on disk returns
100
+ ARRIVED before any bound is evaluated at all. An unanswered wait exits **3**, names which bound
101
+ ended it, and says in as many words that **no writer slot was released**: it is a question for you,
102
+ never permission to dispatch again.
103
+ - **The metric refuses rather than flatters.** The two sides of the ratio are different byte
104
+ quantities — the numerator sums the image bytes of the returned objects, the denominator is the
105
+ framed bundle of the change set's payload and its report — bound not by one buffer but by one
106
+ observable change set: the same HEAD→index→worktree domain, bracketed by digests that refuse when
107
+ drift is detectable. Start from a dirty tree and the result is recorded INELIGIBLE by name instead
108
+ of counted. A change set carrying a binary, a non-regular path or a submodule is REFUSED outright
109
+ at `return` and `fold`, because the shared fingerprint carries no content for those and their bytes
110
+ could move underneath it. Gate output is not accounted at all in this version, and the mode doc
111
+ says so rather than leaving you to find out.
112
+ - **`aggregate` reports one wave and refuses to guess.** Per task class it prints the finished
113
+ threads with the inclusion rules applied — a folded success with provable bytes contributes its
114
+ ratio, one whose bytes are unprovable is excluded from the mean but still counts in the first-pass
115
+ rate, and a failed, degrade-closed or acceptance-failed thread counts as a real zero. Below the
116
+ registered minimum nothing is computed. No pre-registration, an unfinished thread, a recorded
117
+ refusal-to-delegate, an ambiguous wave: each stops the computation by name.
118
+ - **Both bridges ship a version anchor.** Every wrapper that stamps a version into a receipt now
119
+ declares it on one marked line — at least one per bridge, at most one per file, and the requirement
120
+ follows the USE, so a wrapper that never reads the constant is not asked for one. Every scalar
121
+ `AW_BRIDGE_VERSION=` or `+=` occurrence anywhere else in a shipped `bin/*.sh` — comment, help text
122
+ and heredoc body included — is refused by the version-sync verifier. What it deliberately does not
123
+ model is stated rather than implied: a form that sets the name WITHOUT that literal token — an
124
+ array-element setter, a spaced arithmetic assignment, an eval-constructed name — is out of scope,
125
+ so this closes the drift that actually happened, not every drift imaginable.
126
+ agy's wrapper gains only that marker — hence the PATCH — while codex's gains the whole dispatch
127
+ identity.
128
+
129
+ Honest limits, all stated where they bite rather than in a footnote: a receipt is forgeable exactly
130
+ like every record in this family, so what these doors defend against is a buggy or interrupted
131
+ producer and never a hostile one; the fold's binding is equality of the visible canonical payload,
132
+ which is a change detector rather than a cryptographic identity of the tree; and at most ONE in-tree
133
+ delegated dispatch at a time remains a bar you keep, not a mechanism that enforces it.
134
+
135
+
136
+
7
137
  ## 5.4.0 — a check that certifies nothing now says so, and the render stops promising what no host guarantees (AD-089)
8
138
 
9
139
  **A gate matrix could run green while verifying nothing, and the kit itself was what built it.**
package/README.md CHANGED
@@ -243,6 +243,7 @@ file), or run the guarded `/agent-workflow-kit uninstall`.
243
243
  | `/agent-workflow-kit commit-guard` | any time | **the read-only pre-commit guard** (D10) — makes the commit capture the whole current working tree, so «verified» and «about to be committed» are the same bytes (the receipt itself has a stated residual — see the mode doc). FIRST it refuses an **INDEX that lags the verified working tree** (the gates and the fingerprint describe the WORKING tree while `git commit` takes the INDEX alone, and the fingerprint cannot tell them apart — so a lagging index used to ship a strict subset of what was verified): unstaged tracked paths or reviewable untracked-not-ignored paths, named up to a bounded cap with the remainder stated, a dirty tracked **submodule** named separately with its own recovery, and fail-closed on an undecidable probe. This deliberately blocks a partial commit. Then it binds the LATEST completed `run-gates --final` receipt to the EXACT current tree: refuses on a missing/red/stale receipt, fingerprint drift under the run, a dangling later attempt, declaration content drift, evidence-hash or lcov drift, or unsatisfied review obligations (the same review-state decision, recomputed over a sanitized env — forged out-of-repo stores never satisfy). Re-runs NO gate or test. Wire it into `.git/hooks/pre-commit` (the installer writes the RESOLVED invocation). `git commit --no-verify` stays the stated residual. |
244
244
  | `/agent-workflow-kit recommendations` | any time (every `upgrade` ends with it) | **read-only deployment advisor** (AD-044) — computes what in THIS deployment is configured sub-optimally (allowlist not seeded, autonomy render drifted, OS sandbox unavailable, gates undeclared, bridge friction, sandbox-mask clutter, an unacknowledged sandbox recipe) and renders **verdict-first**: one composed verdict line (does anything need attention?), then each item as **{severity · what · one-line benefit · an optional `recipe:` line (the sandbox-lane live recipe, the worktrees-dir hand-apply-first grant advice, or the agents hidden-mode reconcile follow-up) · the exact consent-gated apply one-liner}**. The agent PRESENTS the section in the user's conversational language — every fact and count, nothing added or dropped; commands, paths, hosts and rule strings byte-exact; raw tool block on request — and runs EXACTLY the rendered one-liners only on your yes, surfacing each item's posture note first. Renders **present-even-when-empty** (`no recommendations — flow optimal.`); a failed probe degrades to a stated skip line. Registry strings are fact-true frozen one-line data (posture/risk notes live in the mode doc at the consent moment); the kit never seeds `sandbox.network.allowedDomains` / `filesystem.allowWrite` (**HAND-APPLY** territory), and the sandbox-lane item's convergence is a neutral fingerprint acknowledgement recorded by a consent-gated ack writer into `docs/ai/acks.json` — never a security key (the recipe is documented per bridge in `capability.json` `networkHosts` + `writableDirs`). `--cwd` is required (the target project is explicit); never writes, never commits, never runs a subscription CLI. |
245
245
  | `/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, the ledger's own class/scope vocabulary, and the autonomy-doctor EXIT/status/trusted-dir contract) 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. |
246
+ | `/agent-workflow-kit dispatch` | any time | **the delegation engine** — makes "how much does delegating a sub-task actually buy?" a measured number instead of a feeling. `check <file>` validates a sub-task brief's contract block and exits 0/1 naming the first violated field — **form only**: whether the task is genuinely bounded, its design decided and its acceptance adequate stays your judgment, and a well-formed absurdity passes here by construction. `register` pre-registers an acceptance wave (step classes, pairing key, minimum observations per class, the mean and first-pass thresholds) so the bar can never be chosen after the results it judges — immutable per wave. `observe` records ONE hand-written observation (`solo-construction`, the baseline whose ratio is 1 by construction — except over a scope measuring zero bytes, which has no ratio at all and is recorded ineligible by name — or `self-reported`) — delegated numbers are never hand-written, they are derived. The writer verbs are where that derivation happens: `open` puts a delegated thread on the record with every mint-time field copied from the brief's own header, refusing a deadline the wrapper's cap plus its kill grace would not fit inside, and recording whether the tree it started from was clean (a dirty one makes the result honestly unmeasurable rather than quietly counted); `await` waits for that one dispatch to answer and writes nothing — only the finished receipt satisfies it, a run still holding the nonce means keep waiting, and a wait that runs out says so with its own exit code, names whether the deadline or your own timeout ended it, and authorizes nothing: a wait that ended without an answer is a question for you, never permission to dispatch again; `return` absorbs the receipt the wrapper minted — only a finished one, checked against the contract it actually ran, its deadline and its own report, and refused outright when the tree hides changes from git or moves while the return is being computed — and derives the bytes from git rather than from anyone's claim; `fold` is the acceptance, and it refuses if the tree moved since the return — precisely, it re-confirms **equality of the visible canonical payload**, which is a change detector rather than a cryptographic identity of the tree: that payload is unframed and carries no file mode, so a content or symlink target that imitates the marker opening the next entry can alias two trees, and an executable-bit flip moves nothing (both named as residuals in the mode doc, with the fix queued). Where the payload cannot follow an object's bytes at all — a binary, a non-regular path, a submodule, a symlink whose target is not valid UTF-8 — `return` and `fold` **refuse** rather than promise what they cannot check. `degrade` closes a thread that never earned a fold, on the record and with its reason. `aggregate` prints one wave: the registered thresholds, every observation as context, and per step class the finished threads — a folded success with git-provable bytes contributes its ratio, one whose bytes are unprovable is excluded from the mean but still counts in the first-pass rate, and a failed thread, a degrade-closed one, or one folded after failing acceptance each count as a real zero. Below the registered minimum nothing is computed (insufficient); at or above it is computed and labeled PILOT evidence. It REFUSES rather than guessing: no pre-registration, an unfinished thread in scope, a recorded refusal-to-delegate that never opened a thread, or an ambiguous wave each stop the computation by name. Writes only its own append-only ledger inside the git dir (never committable); never commits, never runs a subscription CLI. |
246
247
  | `/agent-workflow-kit worktrees` | any time | **parallel feature worktrees** — run several features in DIFFERENT agent sessions on one repo, zero interference on working-tree files (the ONE exception is the dependency cache, below): `provision <slug> --plan <file>` creates a sibling git worktree on branch `aw/<slug>` and populates it (registry-derived footprint copy-if-missing — a tracked file is never overwritten; EXACTLY ONE seeded feature plan; the `handoff-<slug>.md` record from minute zero; `node_modules` symlinked where the link stays ignored — a shared MUTABLE dependency cache: writes through it hit MAIN's node_modules; for isolation run the printed isolated-install command (`--install` only PRINTS it; on `--resume` run the printed unlink-first recovery first); absolute root-pinned gate commands rebased on untracked copies only, and only while their bytes equal the MAIN source or its rebased form — user-modified copies stay untouched); `list` is read-only (slug, branch, base, dirty, handoff); `land <slug> --prepare` locks the common git dir, fail-closes on divergence or incomplete satellite state, transfers the complete accepted satellite diff onto a CLEAN main, runs sync plus the declared gates, and reports HEAD/TRANSFER/PREPARED OIDs — the commit ALWAYS stays a dialogue ask; `cleanup <slug>` takes the same lock and removes a LANDED worktree only after live landed-verification against main HEAD, while `--abandon` is the ONE destructive arm (destroys unlanded work; **no preview step** on any writer). The parent dir is the `docs/ai/worktrees.json` `parentDir` setting (default: the repo's sibling parent); an unwritable parent degrades to printed maintainer-pasted commands, and the one-time host consent that makes it promptless surfaces via `recommendations`. Never commits, never pushes, never runs a subscription CLI. |
247
248
  | `/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. |
248
249
  | `/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. |
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: '5.4.0'
6
+ version: '5.6.0'
7
7
  ---
8
8
 
9
9
  # agent-workflow-kit
@@ -203,6 +203,10 @@ read-only — read `${CLAUDE_SKILL_DIR}/references/modes/commit-guard.md` before
203
203
 
204
204
  read-only — read `${CLAUDE_SKILL_DIR}/references/modes/doc-parity.md` before acting.
205
205
 
206
+ ### Mode: dispatch
207
+
208
+ writer — read `${CLAUDE_SKILL_DIR}/references/modes/dispatch.md` before acting.
209
+
206
210
  ### Mode: worktrees
207
211
 
208
212
  writer — read `${CLAUDE_SKILL_DIR}/references/modes/worktrees.md` before acting.
@@ -2,7 +2,7 @@
2
2
  name: antigravity-cli-bridge
3
3
  description: Delegate work to Google's Antigravity CLI (`agy`) — the successor to Gemini CLI — to reach Gemini, Claude, and GPT-OSS models under a Google AI Pro/Ultra subscription from the terminal. Use when the user wants to run a headless `agy` prompt, hand a focused task or second-opinion review to `agy`, install or authenticate Antigravity CLI, check or economise its quota/models, bridge project context into `agy`, set up a second delegated-execution backend beside Codex, or troubleshoot `agy` flags, models, auth, conversations, or its no-JSON headless behaviour.
4
4
  metadata:
5
- version: '5.1.0'
5
+ version: '5.1.1'
6
6
  ---
7
7
 
8
8
  # antigravity-cli-bridge
@@ -326,7 +326,7 @@ DEFAULT_AGY_REVIEW_MODEL="Gemini 3.1 Pro (High)"
326
326
  # Review-receipt identity (AD-038). AW_BRIDGE_VERSION mirrors this bridge's SKILL.md/capability.json
327
327
  # version (drift-guarded by agy-review.test.mjs against capability.json).
328
328
  AW_RECEIPT_BACKEND="agy"
329
- AW_BRIDGE_VERSION="5.1.0"
329
+ AW_BRIDGE_VERSION="5.1.1" # aw-version-anchor
330
330
  # `-` not `:-` so an EXPLICIT empty AGY_MODEL= survives (drop --model, use settings.json — agy.sh:52).
331
331
  AGY_MODEL="${AGY_MODEL-$DEFAULT_AGY_REVIEW_MODEL}"
332
332
  # D5 control-byte screen — IMMEDIATELY after resolution, BEFORE the off-frontier advisory (or any
@@ -3,7 +3,7 @@
3
3
  "schema": 1,
4
4
  "name": "antigravity-cli-bridge",
5
5
  "kind": "execution-backend",
6
- "version": "5.1.0",
6
+ "version": "5.1.1",
7
7
  "provides": ["review", "probe"],
8
8
  "posture": { "model": "Gemini 3.1 Pro (High)" },
9
9
  "roles": {
@@ -2,7 +2,7 @@
2
2
  name: codex-cli-bridge
3
3
  description: Delegate work to the OpenAI Codex CLI (`codex`) under a ChatGPT subscription — run plan/instruction EXECUTION in a sandboxed workspace, or get a read-only ADVISORY review of a plan or working-tree diff — as a second delegated-execution backend beside Antigravity. Use when the user wants to hand a bounded coding task or plan to `codex exec`, get a second-opinion review from codex, install or authenticate Codex CLI, understand its sandbox/network/approval policy, drive codex efficiently from the main agent (exec vs review, resume, the commit boundary), bridge project context (`AGENTS.md`) into codex, or troubleshoot codex flags, models, auth, or its no-TTY headless behaviour.
4
4
  metadata:
5
- version: '3.4.1'
5
+ version: '3.5.0'
6
6
  ---
7
7
 
8
8
  # codex-cli-bridge
@@ -90,6 +90,9 @@ codex-exec <file|-> -- <extra codex flags...> # GUARDED passthrough after `-
90
90
  codex-exec --resume-last docs/plans/<slug>.md # continue the last session (id from the sidecar)
91
91
  echo "now do step 2 ..." | codex-exec --resume <session-id> -
92
92
 
93
+ # ACCOUNTED EXECUTION (the delegation ledger's exec lane — see "Dispatch identity" below):
94
+ codex-exec --nonce <n> docs/plans/<slug>-dispatch.md # mints a fail-closed exec receipt
95
+
93
96
  # REVIEW (read-only sandbox — codex cannot edit anything, only emits findings):
94
97
  codex-review plan docs/plans/<slug>.md # critique a plan
95
98
  codex-review code # review the current working-tree diff (precomputed)
@@ -135,17 +138,53 @@ defeat a policy is guarded — see [§ Models](#models-quality-first-pinned).
135
138
  |---|---|---|
136
139
  | `CODEX_MODEL` | `gpt-5.6-sol` (pinned) | model; non-default REFUSED unless `CODEX_PROBE=1` |
137
140
  | `CODEX_EFFORT` | `xhigh` (pinned) | reasoning effort; non-default REFUSED unless `CODEX_PROBE=1` |
138
- | `CODEX_HARD_TIMEOUT` | `3600` (exec) / `1800` (review) | hard wall-clock cap (seconds) via `timeout`/`gtimeout`; exit 124/137 ⇒ "exceeded hard cap". No `timeout` binary ⇒ exec warns loudly + runs uncapped; `codex-review` REFUSES pre-spend (fail-closed preflight). |
141
+ | `CODEX_HARD_TIMEOUT` | `3600` (exec) / `1800` (review) | hard wall-clock cap (seconds) via `timeout`/`gtimeout`; exit 124/137 ⇒ "exceeded hard cap". No `timeout` binary ⇒ a nonce-less exec warns loudly + runs uncapped, a **nonced** exec REFUSES pre-spend (an accounted dispatch that cannot be capped can never honour the terminal-exit rule), and `codex-review` REFUSES pre-spend (fail-closed preflight). |
139
142
  | `CODEX_SERVICE_TIER` | unset (standard tier) | **SPEND knob**: `priority` (catalog name "Fast") = ~1.5× token speed at a **2.5× credit rate** on gpt-5.6-sol — quality-neutral (same model). codex accepts any `-c service_tier` string silently (probe-pinned 2026-07-05), so the wrapper validates: an unsupported value warns and runs standard. Env or settings file. |
140
143
  | `CODEX_SESSION_FILE` | `./.codex-last-session` | where `codex-exec` records the session id and where `--resume-last` reads it |
141
144
  | `CODEX_REVIEW_MAX_TOTAL_BYTES` | `1500000` | `codex-review code`: above this the assembled diff goes via a git-dir temp file instead of inline — never truncated |
142
145
  | `AW_REVIEW_NONCE` | unset | the flow dispatch nonce (safe grammar `[A-Za-z0-9._-]{1,64}` — anything else refuses pre-spend). `codex-review … --nonce <n>` is the plain-argument equivalent (one seam; flag and a non-empty env must agree, a disagreeing pair refuses pre-spend) — the lane for hosts whose dispatch policy has no env-prefix form. When supplied, a successful review first mints the finding MANIFEST `agent-workflow-finding-manifest-codex-<nonce>.json` beside the receipts file (atomic, no-clobber, ORDERED before the receipt append) — a failed mint EXCLUDES the receipt, so a nonce-supplied dispatch never lands a receipt without its readable manifest; nonce-less runs add no nonce field and mint nothing (the `wrapperVersion` field every receipt carries moves with each release) |
146
+ | `AW_DISPATCH_NONCE` | unset | the **delegation** dispatch nonce (same safe grammar; anything else refuses pre-spend). `codex-exec [--nonce <n>] <plan-file>` is the plain-argument equivalent — ONE seam, recognised only BEFORE the prompt operand (after it, or after a literal `--`, it is passthrough payload). When supplied, the run is ACCOUNTED: see [§ Dispatch identity](#dispatch-identity-the-accounted-exec-lane). |
147
+ | `AW_DELEGATION_STORE` | unset (the git common dir) | absolute path of the delegation ledger; its **dirname** is where a nonced run's receipt and report land. Relative, or ending in a path separator, refuses pre-spend — the same rule the kit's store applies. |
143
148
  | `CODEX_REVIEW_SCHEMA` | unset | `codex-review`: `=1` returns findings as a validated JSON object (`--output-schema`), with a raw-text fallback. Default off. |
144
149
  | `CODEX_PROBE` | unset | `=1` ⇒ throwaway-probe mode: relaxes the model/effort guard AND the tier-2 passthrough guard (echoed loudly). Never for real work. |
145
150
 
146
151
  The git-write shim, `--ignore-user-config`, and the `*_API_KEY` scrub are NOT env-tunable — they are
147
152
  fixed invariants.
148
153
 
154
+ ### Dispatch identity — the accounted exec lane
155
+
156
+ A **nonced** `codex-exec` run has an identity the delegation ledger can absorb. Everything here is
157
+ skipped entirely without a nonce: the wrapper is byte-unchanged, writes no artifact and needs no
158
+ `node`.
159
+
160
+ - **Pre-spend, it RESERVES the nonce.** Immediately before the CLI runs — after every preflight and
161
+ after the posture banner — it publishes `agent-workflow-exec-receipt-<len>-<backend>-<nonce>.json`
162
+ in state `reserved`, atomically and **no-clobber**, beside the delegation store. A second dispatch
163
+ on the same nonce (or a leftover report under that name) refuses **before any spend**. So does a
164
+ run with no capping binary, without `node`, with the prompt on stdin instead of a contract file, or
165
+ with a file carrying no ` ```aw-dispatch-contract ` block.
166
+ - **`contractDigest` is computed HERE**, by the wrapper, from the dispatch file it was handed — an
167
+ independent value, never a copy of what the ledger holds, so `dispatch return` can refuse a run
168
+ that executed a *different* contract than the one it opened.
169
+ - **At exit it publishes, in this ORDER**: verify the reservation is still ours → write the
170
+ delegate's final message to `agent-workflow-exec-report-<len>-<backend>-<nonce>.txt` → verify
171
+ again → replace the reservation with the `terminal` receipt. An artifact that has arrived therefore
172
+ always has a complete report behind it, and a **foreign owner publishes nothing at all**.
173
+ - **The outcome is a SUBSET** the run can prove about itself: exit 0 with a session id → `success`,
174
+ exit 0 without one → `missing-identity`, any nonzero exit (124/137 included) →
175
+ `transport-failure`. Every orchestrator judgment is recorded later, at absorb time.
176
+ - **FAIL-CLOSED, unlike the review receipt.** A review receipt that cannot be written only warns; an
177
+ exec receipt that cannot be written leaves an EDITED tree with no accounting, so the wrapper exits
178
+ nonzero and calls the tree partial/dirtied — never untouched. The two statuses carry **different**
179
+ recoveries:
180
+ - **71** — a publication stopped. The reservation is the run's own, so absorb the thread with
181
+ `dispatch return --nonce <n> --no-receipt --exit-status <n> --outcome <o>`. The message says
182
+ whether the report reached disk: if it did the absorb reads it, if it did not the absorb records
183
+ `reportLength 0` and the metric is ineligible by the name `empty-report`.
184
+ - **70** — the reservation could not be verified *before* anything was published, so nothing was.
185
+ `--no-receipt` is **not** the recovery here: it would source `wrapperVersion` and `posture` from
186
+ an artifact that belongs to another run. Establish what replaced the reservation first.
187
+
149
188
  ### Settings file (host-level, survives kit upgrades)
150
189
 
151
190
  `${XDG_CONFIG_HOME:-~/.config}/agent-workflow/bridge-settings.conf` holds `KEY=VALUE` lines,
@@ -233,8 +272,16 @@ The wrappers work in any git repo where `codex` is installed and authenticated.
233
272
  restates it via `-c`; only a *raw* `codex exec resume` (bypassing the wrapper) loses the posture.
234
273
  - **Hard timeout** — a hung run is killed at `CODEX_HARD_TIMEOUT` (exec 3600s / review 1800s) and
235
274
  reported (exit 124/137); raise it for a known-healthy slow run. If neither `timeout` nor `gtimeout`
236
- is on `PATH`, `codex-exec` warns loudly and runs uncapped; `codex-review` refuses pre-spend
237
- (the fail-closed preflight — an uncapped review run no longer exists).
275
+ is on `PATH`, a nonce-less `codex-exec` warns loudly and runs uncapped, a **nonced** one refuses
276
+ pre-spend, and `codex-review` refuses pre-spend (the fail-closed preflight — an uncapped review run
277
+ no longer exists).
278
+ - **The wrapper cannot enforce an ABSOLUTE deadline** — it applies its own cap from ITS start and
279
+ never reads the ledger, so a dispatch started long after `dispatch open` is caught at absorb time
280
+ (the return refuses a late receipt), not pre-spend. Keeping that window small is the
281
+ orchestrator's rule: `open` is the last act before the dispatch.
282
+ - **The gate output is not accounted** — the run trace is a temp file the EXIT trap removes, so a
283
+ nonced run's report carries the delegate's final message only; the metric counts the returned
284
+ change set, never what the gates printed.
238
285
  - **Native `codex review` is out of scope** — it rejects `--ignore-user-config` (would load a personal
239
286
  `config.toml` and break the subscription/config-isolation invariant) and can't be cleanly captured;
240
287
  `codex-review` runs `codex exec` over a precomputed diff instead.