@sabaiway/agent-workflow-kit 5.3.0 → 5.5.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 (46) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/README.md +2 -1
  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 +53 -5
  8. package/bridges/codex-cli-bridge/bin/codex-exec.sh +622 -30
  9. package/bridges/codex-cli-bridge/bin/codex-exec.test.mjs +731 -3
  10. package/bridges/codex-cli-bridge/bin/codex-review.sh +1 -1
  11. package/bridges/codex-cli-bridge/capability.json +15 -10
  12. package/bridges/codex-cli-bridge/references/sandbox-and-flags.md +16 -12
  13. package/capability.json +1 -1
  14. package/package.json +1 -1
  15. package/references/modes/core-evidence.md +1 -1
  16. package/references/modes/coverage-check.md +1 -1
  17. package/references/modes/dispatch.md +29 -0
  18. package/references/modes/gates.md +7 -2
  19. package/references/modes/receipt-deadline.md +3 -3
  20. package/references/modes/recommendations.md +3 -1
  21. package/references/modes/upgrade.md +1 -1
  22. package/references/modes/velocity.md +5 -1
  23. package/references/scripts/migrate-gates.mjs +102 -10
  24. package/references/scripts/migrate-gates.test.mjs +37 -0
  25. package/tools/commands.mjs +7 -0
  26. package/tools/core-evidence.mjs +79 -5
  27. package/tools/coverage-check.mjs +23 -7
  28. package/tools/coverage-producer.mjs +68 -0
  29. package/tools/coverage-state.mjs +24 -0
  30. package/tools/declared-paths.mjs +32 -0
  31. package/tools/detect-backends.mjs +5 -4
  32. package/tools/dispatch-record.mjs +10 -3
  33. package/tools/dispatch-store.mjs +392 -0
  34. package/tools/dispatch.mjs +1779 -0
  35. package/tools/doc-parity.mjs +27 -4
  36. package/tools/exec-producer.mjs +483 -0
  37. package/tools/exec-receipt.mjs +263 -0
  38. package/tools/flow-store.mjs +111 -462
  39. package/tools/gates-declaration.mjs +49 -0
  40. package/tools/gates-init.mjs +83 -6
  41. package/tools/receipt-deadline.mjs +25 -3
  42. package/tools/recommendations.mjs +63 -19
  43. package/tools/release-scan.mjs +33 -0
  44. package/tools/run-gates.mjs +111 -32
  45. package/tools/store-append.mjs +444 -0
  46. package/tools/velocity-profile.mjs +102 -23
package/CHANGELOG.md CHANGED
@@ -4,6 +4,144 @@ 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.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)
8
+
9
+ **"How much does handing this off actually buy?" had no answer, because nothing wrote the answer
10
+ down.** A delegated task went out, something came back, and whether it was worth it was a judgement
11
+ made from memory. This release gives the handoff an **identity**, a **deadline** and an
12
+ **accounting**: the wrapper that runs your delegate now claims its work before spending anything and
13
+ publishes what it can prove afterwards, and the kit absorbs that into an append-only ledger you can
14
+ read back per task class. The number it reports is deliberately hard to fake and easy to refuse — it
15
+ would rather print INELIGIBLE with a reason than a figure it cannot stand behind.
16
+
17
+ - **A delegated run now has a name, and the name is claimed BEFORE the money is spent.** Pass
18
+ `codex-exec --nonce <n>` and the wrapper writes a reservation beside the ledger, atomically and
19
+ no-clobber, before it starts the CLI: a second dispatch on the same nonce refuses while it is still
20
+ free to refuse. At exit the reservation is replaced by the finished receipt, and the ORDER is the
21
+ guarantee — the delegate's report is published first, the receipt last, so anything that has
22
+ arrived always has a complete report behind it. A run that cannot publish exits nonzero and says
23
+ the tree is dirtied rather than leaving you to discover it. **An invocation without `--nonce` is
24
+ byte-for-byte what it always was**: no reservation, no receipt, no extra process.
25
+ - **Five new verbs on `dispatch` — four that write, one that only reads — and none of them invents a
26
+ second rulebook.** `open` puts a thread on the record with every mint-time field copied from the
27
+ task brief's own header; `await` waits for that one dispatch to answer; `return` absorbs the
28
+ wrapper's receipt; `fold` is the acceptance; and `degrade` closes a thread that never earned one,
29
+ on the record and with its reason. The ledger's
30
+ existing preflight stays the single legality door — the four WRITER verbs assemble a record and
31
+ pass its refusals through in the store's own words, while `await` writes nothing at all.
32
+ - **`dispatch await` waits, and a wait that ends without an answer authorizes nothing.** Only the
33
+ FINISHED receipt satisfies it; a run still holding the nonce means keep waiting; an artifact from a
34
+ neighbouring feature refuses rather than pretending to answer. The bound is the deadline recorded
35
+ when the thread opened — not a fresh timer per wait — so `--timeout` defaults to the time actually
36
+ remaining, and while nothing has arrived and the dispatch is still inside its deadline one reaching
37
+ past it is refused rather than quietly shortened; a terminal receipt already on disk returns
38
+ ARRIVED before any bound is evaluated at all. An unanswered wait exits **3**, names which bound
39
+ ended it, and says in as many words that **no writer slot was released**: it is a question for you,
40
+ never permission to dispatch again.
41
+ - **The metric refuses rather than flatters.** The two sides of the ratio are different byte
42
+ quantities — the numerator sums the image bytes of the returned objects, the denominator is the
43
+ framed bundle of the change set's payload and its report — bound not by one buffer but by one
44
+ observable change set: the same HEAD→index→worktree domain, bracketed by digests that refuse when
45
+ drift is detectable. Start from a dirty tree and the result is recorded INELIGIBLE by name instead
46
+ of counted. A change set carrying a binary, a non-regular path or a submodule is REFUSED outright
47
+ at `return` and `fold`, because the shared fingerprint carries no content for those and their bytes
48
+ could move underneath it. Gate output is not accounted at all in this version, and the mode doc
49
+ says so rather than leaving you to find out.
50
+ - **`aggregate` reports one wave and refuses to guess.** Per task class it prints the finished
51
+ threads with the inclusion rules applied — a folded success with provable bytes contributes its
52
+ ratio, one whose bytes are unprovable is excluded from the mean but still counts in the first-pass
53
+ rate, and a failed, degrade-closed or acceptance-failed thread counts as a real zero. Below the
54
+ registered minimum nothing is computed. No pre-registration, an unfinished thread, a recorded
55
+ refusal-to-delegate, an ambiguous wave: each stops the computation by name.
56
+ - **Both bridges ship a version anchor.** Every wrapper that stamps a version into a receipt now
57
+ declares it on one marked line — at least one per bridge, at most one per file, and the requirement
58
+ follows the USE, so a wrapper that never reads the constant is not asked for one. Every scalar
59
+ `AW_BRIDGE_VERSION=` or `+=` occurrence anywhere else in a shipped `bin/*.sh` — comment, help text
60
+ and heredoc body included — is refused by the version-sync verifier. What it deliberately does not
61
+ model is stated rather than implied: a form that sets the name WITHOUT that literal token — an
62
+ array-element setter, a spaced arithmetic assignment, an eval-constructed name — is out of scope,
63
+ so this closes the drift that actually happened, not every drift imaginable.
64
+ agy's wrapper gains only that marker — hence the PATCH — while codex's gains the whole dispatch
65
+ identity.
66
+
67
+ Honest limits, all stated where they bite rather than in a footnote: a receipt is forgeable exactly
68
+ like every record in this family, so what these doors defend against is a buggy or interrupted
69
+ producer and never a hostile one; the fold's binding is equality of the visible canonical payload,
70
+ which is a change detector rather than a cryptographic identity of the tree; and at most ONE in-tree
71
+ delegated dispatch at a time remains a bar you keep, not a mechanism that enforces it.
72
+
73
+
74
+
75
+ ## 5.4.0 — a check that certifies nothing now says so, and the render stops promising what no host guarantees (AD-089)
76
+
77
+ **A gate matrix could run green while verifying nothing, and the kit itself was what built it.**
78
+ Neither declaration path ever wired a coverage PRODUCER, yet both declared the coverage CHECKER — so
79
+ a fresh `gates-init` and an `upgrade` alike could leave a project whose `--final` prints three
80
+ `PASS`, `lcov-sha256=none`, `attested=yes`, `status=ok`, exit 0. The honest signal existed on one
81
+ inner line; it reached no surface a consumer keys on. This release stops both kit-owned declaration
82
+ paths from ever ADDING a producer-less pair, makes the withheld verdict travel, and stops the
83
+ autonomy render asserting host behaviour it cannot know. A pair you declare by hand stays yours —
84
+ the kit reports it, it never removes it. Nothing gains a state: exit codes, the `status=` token, the
85
+ receipt `status` enum, `--final` acceptance and the commit-guard disposition are untouched, so an
86
+ optional-coverage project never goes red by surprise.
87
+
88
+ - **Neither kit-owned declaration path ADDS a coverage checker without a producer.**
89
+ `gates-init` wires the lcov reporter flags onto the one allowlist suite body that produces
90
+ coverage unaided, WITHHOLDS the `coverage-check` candidate with a named reason when neither the
91
+ offer nor the existing declaration carries a producer, and — this path alone — refuses at WRITE
92
+ time on the MERGED declaration, because an offer-level check alone still let
93
+ `--apply --only coverage-check` write a dead checker, still let a producer land after an
94
+ already-last checker, and still let a SECOND canonical checker in under a different id. The
95
+ ordering refusal names ORDERING as the cause, so you reorder instead of concluding the producer
96
+ was rejected. `migrate-gates` stops adding the checker into a producer-less declaration and
97
+ reports an already-declared one as INERT — loudly, with the remedy, and removing nothing for you.
98
+ - **One CLOSED producer predicate, shared by every consumer.** Recognition covers the full command
99
+ forms the kit itself emits — never a substring probe, because `echo "$AW_GIT_DIR/…"` or a
100
+ half-written flag set would pass one. The tail rule is a POSITIVE path-shaped grammar rather than
101
+ an operator blocklist: `node --test <flags> && rm -f <lcov>` runs the suite and then deletes the
102
+ file, so an open-ended tail would certify a producer that leaves nothing behind. The residual is
103
+ stated in the source rather than papered over — the screen judges source bytes, so the claim is
104
+ "configured with the reporters", never "the lcov survives the command"; a run that produces none
105
+ is still caught honestly at runtime as `skipped-no-lcov`.
106
+ - **`attested=` binds to the BYTES consumed.** A run that read nothing never certifies, however
107
+ valid its final-run context. The field states that a VERDICT WAS ISSUED — not that coverage
108
+ passed — so a valid handshake over uncovered lines still reads `yes` and still exits 1.
109
+ - **The summary line carries a new closed `coverage=` field** — `certified` / `not-run` / `none` /
110
+ `unknown`, one value defined for every run outcome — and the checker's table row names a withheld
111
+ verdict. Both are derived by CROSS-READING the checker's two anchored machine lines, so a missing,
112
+ duplicated or self-contradicting pair reads `unknown` rather than `certified`. The `--final`
113
+ receipt records the run's own token, and `core-evidence summary` renders the qualifier FROM it
114
+ instead of guessing from `lcovSha256` — which says what a receipt binds and never whether a
115
+ verdict was issued. A pre-5.4.0 receipt is named as a legacy receipt, never as a claim about what
116
+ it read.
117
+ - **New advisor item `gates-inert`** for a declaration that runs green and certifies nothing, with
118
+ two causes and two remedies. Cause A — a canonical `coverage-check` with no producer BEFORE it
119
+ (none at all, or one declared after it, which writes the lcov too late and lets stale bytes be
120
+ certified) — is HAND-APPLY, since the append-only fill cannot reorder an existing declaration.
121
+ Cause B — every declared gate is one of the kit's own checkers — renders the consent-gated
122
+ `gates-init` preview. Cause A decides through the SAME producer-before-checker rule the
123
+ `gates-init` fill enforces at write time — one home, so the advisor and the fill cannot drift
124
+ apart; cause B is advisor-only, with no refusal path behind it. `--final` acceptance is unchanged
125
+ either way: it still requires exactly one canonical coverage checker declared last, and it never
126
+ inspects producers. `flow optimal` no longer renders over either cause.
127
+ - **Every settings-derived RUNTIME claim in the autonomy render is now host-conditional.** Not only
128
+ the bridge-tier exclusion: `allowWrite`, `allowedDomains` and foreign exclusions are all claims
129
+ about what a HOST does with a settings key, and whether a host honours them is runtime-unknowable
130
+ — this kit's own mode doc has recorded that from live observation, while three separate surfaces
131
+ went on promising the bridge wrappers run outside the sandbox. The classification is unchanged;
132
+ only the unconditional promise is gone. The `allowWrite` degrade now resolves its entries
133
+ (tilde, relative and absolute, on segment-aware containment shared with the advisor's
134
+ worktrees-dir lane) and NAMES the external survivors instead of counting them — an entry pointing
135
+ inside the repo or `$TMPDIR` is no longer reported as an `fs_outside_repo` weakening at all, and
136
+ an unreadable value is its own UNVERIFIABLE class that asserts no weakening.
137
+ - **The bundled `codex-cli-bridge` mirror moves to 3.4.1** — a bundled-only bump carrying the fixed
138
+ `codex exec resume` argv, so the changed bridge bytes in this tarball ship under a version of
139
+ their own instead of silently.
140
+
141
+ Upgrading an existing project: nothing breaks and nothing is rewritten for you. If your declaration
142
+ already carries the dead pair, `status`/`upgrade` now say so and hand you the remedy — the reorder
143
+ case deliberately stays hand-applied.
144
+
7
145
  ## 5.3.0 — a check must speak where it is built to speak: the two silent checks (AD-088)
8
146
 
9
147
  **Two shipped checks stayed SILENT at exactly the point they exist to speak** — one a GATE that
package/README.md CHANGED
@@ -239,10 +239,11 @@ file), or run the guarded `/agent-workflow-kit uninstall`.
239
239
  | `/agent-workflow-kit sandbox-masks` | any time | **cosmetic exclude lane for sandbox device masks** — an OS sandbox (Claude Code) injects character-device masks into the work tree as untracked `git status` noise; the review domain already ignores them **by construction** (never-committable untracked classes — char/block devices, FIFOs, sockets — are excluded from the fingerprint, the assembled review payload, and the clean checks). This mode hides them from `git status` too: flagless = read-only probe (derives the CURRENT mask set from the unfiltered walk + lstat — never a frozen list — and revalidates fenced entries, loudly flagging one that became a real path); `--apply` = consent-gated FULL-BLOCK replace of its own fenced block in `git rev-parse --git-path info/exclude` (stale masks drop by construction; `--clear` always means REMOVE the block — it takes precedence over the derivation). Writes ONLY its fence — never `.gitignore`, never global config; symlinked/non-regular exclude paths and malformed fences fail closed. Watch note: a real file at an excluded path is silently skipped by bulk staging (`git add -A`/`git add .`) — delete the stale line first; the probe flags exactly this case. |
240
240
  | `/agent-workflow-kit grounding` | any time | **grounded-review facts assembler** — mechanizes populating `agy-review --facts @f`: slices your entry-point's **Hard Constraints** section verbatim (exactly one match, else a loud stop) and/or a plan's decision-bearing sections (`## Approach` + `## Verification` required, `## Decisions (locked)` when present; duplicates stop), under the same byte budget the agy wrapper enforces (minus `--reserve-bytes` for the artifact share), with a loud tail-trim on overflow. `--autonomy` (AD-044) appends the COMPUTED effective autonomy policy from the git-top `docs/ai/autonomy.json` (every red-line + per-activity level, stated source line; absent file → the computed defaults ARE the policy, exit 0; a malformed policy fails CLOSED, exit 1). Prints to stdout; `--out` writes **one scratch file only** — system-temp outside the repo ($TMPDIR / /tmp, rewritable) or a **fresh** gitignored in-repo path (create-only, exclusive write; an existing in-repo file, even gitignored, is refused — the `.env` clobber class); tracked, not-ignored-in-repo, other outside-repo, and symlink/non-regular destinations are all refused. Never commits, never runs a subscription CLI. |
241
241
  | `/agent-workflow-kit core-evidence` | any time | **the ONE loop-evidence writer** (strip-the-kit) — every core evidence record lands in a single append-only JSONL store inside the git dir (never committable; versioned schema, latest-per-key supersession, byte-identical duplicates refused, malformed lines fail every reader closed). `red-proof "<file>#<pattern>"` declares an observed-red **BEFORE a bugfix** (N/N red runs + content custody + base + the pre-fix fingerprint; green/mixed/timeout are DISTINGUISHED refusals — nothing written); `degrade --backend --reason` is the ONLY escape for an unavailable review backend (per-tree, never all backends); `summary` renders the whole loop state statelessly (gate result · per-backend verdicts · red-proofs · degrades) — no ledger, no rounds, nothing remembered. Honest residual: records are forgeable — self-discipline, not a security boundary. Never commits, never runs a subscription CLI. |
242
- | `/agent-workflow-kit coverage-check` | any time | **the final-run checker** (D3(c)+(d)) — **certifies coverage ONLY inside the `--final` run that owns the lcov** (ownership is exclusive by CONVENTION over the fixed path, not enforced — a concurrent writer to it is a stated residual, queued as LCOV-EXCLUSIVE-OWNERSHIP): an artifact on disk proves nothing about the tree it came from, so a standalone run prints its findings and states `attested=no` / `NO VERDICT` rather than a PASS (an lcov that predates an edit would otherwise certify a line the suite never executed). The runner passes a nonce whose one-way commitment over `{nonce, fingerprint, base}` is the `final-start.attempt` it recorded; a context describing another tree, or matching no recorded attempt, is a REFUSAL, never a verdict. Findings are unchanged — reads the lcov the declared `unit-tests` gate produced at the FIXED git-dir path and fails on any uncovered CHANGED executable Node line (listed `file:line`; a changed file absent from the map is a file-level red; out-of-domain/unsupported files are LISTED — the claim narrowed honestly); VERIFIES every current-base red-proof declaration (bound test exists · custody hash unchanged · green N/N now · pre-fix fingerprint differs); prints `lcov-sha256=<hex|none>` of the exact bytes it consumed — the sha the `--final` receipt binds and re-hashes. An absent lcov is a LOUD `skipped-no-lcov`; a symlinked path is a refusal. `--check` is the gate exit code — declare it as the LAST gate (`run-gates --final` refuses otherwise). Read-only. |
242
+ | `/agent-workflow-kit coverage-check` | any time | **the final-run checker** (D3(c)+(d)) — **certifies coverage ONLY inside the `--final` run that owns the lcov** (ownership is exclusive by CONVENTION over the fixed path, not enforced — a concurrent writer to it is a stated residual, queued as LCOV-EXCLUSIVE-OWNERSHIP): an artifact on disk proves nothing about the tree it came from, so a standalone run prints its findings and states `attested=no` / `NO VERDICT` rather than a PASS (an lcov that predates an edit would otherwise certify a line the suite never executed). `attested=` claims a verdict was ISSUED, pass or fail — a run over uncovered lines still reads `attested=yes` and still exits 1, and a run whose coverage arm never executed (no lcov) reads `attested=no` even inside `--final`, because nothing was read and nothing is certified. The runner passes a nonce whose one-way commitment over `{nonce, fingerprint, base}` is the `final-start.attempt` it recorded; a context describing another tree, or matching no recorded attempt, is a REFUSAL, never a verdict. Findings are unchanged — reads the lcov the declared `unit-tests` gate produced at the FIXED git-dir path and fails on any uncovered CHANGED executable Node line (listed `file:line`; a changed file absent from the map is a file-level red; out-of-domain/unsupported files are LISTED — the claim narrowed honestly); VERIFIES every current-base red-proof declaration (bound test exists · custody hash unchanged · green N/N now · pre-fix fingerprint differs); prints `lcov-sha256=<hex|none>` of the exact bytes it consumed — the sha the `--final` receipt binds and re-hashes. An absent lcov is a LOUD `skipped-no-lcov`; a symlinked path is a refusal. `--check` is the gate exit code — declare it as the LAST gate (`run-gates --final` refuses otherwise). Read-only. |
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.3.0'
6
+ version: '5.5.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.0'
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)
@@ -112,7 +115,8 @@ receipt field. **Quote the posture banner verbatim** when labeling a dispatch.
112
115
  escalation is refused and reported, never interactively approved. The wrappers capture only codex's
113
116
  **final message** (`-o`), so output is clean; the JSON event stream + reasoning go to a run trace
114
117
  that is **read before it is discarded**. Fresh and resumed runs share **ONE** capture posture
115
- (`-o` + `--json` + `--color never`, everything redirected into the trace), so both modes have the
118
+ (`-o` + `--json`, everything redirected into the trace; `--color never` rides the fresh lane only —
119
+ `codex exec resume` does not accept it), so both modes have the
116
120
  same evidence surface — and the wrapper scans that surface on **every completed run**: a run that
117
121
  SURVIVES a nested-sandbox failure exits 0 with an ungrounded answer, so on `rc == 0` it prints the
118
122
  answer first and then warns loudly on stderr when one `command_execution` item with a **proven**
@@ -134,17 +138,53 @@ defeat a policy is guarded — see [§ Models](#models-quality-first-pinned).
134
138
  |---|---|---|
135
139
  | `CODEX_MODEL` | `gpt-5.6-sol` (pinned) | model; non-default REFUSED unless `CODEX_PROBE=1` |
136
140
  | `CODEX_EFFORT` | `xhigh` (pinned) | reasoning effort; non-default REFUSED unless `CODEX_PROBE=1` |
137
- | `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). |
138
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. |
139
143
  | `CODEX_SESSION_FILE` | `./.codex-last-session` | where `codex-exec` records the session id and where `--resume-last` reads it |
140
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 |
141
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. |
142
148
  | `CODEX_REVIEW_SCHEMA` | unset | `codex-review`: `=1` returns findings as a validated JSON object (`--output-schema`), with a raw-text fallback. Default off. |
143
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. |
144
150
 
145
151
  The git-write shim, `--ignore-user-config`, and the `*_API_KEY` scrub are NOT env-tunable — they are
146
152
  fixed invariants.
147
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
+
148
188
  ### Settings file (host-level, survives kit upgrades)
149
189
 
150
190
  `${XDG_CONFIG_HOME:-~/.config}/agent-workflow/bridge-settings.conf` holds `KEY=VALUE` lines,
@@ -232,8 +272,16 @@ The wrappers work in any git repo where `codex` is installed and authenticated.
232
272
  restates it via `-c`; only a *raw* `codex exec resume` (bypassing the wrapper) loses the posture.
233
273
  - **Hard timeout** — a hung run is killed at `CODEX_HARD_TIMEOUT` (exec 3600s / review 1800s) and
234
274
  reported (exit 124/137); raise it for a known-healthy slow run. If neither `timeout` nor `gtimeout`
235
- is on `PATH`, `codex-exec` warns loudly and runs uncapped; `codex-review` refuses pre-spend
236
- (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.
237
285
  - **Native `codex review` is out of scope** — it rejects `--ignore-user-config` (would load a personal
238
286
  `config.toml` and break the subscription/config-isolation invariant) and can't be cleanly captured;
239
287
  `codex-review` runs `codex exec` over a precomputed diff instead.