[BUG] A running workflow leaves no record on disk, so liveness cannot be checked and dispatch collides
Environment
- CLI 2.1.247, macOS darwin-arm64, Max 20x, main loop Opus 5
- Also present on 2.1.246
What happens
The run record at ~/.claude/projects/<slug>/<session>/workflows/wf_<id>.json is created when the run ends, not when it starts. While a workflow is running there is nothing in that directory representing it.
The practical effect is that the only obvious way to ask "what is running right now" always answers "nothing." A session that checks before dispatching sees an empty or all-completed directory and concludes the fleet is drained, then launches a second run onto work already in flight.
Evidence
Across 139 recorded runs on this machine, comparing each JSON file's birth time to the startTime field it contains:
run status born-start json-last dur
wf_914c1b85-8d1 completed 7528.8s 0.0s 7528.8s
wf_5922a0b7-acf completed 5521.0s 0.0s 5521.0s
wf_b4b251b7-eb8 completed 2114.5s 0.0s 2114.5s
wf_758eba10-c9c completed 1880.8s 0.0s 1880.8s
wf_5f704081-cf5 completed 1799.3s 0.0s 1799.3s
...
json created after half the run had elapsed: 100 of 100 measurable runs
born-start equals the run duration exactly in every case, and the file is never modified after creation (json-last is 0.0s against the last transcript write). So the file is not created at launch and updated, it is created once, at completion.
The first row is a run that went 2 hours 5 minutes with no on-disk record of its existence at any point during it.
Status values observed across 400 sampled files: 133 completed, 3 killed, 3 failed, 261 with no status field at all (older format). No value ever represents a run in progress.
Impact
On 2026-08-23 this produced a wrong conclusion ("fleet drained") while 12 workflows were running, and the next dispatch collided on a unit already being worked. It is a silent failure: the directory is not empty in a way that looks broken, it looks like a clean finished history.
It also interacts badly with compaction. A compacted session has lost its in-memory handles, so disk is the only place left to look, and disk is exactly where a live run does not appear.
Ask
Either one of these fixes it:
- Write
wf_<id>.jsonat launch with a status ofrunning, and update it on completion. This is the smaller change and makes the existing directory answer the question correctly. - Ship a
claude workflows status/claude tasks listthat reports live runs.
Workaround
Live runs are observable, just not where you would look. The transcript directory is created at launch:
~/.claude/projects/<slug>/<session>/subagents/workflows/wf_<id>/*.jsonl
A wf_<id>/ directory whose newest .jsonl was written under ~5 minutes ago is a live run. Note that a quiet agent is usually mid-write rather than dead, so a single sample is not enough; two samples 60 to 90 seconds apart, checking whether the file is still growing, is reliable.