@sabaiway/agent-workflow-kit 1.16.0 → 1.18.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 CHANGED
@@ -4,6 +4,71 @@ Semantically versioned ([semver](https://semver.org)), newest first. The `versio
4
4
  is the current release. `upgrade` mode reads a project's `docs/ai/.workflow-version` and applies
5
5
  every `migrations/<version>-<slug>.md` newer than it, in semver order.
6
6
 
7
+ ## 1.18.0 — Agent-writable orchestration config (`set-recipe`), version-aware setup, durable session contracts (kit)
8
+
9
+ A **feature** release. The per-project recipe config (`docs/ai/orchestration.json`) is no longer
10
+ hand-edit-only: a new **`set-recipe`** writer turns plain-language intent into a validated, previewed,
11
+ atomic write — and `setup` now surfaces bridge versions and proactively offers to set the review recipe
12
+ when a backend becomes ready. The deployment-lineage head stays **`1.3.0`** (no `docs/ai` structural
13
+ change, no migration); the kit **package** version is a separate axis.
14
+
15
+ - **`/agent-workflow-kit set-recipe` (new WRITER).** The agent maps plain language → explicit
16
+ `--set <activity>.<slot>=<recipe>` / `--unset <activity>.<slot>` ops; the kit validates → merges →
17
+ **previews by default** → writes only on `--write`. Split modules: `tools/orchestration-config.mjs`
18
+ (schema/read/pure — the shared slot-recipe validity table + `parseOp` / `applySetOps` /
19
+ `serializeConfig` / the canonical-refresh helpers) and `tools/orchestration-write.mjs` (the **only**
20
+ fs-writer — deployment gate, exclusive-create temp + rename, symlink/TOCTOU-safe, last-writer-wins).
21
+ `procedures` never imports the writer → the read-only invariant is **structural**. Renamed from the
22
+ planned `orchestrate` (it never *runs* a recipe). Hand-editing the file stays fully supported.
23
+ - **Setup surfaces versions + closes the loop.** Each skill line shows the bridge version (`(vX)` for a
24
+ fresh place / equal refresh, `(vOld → vNew)` on a bump, never `vnull → …`); a closing pointer at
25
+ `/agent-workflow-kit status`; and — re-detecting AFTER apply — a proactive `set-recipe` offer for
26
+ **both** `plan-authoring.review` and `plan-execution.review` when a review backend just became ready.
27
+ - **Canonical-refresh reaches the filled base.** `inject-methodology` refreshes a filled pointer slot to
28
+ the current engine canon when its content matches a known-prior fragment (a customization is preserved
29
+ + advised); the `_README` refresh reuses the same `refreshIfCanonical` helper, and the upgrade
30
+ config-ensure is now seed-**or-refresh**.
31
+ - **Docs.** New `### Mode: set-recipe`; `procedures` / `velocity` / README no longer say the config is
32
+ "never written for you". Tarball **72 → 75** (three new `tools/*.mjs`).
33
+
34
+ ## 1.17.0 — Hardened Codex bridge: quality-first delegation, clean capture, enforced git-write boundary (kit)
35
+
36
+ A **feature** release. The bundled `codex-cli-bridge` (`bridges/codex-cli-bridge/`) is overhauled to
37
+ make delegating to the OpenAI Codex CLI faster, quieter, and safer **without lowering output quality** —
38
+ economy comes only from quality-neutral waste removal, never a model/effort downgrade. The bridge's own
39
+ contract bumps to **`2.0.0`** (MAJOR — the hardened wrappers now *refuse* inputs the `1.0.0` wrappers
40
+ silently accepted). The kit's own modes/CLI are unchanged, so the kit is a MINOR bump; the
41
+ deployment-lineage head stays **`1.3.0`** (no `docs/ai` structural change, no migration). The kit
42
+ **package** version is a separate axis.
43
+
44
+ - **Quality-first — no silent downgrade.** Both wrappers pin frontier `gpt-5.5` @ `xhigh` and **refuse
45
+ with a loud error** if `CODEX_MODEL`/`CODEX_EFFORT` resolves to a non-default, unless the explicit
46
+ throwaway `CODEX_PROBE=1` mode is set (echoed loudly). Outside that probe mode the passthrough guard
47
+ now blocks **every** model/context/policy-affecting flag (`-m/--model`, `--add-dir`, `-C/--cd`,
48
+ `-p/--profile`, `--oss`, …), not just the previous subset.
49
+ - **Clean output capture.** `-o` (final message only) + a `--json` event trace +
50
+ `hide_agent_reasoning=true` + `--color never` replace the streamed reasoning transcript; the session id
51
+ is persisted to a sidecar (`CODEX_SESSION_FILE`) for resume; on failure the trace tail is surfaced to
52
+ stderr (no silent failure). Reasoning still runs at `xhigh` — quality unchanged.
53
+ - **Hard timeout.** New `CODEX_HARD_TIMEOUT` (`timeout`/`gtimeout`, generous `xhigh`-sized defaults —
54
+ exec `3600` s / review `1800` s, `--kill-after=15s`); a hard kill (124/137) reports `codex exceeded
55
+ hard timeout`. A host with no `timeout` warns and runs uncapped (no silent skip).
56
+ - **Precomputed-diff review.** `review code` now assembles the diff itself (`git status` + cached/unstaged
57
+ `git diff` + untracked file **contents**, binary-skipped; a payload above the
58
+ `CODEX_REVIEW_MAX_TOTAL_BYTES` threshold goes via a repo-local temp file, never truncated) and feeds it
59
+ to `codex exec` — killing the agentic
60
+ discovery roaming that read unrelated files (incl. `~/.claude`). Reads stay `read-only` for
61
+ surrounding-file context; a no-change preflight exits before spending a run. Optional structured
62
+ findings via `CODEX_REVIEW_SCHEMA=1` (default off, raw-text fallback).
63
+ - **Invariant-preserving resume + enforced git-write boundary.** A dedicated `--resume-last` /
64
+ `--resume <id>` entrypoint re-establishes every wrapper invariant (`--ignore-user-config`, the pin,
65
+ posture restated via `-c`). A **physical `git` shim** (a real executable on a temp `PATH`, since
66
+ `execve` bypasses bash functions) enforces a strict read allowlist and blocks every write verb by
67
+ default — defence beyond the prompt contract.
68
+ - **First hermetic bridge tests + tarball `70 → 72` files.** `bridges/codex-cli-bridge/bin/{codex-exec,codex-review}.test.mjs`
69
+ ship as byte-identical mirror payload (matching `agy.test.mjs`); `npm pack --dry-run --json`
70
+ re-verified. The byte-identical bridge mirror + `capability.json` stay valid.
71
+
7
72
  ## 1.16.0 — Onboarding & discoverability: `help`, honest versioning, an enriched `status` (kit)
8
73
 
9
74
  A **feature** release (additive, backward-compatible). Makes the kit self-explanatory: a discoverable
package/README.md CHANGED
@@ -223,7 +223,8 @@ command is printed).
223
223
  | `/agent-workflow-kit setup [backend]` | opt-in, any time | **link-only** auto-setup of a bridge: places the bundled bridge skill (only into an absent / empty / managed dir — never overwrites an unmanaged one) + links its wrappers onto `PATH` via managed symlinks (idempotent; refuses to clobber a non-symlink; try `--dry-run` to preview). The binary install + the one-time subscription login stay **manual**: it prints the exact **login** command and points the binary install at each bridge's `setup/README.md`. POSIX wrappers — on Windows use WSL. Never commits, never runs a subscription CLI. |
224
224
  | `/agent-workflow-kit status` | any time | **read-only** single view of **versions + deployment + settings + bridges**: which members (kit / memory / engine / the two bridges) are installed and at what version (with an honest "installed on this machine" note when one is behind) and — in a project — what's deployed (`docs/ai`, the version stamps, and the **visibility**: visible / hidden / unclear), plus your settings (orchestration recipes, attribution, velocity) and the bridges' readiness. The two version axes (package number vs deployment-structure head) stay decoupled. Never writes, never commits, never runs a subscription CLI. |
225
225
  | `/agent-workflow-kit recipes` | any time | **read-only** orchestration advisor: presents four named recipes for composing the bridges into plan → execute → review — **Solo / Reviewed / Council / Delegated** — plans + recommends one for your environment (degrading with a stated reason when a backend isn't ready), and offers the choice. The orchestrator runs it via the bridge skills and **always commits**; the kit never executes a recipe, never runs a subscription CLI, never commits. |
226
- | `/agent-workflow-kit procedures <activity>` | any time | **read-only** activity-procedures advisor: prints a named activity's ordered steps (`plan-authoring` / `plan-execution`) read **live** from the engine, plus the **resolved recipe per slot** from your hand-edited `docs/ai/orchestration.json` + backend readiness (default Reviewed when a backend is ready, Council on request, slot-aware incl. Delegated). `--override <slot>=<recipe>` adjusts one slot per run. Composes with `recipes`; never writes, never commits, never runs a subscription CLI. |
226
+ | `/agent-workflow-kit procedures <activity>` | any time | **read-only** activity-procedures advisor: prints a named activity's ordered steps (`plan-authoring` / `plan-execution`) read **live** from the engine, plus the **resolved recipe per slot** from your `docs/ai/orchestration.json` (agent-writable via `set-recipe`, or hand-edited) + backend readiness (default Reviewed when a backend is ready, Council on request, slot-aware incl. Delegated). `--override <slot>=<recipe>` adjusts one slot per run. Composes with `recipes`; never writes, never commits, never runs a subscription CLI. |
227
+ | `/agent-workflow-kit set-recipe` | any time | **config writer** for `docs/ai/orchestration.json`: tell the agent your preference in plain language and it maps it to explicit `--set <activity>.<slot>=<recipe>` / `--unset` ops; the kit validates, **previews by default**, and writes only on `--write` (deployment-gated, atomic, symlink/TOCTOU-safe), resolving the effective recipe vs live readiness. Writes **only** that file — **never runs a backend, never commits**; hand-editing stays fully supported. |
227
228
  | `/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. |
228
229
  | `/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 redirection/command-substitution residual remains, closed by a deferred hook); a direct commit/push/publish still asks. `--dry-run` first. |
229
230
 
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: agent-workflow-kit
3
3
  description: Deploy or upgrade a portable AI-agent memory-and-workflow system in any project. Use when the user wants to bootstrap `docs/ai/` + an entry-point `AGENTS.md` (+ `CLAUDE.md` alias) + cap/archive/index enforcement in a new or existing repo, set up the Memory Map and session protocols, install the docs-rotation pre-commit hook, or run `/agent-workflow-kit` / `/agent-workflow-kit upgrade`. Triggers on phrases like "set up the memory system", "deploy the AI workflow here", "bootstrap docs/ai", "upgrade the workflow".
4
4
  disable-model-invocation: true
5
5
  metadata:
6
- version: '1.16.0'
6
+ version: '1.18.0'
7
7
  ---
8
8
 
9
9
  # agent-workflow-kit
@@ -107,7 +107,8 @@ Pick the mode from the user's invocation. Auto-detect an existing `docs/ai/` to
107
107
  - **`/agent-workflow-kit setup [backend]`** — the **link-only**, opt-in companion to `backends`: place the bundled bridge skill + link its wrappers onto `PATH`. **In-agent only** — `init` (npx) never places bridges. The binary install + the interactive subscription login stay **manual** (it prints the exact commands); idempotent; refuses to clobber a non-symlink; never commits, never runs a subscription CLI.
108
108
  - **`/agent-workflow-kit status`** — read-only view of the **whole family**: which members (kit / memory / engine / the two bridges) are installed, at what version, and — in a project — what is deployed (`docs/ai`, the version stamps, the hidden-mode fence). Never writes, never commits, never runs a subscription CLI.
109
109
  - **`/agent-workflow-kit recipes`** — read-only **orchestration advisor**: present the four recipes (Solo / Reviewed / Council / Delegated) over the bridges' role vocabulary, plan + recommend one for the current environment, and offer the choice. **The orchestrator executes the chosen recipe via the bridge skills and always commits** — the kit only surfaces/selects/plans it; it never executes a recipe, never runs a subscription CLI, never commits.
110
- - **`/agent-workflow-kit procedures <activity>`** — read-only **activity-procedures advisor**: print the ordered steps of a named activity (`plan-authoring` / `plan-execution`) read **live** from the installed engine (`references/procedures.md`), and the **resolved effective recipe per slot** from the per-project `docs/ai/orchestration.json` (hand-edited, strict JSON) + backend readiness (default = Reviewed when a backend is ready, Council on request, slot-aware incl. Delegated; graceful default vs loud override degradation). A per-run `--override <slot>=<recipe>` overrides one slot. Composes with `recipes` (which stays read-only); never writes, never commits, never runs a subscription CLI.
110
+ - **`/agent-workflow-kit procedures <activity>`** — read-only **activity-procedures advisor**: print the ordered steps of a named activity (`plan-authoring` / `plan-execution`) read **live** from the installed engine (`references/procedures.md`), and the **resolved effective recipe per slot** from the per-project `docs/ai/orchestration.json` (strict JSON; agent-writable via `set-recipe` or hand-edit) + backend readiness (default = Reviewed when a backend is ready, Council on request, slot-aware incl. Delegated; graceful default vs loud override degradation). A per-run `--override <slot>=<recipe>` overrides one slot. Composes with `recipes` (which stays read-only); never writes, never commits, never runs a subscription CLI.
111
+ - **`/agent-workflow-kit set-recipe`** — the **config writer** for `docs/ai/orchestration.json`: turn the user's plain language into explicit `--set <activity>.<slot>=<recipe>` / `--unset` ops; the kit validates, merges, **previews by default**, and writes only on `--write` (deployment-gated, atomic, symlink/TOCTOU-safe). Resolves the effective recipe vs live readiness (degradation honesty on both paths). **Writes only `docs/ai/orchestration.json`; never runs a backend, never commits.** Hand-editing the file stays fully supported.
111
112
  - **`/agent-workflow-kit uninstall`** — the **guarded teardown** companion to `init`/`setup`. Removes what they placed — installed skill dirs + the bridge wrappers — and, in a project, reverses the hidden-mode fence + the marker pre-commit hook. **Never deletes user-authored content**: it prints the exact `rm` for `docs/ai` / `AGENTS.md` and an **edit** for `.claude/settings.json` (the `includeCoAuthoredBy` key + any velocity `permissions.*`), for you to run by hand. `--dry-run` first, always; preflight-then-mutate; never commits.
112
113
  - **`/agent-workflow-kit velocity`** — opt-in onboarding **velocity profile**: seed a fixed, audited **read-only** Claude Code allowlist into `.claude/settings.json` so routine read-only commands stop idling on approval prompts; 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.** `--dry-run` first.
113
114
 
@@ -283,9 +284,9 @@ Fill strategy:
283
284
 
284
285
  **Hidden-mode footprint reconcile — stamp-independent, same gate, BEFORE the equal-head short-circuit (D9 / AD-014).** A deployment does not record whether it chose `hidden`, so first **infer visibility**: `node ${CLAUDE_SKILL_DIR}/tools/hide-footprint.mjs --dir <project> --reconcile --dry-run` (writes **zero bytes**). It reports one of — **visible** (the entry point is tracked) → nothing to do; **ambiguous** (untracked but not ignored — could be a fresh uncommitted repo, or a hide that broke) → **ASK** the user which it is, never guess; **hidden** → re-run without `--dry-run` to migrate any older **machine-global** hide to the **project-local** `.git/info/exclude` (one managed block; folds in the legacy `.claude/skills/` line), idempotently (a clean re-run is zero-diff). Handle its surfaced paths exactly as bootstrap step 9 (already-committed → show `git rm --cached`, ask before `--include`; generic-name present file → ask; **leftover machine-wide ignore block → ASK before `--remove-global`**, default keep + report). No Node on the agent host / Windows → as step 9. This runs on **every** hidden upgrade, like the methodology slot — no lineage-head bump, no migration file.
285
286
 
286
- **Orchestration config ensure — stamp-independent, same gate, BEFORE the equal-head short-circuit.** Ensure `docs/ai/orchestration.json` exists: **create it if missing**, **preserve it byte-for-byte if it already exists** (a user may have edited it — never clobber it). In the **delegated** path memory does this from its own template (memory upgrade step 2); in the **fallback** path the kit seeds it from `${CLAUDE_SKILL_DIR}/references/templates/orchestration.json`. Like the pointer slots + the footprint reconcile, this lets an equal-head (`1.3.0`) deployment gain the config seed **without a lineage-head bump or a migration file** (it is a `.json`, inherently outside the docs cap-validator). Report it in the step 4 / step 8 success report (config *seeded* vs *already present*).
287
+ **Orchestration config ensure (seed-or-refresh) — stamp-independent, same gate, BEFORE the equal-head short-circuit.** Ensure `docs/ai/orchestration.json` exists **and its onboarding note is current**: **create it from the template if missing**; **if it already exists, preserve every activity/slot the user set, and refresh ONLY the `_README` note when the existing one still matches a known prior canonical** — the tested `refreshIfCanonical` / `refreshReadme` in `tools/orchestration-config.mjs` is the source of truth for that decision (normalize CRLF/whitespace before comparing; a *customized* `_README` is preserved verbatim; a *malformed* existing config is **preserved + a loud warning**, never clobbered or silently skipped). The current note points at `/agent-workflow-kit set-recipe` (the config is now agent-writable no more "never written for you"). **The refresh helper is kit-owned** — in the **delegated** path memory only seeds/preserves the file (memory upgrade step 2) and the **kit** then applies the `_README` refresh; in the **fallback** path the kit seeds-or-refreshes directly from `${CLAUDE_SKILL_DIR}/references/templates/orchestration.json`. (Memory stays standalone — it never depends on this helper.) Like the pointer slots + the footprint reconcile, this reaches an equal-head (`1.3.0`) deployment **without a lineage-head bump or a migration file** (it is a `.json`, inherently outside the docs cap-validator). Report it in the step 4 / step 8 success report (config *seeded* / *note refreshed* / *already current* / *customized — preserved*).
287
288
  4. **Equal-head exit — a real successful-exit report, not a bare stop.** If the stamp **equals** the head, the lineage is up to date — but step 3 (the methodology-slot **and** hidden-mode footprint reconciles) ran first and may have changed things, so this is a proper exit report, not a no-op:
288
- - **Report step 3's outcome in plain language** — for **each** pointer (workflow-methodology and orchestration-recipes) whether it was *added*, was *already present* (nothing changed), or was *skipped because the entry point is over its line limit* (the cap-refusal soft-skip from step 3, with its reason); whether the `docs/ai/orchestration.json` config was *seeded* or was *already present* (a user edit is preserved); and, for a hidden deployment, whether the hidden-mode footprint was *moved to project-local*, was *already project-local* (nothing changed), or needed a question (ambiguous visibility / a leftover machine-wide block). Plain wording only — never the reconcile/slot/anchor/marker terms (Gotcha: never leak kit internals).
289
+ - **Report step 3's outcome in plain language** — for **each** pointer (workflow-methodology and orchestration-recipes) whether it was *added*, was *already present* (nothing changed), or was *skipped because the entry point is over its line limit* (the cap-refusal soft-skip from step 3, with its reason); whether the `docs/ai/orchestration.json` config was *seeded* (created from the template), had its onboarding note *refreshed*, was *already current*, or carried a *customized note that was preserved* (a user edit is never clobbered); and, for a hidden deployment, whether the hidden-mode footprint was *moved to project-local*, was *already project-local* (nothing changed), or needed a question (ambiguous visibility / a leftover machine-wide block). Plain wording only — never the reconcile/slot/anchor/marker terms (Gotcha: never leak kit internals).
289
290
  - **Name the version axis so the package number isn't mistaken for a newer release.** When you state the deployment is up to date, say it is current at the **deployment-lineage head** (`1.3.0`) and add one plain line: this head versions the deployed `docs/ai` structure and is a **separate axis** from the kit **package** version published on npm/GitHub (the larger number users see on the repo/npm page). A packaging-only release can bump that package version **without** moving the head — the head advances only when the deployed `docs/ai` structure changes — so an equal-head report is **not** a stale deployment even though GitHub shows a higher package number. (This is the only place the two axes meet the user in `upgrade`; surfacing it here prevents the recurring "but GitHub shows a higher version" confusion.)
290
291
  - **Print the report footer** in the canonical order (version block → one-line backend-status line → welcome mat — the shared contracts above; rendered from the helpers, same host-can't-run skip-with-reason). The welcome mat closes on **one** caveat-aware next step (a behind member first, else `setup` / `recipes` / `velocity`).
291
292
  - **Then ask before committing — never auto-commit.** If step 3 added the slot (or anything else changed), report it and ask. If step 3 was a pure zero-diff no-op and nothing else changed, say **"already up to date"** and still print the read-only version block + backend line.
@@ -320,6 +321,11 @@ For each backend it:
320
321
  2. **Links its wrappers** (`codex-exec` / `codex-review`; `agy-run`) onto `--bindir` via **managed symlinks** — replacing only a symlink that already points at our source. A non-symlink or a foreign symlink → **STOP**; it **preflights every target first**, so a conflict on one wrapper makes **zero** changes. If `--bindir` is not on `PATH`, it prints the one-line `export PATH=…` to add — it never edits a shell rc.
321
322
  3. **Guides the manual, secret-bearing steps it will NOT automate** — the binary install (each bridge's `setup/README.md` §1) and the one-time interactive subscription login (`codex login` / `agy`) — printing the exact command for whichever axis is still missing (axis-aware: it can ask for both the CLI and the login at once).
322
323
 
324
+ **Close-the-loop output (surface both, localized).** The tool prints, after the per-backend report:
325
+ - a **bridge version** on each skill line — `(vX)` for a fresh place / equal refresh, `(vOld → vNew)` when a refresh bumps the bridge (never `vnull → …`);
326
+ - a **status pointer** — the full family + deployment version view lives in `/agent-workflow-kit status`;
327
+ - a **proactive recipe offer** when a setup just made a review backend ready (re-detected AFTER apply, so it reflects the real new state): it prints `/agent-workflow-kit set-recipe --set plan-authoring.review=<depth>` **and** `…plan-execution.review=<depth>` (Council when both are ready, else Reviewed). Relay it in plain language: offer to set the review recipe for **both** planning and execution review (preview first; you'll write it via *Mode: set-recipe*, or they can hand-edit) — never offer only `plan-execution`. Ask if the scope is unclear.
328
+
323
329
  **Windows:** the wrappers are POSIX `.sh`; on `win32` it reports *unsupported — use WSL* and mutates nothing.
324
330
 
325
331
  **Exit codes:** `0` = done / already set up / only manual steps remain (guidance is never a failure); **non-zero** = a STOP (a dir/symlink it refuses to clobber), a bad argument, a missing bundle, or a native fs error (the underlying reason is preserved in the message).
@@ -371,7 +377,7 @@ The two v1 activities (canon in the **installed engine**, `references/procedures
371
377
 
372
378
  Run **`node ${CLAUDE_SKILL_DIR}/tools/procedures.mjs <activity> [--override <slot>=<recipe>]… [--json]`**. It reads the activity's steps live from the engine and prints them **verbatim**, then the **resolved effective recipe per slot** from the per-project config + the read-only backend detector:
373
379
 
374
- 1. **Config = `docs/ai/orchestration.json`** — strict JSON, **hand-edited** (the kit reads + validates it; `recipes` stays read-only — there is no writer). Shape: `{ "<activity>": { "<slot>": "<recipe>" } }`; all slots optional (an absent slot → its computed default, stated); an optional `"_README"` string is allowed + ignored. `review` accepts `solo|reviewed|council`; `execute` accepts `solo|delegated`. Seeded by `init` (a user-editable template) — see *Mode: bootstrap*.
380
+ 1. **Config = `docs/ai/orchestration.json`** — strict JSON, **agent-writable via `/agent-workflow-kit set-recipe` (Mode: set-recipe) OR hand-edited** (the kit reads + validates it; `procedures`/`recipes` stay read-only — the writer is `set-recipe`). Shape: `{ "<activity>": { "<slot>": "<recipe>" } }`; all slots optional (an absent slot → its computed default, stated); an optional `"_README"` string is allowed + ignored. `review` accepts `solo|reviewed|council`; `execute` accepts `solo|delegated`. Seeded by `init` (a user-editable template) — see *Mode: bootstrap*.
375
381
  2. **Default resolution (config silent):** `review` → Reviewed if any review-capable backend is `ready`, else Solo (never Council by default); `execute` → Solo (Delegated is opt-in). **Degradation:** a config/computed default degrades **gracefully with a stated reason** (Council → Reviewed → Solo; Delegated → Solo); a per-run **`--override <slot>=<recipe>`** that can't be satisfied degrades **loudly** (a flagged warning, so you tell the user) — but is **still exit 0** (a valid request that gracefully degraded).
376
382
  3. **Exit codes:** `0` success; `2` usage (unknown `<activity>` / bad `--override` — a bare `--override <recipe>`, an unknown slot, an invalid recipe-for-slot, or a duplicate slot); `1` config error (malformed / schema-invalid / unreadable `orchestration.json`) **or** engine error (the installed engine is absent / invalid / **too old** to ship `references/procedures.md` — upgrade it with `npx @sabaiway/agent-workflow-engine@latest init`). A `1`/`2` failure is loud (`path: reason`), never a silent fallback.
377
383
 
@@ -379,6 +385,30 @@ Run **`node ${CLAUDE_SKILL_DIR}/tools/procedures.mjs <activity> [--override <slo
379
385
 
380
386
  **Invariants:** read-only · never writes · never commits · never runs a subscription CLI · the deterministic resolution is the kit's, the recipe execution is the orchestrator's.
381
387
 
388
+ ### Mode: set-recipe
389
+
390
+ The **config writer** for `docs/ai/orchestration.json` — the answer to *"set my standing recipe preference without hand-editing JSON."* **Division of labor (AD-025):** YOU turn the user's plain language into explicit ops; the KIT does the deterministic validate → merge → preview → write. It **previews by default** (writes nothing); `--write` applies. It **never runs a backend and never commits**. Hand-editing `docs/ai/orchestration.json` stays fully supported — this is an offered convenience, never a lock.
391
+
392
+ **Map the user's plain language → explicit ops** (the kit ships no NL parser; it performs no `all`-magic, so you expand scope explicitly, asking when unclear):
393
+
394
+ | user says (RU/EN) | op | scope |
395
+ |---|---|---|
396
+ | "оба ревьюят" / "both review" | `--set <activity>.review=council` | **disambiguate**: which activity? If both, pass `--set plan-authoring.review=council --set plan-execution.review=council`. |
397
+ | "один ревьюер" / "one reviewer" | `--set <activity>.review=reviewed` | per the named activity, else ask |
398
+ | "делегируй исполнение" / "delegate execution" | `--set plan-execution.execute=delegated` | execution only |
399
+ | "верни как было / сам" / "revert / do it myself" | `--unset <activity>.<slot>` | the named slot → its computed default |
400
+
401
+ Run **`node ${CLAUDE_SKILL_DIR}/tools/set-recipe.mjs [--set <activity>.<slot>=<recipe>]… [--unset <activity>.<slot>]… [--write] [--json]`**:
402
+
403
+ 1. **Grammar — always fully-qualified `<activity>.<slot>`** (the kit never guesses the activity; a bare `review=council` is rejected). `review` accepts `solo|reviewed|council`; `execute` accepts `solo|delegated`. Activities/slots: `plan-authoring.review`, `plan-execution.execute`, `plan-execution.review`.
404
+ 2. **Preview by default** — prints `current → proposed` for the **changed** slots only, plus the **effective recipe resolved against live backend readiness** (degradation stated honestly, e.g. *council requested, 1 ready reviewer → runs reviewed until a 2nd backend is ready*). It writes **nothing**. Re-run with **`--write`** to apply (same effective/degradation note — a direct `--write` is never quieter than the preview). `--unset` returns a slot to its computed default (reverting needs no hand-edit either). A no-op `--set` (slot already equals) writes nothing and never re-seeds the onboarding note.
405
+ 3. **`--write`** applies via a hardened, atomic write (deployment-gated — refuses to scatter a config into a repo with no `docs/ai`; exclusive-create temp + rename; symlink/TOCTOU-safe; last-writer-wins). It preserves the onboarding note + every untouched slot, normalizing to canonical 2-space JSON.
406
+ 4. **Exit codes:** `0` success (an explicit recipe that gracefully degrades is still `0`); `2` usage (a bare/duplicate op, or `--write` with no ops); `1` config error (malformed/unreadable config — the file is left **untouched**, never clobbered) or a write STOP (no deployment / a symlinked config). A `1`/`2` failure is loud; on a malformed config, offer to show the parse error so you can help the user fix the JSON.
407
+
408
+ Output is **English/structured** — **localize it to the user's conversational language** when you narrate. Surface the effective-recipe/degradation note plainly.
409
+
410
+ **Invariants:** writer (writes only `docs/ai/orchestration.json`) · never commits · never runs a subscription CLI · previews by default · degradation honesty on preview AND `--write` · hand-edit stays first-class.
411
+
382
412
  ### Mode: uninstall
383
413
 
384
414
  The **guarded teardown** — the inverse of `init` (the kit + engine skills) + `setup` (the bridges) + a hidden deploy. **In-agent, opt-in**, and built around one hard rule: **it never deletes user-authored content.** Run **`--dry-run` first, always**, show the user the classified plan in plain language, get explicit consent, then re-run with `--yes`. It **never commits**.
@@ -411,7 +441,7 @@ Run `node ${CLAUDE_SKILL_DIR}/tools/velocity-profile.mjs [--dry-run | --apply] [
411
441
  - **"Keep per-edit approval prompts (recommended)"** — seed only the read-only allowlist; file edits still prompt.
412
442
  - **"Auto-accept file edits (`defaultMode: acceptEdits`)"** — present the honest FULL posture: it auto-applies Edit/Write AND auto-runs `mkdir`/`touch`/`mv`/`cp` in the working dir, is paired with the read-only allowlist, and — stated plainly — a settings-level allow rule is a **trust posture, not a sandbox**: a read-only entry can still write a file via output redirection, and (Claude Code's allow rules do not inspect command substitution) could in principle run another command via `cmd $(…)`. velocity **never adds `commit`/`push`/`publish` as allow rules** — so a direct `git push` still ASKs — but that same redirection/substitution residual means they are not *fully* closed until the deferred PreToolUse hook (family backlog). Note also that a `defaultMode` in `settings.local.json` would override this project-level write (local > project), since velocity writes only `.claude/settings.json`.
413
443
  3. **Only on an explicit yes**, re-run with `--apply` (add `--accept-edits` only if they chose the second option). It merges-don't-clobber (preserves `includeCoAuthoredBy`, every key, and existing allow entries) and writes **only** `.claude/settings.json`.
414
- 4. **Surface delegation-readiness, read-only.** If they want a step run Delegated, point them at the hand-edited `docs/ai/orchestration.json` (*Mode: procedures*); the tool never writes it.
444
+ 4. **Surface delegation-readiness, read-only.** If they want a step run Delegated, set it with `/agent-workflow-kit set-recipe --set plan-execution.execute=delegated` (*Mode: set-recipe*) or by hand-editing `docs/ai/orchestration.json`; **velocity itself never writes the orchestration config.**
415
445
 
416
446
  **Invariants:** creates `.claude/` if absent and writes **only** `.claude/settings.json` (no other file); **never** allowlists commit/push/publish; **never** writes `settings.local.json`; never commits; opt-in `acceptEdits`, never silent.
417
447
 
@@ -491,6 +521,6 @@ Deploy these into `AGENTS.md`; remove rows that don't apply to the stack.
491
521
  - [`references/scripts/`](references/scripts/) — the Node enforcement scripts (caps + staleness + index-freshness gate, 3-tier archive, hook installer) and their unit tests.
492
522
  - [`migrations/`](migrations/) — per-version upgrade steps; see `migrations/README.md`.
493
523
  - [`launchers/`](launchers/) — run the bootstrapper from non-Claude agents (`SKILL.md` is a native Codex skill; a Devin Desktop workflow launcher + install script). See `launchers/README.md`.
494
- - [`tools/`](tools/) — the family-wide tooling the kit **owns and ships**: `manifest/{schema.md,validate.mjs}` (the `capability.json` schema + the validator the kit runs as the memory detector, and root CI invokes), `commands.mjs` (the canonical **command catalog** + the pure `routeInvocation` router behind `/agent-workflow-kit help` and the safe unknown-invocation routing rule — one source of truth for the command surface, drift-guarded against the `### Mode:` headers), `delegation.mjs` (the executable delegate/fallback decision + hand-off plan), `inject-methodology.mjs` + `engine-source.mjs` (the bounded **two-slot** reconciliation — ensure-slot / inject-if-empty / cap for the `workflow:methodology` **and** `workflow:orchestration` pointers; both fragments read **live** from the installed `agent-workflow-engine` via `engine-source.mjs` (`deps.rel` selects which) — the family's one source of truth, no bundled mirror; fail-loud when the engine is needed but absent, orchestration soft-skipped when it would bust the cap), `detect-backends.mjs` (the read-only **backend detector** behind `/agent-workflow-kit backends`, plus the axis-aware `guideFor`; exports the readiness consts the planner reuses), `recipes.mjs` (the read-only **recipe planner** behind `/agent-workflow-kit recipes` — `RECIPES` / `planRecipe` / `recommendRecipe` over the bridges' role vocabulary, drift-guarded against `provides`/`cost`/`quota` + an engine↔kit recipe-name parity guard; pure, never runs a subscription CLI; also exports the pure `ACTIVITIES` / `resolveActivityRecipe` activity-procedures resolver), `procedures.mjs` (the read-only **activity-procedures advisor** behind `/agent-workflow-kit procedures` — reads `references/procedures.md` live from the engine via `engine-source.mjs`, reads + validates the hand-edited `docs/ai/orchestration.json`, and prints the steps + the resolved effective recipe per slot; drift-guarded activity/slot table vs the canon; read-only, never runs a subscription CLI), `setup-backends.mjs` (the **link-only** backend setup behind `/agent-workflow-kit setup` — place the bundled bridge + link wrappers), `fs-safe.mjs` (the shared symlink-traversal-safe copy/link/**remove/unlink** primitives that `setup-backends`, the npx installer, and the uninstaller use), `known-footprint.mjs` + `hide-footprint.mjs` (the **hidden-mode** registry + the single hide-writer behind step 9 / the upgrade reconcile — one managed block in the **project-local** `.git/info/exclude` covering the full AI/agent footprint; pinned by `known-footprint.test.mjs` drift-guard + `hide-footprint.test.mjs` / `.integration.test.mjs`), `family-registry.mjs` (the **unified family registry** behind `/agent-workflow-kit status` — aggregates every member's `capability.json`; pinned by a `family-registry.test.mjs` drift-guard), `uninstall.mjs` (the **guarded teardown** behind `/agent-workflow-kit uninstall` — classify each surface, preflight-then-mutate, never delete user-authored content), and `release-scan.mjs` (the attribution-off release gate). The bundled bridge skill mirrors live under [`bridges/`](bridges/) (byte-identical to the repo-root bridges, pinned by `test/bridges-mirror.test.mjs`). See [`tools/manifest/schema.md`](tools/manifest/schema.md).
524
+ - [`tools/`](tools/) — the family-wide tooling the kit **owns and ships**: `manifest/{schema.md,validate.mjs}` (the `capability.json` schema + the validator the kit runs as the memory detector, and root CI invokes), `commands.mjs` (the canonical **command catalog** + the pure `routeInvocation` router behind `/agent-workflow-kit help` and the safe unknown-invocation routing rule — one source of truth for the command surface, drift-guarded against the `### Mode:` headers), `delegation.mjs` (the executable delegate/fallback decision + hand-off plan), `inject-methodology.mjs` + `engine-source.mjs` (the bounded **two-slot** reconciliation — ensure-slot / inject-if-empty / cap for the `workflow:methodology` **and** `workflow:orchestration` pointers; both fragments read **live** from the installed `agent-workflow-engine` via `engine-source.mjs` (`deps.rel` selects which) — the family's one source of truth, no bundled mirror; fail-loud when the engine is needed but absent, orchestration soft-skipped when it would bust the cap), `detect-backends.mjs` (the read-only **backend detector** behind `/agent-workflow-kit backends`, plus the axis-aware `guideFor`; exports the readiness consts the planner reuses), `recipes.mjs` (the read-only **recipe planner** behind `/agent-workflow-kit recipes` — `RECIPES` / `planRecipe` / `recommendRecipe` over the bridges' role vocabulary, drift-guarded against `provides`/`cost`/`quota` + an engine↔kit recipe-name parity guard; pure, never runs a subscription CLI; also exports the pure `ACTIVITIES` / `resolveActivityRecipe` activity-procedures resolver), `procedures.mjs` (the read-only **activity-procedures advisor** behind `/agent-workflow-kit procedures` — reads `references/procedures.md` live from the engine via `engine-source.mjs`, reads + validates the agent-writable `docs/ai/orchestration.json` via `orchestration-config.mjs`, and prints the steps + the resolved effective recipe per slot; drift-guarded activity/slot table vs the canon; read-only, never imports the writer, never runs a subscription CLI), `orchestration-config.mjs` (the config **schema/read/pure-transform core** — `loadConfig`/`validateConfig`/the shared slot-recipe validity + `parseOp`/`applySetOps`/`serializeConfig`/the canonical-refresh helpers; no fs writes), `orchestration-write.mjs` (the **only** config fs-writer — a deployment-gated, atomic, symlink/TOCTOU-safe `writeConfig`; imported by `set-recipe` alone, never by `procedures`), `set-recipe.mjs` (the **config writer** behind `/agent-workflow-kit set-recipe` — validate → merge → preview-by-default → write; never runs a backend, never commits), `setup-backends.mjs` (the **link-only** backend setup behind `/agent-workflow-kit setup` — place the bundled bridge + link wrappers), `fs-safe.mjs` (the shared symlink-traversal-safe copy/link/**remove/unlink** primitives that `setup-backends`, the npx installer, and the uninstaller use), `known-footprint.mjs` + `hide-footprint.mjs` (the **hidden-mode** registry + the single hide-writer behind step 9 / the upgrade reconcile — one managed block in the **project-local** `.git/info/exclude` covering the full AI/agent footprint; pinned by `known-footprint.test.mjs` drift-guard + `hide-footprint.test.mjs` / `.integration.test.mjs`), `family-registry.mjs` (the **unified family registry** behind `/agent-workflow-kit status` — aggregates every member's `capability.json`; pinned by a `family-registry.test.mjs` drift-guard), `uninstall.mjs` (the **guarded teardown** behind `/agent-workflow-kit uninstall` — classify each surface, preflight-then-mutate, never delete user-authored content), and `release-scan.mjs` (the attribution-off release gate). The bundled bridge skill mirrors live under [`bridges/`](bridges/) (byte-identical to the repo-root bridges, pinned by `test/bridges-mirror.test.mjs`). See [`tools/manifest/schema.md`](tools/manifest/schema.md).
495
525
  - [`capability.json`](capability.json) — the kit's own `agent-workflow` family manifest (`kind: composition-root`).
496
526
  - [`CHANGELOG.md`](CHANGELOG.md) — version history of this kernel.
@@ -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: '1.0.0'
5
+ version: '2.0.0'
6
6
  ---
7
7
 
8
8
  # codex-cli-bridge
@@ -46,21 +46,28 @@ this skill. Both wrappers enforce the subscription path before invoking codex:
46
46
  regardless of that flag);
47
47
  - they **preflight `codex login status`** and refuse to run unless it reports `Logged in using ChatGPT`.
48
48
 
49
- ## Models
49
+ ## Models quality-first pinned
50
50
 
51
- The wrappers default to `gpt-5.5` at reasoning effort `xhigh` (the strongest setting verified in this
52
- environment), both overridable per call. `codex --version` reports the CLI version, **not** the model
53
- list check your Codex CLI / ChatGPT account for the model slugs available to you, or let a wrong
54
- `-m` surface the error.
51
+ Delegated codex work ALWAYS runs on the **frontier model at maximum reasoning effort**: the wrappers
52
+ **pin** `gpt-5.5` / `xhigh` and **refuse** (exit 2, loud) a non-default `CODEX_MODEL` / `CODEX_EFFORT`
53
+ knowingly-worse output is never traded for quota. The pin is deliberate (an explicit `-m gpt-5.5`
54
+ guarantees the *strongest* model, not merely the CLI's current default); a release-time gate against
55
+ <https://developers.openai.com/codex/models> re-checks that `gpt-5.5` is still the strongest selectable
56
+ Codex model. Economy comes only from **quality-neutral waste removal** (clean capture, a hard timeout,
57
+ a precomputed review diff, `resume` instead of re-sending context), never from a downgrade.
58
+
59
+ The ONLY escape is a **throwaway probe** whose result is effort-independent (a reachability / smoke
60
+ check): set `CODEX_PROBE=1` (echoed loudly) to relax the model/effort guard. Never use a probe run's
61
+ output as real delegated work.
55
62
 
56
63
  | Variable | Default | Effect |
57
64
  |---|---|---|
58
- | `CODEX_MODEL` | `gpt-5.5` | model passed to `-m` |
59
- | `CODEX_EFFORT` | `xhigh` | reasoning effort passed to `-c model_reasoning_effort=…` |
65
+ | `CODEX_MODEL` | `gpt-5.5` (pinned) | model passed to `-m`; a non-default is REFUSED unless `CODEX_PROBE=1` |
66
+ | `CODEX_EFFORT` | `xhigh` (pinned) | reasoning effort (`-c model_reasoning_effort=…`); non-default REFUSED unless `CODEX_PROBE=1` |
60
67
 
61
- ```bash
62
- CODEX_MODEL=<slug> CODEX_EFFORT=<low|medium|high|xhigh> codex-exec <file>
63
- ```
68
+ `codex --version` reports the CLI version, **not** the model list. Quota is metered in **messages**
69
+ (a rolling 5h window + a weekly cap), not raw tokens — which is why the levers above are about removing
70
+ waste, never lowering quality. Full knob list: [§ Environment knobs](#environment-knobs).
64
71
 
65
72
  ## Usage
66
73
 
@@ -70,27 +77,55 @@ Drive codex only through the two wrappers (installed on `PATH`), run from the ta
70
77
  # EXECUTION (workspace-write sandbox, network OFF, never prompts):
71
78
  codex-exec docs/plans/<slug>.md # drive a plan file
72
79
  echo "apply review fix: ..." | codex-exec - # ad-hoc instruction from stdin
73
- CODEX_MODEL=<slug> codex-exec <file> # override the model
74
- codex-exec <file|-> -- <extra codex flags...> # passthrough codex flags after `--`
80
+ codex-exec <file|-> -- <unguarded codex flags...> # passthrough codex flags after `--` (guarded ones rejected)
81
+
82
+ # RESUME (iterate on the SAME session without re-sending context):
83
+ codex-exec --resume-last docs/plans/<slug>.md # continue the last session (id from the sidecar)
84
+ echo "now do step 2 ..." | codex-exec --resume <session-id> -
75
85
 
76
86
  # REVIEW (read-only sandbox — codex cannot edit anything, only emits findings):
77
87
  codex-review plan docs/plans/<slug>.md # critique a plan
78
- codex-review code # review the current working-tree diff
88
+ codex-review code # review the current working-tree diff (precomputed)
79
89
  codex-review code "focus on the new reducer" # review with extra focus
80
90
  ```
81
91
 
82
92
  `codex exec` is headless: there is **no TTY**, so `approval_policy=never` — anything needing
83
- escalation is refused and reported, never interactively approved. Extra `codex` flags go after a
84
- literal `--`; args without the separator are rejected (never silently dropped). Full flag/policy
85
- detail: [`references/sandbox-and-flags.md`](references/sandbox-and-flags.md).
93
+ escalation is refused and reported, never interactively approved. The wrappers capture only codex's
94
+ **final message** (`-o`; the JSON event stream + reasoning go to a discarded trace), so output is
95
+ clean; a successful **non-resume** `codex-exec` also records the session id to a sidecar
96
+ (`${CODEX_SESSION_FILE:-./.codex-last-session}`) so `--resume-last` can find it. Extra `codex` flags
97
+ go after a literal `--`; the wrapper rejects any that would defeat the policy or the pinned model (see
98
+ [§ Environment knobs](#environment-knobs) and the flag tiers in
99
+ [`references/sandbox-and-flags.md`](references/sandbox-and-flags.md)); args without the separator are
100
+ rejected, never silently dropped.
101
+
102
+ ## Environment knobs
103
+
104
+ All optional; the defaults are the supported path. Anything that would lower quality (model/effort) or
105
+ defeat a policy is guarded — see [§ Models](#models-quality-first-pinned).
106
+
107
+ | Variable | Default | Effect |
108
+ |---|---|---|
109
+ | `CODEX_MODEL` | `gpt-5.5` (pinned) | model; non-default REFUSED unless `CODEX_PROBE=1` |
110
+ | `CODEX_EFFORT` | `xhigh` (pinned) | reasoning effort; non-default REFUSED unless `CODEX_PROBE=1` |
111
+ | `CODEX_HARD_TIMEOUT` | `3600` (exec) / `1800` (review) | hard wall-clock cap (seconds) via `timeout`/`gtimeout`; exit 124/137 ⇒ "exceeded hard cap". No `timeout` binary ⇒ loud warning + uncapped (never silent). |
112
+ | `CODEX_SESSION_FILE` | `./.codex-last-session` | where `codex-exec` records the session id and where `--resume-last` reads it |
113
+ | `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 |
114
+ | `CODEX_REVIEW_SCHEMA` | unset | `codex-review`: `=1` returns findings as a validated JSON object (`--output-schema`), with a raw-text fallback. Default off. |
115
+ | `CODEX_PROBE` | unset | `=1` ⇒ throwaway-probe mode: relaxes the model/effort guard AND the tier-2 passthrough guard (echoed loudly). Never for real work. |
116
+
117
+ The git-write shim, `--ignore-user-config`, and the `*_API_KEY` scrub are NOT env-tunable — they are
118
+ fixed invariants.
86
119
 
87
120
  ## Project context (how `codex` sees the repo)
88
121
 
89
- From its **current working directory** `codex` auto-reads the root **`AGENTS.md`** so when you run a
90
- wrapper from a project root, the project's Hard Constraints are available to codex with no wiring (a
122
+ `codex` auto-**merges** `AGENTS.md` (root→cwd, plus a global `~/.codex/AGENTS.md`) straight into its
123
+ developer context, truncated at `project_doc_max_bytes` (default 32 KiB) so when you run a wrapper
124
+ from a project root, the project's Hard Constraints are already in front of the model with no wiring (a
91
125
  probe confirmed codex returned a repo's declared dialogue language from `AGENTS.md`). The wrappers
92
- therefore **hardcode no project rules**: the orchestrator contract tells codex to read the target
93
- `AGENTS.md` and obey it.
126
+ therefore **hardcode no project rules**, and the orchestrator contract is **lean**: it tells codex to
127
+ *obey* the already-merged `AGENTS.md` Hard Constraints + declared gates — it does NOT waste a step
128
+ telling codex to go *read* a file that is already in context.
94
129
 
95
130
  **Fallback is strict.** Both wrappers preflight that they run inside a git work tree and that a root
96
131
  `AGENTS.md` exists — if either is missing they **STOP and report** (a wasted subscription run is
@@ -105,17 +140,28 @@ See [`references/driving-codex.md`](references/driving-codex.md) for the full pl
105
140
  - **`codex-exec` for doing, `codex-review` for judging.** Use exec to implement a plan/fix under the
106
141
  sandbox; use review to get advisory findings on a plan or diff without any edits.
107
142
  - **The orchestrator commits — codex never does.** The execution contract forbids every git write
108
- (branch/add/commit/stash/reset/checkout/tag/rewrite); you review codex's diff, then commit yourself.
143
+ (branch/add/commit/stash/reset/checkout/tag/rewrite), and `codex-exec` additionally enforces it with
144
+ a physical **git-write shim** on the codex subprocess's `PATH`: read-only git verbs pass through,
145
+ every write/unknown verb is blocked (codex spawns `git` via `execve`, which bypasses shell
146
+ functions — so the boundary must be a real file). You review codex's diff, then commit yourself.
109
147
  - **Treat output as advisory** and verify before acting — re-run the project's gates yourself, reject
110
148
  advice that conflicts with user instructions or repo rules.
111
149
  - **Hand codex a self-contained task.** It cannot see your conversation — for an ad-hoc instruction,
112
150
  embed the goal, the relevant paths, and the expected result; codex reads `AGENTS.md` for the rules.
113
- - **Re-dispatch with `codex exec resume`** (run codex directly the wrapper's flag/stdin shape can't
114
- host the `resume` subcommand) instead of re-sending context. **Caveat:** resume runs outside the
115
- wrapper and may not re-accept `--sandbox` / policy flags restate the policy, or start a fresh
116
- `codex-exec` run when a guaranteed sandbox/network posture matters.
151
+ - **Iterate with `codex-exec --resume-last` / `--resume <id>`** instead of re-sending context. The
152
+ resume entrypoint re-establishes EVERY wrapper invariant (subscription-only, `--ignore-user-config`,
153
+ the pinned model/effort) and **restates the full posture via `-c`**`codex exec resume` resets the
154
+ sandbox/approval/network posture and rejects the `-s`/`--add-dir`/`-C` posture flags, so the wrapper
155
+ sets `sandbox_mode=workspace-write` + `approval_policy=never` +
156
+ `sandbox_workspace_write.network_access=false` explicitly. It reads the session id from the sidecar
157
+ (`--resume-last`) or takes it as an argument.
117
158
  - **Network is OFF in exec.** New dependencies and any network step are installed by hand, then codex
118
159
  is re-dispatched.
160
+ - **`codex-review code` precomputes the diff.** The wrapper assembles the change set (repo map, status,
161
+ staged + unstaged diff, untracked file contents) and feeds it in, so codex does not roam the
162
+ filesystem rediscovering it; a clean tree exits 0 before a run is spent. Native `codex review` is
163
+ deliberately NOT used — it rejects `--ignore-user-config` and would load a personal config.toml,
164
+ breaking the subscription/config-isolation invariant.
119
165
 
120
166
  ## Complementary skills (optional, standalone-first)
121
167
 
@@ -140,8 +186,15 @@ The wrappers work in any git repo where `codex` is installed and authenticated.
140
186
  install dependencies or reach the network — do that by hand, then re-dispatch.
141
187
  - **No live approvals** — `codex exec` has no TTY, so `approval_policy=never`; an action that would
142
188
  need escalation is reported, not approved interactively.
143
- - **`resume` may drop sandbox/policy flags** — restate the policy or start a fresh run when the
144
- posture matters (see the driving reference).
189
+ - **`resume` resets the posture** — `codex exec resume` rejects `-s`/`--add-dir`/`-C` and forgets the
190
+ original sandbox/approval/network policy. The `codex-exec --resume`/`--resume-last` entrypoint
191
+ restates it via `-c`; only a *raw* `codex exec resume` (bypassing the wrapper) loses the posture.
192
+ - **Hard timeout** — a hung run is killed at `CODEX_HARD_TIMEOUT` (exec 3600s / review 1800s) and
193
+ reported (exit 124/137); raise it for a known-healthy slow run. If neither `timeout` nor `gtimeout`
194
+ is on `PATH` the wrapper warns loudly and runs uncapped (never silently).
195
+ - **Native `codex review` is out of scope** — it rejects `--ignore-user-config` (would load a personal
196
+ `config.toml` and break the subscription/config-isolation invariant) and can't be cleanly captured;
197
+ `codex-review` runs `codex exec` over a precomputed diff instead.
145
198
  - **bubblewrap** — on Linux, if `bubblewrap` is not on `PATH` codex prints a warning and uses a
146
199
  bundled copy; install it via your package manager to silence the warning.
147
200
  - codex output is advisory and may be incomplete or out of date — the main agent verifies before