fix(cron): skip completed restart catchup slots#101998
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 17, 2026, 9:15 PM ET / July 18, 2026, 01:15 UTC. Summary PR surface: Source +44, Tests +156. Total +200 across 4 files. Reproducibility: yes. from source and supplied real-service evidence: a persisted due cron slot with Review metrics: none identified. 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:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the bounded scheduler fix after normal exact-head maintainer review, preserving the inclusive slot comparison and its coverage for stale completed, later-missed, and exact-restart-boundary cron slots. Do we have a high-confidence way to reproduce the issue? Yes, from source and supplied real-service evidence: a persisted due cron slot with Is this the best way to solve the issue? Yes. The inclusive previous-slot helper is the narrow maintainable solution because it fixes the stale-completed-slot replay without losing the later missed slot or the slot due exactly at restart. AGENTS.md: unclear because the file could not be read completely. Codex review notes: model internal, reasoning high; reviewed against 1c331b9b0ff3. Label changesLabel justifications:
Evidence reviewedPR surface: Source +44, Tests +156. Total +200 across 4 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
|
|
I think this branch still has one restart-boundary gap before it becomes the canonical fix for #101988. Best-fix comparison:
The concrete issue I see in this branch is the exact-boundary case. This patch falls through from the due So with a persisted minutely cron state like I would not treat this as the best final fix unless it ports the boundary replay coverage/fix from #102004 or explicitly proves that due-exactly-at-restart cron slots are intentionally outside startup catch-up. The strongest canonical path looks like combining this PR's real CronService proof with #102004's boundary-preserving test shape. |
|
A/B verified locally against base SHA. Ran vitest with the PR's test file against the PR's fix (B) and against the base's fix (A). Result: CLEAN A/B The new test |
Co-authored-by: 李兰 0668001394 <[email protected]> Co-authored-by: NianJiuZst <[email protected]>
d279df5 to
17a48ce
Compare
|
Merged via squash.
|
* fix(cron): preserve exact restart boundaries Co-authored-by: 李兰 0668001394 <[email protected]> Co-authored-by: NianJiuZst <[email protected]> * fix(cron): suppress skipped restart slots --------- Co-authored-by: Peter Steinberger <[email protected]> Co-authored-by: NianJiuZst <[email protected]>
Closes #101988
What Problem This Solves
Gateway restart catch-up could treat a stale persisted cron
nextRunAtMsas runnable before checking whether the job had already completed that schedule slot. For isolated agent-turn cron jobs, this could defer and rerun a successful daily reminder after restart, causing duplicate notifications.Why This Change Was Made
The runnable check now recognizes the specific restart state where a cron job has a due
nextRunAtMs,lastRunStatus: ok, andlastRunAtMsalready covers that due slot. Instead of immediately marking the job runnable, it falls through to the existing previous-slot guard so only genuinely missed later slots are replayed. Failed or skipped jobs still keep their existing retry behavior.User Impact
Users should no longer receive duplicate isolated-agent cron messages after restarting the Gateway when the current schedule tick already ran successfully. Legitimate missed cron work and failure retry paths remain eligible for catch-up.
Evidence
node scripts/run-vitest.mjs src/cron/service.restart-catchup.test.ts src/cron/service/timer.regression.test.tsgit diff --checkReal behavior proof
Behavior addressed: Restart catch-up skips a stale due cron slot when the isolated agent-turn job already completed that slot successfully.
Environment tested: Linux, Node v22.22.0, local source checkout on branch
fix/101988-cron-catchup-window, isolated temporaryOPENCLAW_HOMEandOPENCLAW_STATE_DIR.Steps run after the patch: Created a real cron store with an isolated agent-turn cron job whose persisted
nextRunAtMswas 2025-12-13 09:10 UTC,lastRunStatuswasok, andlastRunAtMswas 2025-12-13 09:10:30 UTC; started the productionCronServiceat 2025-12-13 11:00 UTC and listed the stored job.Evidence after fix:
Observed result after the fix: Gateway startup did not run or defer the already-completed isolated agent-turn slot; no agent job, heartbeat, or started event was emitted, and the job advanced to the next natural daily cron slot.
Not tested: A live macOS Gateway restart with real channel delivery credentials was not exercised locally.