Commit / PR Controls Becoming Stale (app-server research)

Open 💬 2 comments Opened Apr 13, 2026 by Fuiste

What version of the Codex App are you using (From “About Codex” dialog)?

26.409.20454 (1462)

What subscription do you have?

Pro ($200)

What platform is your computer?

Darwin 23.4.0 arm64 arm

What issue are you seeing?

I've been noticing flaky commit/open PR/view PR state in the Codex desktop app. Digging into the app server code, I discovered a potential app-server state loss bug that might warrant further attention.

Some live-thread lifecycle paths rebuild Thread from config snapshots and can return thread.gitInfo = null, despite canonical git metadata being available from persisted thread metadata / rollout summaries.

If I'm following right, that means branch / repo identity can be lost during thread reads, forks, and listener reattachment flows. I'm not sure fixing this resolves PR-button weirdness, but that it could remove one of the inputs downstream UI state may depend on.

I validated a small fork patch that preserves thread.gitInfo across those paths without changing API shape.

What steps can reproduce the bug?

I do not have a clean end-user desktop repro for the full PR-button symptom yet, so I am reporting the narrower verified app-server bug here.

Concrete verified reproduction at the code level:

  1. Create or load a thread where git metadata already exists in either:
  • persisted thread metadata, or
  • rollout summary metadata
  1. Exercise a live-thread lifecycle path that rebuilds Thread from snapshot/config state, such as:
  • loaded thread/read
  • thread/fork (materialized or ephemeral)
  • thread listener reattach / watch-manager refresh
  1. Observe that thread.gitInfo can come back as null even though branch/origin metadata already exists for that thread.

I validated this on my fork with targeted regression coverage for:

  • loaded thread/read preserving persisted git metadata
  • materialized thread/fork preserving branch/origin identity
  • ephemeral thread/fork preserving branch/origin identity
  • existing resume coverage for persisted git metadata still passing

What is the expected behavior?

If a thread already has canonical git metadata available, thread.gitInfo should remain stable across live-thread lifecycle transitions.

More specifically:

  • loaded thread/read should not erase branch/origin identity
  • thread/fork should preserve known branch/origin identity
  • listener reattach / live refresh paths should not degrade known git metadata to null

I'm not asserting that desktop should permanently trust stale PR attachment state, but I think shared server responses should not drop already-known branch/repo identity.

Additional information

What I found in the code:

In codex-rs/app-server/src/codex_message_processor.rs, some live-thread flows were using snapshot-built Thread values even though those snapshot builders do not hydrate git metadata.

Affected paths I traced:

  • thread/start
  • loaded thread/read
  • thread listener reattach / watch-manager upsert
  • resumed fork history
  • ephemeral thread/fork

I also found that materialized fork responses might need a small fallback because the newly written fork summary may be blank for git metadata even when the source rollout already has branch/origin info.

I validated a narrow fork patch that:

  • hydrates thread.gitInfo from persisted thread metadata first
  • falls back to rollout-derived summary
  • returns None only when neither source has git metadata

Scope boundaries of the patch:

  • no new RPCs
  • no new Thread fields
  • no protocol/schema changes
  • no PR merge/closure detection
  • no changes to thread/metadata/update semantics
  • no changes to rollout git capture semantics

Fork reference, if useful for inspection:

  • branch: fix/thread-git-info-live-snapshots
  • draft PR: Fuiste/codex#1

Related context:

  • #16186
  • #4043

I'm filing this as a narrow server-side correctness bug that _might_ contribute to desktop PR-state flakiness, I"m not sure it explains or fixes all desktop PR-button behavior.

My fork PR for reference: https://github.com/Fuiste/codex/pull/1

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗