fix(cron): abort superseded reconciliation hooks#104368
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e556346961
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ) { | ||
| return; | ||
| } | ||
| await params.runHook(event, { |
There was a problem hiding this comment.
Preserve ordered delivery for legacy cron hooks
When an existing cron_reconciled plugin handler performs a durable external projection but has not yet been updated to honor the new abortSignal, a slow startup handler can now continue after a reload handler and overwrite the newer scheduler snapshot. The previous dispatchTail serialized generations so the reload callback ran after the stale callback settled; this call now lets both run concurrently, and abort is only advisory to plugin code. For shipped/external plugins using the existing hook contract, this can turn a reload from current-wins into stale-wins, so keep legacy ordered delivery or make the concurrent/abort-driven behavior opt-in.
Useful? React with 👍 / 👎.
|
Codex review: needs real behavior proof before merge. Reviewed July 11, 2026, 6:12 AM ET / 10:12 UTC. Summary PR surface: Source +17, Tests +41, Docs +9, Other 0. Total +67 across 8 files. Reproducibility: yes. Current main's Review metrics: 1 noteworthy metric.
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:
Next step before merge
Security Review detailsBest possible solution: Land a single first-release hook contract in which each exact scheduler snapshot owns an abort signal, newer snapshots dispatch without stale head-of-line blocking, and durable consumers pass the signal through every side effect and reject post-abort acceptance. Do we have a high-confidence way to reproduce the issue? Yes. Current main's Is this the best way to solve the issue? Yes. Because the hook has not shipped, lifecycle-owned cancellation plus immediate replacement dispatch is the narrowest canonical fix; retaining or adding an opt-in legacy ordering mode would preserve the reported bug and create unnecessary parallel behavior. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against c702719eda74. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +17, Tests +41, Docs +9, Other 0. Total +67 across 8 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
|
|
Land-ready verification on the current head
Known proof gaps: none for the OpenClaw hook contract. Host-specific durable projection acceptance remains integration-owned and is not required for this nonblocking lifecycle hook. |
|
Merged via squash.
|
* origin/main: fix(cron): abort superseded reconciliation hooks (#104368) ci(release): expose Telegram runtime preflight stage (#104387) fix(status): avoid false shell-wrapper audit warnings (#81778) fix: retry live Gateway readiness proof (#104374) fix(exec-approval): stop misattributing Allow Always unavailability to policy (#97740) fix: preserve Mac bundle during live builds (#104376) chore(docs): translate with GPT-5.6 xhigh test: wire Control UI suite into CI, fix its broken tests, drop dead harness surface (#104361) fix(ui): hide group submenu separator when New group is the only entry (#104370) fix(discord): reset progress drafts across queued turns (#102341) docs(cli): clarify that exec-policy show and approvals get exclude per-session /exec overrides (#94999) fix(discord): single-source thread-binding default placement and guard artifact parity (#104342) fix(agents): add tool-activity heartbeat to keep subagent alive during tool calls (#95536) fix(maint): reuse recent same-PR hosted gates (#104355)
* fix(cron): abort superseded reconciliation hooks * fix(ci): align plugin SDK surface budget
* origin/main: fix(cron): abort superseded reconciliation hooks (openclaw#104368) ci(release): expose Telegram runtime preflight stage (openclaw#104387) fix(status): avoid false shell-wrapper audit warnings (openclaw#81778) fix: retry live Gateway readiness proof (openclaw#104374) fix(exec-approval): stop misattributing Allow Always unavailability to policy (openclaw#97740) fix: preserve Mac bundle during live builds (openclaw#104376) chore(docs): translate with GPT-5.6 xhigh test: wire Control UI suite into CI, fix its broken tests, drop dead harness surface (openclaw#104361) fix(ui): hide group submenu separator when New group is the only entry (openclaw#104370) fix(discord): reset progress drafts across queued turns (openclaw#102341) docs(cli): clarify that exec-policy show and approvals get exclude per-session /exec overrides (openclaw#94999) fix(discord): single-source thread-binding default placement and guard artifact parity (openclaw#104342) fix(agents): add tool-activity heartbeat to keep subagent alive during tool calls (openclaw#95536) fix(maint): reuse recent same-PR hosted gates (openclaw#104355)
Fixes #104363
AI-assisted implementation; maintainer-reviewed and source-verified.
What Problem This Solves
Fixes an issue where operators projecting OpenClaw cron wakes into an external scheduler could retain a stale projection when a startup callback was still retrying during cron reload.
The newer
cron_reconciledcallback was serialized behind the stale callback, so it could not promptly abort the older durable host write or adopt the replacement scheduler.Why This Change Was Made
Each reconciled scheduler snapshot now owns an
AbortSignal. Arming a newer scheduler or closing the Gateway aborts the previous signal immediately, and the replacement reconciliation dispatches without waiting behind stale observer work.The public hook context and safe projection example carry that lifecycle-owned signal through durable acceptance. The change does not turn observation hooks into readiness-critical services and does not add a second cron authority.
User Impact
Scale-to-zero and external-scheduler integrations can supersede stale cron projections promptly during reload. A slow or retrying prior callback no longer hides the current scheduler snapshot.
Evidence
pnpm test src/gateway/server-cron-reconciled.test.ts src/plugins/wired-hooks-gateway.test.ts(19 assertions passed).check:changedgate passed.