Persistent app-created tasks lose original transcripts on bounded subagent history migration (source=vscode)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of the Codex App are you using (From “About Codex” dialog)?
The exact desktop build that performed the original rewrite is not established. The remote host had codex-cli 0.154.0 during the September 11–14, 2026 investigation; the four affected rollout headers record cli_version: "0.144.5". A stored header version is not necessarily the version that last rewrote the file. The source analysis below is pinned to rust-v0.154.0, not a claim that this was the first affected release.
What subscription do you have?
Not established from the diagnostic artifacts. The identified code path is local history migration, not a model inference failure.
What platform is your computer?
Codex desktop using an SSH-connected Linux x86_64 execution/storage host. The inspected host reports Linux 5.15.0-186-generic. Desktop client OS/build is not established in this report.
What issue are you seeing?
Four persistent, user-facing tasks lost their older durable conversation history. These were created through the app's create_thread tool as independent workstreams, remained in the sidebar, and received direct user follow-ups over several weeks. They were not intended as disposable worker contexts.
There are two distinct problems:
- Earlier assistant messages no longer exist as message records in the tasks' own retained rollouts. The remaining history begins around a compacted working-context snapshot. Fixing visibility/indexing does not recover those missing records.
- The retained suffix was itself hidden by a subagent-history boundary at the end of the migrated file. This second problem matches #38762, but repairing it only exposes the suffix—not the lost original transcript.
This report focuses on the first problem and a concrete migration route that can cause it even when the session source is vscode. Related reports: #44363 and #45350. The additional evidence here is the distinction between user-facing app-created peer tasks and actual inherited worker histories, plus independent remnants of missing replies in the coordinator's saved task-read outputs.
Classification of the affected tasks
All four inspected headers have:
{
"source": "vscode",
"thread_source": "subagent",
"history_mode": "paginated"
}
Neither parent_thread_id nor forked_from_id has a non-null value in those inspected headers. The coordinator's saved creation calls used create_thread, not spawn_agent, and did not explicitly supply threadSource. This does not prove there is no relationship metadata elsewhere; it demonstrates that a task can be treated as a subagent for migration despite its ordinary app session source and persistent user-facing use.
Evidence that this is more than a blank UI
- Before repair, three tasks had zero projected turns. The fourth exposed only turns appended after its stored boundary.
- Copy-first experiments corrected the boundary and rebuilt native projections without modifying any rollout body bytes. Later controlled repair restored readable retained history for all four tasks.
- A separate read-only reconstruction found 758 assistant-text fragments in the coordinator's saved task-read tool outputs that were absent from the corresponding primary task logs' message records: 270, 204, 57, and 227 across the four tasks.
- Those fragments were traced back to exact archived source records. They are not inferred or generated replacements. They are also not necessarily distinct complete messages: tool outputs can be truncated or contain overlapping versions, so these counts must not be interpreted as 758 complete lost turns.
- Post-loss backups, source hashes, and body-byte preservation checks separate the original loss from our later visibility repair. We do not have a complete pre-rewrite backup of the four original rollouts; the total number of lost records and exact writer/timestamp remain unknown.
Concrete source path requiring investigation
In rust-v0.154.0:
rollout_migration.rsclassifies a rollout as Subagent when eitherSessionSource::SubAgentorthread_source == Subagentis present. Thussource=vscodedoes not protect a persistent peer task from this route.subagent::select_bounded_contextreverse-scans for sufficient model-resume context. Its rationale is avoiding duplicated inherited parent history. Sufficient resume context is not equivalent to preserving the task's own historical transcript.- The migration writes that bounded context as the replacement rollout, then sets the subagent display boundary to the resulting end ordinal.
- Publication renames the staged file over the canonical rollout. This publication path does not retain the overwritten original as a backup.
The source establishes a destructive bounded-history migration path matching these classifications. Attributing the original production losses to this exact invocation is still an inference, not a captured before/after migration reproduction. An earlier compaction writer could also have contributed. The missing original message records, however, are an observed recovery limitation independent of that attribution.
What steps can reproduce the bug?
Observed conditions: create persistent tasks through app delegation, converse with them directly over many turns/compactions, and reopen them around the legacy-to-paginated transition. Their history is empty or begins at “Context automatically compacted”; visibility repair reveals only the retained suffix.
I have not deliberately rerun a destructive migration against production sessions. A proposed isolated synthetic regression test, not a claimed completed reproduction, is:
- Create a legacy rollout with
source=vscode,thread_source=subagent, and unique child-owned user/assistant sentinel messages before a valid compaction checkpoint, plus later task-local turns. Make it persistent/user-visible. - Preserve the input fixture and migrate only the disposable copy using the version-matched local-store migration.
- Verify that every own-history sentinel remains recoverable from durable storage, separately from the bounded model-resume context.
- Verify
thread/read/thread/turns/listexpose task-owned history while excluding only proven inherited parent history. - Compare against
thread_source=userand a genuine inherited subagent fixture.
What is the expected behavior?
- Bounding model context must not silently delete a persistent task's durable transcript.
- Deduplication of inherited parent history must preserve the task's own earlier turns, including direct user conversations.
- A classification used for analytics/delegation should not, by itself, turn a persistent app task into a disposable history store.
- If a lossy migration is intentional, retain a recoverable original and require explicit user consent; successful projection to EOF is not proof that history was preserved.
- Provide a supported recovery/export route for affected tasks. Correcting projection alone is insufficient once source records are gone.
Additional information
Raw rollouts, task identifiers/names, private repository details, local paths, and database files are intentionally not attached. Private diagnostic archives and checksums have been retained. The source links and sanitized observations above should permit investigation without publishing conversation contents.
No claim is made that later context recollections reconstruct the complete original logs. The original transcript loss is the issue; the recovery work only made surviving records readable and preserved independently surviving fragments.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with codex-rs/thread-store/src/local/rollout_migration.rs, especially subagent classification and replacement-file publication, then read rollout_migration/subagent.rs and the related reports. Build the proposed isolated synthetic fixtures and run the version-matched local-store migration; done means persistent task-owned history remains recoverable while inherited parent history is bounded without destructive loss.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100