Codex on codex-acp shim
Child of epic 7191 "Converge every runner on one agent contract: ACP-native". Settled inputs: PRD (task 7189), architecture (task 7190). Architecture boundary C11. Depends on the pins child including its Codex shared-daemon measurement (read its README entry first; launch Codex the way it prescribes), plus the capability, host and switch children.
## Original requirements (PRD, verbatim)
**R1 — ACP is the wire.** … A vendor CLI that does not serve ACP natively is driven through a provider shim that speaks ACP outward and the vendor's host protocol inward (Codex: `codex app-server`; …), never the TUI through tmux, for runner dispatch.
**R12** (Codex leg): The Codex shared app-server daemon's effect on process-ancestry identity (ADR-0083) is measured before Codex runs on the new runtime.
Epic report §3 Codex gaps: assigned session id, resume, error-while-alive, SessionEnd on signal, per-dispatch settings, multi-repo `--add-dir`, API key never in env, hook trust without bypass flag.
## Approach (architecture, verbatim)
**C11: Codex on codex-acp** (+ fixtures; closes the §3 gaps or records typed gaps). Provider mapping: Codex (oauth, api_key) → `codex-acp` (on `codex app-server`). Closes on the app-server: assigned id (`thread/start` id), resume, error-while-alive (turn failed → `error`), SessionEnd on signal (host supervision), per-dispatch settings (`-c`, own config home), `--add-dir` (`additionalDirectories`), hook trust (managed hooks in `requirements.toml`, no bypass flag). **API key never in env**: `--with-api-key` from stdin into a per-account `CODEX_HOME` auth store, else a typed gap. Upstream, pinned, fork on gap (A2): fork into `packages/acp-forks/codex-acp` only when a measured gap cannot be closed through config or `_meta`; the pin then names the fork commit. Usage tokens via `_meta["jaah.ai"].usage` (D-USE-1) — fork on gap or map the adapter's vendor `_meta`. Implement `acp_launch(ctx) -> AcpLaunch` on the Codex adapter; update the Codex catalogue `Capabilities` and `gaps`. Record fixtures at the pin (dispatch → events → question answered >10 minutes later → settle; usage-limit frame; turn-failed error while alive). Add Codex's section to the runtime part of `apps/jaahd/README.md` with the measured versions.
Credentials & reach: AC-1 Codex api_key lane, AC-17 key-not-in-env | Codex API-key account on dev | verified (operator answer). AC-1 Codex | signed-in accounts on a dev node | verified (A8). AC-1 static/MicroVM legs | dev static node, dev MicroVM node | verified. AC-1–AC-4 | `jaah/debug/main/operator-login` | verified. AC-1 merged-PR leg | dev test project via operator login | verified. AC-3 `/proc/<pid>/environ` | read in the console via the host's `session_start` self-check event | verified.
Out of scope: Do NOT touch other providers or delete the Codex transcript parser/hooks (legacy stays dormant). PRD §5 verbatim:
- MUST NOT delete the legacy paths (D5); MUST NOT file that task.
- MUST NOT publish (D2). MUST NOT change runner permission posture (D6). MUST NOT drop or regress any current Claude Code capability (R10). MUST NOT remove the console terminal/TUI view (D3). MUST NOT submit an upstream ACP RFD (D8). MUST NOT integrate with T3 Code's RPC or MCP API.
- MUST NOT change the task lifecycle states or the merge lane. MUST NOT change billing beyond usage ingestion. MUST NOT add vendors. MUST NOT touch `apps/mobile`.
- MUST NOT put a token in the agent's environment or weaken process-ancestry identity (ADR-0083); MUST NOT add a second verb table.
Done means:
- AC-1 (Codex, oauth and api_key) Coder task end-to-end. → verify: on dev, create a `coder` task on a test project targeting Codex, dispatch to a static node, observe in the task view (a) live event stream entries of the normalised kinds, (b) a question raised by the agent appears as a question card and the typed answer reaches the agent, (c) the task ends `done` via the extension/MCP settle with a merged PR. Repeat on a MicroVM node. Fails if it needs a tmux pane/TUI scrape or a vendor transcript parser.
- AC-17 (report §3) Codex gaps. Each of the eight Codex gaps (assigned session id, resume, error-while-alive, SessionEnd on signal, per-dispatch settings, multi-repo `--add-dir`, API key never in env, hook trust without bypass flag) is either closed (verify by the matching AC-1/AC-3-style flow on Codex) or shown in the console provider page as a typed capability flag with its reason. The PR body carries the eight-row table: gap → closed (evidence) | typed gap (reason).
- AC-8 (launch leg) → verify: Codex is launched as the pins child's shared-daemon measurement prescribes (flag or config visible in launch.json / the test).
- AC-6 (Codex) → verify: replay fixture of a usage-limit frame; classified usage_limit with a reset time; existing spillover still applies.
- AC-9 (Codex) → verify: `./dc check full` runs the Codex fixtures recorded at the pin and passes.
Required checks: ./dc check full
Outcome
Codex now runs on upstream codex-acp 2.2.2 over the pinned codex-cli 0.163.0 (no fork), with fixtures recorded at the pin. 7 of 8 gaps closed; MicroVM API key is a typed gap. Lane gate green, PR #5981 merged 632c7c8, deploy superseded. Live dev AC-1 deferred to 7281.
Artifacts
Activity
- Draft
- Ready
- Runner started
- Runner ended (done)