@sabaiway/agent-workflow-kit 14.19.1 → 14.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/README.md +1 -1
- package/SKILL.md +1 -1
- package/bridges/antigravity-cli-bridge/SKILL.md +45 -50
- package/bridges/antigravity-cli-bridge/bin/agy-model-posture.test.mjs +257 -0
- package/bridges/antigravity-cli-bridge/bin/agy-review-harness.test.mjs +10 -3
- package/bridges/antigravity-cli-bridge/bin/agy-review-honesty.test.mjs +20 -21
- package/bridges/antigravity-cli-bridge/bin/agy-review-model-screen.test.mjs +4 -4
- package/bridges/antigravity-cli-bridge/bin/agy-review.sh +120 -48
- package/bridges/antigravity-cli-bridge/bin/agy-review.test.mjs +22 -62
- package/bridges/antigravity-cli-bridge/bin/agy.sh +109 -16
- package/bridges/antigravity-cli-bridge/bin/agy.test.mjs +5 -5
- package/bridges/antigravity-cli-bridge/capability.json +14 -7
- package/bridges/antigravity-cli-bridge/references/driving-agy.md +16 -20
- package/bridges/antigravity-cli-bridge/references/models-and-flags.md +10 -27
- package/bridges/codex-cli-bridge/SKILL.md +57 -49
- package/bridges/codex-cli-bridge/bin/codex-exec.sh +145 -46
- package/bridges/codex-cli-bridge/bin/codex-exec.test.mjs +28 -55
- package/bridges/codex-cli-bridge/bin/codex-model-posture.test.mjs +371 -0
- package/bridges/codex-cli-bridge/bin/codex-review.sh +134 -36
- package/bridges/codex-cli-bridge/bin/codex-review.test.mjs +33 -45
- package/bridges/codex-cli-bridge/capability.json +22 -8
- package/bridges/codex-cli-bridge/references/driving-codex.md +18 -15
- package/bridges/codex-cli-bridge/references/sandbox-and-flags.md +16 -12
- package/bridges/codex-cli-bridge/setup/README.md +3 -3
- package/capability.json +1 -1
- package/package.json +1 -1
- package/references/modes/bridge-settings.md +10 -7
- package/references/modes/jev.md +3 -2
- package/references/modes/recipes.md +1 -1
- package/references/modes/recommendations.md +2 -1
- package/references/modes/review-state.md +1 -1
- package/references/vendor/typesafe-ai/LICENSE +21 -0
- package/references/vendor/typesafe-ai/SKILL.md.pinned +149 -0
- package/tools/ack-store.mjs +2 -0
- package/tools/bridge-catalog.mjs +114 -0
- package/tools/bridge-posture.mjs +11 -2
- package/tools/bridge-settings-read.mjs +41 -5
- package/tools/bridge-settings.mjs +111 -23
- package/tools/detect-backends.mjs +6 -6
- package/tools/family-registry.mjs +3 -3
- package/tools/jev-facts.mjs +101 -4
- package/tools/jev-guide.mjs +31 -12
- package/tools/jev-skill.mjs +231 -0
- package/tools/manifest/schema.md +1 -1
- package/tools/manifest/validate.mjs +3 -2
- package/tools/procedures.mjs +3 -3
- package/tools/recipes.mjs +2 -2
- package/tools/recommendations.mjs +49 -4
- package/tools/review-state.mjs +1 -1
|
@@ -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: '
|
|
5
|
+
version: '4.0.0'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# codex-cli-bridge
|
|
@@ -46,39 +46,40 @@ 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
|
|
50
|
-
|
|
51
|
-
Delegated codex work
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
49
|
+
## Models: the host posture
|
|
50
|
+
|
|
51
|
+
Delegated codex work runs on the **host posture**: `CODEX_MODEL` and `CODEX_EFFORT` from the bridge
|
|
52
|
+
settings file `${XDG_CONFIG_HOME:-~/.config}/agent-workflow/bridge-settings.conf`, else the built-in
|
|
53
|
+
default `gpt-6.1-sol` / `high`. **`/agent-workflow-kit bridge-settings`** shows the models the
|
|
54
|
+
installed `codex` offers and sets the host posture (checked against that list before it writes).
|
|
55
|
+
Before any run is spent the wrappers check the effective model and
|
|
56
|
+
effort against the installed CLI's catalog (`codex debug models`, the entries offered for listing): a
|
|
57
|
+
model or effort it does not offer is refused (exit 2) with the offered list and the settings-file lines
|
|
58
|
+
that set an offered posture. An unreadable catalog is one stderr warning and the run proceeds — codex
|
|
59
|
+
itself then refuses a model it does not serve.
|
|
60
|
+
|
|
61
|
+
The environment overrides the host posture for one run. A run on anything other than the host posture
|
|
62
|
+
is a **one-off**, whatever set it, and only a probe runs one: without `CODEX_PROBE=1` the wrappers refuse
|
|
63
|
+
it pre-spend (exit 2) and name the remedy — the settings-file lines that make it the host posture, plus
|
|
64
|
+
unsetting `CODEX_MODEL` and `CODEX_EFFORT` in the environment. An environment value equal to the host
|
|
65
|
+
posture is not a one-off; an explicitly empty `CODEX_MODEL=` or `CODEX_EFFORT=` selects the built-in
|
|
66
|
+
default. A nonced `codex-exec` probe one-off is refused too (the exec receipt could not say it ran off
|
|
67
|
+
the host posture), and a probe review's receipt is `probe:true` and never attests.
|
|
68
|
+
|
|
69
|
+
A weaker model is therefore the user's choice in the setting, never the orchestrator's per call. `high`
|
|
70
|
+
is the default effort, not the catalog maximum (`xhigh`, `max` and `ultra` exist above it). Whether the
|
|
71
|
+
default is also the *strongest* selectable Codex model is a hand-checked claim against
|
|
72
|
+
<https://developers.openai.com/codex/models>, with **no automated gate and no recorded date** — a newer
|
|
73
|
+
model is silent until the user sets it or a bridge release moves the default. A retired model fails
|
|
74
|
+
loudly: the catalog check refuses it pre-spend with the offered list and the remedy.
|
|
70
75
|
|
|
71
76
|
Economy comes only from **quality-neutral waste removal** (clean capture, a hard timeout,
|
|
72
|
-
a precomputed review diff, `resume` instead of re-sending context), never from a downgrade.
|
|
73
|
-
|
|
74
|
-
The ONLY escape is a **throwaway probe** whose result is effort-independent (a reachability / smoke
|
|
75
|
-
check): set `CODEX_PROBE=1` (echoed loudly) to relax the model/effort guard. Never use a probe run's
|
|
76
|
-
output as real delegated work.
|
|
77
|
+
a precomputed review diff, `resume` instead of re-sending context), never from a per-call downgrade.
|
|
77
78
|
|
|
78
79
|
| Variable | Default | Effect |
|
|
79
80
|
|---|---|---|
|
|
80
|
-
| `CODEX_MODEL` | `gpt-6-
|
|
81
|
-
| `CODEX_EFFORT` | `high`
|
|
81
|
+
| `CODEX_MODEL` | the setting, else `gpt-6.1-sol` | model passed to `-m`; an environment value off the host posture is a one-off, REFUSED unless `CODEX_PROBE=1` |
|
|
82
|
+
| `CODEX_EFFORT` | the setting, else `high` | reasoning effort (`-c model_reasoning_effort=…`); an environment value off the host posture is a one-off, REFUSED unless `CODEX_PROBE=1` |
|
|
82
83
|
|
|
83
84
|
`codex --version` reports the CLI version, **not** the model list. Quota is metered in **messages**
|
|
84
85
|
(a rolling 5h window + a weekly cap), not raw tokens — which is why the levers above are about removing
|
|
@@ -117,14 +118,15 @@ codex-review code "focus on the new reducer" # review with extra focus
|
|
|
117
118
|
**Honesty + posture (D4/D5):** a run whose final message has no recognized
|
|
118
119
|
`Verdict: <ship|revise|rethink>` line — empty or missing output included — **exits 4 with NO
|
|
119
120
|
receipt**: treat it as a *failed review to re-run*, never a fatal session error. One stderr banner
|
|
120
|
-
states the actual posture (`review posture: model=… effort=… tier=… timeout=…`) and the
|
|
121
|
-
records the same `posture {model, effort, tier}` (tier `null` on the standard tier); control
|
|
122
|
-
in a posture value refuse pre-spend in every mode. `codex-exec` states its posture the same way —
|
|
121
|
+
states the actual posture (`review posture: model=… effort=… tier=… source=… timeout=…`) and the
|
|
122
|
+
receipt records the same `posture {model, effort, tier}` (tier `null` on the standard tier); control
|
|
123
|
+
bytes in a posture value refuse pre-spend in every mode. `codex-exec` states its posture the same way —
|
|
123
124
|
ONE `exec posture: model=… effort=… tier=… sandbox=workspace-write session=fresh|resume:<id>
|
|
124
|
-
timeout=…` stderr line before dispatch (the resume id validated pre-spend). The `
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
source=… timeout=…` stderr line before dispatch (the resume id validated pre-spend). The `source=`
|
|
126
|
+
field (`model:<s>,effort:<s>`, each `default`, `setting` or `environment`) and the `timeout=` field
|
|
127
|
+
are **banner-only** (`timeout=` is exactly the duration handed to `timeout(1)`; on exec `uncapped`
|
|
128
|
+
without a capping binary, while `codex-review` **fails CLOSED pre-spend** there) — informational,
|
|
129
|
+
never a receipt field. **Quote the posture banner verbatim** when labeling a dispatch.
|
|
128
130
|
|
|
129
131
|
Every successful review receipt carries integer `durationS` and `blocking`; the wrapper prints
|
|
130
132
|
`review duration: <n>s`. A plan receipt also carries `artifactPath`, normalized to a repo-relative
|
|
@@ -146,29 +148,29 @@ failure carries both a sandbox-mechanism and a permission/read-only token in its
|
|
|
146
148
|
The exit status stays 0 there (warning, not gate) — read the stderr line. A successful **non-resume**
|
|
147
149
|
`codex-exec` also records the session id to a sidecar
|
|
148
150
|
(`${CODEX_SESSION_FILE:-./.codex-last-session}`) so `--resume-last` can find it. Extra `codex` flags
|
|
149
|
-
go after a literal `--`; the wrapper rejects any that would defeat the policy or the
|
|
151
|
+
go after a literal `--`; the wrapper rejects any that would defeat the policy or the host posture (see
|
|
150
152
|
[§ Environment knobs](#environment-knobs) and the flag tiers in
|
|
151
153
|
[`references/sandbox-and-flags.md`](references/sandbox-and-flags.md)); args without the separator are
|
|
152
154
|
rejected, never silently dropped.
|
|
153
155
|
|
|
154
156
|
## Environment knobs
|
|
155
157
|
|
|
156
|
-
All optional; the defaults are the supported path.
|
|
157
|
-
defeat a policy is guarded — see [§ Models](#models-
|
|
158
|
+
All optional; the defaults are the supported path. The model and effort are the host posture, and
|
|
159
|
+
anything that would defeat a policy is guarded — see [§ Models](#models-the-host-posture).
|
|
158
160
|
|
|
159
161
|
| Variable | Default | Effect |
|
|
160
162
|
|---|---|---|
|
|
161
|
-
| `CODEX_MODEL` | `gpt-6-
|
|
162
|
-
| `CODEX_EFFORT` | `high`
|
|
163
|
+
| `CODEX_MODEL` | the setting, else `gpt-6.1-sol` | model; off the host posture REFUSED unless `CODEX_PROBE=1` |
|
|
164
|
+
| `CODEX_EFFORT` | the setting, else `high` | reasoning effort; off the host posture REFUSED unless `CODEX_PROBE=1` |
|
|
163
165
|
| `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). |
|
|
164
|
-
| `CODEX_SERVICE_TIER` | unset (standard tier) | **SPEND knob**: `priority` (catalog name "Fast") = "2x speed, **increased usage**" in the codex catalog's own words for gpt-6-
|
|
166
|
+
| `CODEX_SERVICE_TIER` | unset (standard tier) | **SPEND knob**: `priority` (catalog name "Fast") = "2x speed, **increased usage**" in the codex catalog's own words for gpt-6.1-sol (cache fetched 2026-10-03); it states no credit-rate figure — quality-neutral (same model). codex accepts any `-c service_tier` string silently (probe-verified), so the wrapper validates: an unsupported value warns and runs standard. Env or settings file. |
|
|
165
167
|
| `CODEX_SESSION_FILE` | `./.codex-last-session` | where `codex-exec` records the session id and where `--resume-last` reads it |
|
|
166
168
|
| `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 |
|
|
167
169
|
| `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) |
|
|
168
170
|
| `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). |
|
|
169
171
|
| `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. |
|
|
170
172
|
| `CODEX_REVIEW_SCHEMA` | unset | `codex-review`: `=1` returns findings as a validated JSON object (`--output-schema`), with a raw-text fallback. Default off. |
|
|
171
|
-
| `CODEX_PROBE` | unset | `=1` ⇒ throwaway-probe mode:
|
|
173
|
+
| `CODEX_PROBE` | unset | `=1` ⇒ throwaway-probe mode: the one route to a one-off model or effort, and it relaxes the tier-2 passthrough guard (echoed loudly); a probe review's receipt never attests. Never for real work. |
|
|
172
174
|
|
|
173
175
|
The git-write shim, `--ignore-user-config`, and the `*_API_KEY` scrub are NOT env-tunable — they are
|
|
174
176
|
fixed invariants.
|
|
@@ -212,11 +214,11 @@ skipped entirely without a nonce: the wrapper is byte-unchanged, writes no artif
|
|
|
212
214
|
`${XDG_CONFIG_HOME:-~/.config}/agent-workflow/bridge-settings.conf` holds `KEY=VALUE` lines,
|
|
213
215
|
**parsed, never sourced** — a file line can never execute code. Precedence: explicit env (even
|
|
214
216
|
empty — `KEY=` disables a knob for one run) > file > built-in default. File-settable keys for this
|
|
215
|
-
bridge: `
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
217
|
+
bridge: `CODEX_MODEL` and `CODEX_EFFORT` (the host posture — see [§ Models](#models-the-host-posture)),
|
|
218
|
+
`CODEX_SERVICE_TIER` (the Fast tier — **increased usage**; enabling it is a consented per-host spend
|
|
219
|
+
decision, never a default), `CODEX_HARD_TIMEOUT`, `CODEX_REVIEW_MAX_TOTAL_BYTES` — exactly the
|
|
220
|
+
manifest `settings` block (the single source; the wrapper constants and `--help` are drift-guarded
|
|
221
|
+
against it, the model keys read by the posture reader instead). The file lives **outside every kit-managed tree**, so a kit refresh/upgrade can
|
|
220
222
|
never wipe it; edit it by hand or via `/agent-workflow-kit bridge-settings` (preview-first,
|
|
221
223
|
consent-gated).
|
|
222
224
|
|
|
@@ -236,6 +238,12 @@ avoided). And the execution contract tells codex: if the project declares **no**
|
|
|
236
238
|
set, **STOP and report** rather than invent checks. Pass `--skip-git-repo-check` to codex only when
|
|
237
239
|
you truly mean it.
|
|
238
240
|
|
|
241
|
+
**The Jev skill in a delegated run.** A `codex-exec` run loads the vendor's Jev skill from the user root the kit's
|
|
242
|
+
`jev-skill` command fills, `~/.agents/skills` — measured 2026-10-02: a run under `--ignore-user-config` listed the
|
|
243
|
+
skills of that root. The run never inherits `TYPESAFE_API_KEY`: the wrappers unset every `*_API_KEY` before codex
|
|
244
|
+
starts. codex exec has no network, so Jev requests are the orchestrator's own, made in the user's environment, and
|
|
245
|
+
their answers are passed into a brief as text.
|
|
246
|
+
|
|
239
247
|
## How the main agent drives `codex` efficiently
|
|
240
248
|
|
|
241
249
|
See [`references/driving-codex.md`](references/driving-codex.md) for the full playbook. Essentials:
|
|
@@ -253,7 +261,7 @@ See [`references/driving-codex.md`](references/driving-codex.md) for the full pl
|
|
|
253
261
|
embed the goal, the relevant paths, and the expected result; codex reads `AGENTS.md` for the rules.
|
|
254
262
|
- **Iterate with `codex-exec --resume-last` / `--resume <id>`** instead of re-sending context. The
|
|
255
263
|
resume entrypoint re-establishes EVERY wrapper invariant (subscription-only, `--ignore-user-config`,
|
|
256
|
-
the
|
|
264
|
+
the host posture's model/effort) and **restates the full posture via `-c`** — `codex exec resume` resets the
|
|
257
265
|
sandbox/approval/network posture and rejects the `-s`/`--add-dir`/`-C` posture flags, so the wrapper
|
|
258
266
|
sets `sandbox_mode=workspace-write` + `approval_policy=never` +
|
|
259
267
|
`sandbox_workspace_write.network_access=false` explicitly. It reads the session id from the sidecar
|
|
@@ -13,17 +13,17 @@
|
|
|
13
13
|
# - network access OFF: new dependencies / network installs are done by a human
|
|
14
14
|
# - approval_policy=never: there is no TTY in exec; anything needing escalation
|
|
15
15
|
# is refused and reported, then handled by hand
|
|
16
|
-
# - the
|
|
16
|
+
# - the host posture's model and reasoning effort (see below)
|
|
17
17
|
# - git WRITES are blocked by a physical shim (codex spawns git via execve, which
|
|
18
18
|
# bypasses shell functions) — the orchestrator owns the commit boundary.
|
|
19
19
|
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
20
|
+
# Host posture (hard rule): delegated codex work runs on the host posture — CODEX_MODEL and
|
|
21
|
+
# CODEX_EFFORT from the bridge settings file, else the built-in default gpt-6.1-sol at effort high
|
|
22
|
+
# (`/agent-workflow-kit bridge-settings` shows the models offered and sets one) — checked against the
|
|
23
|
+
# installed CLI's catalog before any spend. A run on anything else is a one-off, refused unless
|
|
24
|
+
# it is a probe (CODEX_PROBE=1); a nonced dispatch never runs a one-off. Economy comes from
|
|
25
|
+
# quality-neutral waste removal (clean capture, a hard timeout, a lean prompt, resume instead of
|
|
26
|
+
# re-sending context), never from a per-call downgrade.
|
|
27
27
|
#
|
|
28
28
|
# Auth: SUBSCRIPTION ONLY. Uses the cached ChatGPT login under CODEX_HOME
|
|
29
29
|
# (~/.codex). The wrapper unsets every *_API_KEY plus OPENAI_BASE_URL and passes
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
# codex-exec --resume-last <file|-> # continue the last session (iterate, no re-send)
|
|
38
38
|
# codex-exec --resume <session-id> <file|-> # continue a specific session
|
|
39
39
|
# CODEX_HARD_TIMEOUT=7200 codex-exec <file> # raise the hard wall-clock cap (integer seconds)
|
|
40
|
-
# CODEX_PROBE=1 CODEX_MODEL=<slug> codex-exec <file> # throwaway probe (
|
|
40
|
+
# CODEX_PROBE=1 CODEX_MODEL=<slug> codex-exec <file> # throwaway probe (the one route to a one-off)
|
|
41
41
|
set -euo pipefail
|
|
42
42
|
|
|
43
43
|
# --- --help / -h (pre-preflight: no codex, no login, no git tree needed) -------
|
|
@@ -113,7 +113,7 @@ Receipt:
|
|
|
113
113
|
reads it, report-if-present). The post-report lane never claims the reservation still stands,
|
|
114
114
|
because after that point its fate is no longer something this run observed. Every lane names the
|
|
115
115
|
tree as partial/dirtied rather than untouched. A nonce-LESS invocation is byte-unchanged: no
|
|
116
|
-
reservation, no receipt, no artifact, no node.
|
|
116
|
+
reservation, no receipt, no artifact, and it needs no node.
|
|
117
117
|
|
|
118
118
|
Notes:
|
|
119
119
|
nested-sandbox limit: codex-exec ships its OWN OS sandbox (bwrap workspace-write) and cannot run
|
|
@@ -121,7 +121,7 @@ Notes:
|
|
|
121
121
|
(excludedCommands / a per-run consented bypass) on the OBSERVED bwrap/EPERM failure, never a
|
|
122
122
|
preemptive blanket
|
|
123
123
|
exec posture banner: ONE stderr line before dispatch states the ACTUAL run posture —
|
|
124
|
-
exec posture: model=… effort=… tier=… sandbox=workspace-write session=fresh|resume:<id> timeout=… —
|
|
124
|
+
exec posture: model=… effort=… tier=… sandbox=workspace-write session=fresh|resume:<id> source=… timeout=… —
|
|
125
125
|
from RESOLVED post-validation values; the resume id is validated pre-spend, and control bytes in
|
|
126
126
|
any banner field refuse pre-spend
|
|
127
127
|
threat model: the sidecar byte and grammar screens detect corrupted input under a trusted parent
|
|
@@ -129,9 +129,10 @@ Notes:
|
|
|
129
129
|
substitution of core/backend commands — is outside the threat model and can substitute the
|
|
130
130
|
backend itself. Targeted shadow-proof resolution protects banner/dispatch honesty from accidental
|
|
131
131
|
shadowing; it is not an environment security boundary
|
|
132
|
-
the exec posture banner appends a banner-only
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
the exec posture banner appends a banner-only source=model:<s>,effort:<s> field — where each value
|
|
133
|
+
came from: default, setting or environment — then a banner-only timeout=<duration|uncapped> field
|
|
134
|
+
— exactly the duration handed to timeout(1), uncapped when no timeout/gtimeout binary caps the
|
|
135
|
+
run; INFORMATIONAL only: neither is persisted in a receipt or session sidecar
|
|
135
136
|
quote the posture banner verbatim when labeling this dispatch — the banner is the machine-stated
|
|
136
137
|
posture; a prose re-type drifts
|
|
137
138
|
every-run nested-sandbox scan (DUAL policy, deliberately two different rules): the scan runs on
|
|
@@ -149,7 +150,7 @@ Notes:
|
|
|
149
150
|
|
|
150
151
|
Settings file (KEY=VALUE, parsed never sourced; env wins over file, file wins over built-in default):
|
|
151
152
|
${XDG_CONFIG_HOME:-~/.config}/agent-workflow/bridge-settings.conf
|
|
152
|
-
CODEX_SERVICE_TIER — service tier: 'priority' (Fast — "2x speed, increased usage", the codex catalog's own words for gpt-6-
|
|
153
|
+
CODEX_SERVICE_TIER — service tier: 'priority' (Fast — "2x speed, increased usage", the codex catalog's own words for gpt-6.1-sol, cache fetched 2026-10-03; it states no credit-rate figure); a consented SPEND knob, default off (standard tier)
|
|
153
154
|
CODEX_HARD_TIMEOUT — hard wall-clock cap, integer seconds 1..86400 (built-in default 3600)
|
|
154
155
|
|
|
155
156
|
Environment: CODEX_HARD_TIMEOUT (seconds, default 3600), CODEX_PROBE=1 (throwaway probe only), AW_DISPATCH_NONCE (delegation dispatch nonce — mints the exec receipt; the --nonce <n> flag is its plain-argument equivalent), AW_DELEGATION_STORE (absolute delegation-store path; its dirname is where the receipt lands).
|
|
@@ -161,6 +162,8 @@ esac
|
|
|
161
162
|
|
|
162
163
|
# This wrapper's applied settings-file subset (see the shared reader block below).
|
|
163
164
|
AW_SETTINGS_APPLIED="CODEX_SERVICE_TIER CODEX_HARD_TIMEOUT"
|
|
165
|
+
DEFAULT_CODEX_MODEL="gpt-6.1-sol"
|
|
166
|
+
DEFAULT_CODEX_EFFORT="high"
|
|
164
167
|
|
|
165
168
|
# --- Bridge settings file (host-level, kit-independent) — byte-identical across the four wrappers ---
|
|
166
169
|
# ${XDG_CONFIG_HOME:-$HOME/.config}/agent-workflow/bridge-settings.conf holds KEY=VALUE lines,
|
|
@@ -181,7 +184,7 @@ aw_settings_file() {
|
|
|
181
184
|
printf '%s/agent-workflow/bridge-settings.conf' "${XDG_CONFIG_HOME:-$HOME/.config}"
|
|
182
185
|
}
|
|
183
186
|
aw_settings_known() {
|
|
184
|
-
case " CODEX_SERVICE_TIER CODEX_HARD_TIMEOUT CODEX_REVIEW_MAX_TOTAL_BYTES AGY_HARD_TIMEOUT AGY_REVIEW_ALLOW_ADDDIR AGY_REVIEW_MAX_TOTAL_BYTES " in
|
|
187
|
+
case " CODEX_SERVICE_TIER CODEX_HARD_TIMEOUT CODEX_REVIEW_MAX_TOTAL_BYTES AGY_HARD_TIMEOUT AGY_REVIEW_ALLOW_ADDDIR AGY_REVIEW_MAX_TOTAL_BYTES CODEX_MODEL CODEX_EFFORT AGY_MODEL " in
|
|
185
188
|
*" $1 "*) return 0 ;;
|
|
186
189
|
*) return 1 ;;
|
|
187
190
|
esac
|
|
@@ -266,6 +269,37 @@ aw_apply_settings() {
|
|
|
266
269
|
done
|
|
267
270
|
return 0
|
|
268
271
|
}
|
|
272
|
+
aw_read_posture() {
|
|
273
|
+
local key="$1" default="$2" empty="$3" file line value notify=1
|
|
274
|
+
AW_HOST_VALUE="$default"
|
|
275
|
+
AW_HOST_SOURCE="default"
|
|
276
|
+
file="$(aw_settings_file)"
|
|
277
|
+
[[ -n "${AW_SETTINGS_NOTIFIED:-}" ]] && notify=0
|
|
278
|
+
if [[ -f "$file" && -r "$file" ]]; then
|
|
279
|
+
line="$(grep "^${key}=" "$file" 2>/dev/null || true)"
|
|
280
|
+
if [[ -n "$line" ]]; then
|
|
281
|
+
value="${line##*$'\n'}"
|
|
282
|
+
value="${value#*=}"
|
|
283
|
+
if [[ -n "$value" && "$value" != *[$'\x01'-$'\x1f'$'\x7f']* ]]; then
|
|
284
|
+
AW_HOST_VALUE="$value"
|
|
285
|
+
AW_HOST_SOURCE="setting"
|
|
286
|
+
elif (( notify )); then
|
|
287
|
+
echo "warning: $key in bridge settings file '$file' is empty or carries a control byte — using the built-in default '$default'." >&2
|
|
288
|
+
fi
|
|
289
|
+
fi
|
|
290
|
+
fi
|
|
291
|
+
AW_RUN_VALUE="$AW_HOST_VALUE"
|
|
292
|
+
AW_RUN_SOURCE="$AW_HOST_SOURCE"
|
|
293
|
+
if [[ -n "${!key+x}" ]]; then
|
|
294
|
+
AW_RUN_VALUE="${!key:-$empty}"
|
|
295
|
+
AW_RUN_SOURCE="environment"
|
|
296
|
+
fi
|
|
297
|
+
return 0
|
|
298
|
+
}
|
|
299
|
+
aw_read_posture CODEX_MODEL "$DEFAULT_CODEX_MODEL" "$DEFAULT_CODEX_MODEL"
|
|
300
|
+
HOST_CODEX_MODEL="$AW_HOST_VALUE"; CODEX_MODEL="$AW_RUN_VALUE"; CODEX_MODEL_SOURCE="$AW_RUN_SOURCE"
|
|
301
|
+
aw_read_posture CODEX_EFFORT "$DEFAULT_CODEX_EFFORT" "$DEFAULT_CODEX_EFFORT"
|
|
302
|
+
HOST_CODEX_EFFORT="$AW_HOST_VALUE"; CODEX_EFFORT="$AW_RUN_VALUE"; CODEX_EFFORT_SOURCE="$AW_RUN_SOURCE"
|
|
269
303
|
aw_apply_settings
|
|
270
304
|
|
|
271
305
|
# --- Effective-timeout resolver (D5 banner honesty; AD-061) --------------------
|
|
@@ -319,19 +353,15 @@ aw_resolve_timeout_bin() {
|
|
|
319
353
|
printf '%s' "$bin"
|
|
320
354
|
}
|
|
321
355
|
|
|
322
|
-
|
|
323
|
-
DEFAULT_CODEX_EFFORT="high" # pinned reasoning effort — a deliberate posture, not the catalog maximum
|
|
324
|
-
CODEX_MODEL="${CODEX_MODEL:-$DEFAULT_CODEX_MODEL}"
|
|
325
|
-
CODEX_EFFORT="${CODEX_EFFORT:-$DEFAULT_CODEX_EFFORT}"
|
|
326
|
-
# Generous hard wall-clock cap, sized for a slow run at the pinned effort (subscription latency
|
|
356
|
+
# Generous hard wall-clock cap, sized for a slow run at the host posture's effort (subscription latency
|
|
327
357
|
# varies — a trivial reply was observed taking minutes). Raise for a known-healthy
|
|
328
358
|
# long run; lowering it only risks killing real work.
|
|
329
359
|
CODEX_HARD_TIMEOUT="${CODEX_HARD_TIMEOUT:-3600}"
|
|
330
360
|
# Codex service tier (quality-neutral speed knob): default EMPTY ⇒ no
|
|
331
361
|
# service_tier flag (standard tier) — enabling Fast is a consented per-host SPEND act, never a
|
|
332
362
|
# silent default. The only server-catalog tier id on this subscription is 'priority' (catalog
|
|
333
|
-
# display name "Fast": "2x speed, increased usage" in the catalog's own words for gpt-6-
|
|
334
|
-
# fetched 2026-
|
|
363
|
+
# display name "Fast": "2x speed, increased usage" in the catalog's own words for gpt-6.1-sol, cache
|
|
364
|
+
# fetched 2026-10-03; it states no credit-rate figure; quality-neutral — same model). codex itself
|
|
335
365
|
# accepts ANY -c service_tier string silently (probe-verified), so
|
|
336
366
|
# the wrapper validates the effective value: an unsupported one warns and runs on the standard
|
|
337
367
|
# tier — a typo can never silently masquerade as Fast.
|
|
@@ -373,31 +403,15 @@ CHATGPT_LOGIN_GUARD="Logged in using ChatGPT"
|
|
|
373
403
|
# receipt this wrapper mints; scripts/release/version-sync.mjs bumps it under the one-anchor-per-file
|
|
374
404
|
# rule, so a release can never leave it behind (the AD-053 drift class).
|
|
375
405
|
AW_RECEIPT_BACKEND="codex"
|
|
376
|
-
AW_BRIDGE_VERSION="
|
|
406
|
+
AW_BRIDGE_VERSION="4.0.0" # aw-version-anchor
|
|
377
407
|
# The kill grace handed to timeout(1) as --kill-after, and recorded in the receipt as killGraceS:
|
|
378
408
|
# ONE constant, so the number the ledger checks against the dispatch deadline is the number the run
|
|
379
409
|
# actually applied.
|
|
380
410
|
CODEX_KILL_GRACE_S=15
|
|
381
411
|
|
|
382
|
-
# --- Quality-first guard: refuse any non-pinned model/effort ---------------
|
|
383
|
-
# Real delegated runs must use the pinned model at the pinned effort. A throwaway probe
|
|
384
|
-
# (effort-independent result) may opt out with CODEX_PROBE=1, announced loudly.
|
|
385
412
|
if [[ "${CODEX_PROBE:-}" == "1" ]]; then
|
|
386
413
|
echo "warning: CODEX_PROBE=1 — THROWAWAY PROBE MODE. Quality guards relaxed; do NOT use this run's" >&2
|
|
387
414
|
echo " output as real delegated work (model='$CODEX_MODEL' effort='$CODEX_EFFORT')." >&2
|
|
388
|
-
else
|
|
389
|
-
if [[ "$CODEX_MODEL" != "$DEFAULT_CODEX_MODEL" ]]; then
|
|
390
|
-
echo "error: CODEX_MODEL='$CODEX_MODEL' is not the pinned model '$DEFAULT_CODEX_MODEL'." >&2
|
|
391
|
-
echo " Delegated codex work must run on the pinned model at the pinned effort (quality-first)." >&2
|
|
392
|
-
echo " For a throwaway probe whose result is effort-independent, set CODEX_PROBE=1." >&2
|
|
393
|
-
exit 2
|
|
394
|
-
fi
|
|
395
|
-
if [[ "$CODEX_EFFORT" != "$DEFAULT_CODEX_EFFORT" ]]; then
|
|
396
|
-
echo "error: CODEX_EFFORT='$CODEX_EFFORT' is not the pinned effort '$DEFAULT_CODEX_EFFORT'." >&2
|
|
397
|
-
echo " Delegated codex work must run at the pinned reasoning effort (quality-first)." >&2
|
|
398
|
-
echo " For a throwaway probe whose result is effort-independent, set CODEX_PROBE=1." >&2
|
|
399
|
-
exit 2
|
|
400
|
-
fi
|
|
401
415
|
fi
|
|
402
416
|
|
|
403
417
|
# --- Subscription-only guard -------------------------------------------------
|
|
@@ -624,10 +638,10 @@ else
|
|
|
624
638
|
# (1) ALWAYS rejected — they would defeat the subscription / sandbox / approval /
|
|
625
639
|
# config-isolation policy (-c/-s/--full-auto/bypass), switch the provider off
|
|
626
640
|
# the subscription (--oss/--local-provider), load alternate config (-p/--profile),
|
|
627
|
-
# override the
|
|
641
|
+
# override the host posture's model (-m), or break the wrapper-owned clean
|
|
628
642
|
# output / session capture (-o/--json/--color/--output-schema/--ephemeral).
|
|
629
643
|
# CODEX_PROBE=1 NEVER relaxes these: a probe still runs on the subscription, in
|
|
630
|
-
# the sandbox, with clean capture; its model is chosen via CODEX_MODEL,
|
|
644
|
+
# the sandbox, with clean capture; its model is chosen via CODEX_MODEL, never a flag.
|
|
631
645
|
# (2) Probe-relaxable — context/discovery knobs the wrapper otherwise pins; a
|
|
632
646
|
# throwaway probe (CODEX_PROBE=1) may pass them. Need more? invoke `codex` direct.
|
|
633
647
|
if [[ ${#passthrough[@]} -gt 0 ]]; then
|
|
@@ -635,7 +649,7 @@ else
|
|
|
635
649
|
case "$_arg" in
|
|
636
650
|
-c*|--config*|-s*|--sandbox*|--dangerously-bypass-approvals-and-sandbox|--dangerously-bypass-hook-trust|--full-auto|--oss|--local-provider*|-p*|--profile*|-m*|--model*|-o*|--output-last-message*|--json*|--color*|--output-schema*|--ephemeral*)
|
|
637
651
|
echo "error: passthrough flag '$_arg' is not allowed — it would defeat the subscription / sandbox /" >&2
|
|
638
|
-
echo " approval / config-isolation policy, the
|
|
652
|
+
echo " approval / config-isolation policy, the host posture, or the clean output/session" >&2
|
|
639
653
|
echo " capture. It stays blocked even under CODEX_PROBE=1. Invoke 'codex' directly if you must." >&2
|
|
640
654
|
exit 2
|
|
641
655
|
;;
|
|
@@ -666,7 +680,7 @@ if [[ -z "${task//[[:space:]]/}" ]]; then
|
|
|
666
680
|
fi
|
|
667
681
|
|
|
668
682
|
# --- The ACCOUNTED lane: everything below fires only for a NONCED run ---------
|
|
669
|
-
# A nonce-LESS invocation is byte-unchanged — no reservation, no receipt, no artifact, no node —
|
|
683
|
+
# A nonce-LESS invocation is byte-unchanged — no reservation, no receipt, no artifact, needs no node —
|
|
670
684
|
# which is what keeps every existing caller working. The whole mint core rides ONE node script per
|
|
671
685
|
# step (the family floor, codex-review.sh's finding-manifest precedent): a bash re-implementation of
|
|
672
686
|
# atomic no-clobber publication, JSON composition and canonical digesting would be a second, drifting
|
|
@@ -933,7 +947,7 @@ if [[ -n "$resume_mode" ]]; then
|
|
|
933
947
|
else
|
|
934
948
|
# `-o` writes ONLY codex's final message; `--json` streams structured events
|
|
935
949
|
# (thread.started carries the session id). CoT is dropped and colour disabled, so
|
|
936
|
-
# the captured surfaces stay clean. Reasoning still runs at the
|
|
950
|
+
# the captured surfaces stay clean. Reasoning still runs at the run's effort — quality is
|
|
937
951
|
# unchanged; we only stop printing the noise.
|
|
938
952
|
codex_cmd=(codex exec
|
|
939
953
|
--ignore-user-config
|
|
@@ -981,6 +995,91 @@ if [[ -z "$timeout_bin" ]]; then
|
|
|
981
995
|
echo " (install coreutils to enable CODEX_HARD_TIMEOUT=$CODEX_HARD_TIMEOUT)." >&2
|
|
982
996
|
fi
|
|
983
997
|
|
|
998
|
+
# --- The effective model checked against the installed CLI's catalog, then the one-off rule ---
|
|
999
|
+
# Both refuse BEFORE any spend. The read runs after the subscription guard, with the run's
|
|
1000
|
+
# CODEX_HOME and the built-in provider, bounded by the same timeout binary as the run.
|
|
1001
|
+
catalog_env=(env)
|
|
1002
|
+
CODEX_CATALOG_TIMEOUT_S=15
|
|
1003
|
+
aw_codex_remedy() {
|
|
1004
|
+
echo " remedy: set these lines in $(aw_settings_file):" >&2
|
|
1005
|
+
echo " CODEX_MODEL=$1" >&2
|
|
1006
|
+
echo " CODEX_EFFORT=$2" >&2
|
|
1007
|
+
echo " and unset CODEX_MODEL and CODEX_EFFORT in the environment." >&2
|
|
1008
|
+
}
|
|
1009
|
+
aw_codex_catalog_check() {
|
|
1010
|
+
local raw="" rc=0 verdict="" kind="" offered="" model="" effort="" catalog_js=""
|
|
1011
|
+
if [[ -n "$timeout_bin" ]]; then
|
|
1012
|
+
raw="$("${catalog_env[@]}" "$timeout_bin" --kill-after=5s "$CODEX_CATALOG_TIMEOUT_S" codex debug models -c model_provider=openai </dev/null 2>/dev/null)" || rc=$?
|
|
1013
|
+
else
|
|
1014
|
+
raw="$("${catalog_env[@]}" codex debug models -c model_provider=openai </dev/null 2>/dev/null)" || rc=$?
|
|
1015
|
+
fi
|
|
1016
|
+
if (( rc == 124 || rc == 137 )); then
|
|
1017
|
+
verdict="unreadable"$'\t'"it exceeded ${CODEX_CATALOG_TIMEOUT_S}s"
|
|
1018
|
+
elif (( rc != 0 )); then
|
|
1019
|
+
verdict="unreadable"$'\t'"codex debug models exited $rc"
|
|
1020
|
+
elif ! command -v node >/dev/null 2>&1; then
|
|
1021
|
+
verdict="unreadable"$'\t'"no node to parse it"
|
|
1022
|
+
else
|
|
1023
|
+
IFS= read -r -d '' catalog_js <<'CATALOG_JS' || true
|
|
1024
|
+
const [model, effort, defaultModel, defaultEffort] = process.argv.slice(1);
|
|
1025
|
+
const answer = (...fields) => { process.stdout.write(fields.join("\t")); process.exit(0); };
|
|
1026
|
+
const CONTROL = /[\u0000-\u001f\u007f]/;
|
|
1027
|
+
let doc;
|
|
1028
|
+
try { doc = JSON.parse(require("node:fs").readFileSync(0, "utf8")); } catch { answer("unreadable", "its output is not JSON"); }
|
|
1029
|
+
if (doc === null || typeof doc !== "object" || !Array.isArray(doc.models)) answer("unreadable", "it carries no models[]");
|
|
1030
|
+
const offered = doc.models.filter((m) => m !== null && typeof m === "object" && m.visibility === "list");
|
|
1031
|
+
if (offered.some((m) => typeof m.slug !== "string" || m.slug === "" || CONTROL.test(m.slug))) answer("unreadable", "an offered entry carries no usable slug");
|
|
1032
|
+
if (offered.length === 0) answer("unreadable", "it offers no model");
|
|
1033
|
+
const effortsOf = (m) => (Array.isArray(m.supported_reasoning_levels)
|
|
1034
|
+
&& m.supported_reasoning_levels.every((l) => l !== null && typeof l === "object" && typeof l.effort === "string" && !CONTROL.test(l.effort))
|
|
1035
|
+
? m.supported_reasoning_levels.map((l) => l.effort) : null);
|
|
1036
|
+
const rank = (m) => (typeof m.priority === "number" ? m.priority : Number.MAX_SAFE_INTEGER);
|
|
1037
|
+
const refuse = (kind, list) => {
|
|
1038
|
+
const builtIn = offered.find((m) => m.slug === defaultModel);
|
|
1039
|
+
if (builtIn && (effortsOf(builtIn) ?? []).includes(defaultEffort)) answer(kind, list, defaultModel, defaultEffort);
|
|
1040
|
+
const first = [...offered].sort((a, b) => rank(a) - rank(b))[0];
|
|
1041
|
+
const level = first.default_reasoning_level;
|
|
1042
|
+
if (typeof level !== "string" || level === "" || CONTROL.test(level)) answer("unreadable", "the entry for " + first.slug + " carries no default_reasoning_level");
|
|
1043
|
+
answer(kind, list, first.slug, level);
|
|
1044
|
+
};
|
|
1045
|
+
const entry = offered.find((m) => m.slug === model);
|
|
1046
|
+
if (entry === undefined) refuse("model", offered.map((m) => m.slug).join(", "));
|
|
1047
|
+
const efforts = effortsOf(entry);
|
|
1048
|
+
if (efforts === null) answer("unreadable", "the entry for " + model + " carries no supported_reasoning_levels");
|
|
1049
|
+
if (!efforts.includes(effort)) refuse("effort", efforts.join(", "));
|
|
1050
|
+
answer("ok");
|
|
1051
|
+
CATALOG_JS
|
|
1052
|
+
verdict="$(printf '%s' "$raw" | NODE_OPTIONS= node -e "$catalog_js" -- "$CODEX_MODEL" "$CODEX_EFFORT" "$DEFAULT_CODEX_MODEL" "$DEFAULT_CODEX_EFFORT" 2>/dev/null)" || verdict="unreadable"$'\t'"its parser failed"
|
|
1053
|
+
fi
|
|
1054
|
+
IFS=$'\t' read -r kind offered model effort <<<"$verdict" || true
|
|
1055
|
+
case "$kind" in
|
|
1056
|
+
ok) return 0 ;;
|
|
1057
|
+
model)
|
|
1058
|
+
echo "error: CODEX_MODEL='$CODEX_MODEL' ($CODEX_MODEL_SOURCE) is not a model the installed codex offers — refusing before any run is spent." >&2
|
|
1059
|
+
echo " offered: $offered" >&2 ;;
|
|
1060
|
+
effort)
|
|
1061
|
+
echo "error: CODEX_EFFORT='$CODEX_EFFORT' ($CODEX_EFFORT_SOURCE) is not an effort the installed codex offers for $CODEX_MODEL — refusing before any run is spent." >&2
|
|
1062
|
+
echo " offered: $offered" >&2 ;;
|
|
1063
|
+
*)
|
|
1064
|
+
echo "warning: the codex model catalog is unreadable (${offered:-no answer}) — the run proceeds unchecked; codex itself refuses a model it does not serve." >&2
|
|
1065
|
+
return 0 ;;
|
|
1066
|
+
esac
|
|
1067
|
+
aw_codex_remedy "$model" "$effort"
|
|
1068
|
+
exit 2
|
|
1069
|
+
}
|
|
1070
|
+
aw_codex_catalog_check
|
|
1071
|
+
if [[ "$CODEX_MODEL" != "$HOST_CODEX_MODEL" || "$CODEX_EFFORT" != "$HOST_CODEX_EFFORT" ]]; then
|
|
1072
|
+
if [[ "${CODEX_PROBE:-}" != "1" ]]; then
|
|
1073
|
+
echo "error: model=$CODEX_MODEL effort=$CODEX_EFFORT is a one-off — the host posture is model=$HOST_CODEX_MODEL effort=$HOST_CODEX_EFFORT, and only a probe (CODEX_PROBE=1) runs a one-off; refusing before any run is spent." >&2
|
|
1074
|
+
aw_codex_remedy "$CODEX_MODEL" "$CODEX_EFFORT"
|
|
1075
|
+
exit 2
|
|
1076
|
+
fi
|
|
1077
|
+
if [[ -n "$aw_nonce" ]]; then
|
|
1078
|
+
echo "error: a probe one-off (model=$CODEX_MODEL effort=$CODEX_EFFORT) cannot carry a dispatch nonce — the exec receipt could not say it ran off the host posture; refusing before any run is spent (drop the nonce, or run on the host posture)." >&2
|
|
1079
|
+
exit 2
|
|
1080
|
+
fi
|
|
1081
|
+
fi
|
|
1082
|
+
|
|
984
1083
|
# --- D5 exec banner (one line, the ACTUAL run posture; AD-061) -----------------
|
|
985
1084
|
# Emitted from RESOLVED post-validation values, AFTER the resume id is resolved and validated,
|
|
986
1085
|
# BEFORE the dispatch. The timeout field is banner-only (never a receipt/sidecar field): it
|
|
@@ -988,7 +1087,7 @@ fi
|
|
|
988
1087
|
aw_timeout_banner="$(aw_timeout_label "$timeout_bin" "$CODEX_HARD_TIMEOUT")"
|
|
989
1088
|
aw_session_label="fresh"
|
|
990
1089
|
[[ -n "$resume_mode" ]] && aw_session_label="resume:$resume_id"
|
|
991
|
-
echo "exec posture: model=$CODEX_MODEL effort=$CODEX_EFFORT tier=${CODEX_SERVICE_TIER:-standard} sandbox=workspace-write session=$aw_session_label timeout=$aw_timeout_banner" >&2
|
|
1090
|
+
echo "exec posture: model=$CODEX_MODEL effort=$CODEX_EFFORT tier=${CODEX_SERVICE_TIER:-standard} sandbox=workspace-write session=$aw_session_label source=model:$CODEX_MODEL_SOURCE,effort:$CODEX_EFFORT_SOURCE timeout=$aw_timeout_banner" >&2
|
|
992
1091
|
|
|
993
1092
|
# --- The PRE-SPEND reservation (delegation Plan 2 / D1) ------------------------
|
|
994
1093
|
# Written immediately before the CLI runs — after EVERY preflight and after the posture banner, so a
|