Skip to content

unify overdue-prompt logic so the Sentry alert matches the dashboard#446

Merged
jrhizor merged 1 commit into
mainfrom
jrhizor/overdue-prompts-no-sentry-alert
Jul 10, 2026
Merged

unify overdue-prompt logic so the Sentry alert matches the dashboard#446
jrhizor merged 1 commit into
mainfrom
jrhizor/overdue-prompts-no-sentry-alert

Conversation

@jrhizor

@jrhizor jrhizor commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Problem

A deployment had ~300 prompts shown overdue on the admin dashboard but got no Sentry alert, despite #442 shipping the overdue alert.

Root cause: the alert and the dashboard disagreed on what "overdue" means.

  • Dashboard / scheduler (admin.ts, schedule-maintenance.ts) judge per-model: a prompt is overdue if any configured model is past cadence or has never run.
  • Alert (reportOverduePrompts) judged per-prompt off Math.max(...runTimes) — the single most-recent run across all models.

Failed runs write no prompt_runs row (savePromptRun only runs on success), so a broken model is simply absent from the last-runs map. The dashboard flags that prompt; the alert's Math.max picks a healthy model's fresh timestamp and sees nothing wrong. When every overdue prompt is the "one provider down, others fine" kind, the alert computes 0 and returns before ever calling Sentry.

Change

Extract one per-model definition into @workspace/lib/overdue and route all three consumers through it:

Consumer Before After
Dashboard (admin.ts) inline per-model loop getModelOverdueStatus (grace 0) — behavior identical
Scheduler self-healing loop inline per-model loop isPromptOverdue (grace 0) — behavior identical
Alert (reportOverduePrompts) Math.max across all models isPromptOverdue (grace 30m) — now matches the dashboard

The alert keeps its 30-minute grace window (now a graceMs parameter) so jitter and freshly-created prompts don't page; the dashboard passes no grace, so its numbers are unchanged. The only remaining gap is the boundary — a prompt overdue by <30 min shows on the dashboard but doesn't page.

Also removed the stale Runs every 6 hours doc comment; the real schedule is */5 * * * * in the worker entrypoint.

Notes

  • This makes the alert fire for the partial-provider case, but it still only pages if SENTRY_DSN is set in the worker's environment (optional; without it the worker skips Sentry.init() and every capture is a no-op).
  • No changeset: internal ops/monitoring, no user-facing behavior change (dashboard output is identical).

Test plan

  • apps/web + apps/worker tsc --noEmit clean
  • @workspace/lib suite green, incl. new overdue.test.ts covering the fresh-on-one-model / never-run-on-another case and the dashboard-equivalence (grace 0)

The overdue Sentry alert judged a prompt by the most recent run across all
its models (Math.max), while the dashboard and scheduler judge per-model and
treat a model with no recorded run as overdue. Because failed runs write no
prompt_runs row, a prompt broken on one provider but still running on another
looked fresh to the alert, so it never fired even with hundreds of prompts
shown overdue.

Extract one per-model definition into @workspace/lib/overdue and use it in the
dashboard, the scheduler's self-healing pass, and the alert. The alert keeps
its 30-minute grace window (now a graceMs parameter); the dashboard uses no
grace, so behavior there is unchanged.

Also drop the stale "runs every 6 hours" comment — the schedule is every 5
minutes in the worker entrypoint.
@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
elmo Ready Ready Preview, Comment Jul 10, 2026 9:36pm

Request Review

@jrhizor jrhizor merged commit fad33cd into main Jul 10, 2026
9 checks passed
@jrhizor jrhizor deleted the jrhizor/overdue-prompts-no-sentry-alert branch July 10, 2026 21:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant