Subagent data does not survive condensation — durable storage for subagent transcripts
@Soph is already working on this.
Since Aug 19, 2026.
- Dominant language
- Go
- Stars
- 5.1k
- Forks
- 475
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 178
Description
Tracking issue for the one open piece of subagent tracking. Plan doc lives at subagent-durability-plan.md (untracked).
Update 2026-08-20 — the design below is implemented in #2032, not here. That branch
(feat/subagent-stop-capture, trail 1076) started 2026-08-18 as background-subagent capture
and its last ~9 commits built exactly this:session.TaskRecordsas the mid-turn pointer
ledger,WriteOptions.Tasks []TaskPayloadmaterialized into
tasks/<tool-use-id>/{task.json, agent-<id>.jsonl}inside the session checkpoint, with
TranscriptUnavailableReasonfor the transcript-gone case. It cites this issue by number and
carries its own plan atdocs/superpowers/plans/2026-08-19-subagent-durable-records.md.
I filed this issue without spotting that branch — my mistake.What is left after #2032 is the OPF gate and some doc debt. Everything else below is
either done or covered there; ticked items say which.
Status 2026-08-19: the per-agent ephemeral bugs are merged (7 PRs, through #1958).
Durable storage is the one open piece — this issue tracks it.
Problem, one line: condensation builds one checkpoint.WriteOptions per session with no
IsTask/ToolUseID (manual_commit_condensation.go:398), so persistent.go's whole task-write
path is unreachable — no producer anywhere sets IsTask: true. Subagent detail dies at commit,
for every agent. Measured: 0 of the 150 newest entire/checkpoints/v1 commits contain tasks/;
80-checkpoint sample (CC 58, Codex 10, OpenCode 2, Pi 1) had subagent_tokens non-null in 0.
Decision: capture the pointer mid-turn, defer the payload to condensation
SubagentEnd→ small session-state entry only: correlation ID, agent type, description,
declared transcript path, files touched, tokens. No shadow-tree write.- Condensation → read the declared paths, sanitize → externalize images → redact, store.
- Path gone by then → keep the pointer record, metadata says transcript unavailable.
Why: takes per-subagent tree surgery + CAS off the mid-turn hook path; one producer instead of
two mirrored ones (that duplication is what made unreachable code look durable); no misleading
intermediate state. Works on both backends, so refs-only stops being required — still preferred
for lazy fetch of large transcripts.
The pointer must stay mid-turn: for Codex and Cursor, agent_transcript_path arrives on the
stop hook and nowhere else. Dropping it means guessing layouts again — the bug #1958 fixed.
Premise verified: agents do not clean up subagent transcripts (CC 180 files / 121 older
than 2 days; Codex 164 / 164). The comment at manual_commit_condensation.go:1112 claiming
otherwise is wrong, and it is what justified capturing mid-turn.
What's left
-
Per-agent persistence check— done, results in this comment.
No agent cleans up. Droid Workers are ordinary session files sibling to the parent, so
their lifetime equals the parent's. Two agents need a different pointer shape: Copilot
CLI has no subagent transcript file at all (inline in the parent, keyed bytoolCallId,
and itsSubagentEndcarries no correlation ID), and OpenCode's transcripts are
Entire-written disposable handoff files. -
Pick where the payload lands— decided in #2032: thetasks/subtree inside the
session checkpoint (the first option), viaWriteOptions.Tasks []TaskPayload. Works on
both backends, so the refs-only variant is moot. -
OPF gate — the one thing #2032 does not address (zero OPF mentions in its diff).
Verified 2026-08-20:
- git-branch is fine, by luck of design.collectTreeBlobswalks the whole checkpoint
tree and treats every blob exceptcontent_hash.txtas redactable, so
tasks/…/agent-<id>.jsonlandtask.jsonpick up the 9th layer automatically. #2032
writes nocontent_hash.txtinto the task dir, so the apply pass's sibling-full.jsonl
hash recompute is undisturbed.
- git-refs gets nothing.RewriteUnpushedV1WithOPFhas one call site, on the
git-branch pre-push path. With refs as primary, subagent transcripts — the
highest-volume, least-reviewed content in the system — ship with 8 layers while a user
who enabled OPF believes 9 ran.Mitigating: git-branch is still the default primary (`resolvePrimaryType`), so refs is opt-in and today's exposure is limited to adopters. That argues for not blocking #2032 on full OPF-for-refs, not for leaving this undecided — refs is meant to become the default. Suggested resolution: make the materializer backend-aware — on git-refs write `task.json` only and skip the transcript blob until OPF-for-refs lands. Refs users still get the pointer record, git-branch users get the whole feature, and nobody gets a silent redaction downgrade. OPF-for-refs then wants its own issue; it currently has no owner. -
Delete the dead persistent task writer— done in #2032, which replaces it with
theTasksroute. (I had this in #2059 before spotting #2032; closed as redundant.) -
Per-task tokens have nowhere to live— covered in #2032, which routes them
throughTaskRecord/TaskPayload.TokenUsagerather than wideningTaskStepContext. -
Doc debt.
ref-checkpoint-backend.md:25is fixed in #2083. Still open:
- the false:1112comment inmanual_commit_condensation.go("finds nothing on this path
once the agent has cleaned the transcripts up" — they don't); belongs in #2032, which
already edits that file
- #2032's own docs are behind its code: the "Task Steps" section it adds documents
captureInFlightTasks/selectInFlightTasksForSnapshot/
IncrementalTypeBackgroundProgress, none of which exist at its tip, and the durable
materialization — the headline — is undocumented, with the "Committed Checkpoints" tree
listing still showing notasks/ -
Optional:—[Task]entries incheckpoint list --pendingfrom session state
covered in #2032, which buildsRewindPoint{IsTaskCheckpoint: true}from
state.TaskRecords, with distinct running vs completed messages.
Deliberately not in this
- Codex
SubagentAwareExtractor(token aggregation from rollouts) —codex exec --jsonreports
usage only on the terminalturn.completed. agent-integration-checklist.mdhas no subagent section at all.ToolUseID→SubagentCorrelationIDrename; Cursor subagent integration test; moving the
transcript resolver intopathswith claudecode + droid declaring their shared layout.
Context for whoever picks this up: the seven merged PRs that fixed the ephemeral stage are
#1935, #1936, #1938, #1947, #1950, #1964, #1958. This issue is only about the durable stage,
which none of them touched — and which #2032 now implements. #2059 was a redundant
cleanup-only attempt and is closed; #2083 carries the one doc fix that survived it.
Also stacked on #2032: #2034 (trail 1077, background-subagent commit linkage). It forked
before the task-records commits and still keys on session.InFlightTasks, which became
TaskRecords, so it needs a rebase onto #2032's tip before its diff means much.
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.
Assessment
This issue has not been assessed yet.