Add per-parent-task delegation tree (cross-process linkage)#54
Merged
Conversation
Link each delegated sub-call back to the top-level task that spawned it,
across the orchestrator→MCP-child process boundary. The CLI mints a
task_id per routed task; the orchestrator CLI adapter injects it as
TANGLEBRAIN_TASK_ID into the orchestrator subprocess (only when the
delegate tool is injected); the orchestrator forwards env to the MCP
delegate child; run_delegate reads it back and stamps each delegate
record's parent_task_id. The rollup groups delegates by_parent
("Linked to: N parent task(s)"); sub-calls run outside a propagated
task group as "unlinked".
New fields are written only when present, so existing usage records and
readers are unaffected. Manually verified live end-to-end through the
real claude→MCP-delegate boundary (parent + delegate records shared the
same id). The orchestrator-forwards-env hop is a load-bearing assumption,
not a TangleBrain guarantee — a delegate that loses the env degrades
safely to "unlinked", never an error.
Closes the deferred entry-criterion spike for the scatter-gather epic.
e856e1d to
9f6a0fc
Compare
This was referenced Jun 19, 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.
What
Link each delegated sub-call back to the specific top-level task that spawned it, across the
orchestrator → MCP-delegate-child process boundary — the deferred stretch item of the scatter-gather
epic (#39), whose entry criterion was a live-verification spike.
Mechanism:
run_oncemints atask_idper routed task → the orchestrator CLI adapter injects itas
TANGLEBRAIN_TASK_IDinto the orchestrator subprocess env (gated oninject_delegate) → theorchestrator forwards env to the MCP delegate child →
run_delegatereads it back and stamps eachdelegate record's
parent_task_id. The rollup gains aby_parentgrouping("Linked to: N parent task(s)"); sub-calls run outside a propagated task group as
unlinked.New record fields (
task_id,parent_task_id) are written only when present, so existing usagerecords and readers are unaffected.
Why
#39was core-complete with this one stretch item deferred precisely because it can't be testedhermetically — it depends on a real orchestrator CLI forwarding env to the MCP child it spawns.
Test plan
make teston 3.10/3.11/3.12). New unit coverage: env-injectiongating, env read-back, record write/omit,
by_parentgrouping +unlinkedsentinel, router-pathtask_idthreading, all-unlinked format.tanglebrainthrough the real router → claude →delegate_local; theparent task record (
model: claude,task_id: X) and the delegate record (model: gpt-oss-120b,parent_task_id: X) shared the same id. The--statstree rendered "Linked to: 1 parent task(s)".delegate MCP isn't registered. The env-forwarding hop is identical across CLIs, so claude proves
the mechanism. Documented as a load-bearing assumption in
delegate.py(degrades safely tounlinked, never errors).Independent Critic reviewed (diff-only): SHIP; both SHOULD-FIXes addressed (router-path opts test +
load-bearing comment) plus NITs (all-unlinked format, CHANGELOG wording).
Closes #52.