Skip to content

fix(cron): correct coachhelm-safety-net/validation cadence drift - #923

Closed
njrini99-code wants to merge 1 commit into
mainfrom
fix/coachhelm-cron-cadence
Closed

fix(cron): correct coachhelm-safety-net/validation cadence drift#923
njrini99-code wants to merge 1 commit into
mainfrom
fix/coachhelm-cron-cadence

Conversation

@njrini99-code

Copy link
Copy Markdown
Owner

Problem

vercel.json scheduled coachhelm-safety-net and coachhelm-validation weekly (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.json did. Per issue #920 (cause #1): when a round's after(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 past due_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_at both 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 * * 015 * * * * (taken verbatim from the route's own header comment — this overrides the 0 * * * * originally floated for this fix, per "route comments win" instruction)
  • src/lib/admin/cron-registry.ts: cadenceMinutes for both jobs updated from WEEKLY to 30 and 60 respectively, so the Bridge health tab's overdue threshold (1.5× cadence, in classifyCronStatus) 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.json already runs refresh-engagement at */5 * * * * and event-reminders/task-reminders at 0 * * * * 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 — pass
  • npx 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 — pass
  • npx 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 the CRON_REGISTRY ↔ vercel.json path-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

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
@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
helmv3 Ignored Ignored Jul 17, 2026 8:58pm

Request Review

@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

@cursor

cursor Bot commented Jul 17, 2026

Copy link
Copy Markdown

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.

@supabase

supabase Bot commented Jul 17, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project qmnssrrolpinvwjjnufo because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: cb29aca8-dd8a-4396-951e-a8c6eeb45249

📥 Commits

Reviewing files that changed from the base of the PR and between 6d25e44 and aba1bc1.

📒 Files selected for processing (2)
  • src/lib/admin/cron-registry.ts
  • vercel.json

Summary by CodeRabbit

  • Bug Fixes
    • Updated validation checks to run hourly.
    • Updated safety-net checks to run every 30 minutes.
    • Adjusted monitoring so these jobs are correctly recognized as on schedule rather than overdue.

Walkthrough

Updated 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.

Changes

Cron cadence alignment

Layer / File(s) Summary
Schedule and status cadence updates
src/lib/admin/cron-registry.ts, vercel.json
coachhelm-validation now uses a 60-minute cadence and runs at minute 15 of every hour; coachhelm-safety-net now uses a 30-minute cadence and runs every 30 minutes. coachhelm-calibration remains unchanged.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

Suggested labels: ci

🚥 Pre-merge checks | ✅ 11 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title matches the cron drift fix, but it uses the unsupported scope cron instead of an allowed Conventional Commits scope. Change the scope to an allowed value such as coachhelm, e.g. fix(coachhelm): correct coachhelm-safety-net/validation cadence drift.
✅ Passed checks (11 passed)
Check name Status Explanation
Description check ✅ Passed The description accurately describes the cron schedule drift fix and the matching cadenceMinutes updates.
Linked Issues check ✅ Passed The PR satisfies the linked issue’s cron-cadence objective by updating both schedules and aligning health thresholds.
Out of Scope Changes check ✅ Passed The only changes are the two cron schedule files, and both are directly in scope for the cadence-drift fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
No Service-Role In Client Bundles ✅ Passed Changed files are only cron-registry.ts:12-16 and vercel.json:39-50 schedule updates; no SUPABASE_SERVICE_ROLE_KEY or service-role client usage found.
Rls Coverage On New Tables ✅ Passed PR diff changes only src/lib/admin/cron-registry.ts and vercel.json; no migrations were touched, so the RLS rule is not applicable.
Auth Check In Server Actions ✅ Passed No changed files match src/app//actions//*.ts; only src/lib/admin/cron-registry.ts and vercel.json changed, so the auth-order check is not applicable.
Sport-Prefixed Table Names ✅ Passed src/lib/admin/cron-registry.ts:1-44 only defines cron metadata/status logic; no Supabase queries or table names appear in changed TS/TSX files.
No Destructive Writes ✅ Passed PASS: Changed files are only cron config constants (cron-registry.ts:12-31, vercel.json:39-111); no save/submit/sync path or DELETE+INSERT sequence exists.
No Edits To Historical Migrations ✅ Passed Diff only changes src/lib/admin/cron-registry.ts:12-16 and vercel.json:39-51; no supabase/migrations paths appear in the merge-base diff.
Conventional Commits ✅ Passed HEAD subject fix(cron): correct coachhelm-safety-net/validation cadence drift matches the Conventional Commits rule in .coderabbit.yaml:405-409; no contradiction found.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/coachhelm-cron-cadence
  • 🛠️ helm safety pass
  • 🛠️ dashboard ux pass
  • 🛠️ rls test pass

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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the ci CI, Vercel, test, build, deploy label Jul 17, 2026
@njrini99-code

Copy link
Copy Markdown
Owner Author

🤖 Mission Control — PR summary

What it changes: vercel.json scheduled the CoachHelm safety-net (0 4 * * 0) and prediction-validation (0 6 * * 0) crons as weekly, while both route header comments intend every-30-min and hourly. This corrects the drift: safety-net → */30 * * * *, validation → 15 * * * *, and updates cron-registry.ts cadenceMinutes to 30/60 so the Bridge health tab's overdue threshold (1.5× cadence) matches reality. Fixes the config portion of #920 (stuck rounds / un-validated predictions were stranded up to 7 days).

Risk / areas: vercel.json cron schedule, cron-registry.ts, Bridge health tab. Both scans are cheap no-ops when nothing is pending; this Vercel team is on Pro (already runs */5 crons) so no plan-limit blocker.

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 ci. Awaiting required review.

@njrini99-code

Copy link
Copy Markdown
Owner Author

Superseded — landed on main inside merge train #938 (commit a842bd7 within 6ecede6). Branch kept.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci CI, Vercel, test, build, deploy

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[QA] Why insights go stale — five concrete causes, ranked (safety-net cron weekly, silent posture, legacy dedup, cache race, sweep skip)

1 participant