Repository navigation
Claude Code subagent transcripts are never discovered (depth-2 cap) — ~54% of messages invisible on subagent-heavy workflows #207
Description
Context: surfaced while validating the #204 rewrite fix in #200 — the token-exact cross-check there covers main transcripts only; this is the orthogonal coverage gap mentioned in that thread, filed separately as requested.
Summary
The Claude Code analyzer discovers only ~/.claude/projects/<slug>/<session>.jsonl. Claude Code additionally writes per-subagent transcripts under ~/.claude/projects/<slug>/<sessionId>/subagents/**/agent-<agentId>.jsonl (Task tool: Explore / general-purpose / custom agents). Those files sit at depth ≥ 4, so their usage never enters splitrail's totals, uploads, or the leaderboard.
For anyone using subagents heavily, splitrail undercounts by a large factor. On my corpus (~50 days, mixed CLI + subagent workflows), live main transcripts hold 13,704 messages / 18.5M output tokens while live subagent transcripts hold 16,160 messages / 13.7M output tokens — 54% of live messages missing.
Where the cap lives (v3.6.0)
All three discovery paths hard-code depth 2 in src/analyzers/claude_code.rs:
discover_data_sources()—WalkDir::new(projects_dir).min_depth(2).max_depth(2)is_valid_data_path()—relative.components().count() == 2get_data_glob_patterns()—"{home}/.claude/projects/*/*.jsonl"
Observed layout (Claude Code 2.1.150–2.1.198, macOS)
~/.claude/projects/<project-slug>/
├── <sessionId>.jsonl # main transcript (scanned)
└── <sessionId>/subagents/
├── agent-<agentId>.jsonl # NOT scanned
└── agent-<agentId>.meta.json # agentType, e.g. "Explore"
Subagent lines carry the same schema as main-transcript assistant lines (message.id, model, usage, requestId), repeat the parent sessionId, and add agentId + isSidechain: true.
Repro
# any machine that has used the Task tool / subagents:
find ~/.claude/projects -mindepth 3 -name '*.jsonl' | wc -l # files splitrail never sees
find ~/.claude/projects -mindepth 3 -name '*.jsonl' -exec grep -l '"type":"assistant"' {} + | headCompare splitrail stats totals before/after copying one subagent file up to depth 2 (in a scratch $HOME): the totals jump by exactly that file's usage.
Numbers from my corpus (message.id-level dedup, append-only log as reference)
| class | files | messages | outputTokens |
|---|---|---|---|
| live main transcripts (scanned) | 76 | 13,704 | 18,548,947 |
| live subagents/** (not scanned) | 1,423 | 16,160 | 13,738,324 |
Model mix makes the blind spot obvious: on my machine splitrail sees 22 of 5,059 sonnet messages and 0 of 1,566 haiku messages — those models run almost exclusively inside subagents.
Suggested fix
Lift the depth cap and include */*/subagents/**/*.jsonl (or simply walk without max_depth and filter on .jsonl):
- The existing cross-file dedup already keys on
local_hash = fast_hash(requestId_messageId), so any duplication between main and subagent records dedups correctly (I verified token-exact agreement between 3.6.0's main-transcript totals and an independent message.id-keyed ingest — the dedup semantics are sound). is_valid_data_pathand the watcher need the same relaxation, plus the 3.6.0 history store keys by conversation-path hash and should be unaffected (each subagent file becomes its own conversation).- Heads-up for Splitrail Cloud: totals for subagent-heavy users will jump on upgrade; may be worth a release-note line.
Happy to test a branch against my corpus (same fixture as in #200's validation) and report before/after.
Activity
lizhuojunx86 commentedon Jul 21, 2026
The rewrite-side regression fixture from the same validation run is now up as #208.
mike1858 commentedon Jul 22, 2026
Thank you. Closed via #208 and #209.
lizhuojunx86 commentedon Jul 25, 2026
Thanks for #209 — good to see it went through the same local_hash dedup path rather than just lifting the cap; that was the part I was least sure a quick fix would get right.
I wrote up the whole arc (#200 → 3.6.0 → the A/B validation → #207/#208 → 3.6.1) here: https://dev.to/lizhuojunx86/an-append-only-audit-log-caught-two-accounting-bugs-in-a-216-star-usage-tracker-38co — it's mostly about append-only ingest as a prerequisite for trustworthy usage accounting, with splitrail as the worked example. Your turnaround on both is in the timeline as it happened.
Next I'll re-run the frozen-snapshot protocol on 3.6.1 and post the before/after numbers for the subagent class here — 1,423 files / 16,160 messages / 13.7M output tokens that were previously invisible. Should be a reasonable independent check on #209 at a scale that's awkward to synthesize. And re: the audit part you mentioned earlier — happy to send a one-pager on the routing_audit module whenever it's useful, no rush.