[Bug] Compaction loses track of in-flight agents, causing duplicate work
Environment
- CLI 2.1.247, macOS darwin-arm64, Max 20x, main loop Opus 5
- Related: #90034 (a live workflow leaves no record on disk either), #77730 (agent/task IDs stop resolving)
What happens
Compaction rewrites the main window while background agents keep running, untouched. After the rewrite there is no structured record of what is in flight. The compaction summary is free prose, so whether a running agent is mentioned at all depends on whether the model happened to write it down, and in what words.
The consequence is a session that concludes a unit was never started, and dispatches a second agent onto the same output file. Two agents then write the same artifact, and the loser's work is silently overwritten.
The important part is that there is no authoritative place to check. In-memory handles are gone after compaction, and per #90034 the on-disk run record for a workflow is not written until the run finishes. So both the fast path and the fallback path report nothing.
Evidence
Scanning 49 sessions with subagents active in the last 45 days, comparing each subagent transcript's lifespan against compaction timestamps in the parent session:
agent runs alive across a compaction: 11
sessions where that happened: 2 of 49
session agent agent_ran compact_fired_at
788ae070 agent-a3a8a423bad0712bf 352.7m 17.2m in
788ae070 agent-a948fe392f0fa5970 14.7m 4.2m in
788ae070 agent-a01cd75272174fe21 14.7m 10.4m in
788ae070 agent-ad7dce89ea0e31397 12.9m 9.6m in
788ae070 agent-a02e54cb34eb80f78 12.2m 2.1m in
The first row is an agent whose transcript spans 5 hours 52 minutes, with a compaction firing 17 minutes into it. The session that launched it spent the remaining 5.5 hours with no in-memory handle on it.
That same session compacted 31 times in roughly 12 hours, so this is not a rare boundary condition on a long-running job. On a heavy day it is the normal operating state.
What I expected to find, and did not
I expected the compaction summaries to have dropped all mention of the running agents. They had not: 30 of the 31 summaries contain phrases like "in flight" or "still running."
That turned out to be evidence for the report rather than against it. Those mentions survive only because this user maintains a hand-rolled convention of writing an IN FLIGHT: <agent> -> <output path> - started <time> line into a file on disk before every dispatch, specifically to survive compaction. The prose in the summary is a description of that manual bookkeeping, not a record the product maintains. It carries no task IDs, so nothing in it can be used to query, wait on, or stop the agent it names.
So the failure is not that the information is always lost. It is that preserving it is left to the user, in prose, with no identifiers.
Ask
Any one of these would close it:
- Emit a machine-generated "agents in flight" block into every compaction summary: task ID, agent type, launch time, and target output path if known. Not left to the model to remember.
- Keep live agent handles resolvable across a compaction, so
ListAgentsandTaskOutputstill work afterward (this overlaps #77730). - Fix the disk side per #90034, so a compacted session at least has an authoritative place to look.
1 and 3 together would be enough. 1 alone would cover the common case.
Workaround
Write an IN FLIGHT line to a state file on disk before dispatching, and clear it when the output file lands. Check liveness by sampling the size of ~/.claude/projects/<slug>/<session>/subagents/agent-*.jsonl twice, 60 to 90 seconds apart, rather than trusting the transcript. A quiet agent is usually mid-write, not dead: a single long turn can go 5+ minutes with no output.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗