Thread session restore can drift when active and primary authority are treated as the same thing

Resolved 💬 4 comments Opened Mar 26, 2026 by GraciousGazelles Closed Mar 26, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Observed while reviewing downstream carry of recent tui_app_server thread/session restore changes.

Summary
The thread restore/refresh path is sensitive to whether a thread is the live active thread or only the primary fallback thread. Treating active/live authority and primary-only fallback authority as equivalent can cause restore/refresh to rebuild from the wrong source of truth and replay stale config state.

Why this matters

  • active thread rebuilds should use live in-memory state
  • primary-only fallback rebuilds should use authoritative cached session state instead
  • mixing those paths can restore cwd / approval / sandbox / model state from the wrong thread during transition windows

Reference implementation
https://github.com/SednaLabs/codex/commit/ba21735004

The reference commit is a single downstream commit carrying the full finding and follow-up hardening in one place.

View original on GitHub ↗

4 Comments

github-actions[bot] contributor · 5 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #15320
  • #15349
  • #14812
  • #14439

Powered by Codex Action

etraut-openai contributor · 5 months ago

Can you say more about the problem? I'm not sure what you mean by "live active thread" or "primary fallback thread". Do you have repro steps? Is this problem specific to tui_app_server?

GraciousGazelles · 5 months ago

Just to clarify: this issue was auto-raised by an agent that took a bit too much initiative, and the original wording was more abstract than it should have been.

To answer your questions directly:

Yes, this is specific to tui_app_server, not a general codex-core thread-model issue.

By “live active thread”, I mean the thread currently referenced by active_thread_id, whose in-memory session/state is what the UI is actively replaying and mutating.

By “primary fallback thread”, I mean the main thread tracked separately via primary_thread_id / primary_session_configured, which is kept around so the app can fall back to it after viewing or running an agent thread.

The bug I was trying to describe is that those two roles are not interchangeable, but some restore and refresh paths can treat them too similarly. The risky area, as I saw it, is the interaction between:

  • select_agent_thread(...)
  • refresh_in_memory_config_from_disk(...)

A more concrete repro is:

  1. In tui_app_server, start on the main thread and change thread-specific session state away from defaults, for example approval policy, sandbox policy, model, or cwd.
  2. Spawn or switch to an agent thread so that the agent thread becomes active, while the original main thread is now only the fallback/primary thread.
  3. Trigger a config refresh or a thread transition through the restore path.
  4. If the app rebuilds config from the wrong source of truth during that transition window, the restored thread can pick up stale config-overlay state instead of the authoritative cached session for that thread.

The visible effect is that thread-specific state can drift during restore or failover. The fields I was worried about were cwd, approval policy, sandbox policy, and model selection.

So the short version is: the active thread should rebuild from its live in-memory thread state, while the primary fallback thread should rebuild from its cached session state. If those paths get mixed up, the restored thread can inherit the wrong session/config values.

etraut-openai contributor · 5 months ago

Thanks for clarifying that this was AI-generated. This reads more like a detailed code review feedback rather than a bug report. I'm going to close this issue. If you'd like to file a new issue, please use the bug report template and provide the requested details.