fix(agents): preserve sibling reroutes and repair Gateway release E2E - #136807
Conversation
|
🦞👀 Pull request received. I will update this pull request when review starts. |
|
Codex review: blocked before merge. Reviewed September 2, 2026, 11:49 PM ET / September 3, 2026, 03:49 UTC. ClawSweeper reviewWhat this changesThe branch collects and bounds route-change notices from all current sibling subagent completions in a consolidated requester wake, while updating Gateway E2E fixtures to current contracts. Merge readiness⛔ Blocked before merge - 2 items remain Keep this actively maintained, maintainer-labeled PR open. Source review found no introduced blocking defect: it repairs the current-main scheduling-row-only route-notice loss and aligns E2E fixtures with current delivery, environment, and doctor contracts. Priority: P2 Review scores
Verification
How this fits togetherSubagent completion records flow from the registry into a consolidated wake for the parent agent. That wake builds model-visible completion context and returns it through delivery policy, which decides whether route notices remain internal on shared channels. flowchart LR
A[Child subagent completions] --> B[Subagent registry]
B --> C[Current child selection]
C --> D[Consolidated requester wake]
D --> E[Channel visibility policy]
E --> F[Parent agent context]
Decision needed
Why: The PR is explicitly maintainer-labeled and the repository policy reserves protected maintainer work for explicit maintainer handling, even though source review found no blocking patch defect. Before merge
Agent review detailsSecurityNone. PR surfaceSource +17, Tests +14. Total +31 across 6 files. View PR surface stats
Review metrics
Technical reviewBest possible solution: Land a single canonical wake formatter that derives completion findings and route notices from the same current-child batch, retaining the bounded deterministic aggregation and boundary-level coverage. Do we have a high-confidence way to reproduce the issue? Yes, source-reproducible: construct a settled batch where the scheduling child has no route notice and a current sibling does; fetched main reads only the scheduling child at the wake formatter. Is this the best way to solve the issue? Yes: deriving both findings and notices from the existing filtered, deduplicated child selection keeps one authoritative batch boundary and avoids a sibling-specific parallel path. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 4af3fc294575. LabelsLabel justifications:
EvidenceWhat I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
History |
cab7419 to
7a3f5a6
Compare
Root cause: the composed Gateway fixture bypassed required service methods through a context cast after execution-mode projection became mandatory. Owner: the App SDK E2E worker-service fixture now satisfies the complete request-facing contract and asserts supported execution modes. Proof: the original E2E failed 3/3 before and passed 3/3 after; environment owner tests pass (33 tests). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Root cause: a reasonless skipped update is a failed update, so the old fixture exited before reaching its intended database compatibility gate. Owner: the schema-preflight fixture now declares the supported already-current outcome and preserves the schema-refusal assertion. Proof: the original E2E failed 3/3 before and passed 3/3 after; doctor-update owner tests pass (35 tests). No schema or production behavior changes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Root cause: requester and lifecycle fixtures returned text without the terminal send receipt required for external completion delivery, and observed RPC calls before their delivery state had committed. Owner: Gateway-result fixtures now provide confirmed receipts; scenarios wait on committed cleanup and release gated work even on assertion failure. Proof: the rejected requester wake failed 3/3 before and passed 3/3 after. Receipt repairs also resolved four sibling lifecycle failures. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Root cause: four retry-grace scenarios emitted 1970 timestamps under the current fake clock, so the 30-minute delivery deadline had already expired. Owner: each event producer now records Date.now(); grace advances and observable delivery assertions remain unchanged. Proof: all four failed 3/3 with stale timestamps; the corrected sibling suite passes all 14 tests in the final 22-test Gateway E2E run. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Root cause: the wake read route metadata only from its scheduling child, so a rerouted sibling disappeared from the parent's consolidated context. Owner: the requester settle-wake formatter now reuses the current-child selection, deduplicates and sorts route notices, and caps the aggregate at 1024 characters while preserving local and shared-channel visibility. Proof: the original visible-wake assertion still failed after fixture-only repairs and passes after this change. All four reported E2E failures pass 3/3; 39 wake owner tests cover sibling notices, stale owners and the bound. Production growth is 17 lines for bounded, deterministic batch aggregation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
7a3f5a6 to
e56f922
Compare
|
Merged via squash.
|
…openclaw#136807) * test(sdk): enforce the worker environment fixture contract Root cause: the composed Gateway fixture bypassed required service methods through a context cast after execution-mode projection became mandatory. Owner: the App SDK E2E worker-service fixture now satisfies the complete request-facing contract and asserts supported execution modes. Proof: the original E2E failed 3/3 before and passed 3/3 after; environment owner tests pass (33 tests). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(doctor): model an explicit no-op before schema refusal Root cause: a reasonless skipped update is a failed update, so the old fixture exited before reaching its intended database compatibility gate. Owner: the schema-preflight fixture now declares the supported already-current outcome and preserves the schema-refusal assertion. Proof: the original E2E failed 3/3 before and passed 3/3 after; doctor-update owner tests pass (35 tests). No schema or production behavior changes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(subagents): confirm delivery before asserting requester settlement Root cause: requester and lifecycle fixtures returned text without the terminal send receipt required for external completion delivery, and observed RPC calls before their delivery state had committed. Owner: Gateway-result fixtures now provide confirmed receipts; scenarios wait on committed cleanup and release gated work even on assertion failure. Proof: the rejected requester wake failed 3/3 before and passed 3/3 after. Receipt repairs also resolved four sibling lifecycle failures. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(subagents): timestamp fresh lifecycle events from the fixture clock Root cause: four retry-grace scenarios emitted 1970 timestamps under the current fake clock, so the 30-minute delivery deadline had already expired. Owner: each event producer now records Date.now(); grace advances and observable delivery assertions remain unchanged. Proof: all four failed 3/3 with stale timestamps; the corrected sibling suite passes all 14 tests in the final 22-test Gateway E2E run. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(agents): preserve sibling model reroutes in requester wake batches Root cause: the wake read route metadata only from its scheduling child, so a rerouted sibling disappeared from the parent's consolidated context. Owner: the requester settle-wake formatter now reuses the current-child selection, deduplicates and sorts route notices, and caps the aggregate at 1024 characters while preserving local and shared-channel visibility. Proof: the original visible-wake assertion still failed after fixture-only repairs and passes after this change. All four reported E2E failures pass 3/3; 39 wake owner tests cover sibling notices, stale owners and the bound. Production growth is 17 lines for bounded, deterministic batch aggregation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
What Problem This Solves
Resolves a problem where the 2026.9.1 stable release's Gateway E2E validation failed, including a requester wake that dropped a sibling's model-route change notice.
Failure evidence: Full Release Validation, Gateway 4/4 job, release SHA
c92d0ae9c07e757719e676517aa9f9460a40761c.Why This Change Was Made
Requester settle wakes now collect route notices from the same current, deduplicated children as completion findings. Notices are sorted, deduplicated, and bounded to 1,024 characters including an explicit truncation marker. The existing local/shared-channel visibility policy remains authoritative.
The other failures came from fixtures that no longer described current owner contracts:
WorkerEnvironmentServiceContractand proves execution-mode projection. The call was introduced by fix: prevent incompatible cloud runtime dispatches #126585; fix: keep cloud sessions stopped and surface cleanup failures #135583 removed the method-level optional guard. The real service already implements it.skippedupdate is a failed update, not a continuation. The fixture now explicitly supplies the supportedalready-currentno-op and retains the schema-refusal assertion.Each independent cause has its own commit. The change restores the existing subagent handoff and delivery contracts without adding configuration, persistence, schema, or protocol changes. Production delta is +27/-10; the net 17 lines implement current-batch aggregation, deterministic ordering, and a bounded prompt block.
User Impact
Parents receive route-change notices from rerouted siblings even when another child triggers the consolidated wake. External-channel parents continue to keep those notices internal. Release validation now exercises realistic environment, update, and delivery contracts.
Related: #136390 addresses overlapping-wave deferral, a separate invariant; this PR does not include that change.
Evidence
All four original failures reproduced in 3/3 runs before edits and passed 3/3 after repairs, using
test/vitest/vitest.e2e.config.ts, two workers, and the prepared E2E runtime. Fixture-only proof fixed App SDK, doctor, and rejected-wake tests while the visible-wake test still failed on the missing sibling notice before the production fix.The final combined E2E run passed 22/22 tests across four files, including the sibling lifecycle suite. The eight initial sibling failures reduced to four after receipt fixes, then zero after correcting event timestamps.
The initial invocation omitted
OPENCLAW_E2E_USE_PREBUILT_DISTand successfully built the runtime, local plugin artifacts, and subprocess prerequisites. Local proof used macOS and Node 26.8.1; the release job uses Linux and Node 24.19.0.A recent scheduled main E2E run already had the exact App SDK failure in shard 1 and doctor failure in shard 2. Weighted assignment differed; the requester-wake file was absent from that earlier run. Normal
ci.ymldoes not run this full Gateway E2E matrix.Owner unit suites passed 107/107 (39 requester-wake, 33 environment, 35 doctor-update). The final requester-wake suite passed again after test consolidation; the two deferred delivery cases also passed after adopting the existing promise helper.
pnpm check:changedcompleted successfully with every selected gate enabled. Earlier attempts identified test-file line limits and an unsupported TypeScript library reference in the test consolidation; duplicate setup was consolidated and the canonical deferred-promise helper reused. No assertions, gates, or type targets were weakened. Final independent Codex review found no actionable P0–P2 issues. Production is +27/-10; tests are +206/-192. The complete Gateway shard and full release matrix have not been rerun; this PR is the focused repair and local proof for the release owner to integrate.🤖 Generated with Claude Code