Repository navigation
fix(orchestration): closed children follow their parent's replacement - #1369
Merged
Merged
Conversation
…cement (#1283 item 1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… in main Tombstones of MCP-closed children named the parent's old session id, so the parent's successor could not list, read or collect them. carryParent rewrites stored tombstones and child->parent hints, and keeps a bounded, acyclic alias chain for a close whose read predates the swap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…bstone-parent-carry
…t's successor orchestration:carry-parent, called wherever live children are remapped (replace incl. newConversation, Reload Agents) and on Undo Close, only for committed successors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s filed under the successor #1369 review a: createAgent's answer and adoptLateResponse stored the requested (replaced) parent as the child's hint and invalidated only its cache, so the successor served a stale empty list. Both now resolve through the alias chain. Review b: the preload->IPC->bridge boundary, the same-conversation replace carry and alias pruning are now pinned; every single mutation is red. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…bstone-parent-carry
…erer helper's containment #1369 review c: dropping either status-cache invalidation in carryParent, the renderer's identity-pair skip or its .catch left every test green. Also corrects the delete(to) comment: no wired caller revives an id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t swap under the successor #1369 verification a and b: createOrchestrationAgent captured the parent id, awaited the spawn, and filed the child under it; a replacement committed meanwhile had only remapped existing children, so the successor could not list, read or close the new child. The committed-swap helper now records a bounded, acyclic successor map per window, and filing resolves parent and root through it. Red without the resolution; every piece pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts successor q85: the mark is the last step of a delivery that can land long after the create began (a prompt waiting for the composer, or #1370's late adoption). It was addressed with the parent id the tool call captured; after a replacement that id has no window and owns no children, so the mark was lost. Resolved through the alias chain; the combined late-create + replacement path was reproduced against #1375 and passes with this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…spatch #1369 verification a, round 3: the bridge serves one renderer request at a time, so a mark resolved when queued could still dispatch to a parent replaced while it waited. Only the mark is rewritten; other requests act for the parent that asked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
Review disposition (head Fixed
Every fix was red before it landed. Each guard was also removed on its own, and each removal fails a test. Filed as a follow-up, not in this PR
Handed to W4, not pushed here
🤖 Generated with Claude Code |
…bstone-parent-carry
…bstone-parent-carry
This was referenced Sep 27, 2026
fix(orchestration): deliver the bootstrap prompt to a child created after the deadline (#1370)
#1375
Merged
Juliusolsson05
added a commit
that referenced
this pull request
Sep 27, 2026
…esolve the parent lease through its alias chain W2's patch (temp/q85): orchestration.bootstrap_mark_failed on the late path only, and the combined late-create + parent-replacement case. isParentAttached now resolves the parent through #1369's currentParentId, so a parent replaced during the late window keeps its brief flowing to the successor; only a parent with no live successor is gone. Removing the alias resolution fails the replaced-parent test. Orchestration suites green; tsc 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Juliusolsson05
added a commit
that referenced
this pull request
Sep 27, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Refs #1283. This fixes item 1, orchestration tombstones. Item 2 (the Codex handoff window lease) is #1338, and item 3 (PTY attach counts across a renderer reload) is still open.
Plan:
docs/plans/2026-09-27-orchestration-tombstone-parent-carry.md(first commit).Problem
Main keeps a small in-memory tombstone for every child closed through the orchestration MCP. This is how a parent still sees "closed" as a state after the renderer removes the pane. A tombstone matches its parent by the frozen
orchestrationParentId/orchestrationRootId.When parent P is replaced by P′ (replace, provider switch, resume, rewind, Reload Agents), the renderer remaps every LIVE child to P′, but main was never told. So for P′:
list_agentsandread_run_outputsomitted every closed child;read_agenton one of them said not-found;What merges
OrchestrationBridge.carryParent(from, to)(main):to, and invalidates both status caches;closeAgentreads a child before the renderer closes it, so a swap landing in between still files the tombstone under the successor. The chain follows P→P′→P″.todropsto's own outgoing edge, sincetois live again. A hop cap backstops this.createOrchestrationAgentresolves parent and root through a per-window successor map. The map is recorded by the same committed-swap helper, and it is bounded and acyclic.orchestration:carry-parentIPC, and the renderer'scarryOrchestrationParents(idMap)insuccessorCarry.ts, called:workflows:carry-session: workflow runs follow the conversation and are skipped for newConversation; orchestration pointers follow the pane. One channel cannot honour both rules.workflows:carry-session/goal-loop:carry. Malformed input is a no-op.Merge order
Merge before #1374. #1374 makes a restored parent's live children visible, and this PR's Undo Close carry rewrites main's child→parent hints, which #1374's review names as its only residual.
Tests
src/main/ipc/orchestration.test.ts: the real preload method goes through the real IPC handler into the real bridge, and malformed input is covered.orchestrationRuntime.renderer.test.tsx: a create whose parent and root are replaced during its spawn is filed, answered and listed under the successors.OrchestrationBridge.parentCarry.test.ts(the real close flow: pre-read, then close, then tombstone):replacementOwnership(newConversation still carries),reloadAgentsOwnership(the committed successor only, not an orphan) andundoCloseSuccessorCarry(the restored pane, not a bailed restore).carryParentas a no-op;delete(to)cycle guard, the hint remap;2abe9d74(main merged after fix(sessions): a committed Codex handoff releases the predecessor's window lease #1338; the code is unchanged since81314044),npx tsc -bis clean and the focused suites (src/main/orchestration,src/main/ipc, workspace actions, orchestration runtime) pass: 55 files, 385 tests.🤖 Generated with Claude Code