Repository navigation
Description
Status (quality-loop audit, 2026-09-25)
Landed: Prunes are journaled (debugRetention.ts:160-200), and #944's monitor history partly covers item 4.
Remaining: (1) CodexResponsesAdapter has no journal sink and its watchdog releases are console.warn; (3) no console tail; the heartbeat is overwrite-only; (5) no prior-run enrichment.
Acceptance: Items 1, 3 and 5, plus a heartbeat ring unless the monitor history is accepted as its replacement.
Original report
Problem
The new App Run Journal captures a lot of crash context, but the recent OOMs still depended on terminal-only breadcrumbs that are not persisted anywhere durable.
Examples from the crash terminal output:
[CodexResponsesAdapter] watchdog releasing proxy-* ...[debug-retention] pruned ... reason=performance-append ...- Crash-adjacent stdout/stderr context around
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
Once the terminal scrollback is gone, those breadcrumbs are not present in events.jsonl, incidents.jsonl, heartbeat, heap snapshots, or debug bundles.
Related: #363, #364, #365, #368, #369.
Evidence
CodexResponsesAdapterlogs parse/watchdog errors and watchdog releases withconsole.warn, but it is constructed without an AppRunJournal sink. Its own proxy mirror persists upstream proxy events, not adapter watchdog decisions.debugRetention.tslogs structured prune summaries viaconsole.info, but does not record them in the App Run Journal.AppRunJournalonly persists explicitrecord/recordIncidentcalls.- Debug bundles copy incident tails and heartbeat, but not a main-process console tail.
- Heartbeat is overwrite-only, so normal non-perf crash reports show only the last sample, not the growth slope leading into OOM.
Proposed Fix
Add durable, bounded crash-adjacent breadcrumbs:
-
Structured Codex proxy adapter events
- Record watchdog releases and errors into AppRunJournal.
- Include
flowId,requestId,responseId, path, attribution, active flow id,silentForMs, flow count,turnOpened, buffered byte/string lengths, and whetherfinishTurnwas synthesized. - Escalate repeated active-flow watchdog releases into an incident like
codex.responses_adapter.stream_stalled.
-
Structured debug-retention events
- Journal prune results instead of only printing them.
- Include
reason,removed,bytesFreed,scannedBytes,budgetBytes,ttlHours, elapsed time, and ideally per-bucket counts.
-
Bounded console/stdout/stderr tail
- Add a capped
console-tail.jsonlor wrapconsole.warn/info/errorinto a bounded AppRunJournal event sink. - Redact/truncate long payloads.
- Never let the console tail become unbounded or block the process.
- Include the tail in manual debug bundles.
- Add a capped
-
Heartbeat history ring
- Keep a tiny ring of recent samples, e.g. last 60, in addition to overwrite-only
heartbeat.json. - Capture memory slope even when
AGENT_CODE_PERFis off.
- Keep a tiny ring of recent samples, e.g. last 60, in addition to overwrite-only
-
Prior-run incident enrichment
- When recording
app.prior_unclean_shutdown, include pointers to previous run heartbeat history, console tail, Crashpad minidump, heap snapshot, and proxy/debug directories when available.
- When recording
Acceptance
- A future hard OOM can be diagnosed from retained files without relying on terminal scrollback.
CodexResponsesAdapterwatchdog releases are visible in the incident run artifacts.- Debug-retention prune bursts are visible as structured events.
- The journal remains bounded under log storms.
- Manual debug bundles include the new crash-adjacent breadcrumb artifacts.
Activity
Juliusolsson05 commentedon Sep 27, 2026
Narrowed scope (triage 2026-09-27). The prune journal (#389), the monitor history (
MonitorHistoryStore.ts) and prior-run crash-dump hints (previousRunClassifier.ts) already cover most of this. Remaining: (1) journal the Codex adapter watchdog warning, which is still aconsole.warnin codex-headlessCodexResponsesAdapter.ts; (2) keep a small capped copy of recent console output that survives a crash.