Repository navigation
fix(rendering): filter subagent sidechain turns from the main feed (#477, Track A) - #479
Merged
Juliusolsson05 merged 1 commit intoJul 7, 2026
Conversation
, Track A) Subagent (Task/Agent) output was leaking into the parent's MAIN feed: Claude interleaves a subagent's OWN turns into the parent transcript tagged isSidechain:true, and the committed collector was structurally blind to the flag — RawCommittedEntry didn't even carry it, so a sidechain assistant turn (type:'assistant', not meta, text not '<') sailed through to `selected` and painted as a plain main-feed row, with minedToolIds even stamping its inner Read/Bash as committed-owned. Confirmed live and captured in a session recording (#467); diagnosis and plan in #477. TDD: the two committed tests + the e2e adapter fixture were written FIRST and FAILED (the sidechain turn was selected, its Read mined) — that failure IS the leak. Then the fix: - RawCommittedEntry gains isSidechain (the field already flows through the claude codec + history.ts:71; the feed just never honored it — only the session picker did, sessionList.ts:160). - collectCommittedCandidates rejects sidechain entries BEFORE mining tools, reason 'sidechain-filtered' (new RenderReason). Safe by construction: the same activity already renders inside the Task card via the watcher channel (SubAgentState), so nothing is lost. - e2e fixture proves the field flows adapter -> collector -> ledger and only the parent rows paint. This is the COMMITTED (persistent) half. The LIVE proxy-plane half (subagent turns multiplexed on the shared proxy stream, no isSidechain on the wire) is Track B in #477 — needs flow attribution, separate PR. Corpus unchanged (no fixture had sidechain entries); 170 rendering tests; full unit suite 431; both gates clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Track A of #477 — the committed-plane half of the subagent-into-main-feed leak (the persistent one). Diagnosis: Claude interleaves a subagent's own turns into the parent transcript tagged
isSidechain:true; the committed collector was structurally blind to the flag, so they painted as main-feed rows (and their inner Read/Bash got mined as committed-owned).TDD, in the diff: the committed tests + the e2e adapter fixture were written first and failed (sidechain turn selected, its Read mined) — that failure is the captured leak. Then the fix:
RawCommittedEntrygainsisSidechain(the field already flows through the claude codec +history.ts:71; only the session picker ever honored it).collectCommittedCandidatesrejects sidechain entries before mining tools, reasonsidechain-filtered. Safe by construction — the same activity already renders inside the Task card via the watcher channel, so nothing is lost.Confirmed live and captured in a session recording (#467) — the recorder caught the symptom, the diagnosis pinned the one-field root cause, this test-locks it.
Not here: the live proxy-plane half (Track B in #477) — subagent turns multiplexed on the shared mitmproxy stream with no
isSidechainon the wire; needs flow attribution, separate PR.Corpus unchanged; 170 rendering tests; full suite 431; both gates clean.
🤖 Generated with Claude Code