Skip to content

fix(codex): replay legacy user-input requests as blocking - #13509

Merged
juliusmarminge merged 1 commit into
t3code/codex-turn-mappingfrom
v2/codex-replay-isblocking
Sep 24, 2026
Merged

juliusmarminge merged 1 commit into
t3code/codex-turn-mappingfrom
v2/codex-replay-isblocking

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Sep 24, 2026 •

Copy link
Copy Markdown
Member

plan_questions/codex fails on the V2 branch tip (393d7b3): it stalls for 60 seconds and times out.

Codex 0.156 made isBlocking required on item/tool/requestUserInput. The fixture's transcript was recorded on 0.120 and doesn't have it, so the replay client rejects the request as undecodable, and the scenario waits until its deadline. Codex itself treats a missing isBlocking as true (codex-rs/app-server-protocol/src/protocol/v2/item.rs:1778 at rust-v0.156.1, with a test for exactly this legacy case). The replay normalizer already fills other fields old transcripts lack (projectId, sessionId, startedAtMs); this adds isBlocking with Codex's default.

The failing fixture is the regression test.

Verification

  • OrchestratorReplayFixtures.integration.test.ts: 75/75 pass (before: plan_questions/codex failed after 60,272 ms).
  • effect-codex-app-server tests: 38/38. Typecheck: no errors or warnings. Format and lint clean on replay.ts.

Found by the agent re-recording Codex fixtures on 0.156.1 (#13505).

Model: Claude Opus 5.5 (Claude Code)

🤖 Generated with Claude Code


Devin Review

Codex 0.156 requires `isBlocking` on `item/tool/requestUserInput`, and its own
deserializer defaults a missing value to true for older clients. Transcripts
recorded before 0.156 omit it, so the replay client rejected the request and
the Codex plan_questions fixture stalled until its 60 second deadline.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Sep 24, 2026
) {
const params = { ...(normalized.params as Record<string, unknown>) };
// Codex treats a legacy request without `isBlocking` as blocking.
if (params.isBlocking === undefined) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes how replayed inbound requests are delivered, but the PR adds no focused test for it. Could you add a replay test with a legacy item/tool/requestUserInput frame that omits isBlocking, asserting the client receives true, and one with an explicit false to verify it remains unchanged?

Posted via Macroscope — Effect Service Conventions

@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire — 4.9 KiB — 6.8 KiB ✅
Codex Thread snapshot wire — 3.7 KiB — 4.9 KiB ✅
Codex Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Codex Live turn WebSocket decoded — 20.4 KiB — 29.3 KiB ✅
Codex Live turn messages — 2 — 8 ✅
Claude Total thread wire — 4.9 KiB — 6.8 KiB ✅
Claude Thread snapshot wire — 3.7 KiB — 4.9 KiB ✅
Claude Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Claude Live turn WebSocket decoded — 20.7 KiB — 29.3 KiB ✅
Claude Live turn messages — 1 — 8 ✅

Baseline: unavailable · PR result: 16fd173 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 106.1 KiB
  • Claude decoded thread snapshot: 106.4 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

macroscopeapp Bot commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 16fd173

Macroscope's review found this PR approvable — This is a narrowly scoped replay-harness compatibility fix that defaults only legacy user-input frames to blocking while preserving explicit values. Its runtime impact is confined to test/evaluation replay paths, with no production, schema, security, or deployment changes.

You can add or adjust custom eligibility rules. Learn more.

@juliusmarminge
juliusmarminge merged commit 2e85a43 into t3code/codex-turn-mapping Sep 24, 2026
24 of 25 checks passed
@juliusmarminge
juliusmarminge deleted the v2/codex-replay-isblocking branch September 24, 2026 22:16
juliusmarminge added a commit that referenced this pull request Sep 24, 2026
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
juliusmarminge added a commit that referenced this pull request Sep 25, 2026
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant