Repository navigation
Conversation
Codex writes every spawned, review and guardian agent as its own rollout. The
session scanner listed each of them as a conversation, so importing a
project's sessions created a top-level thread per subagent.
A rollout whose session_meta source is `{ subagent: ... }` is no longer
counted or listed. Top-level sessions record a string source and are
unaffected.
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a focused server-side bug fix that prevents Codex subagent rollouts from being incorrectly counted and imported as user sessions, while preserving top-level session behavior. The change is localized and covered by targeted tests, with no schema, deployment, product-default, or static-analysis impact. Notes:
You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe Codex session scanner now skips records whose ChangesCodex subagent filtering
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix · Severity of issue fixed: Low Suggested reviewers: Merge Risk: 🔵 Low · up to Very high-volume Codex homes may miss some recent top-level sessions during import; this is a bounded follow-up risk rather than a general failure. Architecture SummaryArchitecture risk: 🔵 Low · up to The change affects 1 system. Changed systems: Architecture concerns Review detailsSystems and components
Before / after behavior
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Dismissing prior approval to re-evaluate 526519d
Fixes #16222
Problem
Codex writes every subagent it spawns (
spawn_agent), plus its/reviewand guardian agents, as a separate rollout under~/.codex/sessions. The session import scanner treated every rollout as a user conversation. Importing a project's recent sessions therefore created one top-levelimport:codex:<id>thread per subagent, titled after injected setup text such as# AGENTS.md instructions. The project list in onboarding also counted those subagents in its session totals.Change
The first record of a Codex rollout (
session_meta) says where the session came from. Top-level sessions store a stringsource("cli","vscode","exec","unknown") or an object such as{ custom }. Subagents store an object keyedsubagent, which the app-server schema spellssubAgent. The scanner now drops a rollout whosesession_meta.payload.sourcehas either key.This follows the fix area suggested in the triage comment on the issue:
subagent/subAgentkey is present, not only forthread_spawn, so review, compact, guardian and other child agents are excluded too.cwd. A dropped rollout is left out of the project's session count in onboarding, never takes a slot in the import's transcript budget, and is not reported asSkipped, so it raises no "could not be imported" warning.This matches Codex's own resume list, which shows only interactive sources by default. The issue suggests Claude subagents are attached to their parent thread. In fact the scanner skips them too: Claude keeps subagent transcripts in a
subagents/subdirectory the scanner never lists, and inlineisSidechainrecords are ignored.Unchanged or not covered:
parent_thread_idto the imported parent and replaying the child as a subagent turn item. That is a feature, not part of this fix.cwd-bearing record is aturn_contextwritten before anysession_metawould still be listed. None of the 3,272 local rollouts looked like that.Verification
The rollout shapes were checked against the first line of 3,272 local Codex rollouts. Only the type of
sourceand its keys were read. String sources:vscode,exec,unknown,cli. Object sources, allsubagent:thread_spawn(withparent_thread_id,depth,agent_path,agent_nickname,agent_role),review, and{ other: "guardian" }. None of the top-level sessions had an objectsource. The generated Codex app-server schema lists the same split inThreadSourceKind(cli,vscode,exec,appServer,unknown, and thesubAgent*kinds).A new test in
AgentSessionScanner.test.tswrites synthetic rollouts to a temporary Codex home. Each one has asession_meta, aturn_contextthat repeats thecwd, and a user message. The test scans and then lists recent threads through the same scanner instance, so the import reads the candidates cached by the scan:25d5c7cacblists top-level Codex sessions but not the subagents they spawned(sources:"vscode", absent,null,{ custom },subagentwiththread_spawn,reviewand{ other: "guardian" }, and{ subAgent: "compact" })(cd apps/server && vp test run src/project/AgentSessionScanner.test.ts src/project/AgentSessionImporter.test.ts)excludes sandboxes reached through a symlink into the worktrees diralso fails on unmodified code on macOS(cd apps/server && vp run typecheck)error TSorwarning TSvp fmt --check/vp linton the two changed filesknip --workspace apps/server --exportsThis is a server-only change with no UI, so there are no screenshots.
Limitations / not checked: no real import was run on a server. The fixtures are synthetic, and the shapes come from local rollout first lines and the generated schema.
Implemented with Claude Opus 5.5, verified with GPT-6 Astra, coordinated by Claude Fable 5.1 in Claude Code.