fix(subagents): credit requester-consumed descendant completions#95847
fix(subagents): credit requester-consumed descendant completions#95847kklouzal wants to merge 1 commit into
Conversation
8bb832d to
15f5126
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
084b669 to
9ed14d3
Compare
|
Codex review: needs real behavior proof before merge. Reviewed July 18, 2026, 11:16 PM ET / July 19, 2026, 03:16 UTC. Summary PR surface: Source +340, Tests +462, Other 0. Total +802 across 29 files. Reproducibility: yes. at source level: current main can synthesize descendant fallback text without retaining the exact consumed run IDs, while delivered state controls subsequent cleanup and retry behavior. A high-confidence live reproduction artifact is still absent. Review metrics: 1 noteworthy metric.
Stored data model 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:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Keep delivery credit narrowly tied to proven requester consumption, land only after maintainers accept that semantic boundary and the PR includes redacted runtime or persisted-state proof for consumed and unconsumed descendants. Do we have a high-confidence way to reproduce the issue? Yes at source level: current main can synthesize descendant fallback text without retaining the exact consumed run IDs, while delivered state controls subsequent cleanup and retry behavior. A high-confidence live reproduction artifact is still absent. Is this the best way to solve the issue? Unclear: the implementation is focused and avoids broad assumed-delivery credit, but it is the best fix only if maintainers accept requester consumption—not final outward delivery or a durable inbox—as the correct settlement boundary. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against ed546bdcf540. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +340, Tests +462, Other 0. Total +802 across 29 files. View PR surface stats
What 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
Review history (35 earlier review cycles; latest 8 shown)
|
145a2c3 to
808e4f2
Compare
15fd57b to
26e6311
Compare
69ca60c to
a6677b4
Compare
8e9a629 to
1e35fc1
Compare
24dbb93 to
820575a
Compare
2a16231 to
b90507f
Compare
Keep requester-consumed descendant completions credited without duplicate announcements, and model bundled plugin Knip roots needed by the CI dead-code scan.
|
ClawSweeper status: review started. I am starting a fresh review of this pull request: fix(subagents): credit requester-consumed descendant completions This is item 1/1 in the current shard. Shard 0/1. This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking. Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted. |
Summary
This PR fixes a lifecycle/delivery accounting gap for background and cron-owned subagent trees: when a requester actually consumes completed descendant subagent output, the descendant run is now durably credited as delivered instead of later being finalized as failed/suspended solely because no separate visible delivery event occurred.
What Problem This Solves
Requester-owned subagent trees can legitimately consume descendant output without sending a separate descendant-visible delivery event. This is common for cron/background flows where a parent/requester gathers frozen child output, composes its own result, and then delivers that requester result outward. Before this PR, the descendant completion could remain delivery-unproven even though its output had already been consumed by the requester. Later cleanup/finalization could then classify that descendant as failed or suspended, producing delivery state that did not match real behavior. This PR gives the registry an explicit durable signal for that case: requester consumption is delivery evidence only for the exact descendant runs that were consumed, under the matching requester session/run-start window, when the requester path adopts descendant fallback output, so the consumed descendant rows do not later announce or finalize as pending just because the final outward send fails.
User Impact / Intended Outcome
When OpenClaw can prove that a requester consumed descendant subagent output, the matching descendant run receives durable delivery credit:
delivery.statusis set to"delivered"for the matched descendant completion;delivery.status === "delivered"as completed delivery proof;The matching is intentionally narrow. Credit is only applied when all of these are true:
This PR keeps the delivery model explicit:
Linked Context
No exact existing issue/PR was found for
markDescendantCompletionConsumedByRequesteror this exact requester-consumed credit mechanism, so this PR should stand as the focused implementation thread for that behavior.What Changes
When OpenClaw can prove that a requester consumed descendant subagent output, the matching descendant run receives durable delivery credit:
delivery.statusis set to"delivered"for the matched descendant completion;delivery.status === "delivered"as completed delivery proof;The matching is intentionally narrow. Credit is only applied when all of these are true:
Implementation Notes
Core registry/runtime changes:
Main files:
src/agents/subagent-registry-consumption.tssrc/agents/subagent-registry.types.tssrc/agents/subagent-delivery-state.tssrc/agents/subagent-registry.tssrc/agents/subagent-registry-runtime.tssrc/agents/subagent-announce.registry.runtime.tssrc/cron/isolated-agent/delivery-subagent-registry.runtime.tsRequester-consumption paths:
src/cron/isolated-agent/subagent-followup.tssrc/cron/isolated-agent/delivery-dispatch.tssrc/agents/subagent-announce.tssrc/agents/subagent-announce-output.tsrunId.Tests / Verification
Coverage added or extended for:
delivery.status === "delivered"as proof;Primary test files:
src/agents/subagent-registry-consumption.test.tssrc/agents/subagent-delivery-state.test.tssrc/agents/subagent-registry-completion.test.tssrc/agents/subagent-registry.lifecycle-retry-grace.e2e.test.tssrc/agents/subagent-announce.format.e2e.test.tssrc/cron/isolated-agent/subagent-followup.test.tssrc/cron/isolated-agent/delivery-dispatch.double-announce.test.tsEvidence
Rebase/Squash/Proof
13ecca5408cbc94e66105608bfe770d0fc660d76(origin/main,fix(telegram): back off session init spool retries)604bc96e3bc716e545455c9ebaa81ef147a344f10454c42f196646e0929be14477e234eb226049e2--force-with-lease.Rebase/Squash/Proof
Current rebased/squashed PR head:
a6677b4d1ad6d58e4902bfb72d33be59b4b81d78.Latest pushed commit after same-base rebase and squash:
a6677b4d1ad6d58e4902bfb72d33be59b4b81d78.All six coordinated PR branches in this batch were rebased onto the same pinned upstream base commit:
Post-rebase local verification included conflict-marker/diff hygiene plus focused branch-specific gates. Final proof marker for this PR:
Focused validation run after the clean rebase and final nested-child dedupe fix:
Result:
Type checks passed.
Focused Vitest validation passed across 4 shards.
201 focused tests passed.
git diff --checkpassed.Base:
31e941c3fc32a2bbb6aeb0a3ae6f5f46777b2a1bHead after refresh:
a6677b4d1ad6d58e4902bfb72d33be59b4b81d78Branch:
kklouzal/openclaw:p1/requester-consumed-completion-credit-cleanConflict resolution: None for the follow-up refresh. Squashed the existing requester-consumed PR changes plus the cron/SQLite follow-up into one coherent commit.
Behavior proof refreshed: cron now credits
markDescendantCompletionConsumedByRequesterwhen it adopts explicit descendant fallback output, before final direct delivery, so a failed final outward send does not leave already-consumed descendant rows pending. SQLite persistence now derivespending_final_deliveryonly from active delivery statuses (pending,in_progress,suspended), so delivered/requester-consumed rows that retain payload metadata do not rehydrate as pending.Validation:
git diff --check-> passed.node scripts/run-vitest.mjs src/cron/isolated-agent/delivery-dispatch.double-announce.test.ts src/agents/subagent-registry.store.sqlite.test.ts src/agents/subagent-registry-consumption.test.ts src/cron/isolated-agent/subagent-followup.test.ts src/agents/subagent-delivery-state.test.ts-> passed, 5 files / 124 tests across 3 shards.node scripts/run-vitest.mjs src/agents/subagent-registry.test.ts -- -t 'yield|settle|descendant'-> passed, 6 selected tests / 59 skipped.Push: force-with-lease to
kklouzal/openclaw:p1/requester-consumed-completion-credit-cleancompleted.Compatibility and Risk
Risk is moderate because this touches subagent lifecycle/delivery finalization, but the implementation is deliberately constrained:
The main compatibility consideration is that existing delivery state can simply lack the new requester-consumption fields; restore logic treats those fields as optional.
PR/Commit Surface Breakdown
Diff surface against
origin/main...HEADafter the clean rebase:Source: 12 files, +192 / -44
Tests: 6 files, +251 / -12
Total: 18 files, +443 / -56
Reviewer Checklist
Recommended review focus:
src/agents/subagent-registry-consumption.tssrc/cron/isolated-agent/delivery-dispatch.tssrc/agents/subagent-announce.tssrc/agents/subagent-delivery-state.tsMaintenance update: squashed to
6f24d892e13ae42b7c1647a90e8ff050bd4a83d6after test-surface optimization only; behavior coverage and focused validation were preserved.Non-test surface optimization (2026-06-25): squashed cleanup head e569f3a (was 6f24d89); removed duplicated requester-consumed fallback credit construction in delivery dispatch while preserving behavior. Validation: pnpm test -- src/cron/isolated-agent/delivery-dispatch.double-announce.test.ts src/cron/isolated-agent/subagent-followup.test.ts -- --maxWorkers=1 --maxConcurrency=1; git diff --check; pnpm exec oxlint src/cron/isolated-agent/delivery-dispatch.ts.
Lint remediation (2026-06-26): squashed cleanup head 379d437 (was e569f3a); fixed CI
check-lintfailure insrc/agents/subagent-registry-consumption.test.tsby removing an unnecessary empty spread fallback flagged byunicorn(no-useless-fallback-in-spread). Validation:TASK=lint OPENCLAW_LOCAL_CHECK=1 node scripts/run-oxlint-shards.mjs --threads=8;git diff HEAD^..HEAD --check;pnpm exec vitest run src/agents/subagent-registry-consumption.test.ts src/agents/subagent-announcement-consumption.test.ts.