fix: wake yielded parent after subagents finish#97090
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed June 26, 2026, 7:28 PM ET / 23:28 UTC. Summary Reproducibility: yes. Source-level reproduction is high-confidence: current main sets Review metrics: 1 noteworthy metric.
Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land this narrow guard after maintainer review and redacted after-fix runtime proof, or deliberately fold the same guard into the broader yielded-parent lifecycle work if maintainers choose that path. Do we have a high-confidence way to reproduce the issue? Yes. Source-level reproduction is high-confidence: current main sets Is this the best way to solve the issue? Yes for the code shape. The PR is the narrowest maintainable fix I found: ordinary yielded runs stay paused, while only yielded orchestrators explicitly marked for descendant-settle wake can reach the existing announce/wake flow. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against bdd365a34882. Label changesLabel justifications:
Evidence reviewedWhat I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
Sanitized direct log evidence from the original BUG-045 extraction. This is the live before-fix proof; exact session ids, run ids, session keys, task names, local paths, channel target ids, private workflow names, and private PR context are redacted. Parent timeline preserved from the local postmortem memory note: Representative child trajectory terminal rows from the extracted raw logs: {"traceSchema":"openclaw-trajectory","schemaVersion":1,"traceId":"[redacted-child-session-id]","source":"runtime","type":"session.ended","ts":"2026-06-26T02:19:46.863Z","seq":7,"sourceSeq":7,"sessionId":"[redacted-child-session-id]","sessionKey":"agent:[redacted-agent]:subagent:[redacted-child-key]","runId":"[redacted-run-id]","provider":"github-copilot","modelId":"claude-opus-4.7","modelApi":"anthropic-messages","data":{"status":"success","aborted":false,"externalAbort":false,"timedOut":false,"idleTimedOut":false,"timedOutDuringCompaction":false,"timedOutDuringToolExecution":false}}
{"traceSchema":"openclaw-trajectory","schemaVersion":1,"traceId":"[redacted-child-session-id]","source":"runtime","type":"session.ended","ts":"2026-06-26T02:20:09.309Z","seq":7,"sourceSeq":7,"sessionId":"[redacted-child-session-id]","sessionKey":"agent:[redacted-agent]:subagent:[redacted-child-key]","runId":"[redacted-run-id]","provider":"github-copilot","modelId":"claude-opus-4.7","modelApi":"anthropic-messages","data":{"status":"success","aborted":false,"externalAbort":false,"timedOut":false,"idleTimedOut":false,"timedOutDuringCompaction":false,"timedOutDuringToolExecution":false}}
{"traceSchema":"openclaw-trajectory","schemaVersion":1,"traceId":"[redacted-child-session-id]","source":"runtime","type":"session.ended","ts":"2026-06-26T02:20:39.637Z","seq":7,"sourceSeq":7,"sessionId":"[redacted-child-session-id]","sessionKey":"agent:[redacted-agent]:subagent:[redacted-child-key]","runId":"[redacted-run-id]","provider":"github-copilot","modelId":"claude-opus-4.7","modelApi":"anthropic-messages","data":{"status":"success","aborted":false,"externalAbort":false,"timedOut":false,"idleTimedOut":false,"timedOutDuringCompaction":false,"timedOutDuringToolExecution":false}}
{"traceSchema":"openclaw-trajectory","schemaVersion":1,"traceId":"[redacted-child-session-id]","source":"runtime","type":"session.ended","ts":"2026-06-26T02:23:12.099Z","seq":7,"sourceSeq":7,"sessionId":"[redacted-child-session-id]","sessionKey":"agent:[redacted-agent]:subagent:[redacted-child-key]","runId":"[redacted-run-id]","provider":"github-copilot","modelId":"claude-opus-4.7","modelApi":"anthropic-messages","data":{"status":"success","aborted":false,"externalAbort":false,"timedOut":false,"idleTimedOut":false,"timedOutDuringCompaction":false,"timedOutDuringToolExecution":false}}
{"traceSchema":"openclaw-trajectory","schemaVersion":1,"traceId":"[redacted-child-session-id]","source":"runtime","type":"session.ended","ts":"2026-06-26T02:24:06.459Z","seq":7,"sourceSeq":7,"sessionId":"[redacted-child-session-id]","sessionKey":"agent:[redacted-agent]:subagent:[redacted-child-key]","runId":"[redacted-run-id]","provider":"github-copilot","modelId":"claude-opus-4.7","modelApi":"anthropic-messages","data":{"status":"success","aborted":false,"externalAbort":false,"timedOut":false,"idleTimedOut":false,"timedOutDuringCompaction":false,"timedOutDuringToolExecution":false}}Pre-fix source state captured in the same extraction: The original parent JSONL/trajectory was no longer present by the time the bug folder was created, so the parent-side proof above comes from the preserved postmortem/copy. The child terminal rows are direct extracted trajectory rows showing the intended children finished successfully before the parent remained idle. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Merged via squash.
|
* fix: wake yielded subagent parents after descendants settle * fix: wake yielded subagent parents after descendants settle --------- Co-authored-by: Galin Iliev <[email protected]>
* fix: wake yielded subagent parents after descendants settle * fix: wake yielded subagent parents after descendants settle --------- Co-authored-by: Galin Iliev <[email protected]>
* fix: wake yielded subagent parents after descendants settle * fix: wake yielded subagent parents after descendants settle --------- Co-authored-by: Galin Iliev <[email protected]>
* fix: wake yielded subagent parents after descendants settle * fix: wake yielded subagent parents after descendants settle --------- Co-authored-by: Galin Iliev <[email protected]>
Closes #97089
What Problem This Solves
Fixes an issue where users running parent sessions that call
sessions_yieldwhile waiting for subagents could miss the final wake-up after descendant subagents finished, leaving the parent idle until a later manual/user re-entry.Why This Change Was Made
The registry already has a descendant-settle wake path for ended orchestrator runs, but the resume gate returned early for every
sessions_yieldpause. This keeps ordinary yielded runs paused, while allowing yielded orchestrators markedwakeOnDescendantSettleto re-enter the existing descendant wake path.User Impact
Yielded parent sessions can resume when outstanding subagent work settles instead of waiting for a user to poke the session. This improves multi-subagent review and orchestration workflows without changing transport-specific delivery behavior.
Evidence
Live before-fix log evidence
Sanitized direct log evidence from the original BUG-045 extraction. Exact session ids, run ids, session keys, task names, local paths, channel target ids, private workflow names, and private PR context are redacted.
Parent timeline preserved from the local postmortem memory note:
Representative child trajectory terminal rows from the extracted raw logs:
{"traceSchema":"openclaw-trajectory","schemaVersion":1,"traceId":"[redacted-child-session-id]","source":"runtime","type":"session.ended","ts":"2026-06-26T02:19:46.863Z","seq":7,"sourceSeq":7,"sessionId":"[redacted-child-session-id]","sessionKey":"agent:[redacted-agent]:subagent:[redacted-child-key]","runId":"[redacted-run-id]","provider":"github-copilot","modelId":"claude-opus-4.7","modelApi":"anthropic-messages","data":{"status":"success","aborted":false,"externalAbort":false,"timedOut":false,"idleTimedOut":false,"timedOutDuringCompaction":false,"timedOutDuringToolExecution":false}} {"traceSchema":"openclaw-trajectory","schemaVersion":1,"traceId":"[redacted-child-session-id]","source":"runtime","type":"session.ended","ts":"2026-06-26T02:20:09.309Z","seq":7,"sourceSeq":7,"sessionId":"[redacted-child-session-id]","sessionKey":"agent:[redacted-agent]:subagent:[redacted-child-key]","runId":"[redacted-run-id]","provider":"github-copilot","modelId":"claude-opus-4.7","modelApi":"anthropic-messages","data":{"status":"success","aborted":false,"externalAbort":false,"timedOut":false,"idleTimedOut":false,"timedOutDuringCompaction":false,"timedOutDuringToolExecution":false}} {"traceSchema":"openclaw-trajectory","schemaVersion":1,"traceId":"[redacted-child-session-id]","source":"runtime","type":"session.ended","ts":"2026-06-26T02:20:39.637Z","seq":7,"sourceSeq":7,"sessionId":"[redacted-child-session-id]","sessionKey":"agent:[redacted-agent]:subagent:[redacted-child-key]","runId":"[redacted-run-id]","provider":"github-copilot","modelId":"claude-opus-4.7","modelApi":"anthropic-messages","data":{"status":"success","aborted":false,"externalAbort":false,"timedOut":false,"idleTimedOut":false,"timedOutDuringCompaction":false,"timedOutDuringToolExecution":false}} {"traceSchema":"openclaw-trajectory","schemaVersion":1,"traceId":"[redacted-child-session-id]","source":"runtime","type":"session.ended","ts":"2026-06-26T02:23:12.099Z","seq":7,"sourceSeq":7,"sessionId":"[redacted-child-session-id]","sessionKey":"agent:[redacted-agent]:subagent:[redacted-child-key]","runId":"[redacted-run-id]","provider":"github-copilot","modelId":"claude-opus-4.7","modelApi":"anthropic-messages","data":{"status":"success","aborted":false,"externalAbort":false,"timedOut":false,"idleTimedOut":false,"timedOutDuringCompaction":false,"timedOutDuringToolExecution":false}} {"traceSchema":"openclaw-trajectory","schemaVersion":1,"traceId":"[redacted-child-session-id]","source":"runtime","type":"session.ended","ts":"2026-06-26T02:24:06.459Z","seq":7,"sourceSeq":7,"sessionId":"[redacted-child-session-id]","sessionKey":"agent:[redacted-agent]:subagent:[redacted-child-key]","runId":"[redacted-run-id]","provider":"github-copilot","modelId":"claude-opus-4.7","modelApi":"anthropic-messages","data":{"status":"success","aborted":false,"externalAbort":false,"timedOut":false,"idleTimedOut":false,"timedOutDuringCompaction":false,"timedOutDuringToolExecution":false}}Pre-fix source state captured in the same extraction:
The original parent JSONL/trajectory was no longer present by the time the bug folder was created, so the parent-side proof above comes from the preserved postmortem/copy. The child terminal rows are direct extracted trajectory rows showing the intended children finished successfully before the parent remained idle.
Regression proof
Before the fix, the new regression reproduced the bug:
After the fix:
Additional checks:
Real behavior proof
Behavior addressed: A
sessions_yield-paused parent/orchestrator run withwakeOnDescendantSettlewas skipped byresumeSubagentRun, so descendant completion cleanup could not reach the existing parent wake path.Real environment tested: Local OpenClaw source worktree based on
upstream/main, Node/Vitest agent test lane vianode scripts/run-vitest.mjs.Exact steps or command run after this patch:
node scripts/run-vitest.mjs src/agents/subagent-registry.test.ts -- --reporter=verbose;git diff --check;.agents/skills/autoreview/scripts/autoreview --mode local.Evidence after fix: Terminal capture above shows
src/agents/subagent-registry.test.tspassed with66 passed (66), includingwakes a sessions_yield-paused parent when pending descendants settle;git diff --checkpassed with no output; autoreview reported no accepted/actionable findings.Observed result after fix: The regression now observes two announce/wake attempts: the child completion announce and the yielded parent wake announce with
wakeOnDescendantSettle: true.What was not tested: I did not rerun the original live Telegram/github-copilot workflow because it depends on private channel/provider credentials and the original live session state.