fix(cron): correct coachhelm-safety-net/validation cadence drift - #923
fix(cron): correct coachhelm-safety-net/validation cadence drift#923njrini99-code wants to merge 1 commit into
Conversation
vercel.json scheduled both weekly (0 4 * * 0 / 0 6 * * 0) while their own route header comments say every-30-min and hourly (15 * * * *) respectively — a silent config drift that stranded stuck rounds and un-validated predictions for up to 7 days instead of minutes (#920, cause #1). Both scans are cheap no-ops when nothing is pending, and this Vercel team is on Pro (already running */5 and hourly crons), so there's no plan-limit blocker. - vercel.json: safety-net -> */30 * * * *, validation -> 15 * * * * (15 * * * * taken verbatim from the validation route's own header comment, which overrides the originally-proposed 0 * * * *) - cron-registry.ts: cadenceMinutes updated to 30 / 60 so the Bridge health tab's overdue threshold (1.5x cadence) matches reality instead of flagging a healthy job as fine for days after it dies Fixes #920 (config part only; the other four staleness causes in that issue are separate follow-ups). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MMdviLDsAg2YYJ8adsM6fg
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing |
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Summary by CodeRabbit
WalkthroughUpdated the validation and safety-net cron jobs from weekly schedules to hourly and 30-minute cadences, aligning Vercel execution schedules with registry-based status classification. The calibration job remains daily and unchanged. ChangesCron cadence alignment
Estimated code review effort: 1 (Trivial) | ~5 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 11 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (11 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ast-grep (0.44.1)ast-grep could not parse rule config: /ast-grep-rules/../git/.coderabbit/ast-grep/no-explicit-any.yml 🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🤖 Mission Control — PR summary What it changes: Risk / areas: Watch: cron expression correctness; confirm the added cadence doesn't trip a Vercel cron-count limit; that the Bridge overdue math reads the new cadences. CI: ✅ green so far — 34 checks passing, 4 pending, 0 failing; mergeable state CLEAN. Labeled |
Problem
vercel.jsonscheduledcoachhelm-safety-netandcoachhelm-validationweekly (0 4 * * 0/0 6 * * 0), but each route's own header comment states the intended cadence:coachhelm-safety-net— "Schedule: every 30 min (see vercel.json)."coachhelm-validation— "Schedule:15 * * * *(see vercel.json)."This is config drift, not a design change — the route files never moved off their intended cadence,
vercel.jsondid. Per issue #920 (cause #1): when a round'safter(postRoundTrigger)call dies silently (cold start, timeout), the safety-net re-trigger — meant to catch it within 30 minutes — instead waits up to 7 days. Same for un-validated predictions sitting pastdue_date. Meanwhile the (correctly daily) lifecycle cron keeps archiving old insights, so the visible symptom is "everything looks stale and nothing replaces it."Both jobs are cheap no-op scans when nothing is pending — safety-net does a state-column filtered query (
analyzed_at/failed_atboth null) capped at 200 rows/5 concurrency, well inside the 300s function budget; validation pulls due-and-unvalidated predictions capped at 500 rows. Neither does meaningful work on a quiet cadence.Fix
vercel.json:coachhelm-safety-net:0 4 * * 0→*/30 * * * *coachhelm-validation:0 6 * * 0→15 * * * *(taken verbatim from the route's own header comment — this overrides the0 * * * *originally floated for this fix, per "route comments win" instruction)src/lib/admin/cron-registry.ts:cadenceMinutesfor both jobs updated fromWEEKLYto30and60respectively, so the Bridge health tab's overdue threshold (1.5× cadence, inclassifyCronStatus) matches the real schedule instead of tolerating up to ~10 days of silence before flagging either job as overdue.Plan-limit check: this Vercel team (
nick-rinis-projects) is on a paid plan —vercel.jsonalready runsrefresh-engagementat*/5 * * * *andevent-reminders/task-remindersat0 * * * *in production today, so sub-hourly/hourly cadence is not a Hobby-plan (2 crons/day) blocker here.Scope note: this PR is the config part only of #920. The other four staleness causes in that issue (silent
alert_posture, legacy dedup cooldown, stats-cache race, roster-sweep 12h-per-player skip) are separate follow-ups, not touched here.Gates (run in the worktree)
npx tsc --noEmit -p tsconfig.json— passnpx eslint src/lib/admin/cron-registry.ts src/lib/admin/__tests__/cron-registry.test.ts src/app/api/cron/__tests__/cron-job-log-coverage.test.ts— passnpx vitest run src/lib/admin/__tests__/cron-registry.test.ts src/app/api/cron/__tests__/cron-job-log-coverage.test.ts— 8 files / 24 tests pass (includes theCRON_REGISTRY ↔ vercel.jsonpath-contract test)npx vitest run src/test/api/cron/coachhelm-safety-net.test.ts src/test/api/cron/coachhelm-validation.test.ts— 8 files / 48 tests pass (route behavior unaffected — no route code touched)Fixes #920 (config part only).
🤖 Generated with Claude Code