Port Codex app-server durability subset#352
Conversation
Implement the Codex durability plan across fresh launches, REST and WebSocket creates, and restart/recovery paths. - launch fresh Codex sessions without synthetic resume ids and retry initial launch planning with bounded delay plus structured logs - gate fresh Codex input until deterministic identity is captured, including /api/run waiting and explicit failure handling - promote sessionRef only from proven Codex durability, normalize legacy inventory, and preserve Claude live-session history until canonical ids arrive - retire old Codex recovery PTYs safely, repair deterministic recovery bindings, and expand unit/integration/real-provider coverage
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 73f2803cb1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| && modeSupportsResume(m.mode as TerminalMode) | ||
| && !hasCodexCapturedRestoreState | ||
| && ( | ||
| !requestedSessionRef | ||
| || requestedSessionRef.provider !== m.mode |
There was a problem hiding this comment.
Permit Codex restore when durable state already resolved session
The canonical-reference guard rejects terminal.create restores whenever sessionRef is missing, but Codex restores can legitimately derive a canonical session from codexDurability.state === 'durable' (via planCodexCreateRestoreDecision). In that case hasCodexCapturedRestoreState is false and requestedSessionRef is absent, so this branch returns RESTORE_UNAVAILABLE even though effectiveResumeSessionId has already been resolved from durable state. This blocks valid Codex restore flows that rely on stored durability records instead of an explicit client sessionRef.
Useful? React with 👍 / 👎.
Summary
Source content
36528c75: Codex stability implementation, replayed through its clean main-based source series plus the missing fake app-server argv logger used by the selected managed-launch test.843ac2ea: disable Codex apps for Freshell-managed app-server launches.0aff9c2e: clarify Codex sidecar reaper blockers.90c1a539: document the Codex durability bridge invariant.b98e756d: Codex app-server contract hardening for candidate parsing/thread-start evidence/metadata dir; omitted non-subset fresh-agent MCP wording and Claude-only UUID fixture churn.f1739793: capture process exits in the real contract harness.fb0532b7: retry Codex wrapper identity proof.Dependencies
origin/main.Tests
npm run typechecknpm run test:vitest -- test/unit/server/coding-cli/codex-app-server/client.test.ts test/unit/server/coding-cli/codex-app-server/durability-proof.test.ts test/unit/server/coding-cli/codex-app-server/durability-store.test.ts test/unit/server/coding-cli/codex-app-server/launch-planner.test.ts test/unit/server/coding-cli/codex-app-server/launch-retry.test.ts test/unit/server/coding-cli/codex-app-server/remote-proxy.test.ts test/unit/server/coding-cli/codex-app-server/restore-decision.test.ts test/unit/server/coding-cli/codex-app-server/runtime.test.ts test/unit/server/terminal-registry.codex-sidecar.test.ts test/unit/server/terminal-registry.codex-recovery.test.ts test/unit/server/terminal-registry.test.ts test/server/ws-terminal-create-reuse-running-codex.test.ts test/server/ws-protocol.test.ts --run --pool=forks --poolOptions.forks.singleFork=truenpm run test:vitest -- test/unit/client/agentChatSlice.test.ts test/unit/client/components/TerminalView.lifecycle.test.tsx test/unit/client/components/terminal-view-utils.test.ts test/unit/client/lib/tab-registry-snapshot.test.ts test/unit/client/store/persistedState.test.ts test/unit/client/store/selectors/sidebarSelectors.test.ts test/unit/client/store/tabsSlice.test.ts test/e2e/codex-refresh-rehydrate-flow.test.tsx test/e2e/agent-cli-flow.test.ts test/e2e/tabs-view-flow.test.tsx --run --pool=forks --poolOptions.forks.singleFork=truenpm run test:vitest -- test/unit/client/components/agent-chat/AgentChatView.reload.test.tsx --run --pool=forks --poolOptions.forks.singleFork=truenpm run test:vitest -- test/unit/client/components/agent-chat/AgentChatView.split-pane.test.tsx --run --pool=forks --poolOptions.forks.singleFork=truenpm run test:vitest -- test/e2e/agent-chat-restore-flow.test.tsx --run --pool=forks --poolOptions.forks.singleFork=truenpm run buildNote: a combined client/e2e invocation that included the legacy agent-chat files after other jsdom suites hit a reproducible
Maximum call stack size exceededinter-file isolation failure; each implicated agent-chat file passed independently as listed above.