Repository navigation
fix(native-chat): restore build after Codex turn-boundary update - #23794
brennanb2025 wants to merge 2 commits into
Conversation
|
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (1)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review. 📝 WalkthroughWalkthroughThe frame reader no longer uses provider verdicts to classify child-turn failures. It returns an unverifiable turn-ended frame when a non-primary thread closes. Tests cover non-retried errors that remain active until failed-turn completion, and child-thread closure before turn completion. Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to A child remains active until completion or thread closure, while session shutdown clears its task state. No actionable merge risk remains. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change keeps child work in progress until a turn actually completes and treats an incomplete closing thread as unverified. No new public access or control bypass was identified. Confidence is limited by incomplete visibility into restart recovery. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Important
The production change is sound and matches the captured transcript evidence, but the PR leaves a sibling test still asserting the removed behavior, so the suite goes red.
Reviewed changes
- Drop the stale verdict import —
codex-background-task-frames.tsno longer importsreadCodexProviderVerdict(the module deleted by #23682), and theCodexChildTurnEndingalias is gone. This restores the node build. - Child turns now settle on
turn/completedonly — a non-retriederrorno longer produces aturn-endedframe; a child's failed turn settles fromturn/completed'sfailedstatus.thread/closedstill settles a child asunverifiable. - Updated the tracker and child-work evidence tests — both now assert a child stays
workingthrough a non-retried error and settles on completion, and thatthread/closedyieldsunknown.
The direction is correct: the real captures in src/main/codex/__fixtures__/codex-app-server-turn-endings.jsonl show every fatal error (willRetry: false) followed immediately by a turn/completed with status: "failed", and codex-structured-journal-turn-endings-replay.test.ts already pins that contract at the journal layer. This PR makes the child background tracker consistent with it. pnpm tc:node passes.
⚠️ A sibling test still asserts the removed "an error ends the turn" behavior
src/main/codex/codex-structured-child-work-producer.test.ts:335-344 feeds child l1 a non-retried error with no turn/completed, then expects byDescription('lint') to be { membership: 'settled', outcome: 'failed' }. Under the new contract the child stays live, so that step fails (expected { … } to match object { membership: 'settled' … }), and the final record assertion at lines 402-406 (lint → settled/failed) rides on the same step. The PR updated two of the three tests that encoded the old behavior; this third one was missed, so CI will fail. Reproduce with pnpm test src/main/codex/codex-structured-child-work-producer.test.ts (1 of 7 fails).
Technical details
# Stale child-work producer test
## Affected sites
- `src/main/codex/codex-structured-child-work-producer.test.ts:335-344` — the step sends only `{ method: 'error', params: { threadId: LINTER, turnId: 'l1', willRetry: false, error: { message: 'boom' } } }` and asserts `membership: 'settled', outcome: 'failed'`. `readCodexBackgroundTaskFrame` now returns `null` for this frame, so the child remains `live`.
- `src/main/codex/codex-structured-child-work-producer.test.ts:402-406` — the final records list expects `lint` at `settled`/`failed`, which also depends on the omitted completion.
## Required outcome
- The scenario must model what Codex actually emits: keep the `live`/`working` assertion after the `error`, then send `turn/completed` for `l1` with `status: 'failed'` and assert `settled`/`failed` there. The comment at line 335 ("…and no turn/completed") and the final records list need to line up with that.
- Prefer mirroring the shape already used in the updated `codex-background-task-tracker.test.ts` and `codex-child-work-evidence.test.ts` tests rather than inventing a new one.
## Open questions for the human
- The removed code assumed a non-retried `error` can end a **child** turn with no `turn/completed`. Do `spawn_agent` child threads share the primary thread's guarantee (per the fixture) that a fatal error is always followed by `turn/completed`? The fixture only covers primary threads. If a child can be left without a completion, its row stays `working` until `thread/closed` or session end — the PR argues the thread-close fallback and session clear cover that, but the child case is not exercised by a test either way.DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Added the missing
turn/completedstep to the structured child-work producer test (codex-structured-child-work-producer.test.ts:345-350), so thelintchild now settles from its failed completion rather than the non-retriederrorframe, with alive/workingassertion after the error. This resolves the prior review's must-address finding: the sibling test now encodes the new contract, and the finallint→settled/failedrecord assertion lines up. - Confirmed locally: all three touched test files pass (62 tests), including
codex-structured-child-work-producer.test.tsandpnpm tc:node.
The production change (child turns settle on turn/completed only) was vetted in the prior review against the captured transcript fixture; this delta is test-only and brings the last test in line with it.
The open question from the prior review still stands and is not re-raised: whether spawn_agent child threads share the primary thread's guarantee that a fatal error is always followed by turn/completed. The fixture only covers primary threads, so the child case remains exercised only by the thread-close fallback.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

ELI5
The desktop app could not build after the Codex turn-boundary change: background-task handling still imported a file that the change removed. With this fix, the app builds again and a Codex child task stays in progress until Codex actually finishes its turn.
What Changed
Removed the stale import and the old path that treated a non-retried
errorevent as the end of a child turn. The existingturn/completedevent now settles a failed child turn. If its thread closes without completion, the result remains unverifiable. Tests cover both transitions in the task strip and persisted task record.Why
#23682 deleted the imported verdict module while moving turn ownership to explicit turn boundaries. Restoring that module would revive the old assumption that an error always ends a turn, even though Codex can emit an error before its final completion event. This narrow change follows the new boundary and removes the build break without adding another source of lifecycle state.
Linked Issue
No separate issue; follow-up to the regression introduced by #23682.
Visual Proof
N/A — this repairs a compile failure and task-settlement behavior without changing UI layout or copy. The event transitions are covered by focused tests.
Testing
On macOS,
tc-gate pnpm tc:node, 68 targeted tests across four files,pnpm run check:code-quality:changed, andORCA_BACKGROUND_LAUNCH=1 pnpm build:electron-vitepassed. Windows, Linux, and SSH were reviewed for impact but not run for this follow-up; the change adds no platform-specific path or process behavior. CI covers the remaining suites.AI Disclosure
Review
Agent skill upstream boundary
docs/reference/agent-skill-sharing-upstream-boundary.mdand copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.Notes
No new process launch, network call, polling, or data persistence. The existing thread-close fallback remains in place for a child whose completion cannot be observed.
Checklist
N/Awith reason