Behavior today
Review runs (/codex:review, /codex:adversarial-review) start their app-server threads with ephemeral: true (hardcoded in the review path), while task/rescue runs pass persistThread: true. Ephemeral threads never write a rollout to ~/.codex/sessions.
Why this is a problem
- The resume hint is broken for reviews.
/codex:status prints codex resume <session-id> for review jobs, but the thread is memory-only, so that ID goes dead as soon as the broker restarts. The printed hint promises something the implementation can't deliver.
- Review usage is invisible locally. Token usage lives inside the rollout events; with no rollout, review runs never appear in
~/.codex/sessions, so local accounting tools that read the sessions tree (e.g. ccusage codex) see rescue usage but not review usage.
- Two run kinds, two silent behaviors. Users have no reason to expect that a review and a rescue differ in persistence; the asymmetry is surprising and undocumented.
Request
Make review runs persist their threads unconditionally, exactly like task runs — not a flag, not a config option. Uniform behavior means the /codex:status resume hint is truthful for every job kind, and local usage accounting is complete for all plugin activity.
The plumbing already exists: persistThread in scripts/lib/codex.mjs (the thread-start call maps it to ephemeral); the review path just hardcodes ephemeral: true instead of using it.
Behavior today
Review runs (
/codex:review,/codex:adversarial-review) start their app-server threads withephemeral: true(hardcoded in the review path), while task/rescue runs passpersistThread: true. Ephemeral threads never write a rollout to~/.codex/sessions.Why this is a problem
/codex:statusprintscodex resume <session-id>for review jobs, but the thread is memory-only, so that ID goes dead as soon as the broker restarts. The printed hint promises something the implementation can't deliver.~/.codex/sessions, so local accounting tools that read the sessions tree (e.g.ccusage codex) see rescue usage but not review usage.Request
Make review runs persist their threads unconditionally, exactly like task runs — not a flag, not a config option. Uniform behavior means the
/codex:statusresume hint is truthful for every job kind, and local usage accounting is complete for all plugin activity.The plumbing already exists:
persistThreadinscripts/lib/codex.mjs(the thread-start call maps it toephemeral); the review path just hardcodesephemeral: trueinstead of using it.