Skip to content

refactor(gateway): centralize agent wait lifecycle#104147

Merged
obviyus merged 2 commits into
mainfrom
refactor/agent-job-lifecycle
Jul 11, 2026
Merged

refactor(gateway): centralize agent wait lifecycle#104147
obviyus merged 2 commits into
mainfrom
refactor/agent-job-lifecycle

Conversation

@obviyus

@obviyus obviyus commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Closes #104135

What Problem This Solves

Resolves an internal Gateway reliability problem where agent.wait reconciled two independent terminal-state owners: lifecycle observations in the agent job cache and terminal Gateway dedupe entries. Each path maintained its own waiter machinery, and the RPC handler raced both promises before deciding which result won.

Why This Change Was Made

The agent job registry now ingests both lifecycle and dedupe terminal observations, applies the existing canonical terminal-outcome precedence, and owns the only waiter registry. A closed source tag preserves the existing active-chat/run-ID collision behavior. The separate dedupe wait module, handler-level Promise.race, and dead cancellation path are removed.

User Impact

No intended user-visible behavior change. Agent waits now have one deterministic terminal-state owner, while Gateway event fan-out no longer registers one global agent-event listener per waiter.

Evidence

  • Blacksmith Testbox: 224 focused Gateway tests passed; targeted type-aware lint passed.
  • Blacksmith Testbox: 744 broader Gateway tests passed; core and core-test tsgo lanes passed. The environment stopped externally during later full-core lint stripes, so no full check:changed claim is made.
  • Exact-head path gate: core and core-test type lanes, targeted lint, conflict/dependency guards, database-first guard, runtime loader/cycle guards, and pairing/webhook guards passed.
  • GitHub CI on the previous head commit: build artifacts, core lint, production/test types, and the relevant compact Node shard passed. Both QA Smoke failures reproduce on exact origin/main and stop before scenarios because the current release changelog section is missing.
  • Collision repair proof: focused disagreement tests cover older sticky cancellation/timeout state followed by a newer cross-source completion, plus fresh lifecycle completion after a dedupe snapshot.
  • Ephemeral Gateway proof on the exact head commit: full production build, isolated onboarding and state, real Gateway process, normal CLI agent turn, direct agent RPC with two concurrent waits plus a cached wait, and UI-style chat.send with two concurrent waits plus a cached wait.
  • Runtime completion proof: three mocked provider requests completed, every wait finished ok, the Gateway remained healthy afterward, and logs contained no crash markers.
  • Runtime timeout proof: a mocked provider accepted the request and intentionally did not respond. Two concurrent waits and a cached wait all returned a terminal timeout; the Gateway remained healthy afterward and logs contained no crash markers.
  • Ephemeral environments were stopped after verification.
  • Exact focused benchmark: 7.16s before and after; one global lifecycle listener replaces one listener per active waiter.
  • Structured Codex autoreview after the collision repair: clean, no accepted/actionable findings.
  • Production diff: 358 lines removed net.

Sanitized process-level results:

{
  "completion": {
    "cliAgent": "ok",
    "agentConcurrentWaits": ["ok", "ok"],
    "agentCachedWait": "ok",
    "chatConcurrentWaits": ["ok", "ok"],
    "chatCachedWait": "ok",
    "providerRequests": 3,
    "gatewayHealthyAfterRuns": true,
    "crashMarkers": false
  },
  "timeout": {
    "agentConcurrentWaits": ["timeout", "timeout"],
    "agentCachedWait": "timeout",
    "gatewayHealthyAfterRun": true,
    "crashMarkers": false
  }
}

AI-assisted: implementation delegated to an agent, then source-reviewed and verified before push.

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui gateway Gateway runtime size: XL maintainer Maintainer-authored PR labels Jul 11, 2026
@obviyus obviyus self-assigned this Jul 11, 2026
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. labels Jul 11, 2026
@clawsweeper

clawsweeper Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 11, 2026, 1:12 AM ET / 05:12 UTC.

Summary
The PR consolidates Gateway lifecycle and dedupe terminal observations plus agent.wait waiter ownership into agent-job.ts, removing the separate dedupe waiter module and handler-level promise race.

PR surface: Source -358, Tests +35. Total -323 across 9 files.

Reproducibility: not applicable. as a user-facing bug reproduction; the duplicated lifecycle ownership is directly established by current source, and the PR's disagreement tests exercise the ordering invariants that motivated the refactor.

Review metrics: 1 noteworthy metric.

  • Terminal-state owners: 2 consolidated to 1. The review-critical architectural change removes one waiter registry and one handler-level reconciliation path, concentrating all ordering responsibility in agent-job.ts.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #104135
Summary: This PR is the active implementation candidate for the explicitly linked lifecycle-ownership issue; the other related wait reports overlap in subsystem but retain distinct higher-level behavior.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Risk before merge

  • [P1] Merging makes agent-job.ts the sole owner of cached terminal run state and concurrent waiter resolution; a future ordering mistake in this module could stale or mis-associate session outcomes across agent/chat run-ID collisions.

Maintainer options:

  1. Approve the canonical lifecycle owner (recommended)
    Accept the session-state risk with the current focused tests, process-level proof, and exact-head green checks after explicit maintainer ownership approval.
  2. Pause the consolidation
    Keep the PR open or close it if maintainers do not want dedupe-derived terminal state owned by the agent job registry.

Next step before merge

  • [P2] A maintainer should make the explicit permanent-owner decision; no automated code repair or additional contributor proof is currently indicated.

Maintainer decision needed

  • Question: Should agent-job.ts become the permanent single owner of Gateway terminal run state and agent.wait resolution?
  • Rationale: Source review can establish correctness, but the protected maintainer label and linked feature issue reserve this durable Gateway ownership boundary for explicit maintainer intent.
  • Likely owner: steipete — Merged history connects this person most strongly to the canonical terminal precedence and Gateway agent-method integration affected by the ownership choice.
  • Options:
    • Adopt the single registry (recommended): Approve the consolidated owner because it removes the competing waiter state machine while preserving current collision and terminal-precedence behavior.
    • Retain split ownership: Keep lifecycle and dedupe waiters separate if maintainers prefer the existing boundary despite its duplicated reconciliation logic.

Security
Cleared: The actual PR surface is internal Gateway TypeScript and tests with no dependency, workflow, permission, secret, install, publishing, or downloaded-code changes.

Review details

Best possible solution:

Approve one canonical agent-job registry as the permanent owner, retaining the shared terminal-outcome merger and focused collision, retry-grace, timeout, cached-wait, and waiter-cleanup coverage as its contract.

Do we have a high-confidence way to reproduce the issue?

Not applicable as a user-facing bug reproduction; the duplicated lifecycle ownership is directly established by current source, and the PR's disagreement tests exercise the ordering invariants that motivated the refactor.

Is this the best way to solve the issue?

Yes. Consolidating the state owner is narrower and more maintainable than extracting or preserving the handler-level race, and the repaired head reuses the canonical precedence helper instead of creating a parallel policy.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 8f8aad9ae692.

Label changes

Label changes:

  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body provides after-fix exact-head process-level Gateway completion and intentional-timeout runs with concurrent and cached agent/chat waits, provider requests, health checks, and sanitized outputs.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove status: ⏳ waiting on author: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P2: This is a bounded but substantial Gateway reliability refactor with no intended external API or user-visible behavior change.
  • merge-risk: 🚨 session-state: The merged code becomes the sole authority for terminal run selection and waiter wakeups across lifecycle, agent, and chat observations.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body provides after-fix exact-head process-level Gateway completion and intentional-timeout runs with concurrent and cached agent/chat waits, provider requests, health checks, and sanitized outputs.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body provides after-fix exact-head process-level Gateway completion and intentional-timeout runs with concurrent and cached agent/chat waits, provider requests, health checks, and sanitized outputs.
Evidence reviewed

PR surface:

Source -358, Tests +35. Total -323 across 9 files.

View PR surface stats
Area Files Added Removed Net
Source 6 402 760 -358
Tests 3 106 71 +35
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 9 508 831 -323

What I checked:

  • Single canonical registry: The exact head stores terminal observations by lifecycle, agent, and chat source, chooses the freshest dedupe source, then applies the existing terminal-outcome merge contract against lifecycle state. (src/gateway/server-methods/agent-job.ts:461, cfb23c88e919)
  • Prior blocker repaired: The second commit adds source timestamps and disagreement tests covering older sticky timeout or cancellation observations followed by newer cross-source completion; the previous freshness finding no longer reproduces from source. (src/gateway/server-methods/agent-wait-dedupe.test.ts:398, cfb23c88e919)
  • Active-chat behavior preserved: Current main intentionally waits only on chat dedupe for an active chat run, and the PR preserves that collision rule through the source: "chat" registry filter rather than admitting stale agent state. (src/gateway/server-methods/agent.ts:4033, cfb23c88e919)
  • Canonical precedence retained: The registry delegates cancellation and hard-timeout precedence to the existing shared terminal-outcome merger instead of rederiving those rules. (src/agents/agent-run-terminal-outcome.ts:211, 8f8aad9ae692)
  • Current exact-head validation: Live GitHub checks for the current head include passing Gateway runtime boundary, build, lint, production and test types, compact Node shards, QA Smoke, security scans, and the real-behavior-proof gate. (cfb23c88e919)
  • Clean three-way surface: The PR merge base is fab69517b3d4ab4e94ec16f7744f2966769ee611; current main has no intervening changes in the nine touched files, so the branch-behind state does not introduce a touched-surface conflict or regression. (8f8aad9ae692)

Likely related people:

  • steipete: Merged history ties Peter Steinberger to the canonical terminal-outcome precedence work and Gateway agent-method integration that this refactor consolidates. (role: introduced terminal precedence and recent Gateway integrator; confidence: high; commits: b1e5c9d7fa16, acb0e9c1552f, c5d6764f5629; files: src/agents/agent-run-terminal-outcome.ts, src/gateway/server-methods/agent-job.ts, src/gateway/server-methods/agent-wait-dedupe.ts)
  • vincentkoc: Merged history shows Vincent Koc introduced the shared run and wait snapshot shapes and narrowed the terminal-outcome helpers used by both former state owners. (role: shared-state refactor contributor; confidence: high; commits: bb673f47b207, e2c745fc5825, dc384393fc8b; files: src/gateway/server-methods/agent-job.ts, src/gateway/server-methods/agent-wait-dedupe.ts, src/agents/agent-run-terminal-outcome.ts)
  • Pick-cat: Merged history shows a focused fix to pending hard-timeout forwarding in waitForAgentJob, directly adjacent to the waiter contract preserved here. (role: recent job-wait reliability contributor; confidence: medium; commits: 61dce7cb6e88; files: src/gateway/server-methods/agent-job.ts, src/gateway/server-methods/agent-job.timeout-fallback.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (6 earlier review cycles)
  • reviewed 2026-07-11T04:16:20.553Z sha 9780726 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-11T04:24:32.122Z sha 9780726 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-11T04:30:52.654Z sha 9780726 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-11T04:38:48.474Z sha 9780726 :: found issues before merge. :: [P1] Preserve freshest terminal result across agent/chat collisions
  • reviewed 2026-07-11T04:46:45.002Z sha 9780726 :: found issues before merge. :: [P1] Preserve freshest terminal result across agent/chat collisions
  • reviewed 2026-07-11T04:53:45.107Z sha 9780726 :: found issues before merge. :: [P1] Preserve newest-source selection for colliding run IDs

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 11, 2026
@obviyus

obviyus commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. labels Jul 11, 2026
@obviyus

obviyus commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 11, 2026
@clawsweeper clawsweeper Bot added status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jul 11, 2026
@obviyus
obviyus merged commit 79bfa37 into main Jul 11, 2026
132 of 140 checks passed
@obviyus
obviyus deleted the refactor/agent-job-lifecycle branch July 11, 2026 05:26
@obviyus

obviyus commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

Landed via squash onto main.

  • Focused Gateway proof: 224 tests passed across agent job, dedupe wait, timeout fallback, and shared server-method coverage.
  • Exact-head path gate: core/core-test types, targeted lint, and relevant guards passed.
  • Process proof: production build plus isolated real Gateway CLI, agent RPC, chat.send, concurrent waits, cached waits, provider timeout, and post-run health all passed without crash markers.
  • Structured Codex autoreview: clean after the collision and lifecycle repairs.
  • Fresh-head GitHub CI: zero failures.
  • Changelog: not required; internal refactor with no intended user-visible behavior change.
  • Merge commit: 79bfa37

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 11, 2026
* refactor(gateway): centralize agent wait lifecycle
* fix(gateway): preserve agent wait freshness

---------

Co-authored-by: Ayaan Zaidi <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui gateway Gateway runtime maintainer Maintainer-authored PR merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: XL status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Unify agent.wait lifecycle ownership

1 participant