fix(server): parents keep getting woken for every delegated task that finishes - #13938
Conversation
… finishes A delegated-completion cohort allowed one delivery plus one successor, then left every later child result pending with no wake. A parent that fanned out twelve children was woken twice and then waited silently until the user typed. When a delivery settles with results still pending, reserve one successor that carries all of them. Siblings that finish before a delivery starts still join it, and results that land while it is queued or running wait for the next one, so a cohort never has more than one delivery outstanding. Each child becomes pending at most once, so successors are bounded by the cohort's children. The cap was the only reader of settledDeliveryCount, so the field is dropped from the contract; older rows that carry it decode unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a small, isolated orchestration bug fix that restores delivery of late delegated-task results without changing unrelated execution paths. Extensive integration coverage verifies batching, one-outstanding-delivery behavior, cleanup barriers, and complete delivery across a 12-child fan-out. You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: unavailable · PR result: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
b39e62d
into
t3code/codex-turn-mapping
… finishes (pingdotgg#13938) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Closes #12285
A parent that fans out delegated tasks with
delegate_taskstopped being woken after two completion deliveries. The rest of its children kept finishing, but their results stayedpendingwith no wake, and the parent sat "waiting" until the user typed. In the reported DB, both originating runs showdelegatedCompletion.settledDeliveryCount: 2anddelivery: null: two notices got through, and 10 (then 5) completions were silent.Cause
#5311 coalesced sibling completions into one durable delivery per parent-run cohort, which was the right goal. But
Orchestrator.tsalso refused to reserve anything oncesettledDeliveryCount >= 2, in three places: planning a new delivery, reserving a successor when a delivery settles, and batching on mailbox acceptance. So the cohort was hard-capped at one delivery plus one successor.Fix
task_statusand direct-child reads is unchanged.delegate_taskattaches new children to the currently active run, and a delivery run is a new run with its own cohort. Any bound would reintroduce silently dropped wakes, so I didn't add one.settledDeliveryCounthad no other reader, so I dropped it fromOrchestrationV2DelegatedCompletionCohort. Persisted rows that still carry it decode fine, because the schema ignores excess properties by default.Verification
OrchestratorMcpToolkit.integration.test.ts: third and fourth late children now finish while the successor runs. They staypendingbehind the one outstanding reservation, then go out together in a third delivery. All four children enddelivered, with one continuation offer per delivery (3).delivered, with no pending results left, and at most one delivery outstanding at each checkpoint.Orchestrator.tsand contract restored, the updated test fails, timing out waiting for the batched third delivery.vp test run src/mcp/OrchestratorMcpToolkit.integration.test.ts: 2/2 pass.DelegatedCompletionDelivery,ProviderContinuationService,ProjectionStore,QueuedRunOrder,ThreadDeletion,CheckpointCaptureService,SteeringCompletion.integration,SubagentProjection,ProjectionRecovery,RunCompletionReads,TurnStartReadsandOrchestratorMcpServicetests: 79/79 pass.OrchestratorReplayFixtures.integration.test.ts: 96/96 pass.vp exec tsc --noEmit -p .inapps/serverandpackages/contracts: no errors.--exports, server and contracts workspaces): clean.vp linton the touched files: only thelayerUnavailableunused-variable warning, which is already on the base branch.settledDeliveryCount.Model: Claude Opus 5.5 (Claude Code)
🤖 Generated with Claude Code