Codex adapter — end-to-end smoke runbook
Status: GATED ON QUOTA. Last attempt failed with You've hit your usage limit. Visit https://chatgpt.com/codex/settings/usage to purchase more credits. The adapter classified that correctly as runtime-result.status: blocked.
This runbook is the minimum-cost path to flip the Codex manifest from experimental → active once ChatGPT subscription credits are available.
Preconditions
Section titled “Preconditions”codex --versionreportscodex-cli 0.130.0or newer.- The local Codex account has remaining subscription quota. Verify at https://chatgpt.com/codex/settings/usage.
- Repo is on a clean branch off
dev. Suggested branch:chore/codex-e2e-smoke. dist/is up to date:bun run build.
One-shot smoke
Section titled “One-shot smoke”# 1. Allocate a sandbox bound to the missionnode dist/cli.js sandbox create codex-smoke-sb \ --mission codex-e2e-smoke
# 2. Run the mission against the real Codex CLInode dist/cli.js mission run \ .harness/missions/codex-e2e-smoke/mission.yaml \ --runtime codex
# 3. Verifynode dist/cli.js verify codex-e2e-smokeExpected end-state:
.harness/missions/codex-e2e-smoke/runtime-result.yamlhasstatus: passed..harness/missions/codex-e2e-smoke/runtime-final.txtcontains a one-paragraph summary..harness/missions/codex-e2e-smoke/diff.patchcontains exactly one new file:docs/codex-smoke.txt.verifyreports[PASS].
Flip manifest to active
Section titled “Flip manifest to active”After the smoke succeeds, edit:
.harness/adapters/codex.yaml:status: experimental→status: active.src/harness/adapter-add.ts: same change in the Codex template.docs/architecture/adapter-codex.md: append a datedPromoted to activeparagraph under the implementation status section.- Tests: extend
tests/codex.test.tswith a manifest-loader assertionexpect(adapter.status).toBe('active').
Open a PR titled chore(codex): promote adapter to active after E2E smoke and link the runtime-result.yaml + final.txt + diff.patch as evidence.
Failure modes and how to read them
Section titled “Failure modes and how to read them”| Symptom | Where it shows up | Action |
|---|---|---|
runtime-result.status: blocked, error contains usage limit / purchase more credits |
stdout/stderr → errors[] |
Quota exhausted. Top up subscription. Re-run from step 2. |
runtime-result.status: blocked, error: Codex did not write --output-last-message |
exit 0 but final file absent | Codex CLI version regression. Inspect runtime.stdout.log (JSONL events). File issue upstream if reproducible. |
runtime-result.status: failed, Spawn error: ENOENT |
stderr | codex not on PATH. command -v codex to confirm; reinstall via brew install --cask codex. |
runtime-result.status: failed, exit non-zero, no quota text |
stderr | Read runtime.stderr.log and the trailing turn.failed event in runtime.stdout.log. |
| Diff is empty but Codex reported success | diff.patch zero bytes |
Codex did not modify the worktree. Inspect runtime-final.txt for “I would have written …” — usually a sandbox or approval mismatch. Re-check --sandbox workspace-write made it into args. |
Re-running after a partial failure
Section titled “Re-running after a partial failure”The sandbox stays bound to the mission. To retry without rebuilding state:
node dist/cli.js sandbox status codex-smoke-sbnode dist/cli.js mission run \ .harness/missions/codex-e2e-smoke/mission.yaml \ --runtime codexTo start completely fresh:
node dist/cli.js sandbox discard codex-smoke-sb --forcerm -rf .harness/missions/codex-e2e-smokenode dist/cli.js mission create codex-e2e-smoke \ --title "Codex E2E Smoke" \ --workflow research-docs \ --objective "Single timestamp marker file" \ --forcecp examples/missions/codex-e2e-smoke.yaml \ .harness/missions/codex-e2e-smoke/mission.yaml(Or just copy examples/missions/codex-e2e-smoke.yaml into place once — it is the source of truth for the smoke mission packet.)
Why this mission
Section titled “Why this mission”- Single expected artifact (
docs/codex-smoke.txt). Minimizes token spend on the real Codex backend. - Verification check is a one-liner: file exists + contains an ISO 8601 timestamp.
- Diff is trivially reviewable — one new file with one line.
- Exercises every adapter path: planner, runner, JSONL parse, final-message capture, diff capture, runtime-result emission, verify routing into the sandbox worktree.
Acceptance for promotion
Section titled “Acceptance for promotion”The Codex adapter is promoted to active only after all of:
- One real
mission run --runtime codexrun withruntime-result.status: passed. verifyreturns[PASS].runtime-final.txtis non-empty and contains a coherent summary.diff.patchcontains the expected single file.- No silent fallbacks observed — quota/auth/missing-binary still produce
blockednotpassed. bun run testgreen (no regressions in the experimental → active transition).