78 scheduled jobs across two systems. Each job lives in exactly one.
Fonteum runs scheduled work across two cron systems: Inngest (for jobs that need step-level retries, event emission, or observability) and Vercel cron (for lightweight HTTP-only operations). Ownership is decided by the AGENTS.md §cron-doctrine decision tree; the tools/cron-ownership-check.sh CI gate blocks any job that lands in both systems or is missing from this page.
Step-orchestrated work — retries, observability, event emission.
Inngest owns work that needs structured failure handling. Source pullers (network can flap), identity-linker (multi-step batch), webhook-deliverer (per-recipient retry), and citation-discoverer (rate-limited external API) all rely on Inngest’s step primitives + dashboard observability.
| Job ID | Schedule (UTC) | Source file | Purpose |
|---|---|---|---|
ai-content-qa | 0 20 * * 0 | src/inngest/functions/ai-content-qa.ts | Weekly Sunday 20:00 UTC AI content-QA: flag-gated (AI_CONTENT_QA_ENABLED=1). Classifies money pages as ok/thin/stale/duplicate; writes proposals to ai_review_queue. Never edits live pages. |
ai-entity-summaries | 0 22 * * 0 | src/inngest/functions/ai-entity-summaries.ts | Weekly Sunday 22:00 UTC AI entity-summary scaffold: flag-gated (AI_ENTITY_SUMMARIES_ENABLED=1, default OFF). Scaffold only — no-ops until implementation is reviewed. Writes to ai_review_queue only. |
ai-link-suggestions | 0 21 * * 0 | src/inngest/functions/ai-link-suggestions.ts | Weekly Sunday 21:00 UTC AI embedding-based link suggestions: flag-gated (AI_LINK_SUGGESTIONS_ENABLED=1). Uses OpenAI text-embedding-3-small to find semantically similar pages; writes link proposals to ai_review_queue. Never modifies live pages. |
care-compare-asc-monthly | 0 6 1 * * | src/inngest/functions/care-compare-asc-monthly.ts | Monthly CMS Care Compare ASC refresh reminder; emits fonteum/source.refresh_due for the operator-triggered ASC ingest. |
care-compare-dialysis-monthly | 0 6 1 * * | src/inngest/functions/care-compare-dialysis-monthly.ts | Monthly CMS Care Compare Dialysis refresh reminder; emits fonteum/source.refresh_due for the operator-triggered dialysis ingest. |
compliance-change-detector | 0 5 * * * | src/inngest/functions/compliance-change-detector.ts | §pillar5-compliance-change-feed — daily 05:00 UTC. Diffs current in-force exclusion / compromised-flag / ownership (CHOW) facts against the compliance_change_events watermark; records new LEIE/SAM/state exclusions, OIG CIAs, CMS penalties, and CHOW ownership changes; fans out fonteum/compliance.change_detected for subscribers. |
cwv-anomaly-monitor | 0 11 * * * | src/inngest/functions/cwv-anomaly-monitor.ts | Daily 11:00 UTC CWV + data-freshness anomaly monitor: runs PageSpeed Insights against curated pages, checks row-count baselines on key tables, writes anomaly rows to selfheal_anomaly_log, and alerts operator on regressions. |
citation-discoverer | 0 9 * * * | src/inngest/functions/citation-discoverer.ts | Daily OpenAlex poll for papers citing Fonteum data; populates discovered_citations moderation queue. |
daily-refresh-stale-check | 0 9 * * * | src/inngest/functions/source-refresh-reminders.ts | Logs sources that have not refreshed within their declared cadence; surfaces in /freshness degraded badge. |
health-check | 0 7 * * * | src/inngest/functions/health-check.ts | Daily Inngest dashboard ping confirming the function-registration round-trip is alive. |
link-404-watchdog | 0 1 * * * | src/inngest/functions/link-404-watchdog.ts | Daily 01:00 UTC 404/broken-link watchdog: HEADs sitemap URLs, queues 404s in selfheal_redirect_queue with auto-inferred redirect destinations where safe. Operator reviews + approves before any redirect is promoted. |
identity-linker | */5 * * * * | src/inngest/functions/identity-linker.ts | Polling job that resolves NPI ↔ PECOS-ID ↔ CCN ↔ LEIE provider identity links in batches. |
indexnow-retry-nightly | 0 2 * * * | src/inngest/functions/indexnow-retry-nightly.ts | Nightly retry of failed IndexNow URL submissions persisted to failed_indexnow_submissions (F-12). |
m16-ai-referral-share | 0 22 * * 0 | src/inngest/functions/moat-m16-ai-referral.ts | Weekly Sunday 22:00 UTC AI referral traffic share: pulls Plausible referral data for AI assistants and writes an ai_referral_share row to moat_metrics. |
m4-fhir-api-usage | 0 8 * * 1 | src/inngest/functions/moat-m4-fhir-api-usage.ts | Weekly Monday 08:00 UTC FHIR API usage tracker: reads 7d of fhir_request_logs, classifies requests by user-agent class and FHIR resource type, and writes fhir_api_usage rows to moat_metrics. |
m6-press-mentions | 0 11 * * 1 | src/inngest/functions/moat-m6-press-mentions.ts | Weekly Monday 11:00 UTC press-mention tracker: queries DataForSEO News for brand mentions, dedupes by URL, enriches each domain with its DR, and writes press_mention rows to moat_metrics. |
m7-email-list-growth | 0 7 * * 1 | src/inngest/functions/moat-m7-email-list-growth.ts | Weekly Monday 07:00 UTC email-list growth tracker: reads email_subscribers, computes new/unsub/total by source over the trailing 7 days, and writes email_list_growth rows to moat_metrics. |
m8-internal-link-health | 0 8 * * 1 | src/inngest/functions/moat-m8-internal-link-health.ts | Weekly Monday 08:00 UTC internal-link graph audit: crawls the sitemap, counts inbound internal links per page, and writes orphan/violation/healthy/avg_inbound rows (doctrine G7) to moat_metrics. |
m9-topical-authority | 0 1 1 * * | src/inngest/functions/moat-m9-topical-authority.ts | Monthly (1st, 01:00 UTC) topical-authority score: counts pages with GSC impressions per topic cluster and records newest-page rank, writing topical_authority rows to moat_metrics. |
m13-performance-regression | 0 6 * * 1 | src/inngest/functions/moat-m13-performance-regression.ts | Weekly Monday 06:00 UTC performance-regression monitor: runs PageSpeed Insights against curated pages and writes per-metric LCP/INP/CLS/FCP/TBT pass/fail rows (doctrine G3) to moat_metrics. |
m15-dataforseo-spend | 0 9 * * 1 | src/inngest/functions/moat-m15-dataforseo-spend.ts | Weekly Monday 09:00 UTC DataForSEO spend tracker: queries the account balance API and writes balance + burn_rate rows (cost_dataforseo) to moat_metrics; alerts when balance < $10. |
moat-m1-ai-citation | 0 4 * * 2 | src/inngest/functions/moat-m1-ai-citation.ts | Weekly Tuesday 04:00 UTC AI citation-count tracker: queries assistants for Fonteum dataset citations and writes an ai_citation_count row to moat_metrics (headline moat metric). |
moat-m11-fhir-empty | 0 * * * * | src/inngest/functions/moat-m11-fhir-empty.ts | Hourly FHIR empty-bundle monitor: GETs each FHIR resource endpoint and flags any that return an empty Bundle (total=0), writing a fhir_empty_resource row to moat_metrics. |
m19-velocity | 0 23 * * 0 | src/inngest/functions/moat-m19-velocity.ts | Weekly Sunday 23:00 UTC founder-velocity metric: counts merged PRs + route/table growth over the trailing 7 days (GitHub API) and writes an m19_velocity row to moat_metrics. |
m2-research-scorecard | 0 3 * * 1 | src/inngest/functions/moat-m2-research-scorecard.ts | Weekly Monday 03:00 UTC research-study scorecard: classifies each published study as compounding or decaying from GSC impression trend and writes a research_scorecard row to moat_metrics. |
m17-doctrine-pass-rate | 0 4 * * 1 | src/inngest/functions/moat-m17-doctrine-pass-rate.ts | Weekly Monday 04:00 UTC doctrine-gate pass-rate metric: runs the doctrine gates across research/methodology pages and writes an m17_doctrine_pass_rate row to moat_metrics. |
m18-fhir-partner-ping | 30 8 * * 1 | src/inngest/functions/moat-m18-fhir-partner-ping.ts | Weekly Monday 08:30 UTC FHIR partner-ping tracker: reads 7d of fhir_request_logs, flags requests from enterprise healthcare-data vendor user-agents (Komodo, Definitive, Verisys, …) as enterprise probes, and writes alert-fired m18_fhir_partner_ping rows to moat_metrics (acqui-hire diligence signal). |
moat-digest-weekly | 0 1 * * 1 | src/inngest/functions/moat-digest-weekly.ts | Weekly Monday 01:00 UTC (09:00 PHT) founder digest: reads 14d of moat_metrics, computes top-3 movers + week-over-week deltas across all 19 metrics, collects fired alerts, and emails the summary via Resend to MOAT_DIGEST_RECIPIENT. |
methodology-publisher | 0 7 * * * | src/inngest/functions/methodology-publisher.ts | Detects methodology version bumps + emits fonteum/methodology.published event for downstream consumers. |
moat-m10-route-integrity | 0 */6 * * * | src/inngest/functions/moat-m10-route-integrity.ts | Every-6-hours route integrity check across all CRITICAL_ROUTES; emails operator if any route returns 404/500 or a FHIR bundle returns total=0. |
moat-m3-snapshot-depth | 0 1 * * 1 | src/inngest/functions/moat-m3-snapshot-depth.ts | Weekly Monday 01:00 UTC snapshot historical-depth metric: counts retained research_snapshots vintages per dataset and writes a snapshot_depth row to moat_metrics (the data-moat metric). |
moat-m5-claim-volume | 0 2 * * 1 | src/inngest/functions/moat-m5-claim-volume.ts | Weekly Monday 02:00 UTC claim-volume + badge-embed-rate snapshot: counts total/7d/30d claimed facilities, writes a claim_volume row to moat_metrics (network-effect curve). |
records-request-reminders | 0 8 * * * | src/inngest/functions/records-request-reminders.ts | Scans outstanding public-records requests; emails operator when SLA breach is imminent (e.g. AZ ROC PR-0006673). |
seo-schema-watchdog | 0 3 * * * | src/inngest/functions/seo-schema-watchdog.ts | Daily 03:00 UTC SEO/schema regression watchdog: fetches curated production pages, validates title/meta/H1/canonical/JSON-LD presence, runs a cross-page duplicate-title/duplicate-meta-description pass, writes results to selfheal_seo_checks, and alerts operator on failures. |
snapshot-staleness-watchdog | 0 4 * * * | src/inngest/functions/snapshot-staleness-watchdog.ts | Daily 04:00 UTC research_snapshots staleness watchdog: for each active snapshot-bearing source, compares the freshest snapshot_date against the source's own refresh_cadence_days, writes snapshot_stale rows to selfheal_anomaly_log, and alerts operator when any provenance snapshot has gone stale. |
sitemap-orphan-audit | 0 5 * * 3 | src/inngest/functions/sitemap-orphan-audit.ts | Weekly Wednesday 05:00 UTC sitemap/orphan/internal-link audit: flags orphan pages (0 inbound), pages below the 3-link doctrine threshold, and sitemap URLs returning 404. Writes to selfheal_page_audit. |
refresh-reminder-<family> | per-source from cron-sources.cron_expression | src/inngest/functions/source-refresh-reminders.ts | Family-specific cadence reminder that nags the operator to refresh a source on schedule (NPPES, Care Compare, etc.). |
source-health-monitor | */15 * * * * | src/inngest/functions/source-health-monitor.ts | HEAD probe per source upstream URL; flips source_health_status row + emits fonteum/source.health_status_changed. |
source-schema-drift-monitor | 0 8 * * 1 | src/inngest/functions/source-schema-drift-monitor.ts | Weekly Monday 08:00 UTC schema-fingerprint check per registered source (URL resolves + file format + depended-on columns present). Records drift to source_schema_drift and fails loud when a publisher changes a column/format/URL. |
source-puller-bea-regional | 0 6 1 10 * | src/inngest/functions/source-puller-bea-regional.ts | Annual October BEA Regional pull — area-level GDP + per-capita income. |
source-puller-bls-oews | 0 6 1 5 * | src/inngest/functions/source-puller-bls-oews.ts | Annual May BLS OEWS pull — occupational employment + wage statistics. |
source-puller-hrsa-hpsa | 0 6 1 1,4,7,10 * | src/inngest/functions/source-puller-hrsa-hpsa.ts | Quarterly HRSA HPSA pull — Health Professional Shortage Area designations. |
source-puller-leie | 0 6 1 * * | src/inngest/functions/source-puller-leie.ts | Monthly OIG LEIE pull — federal program exclusions list. |
source-puller-pecos | 0 6 * * 0 | src/inngest/functions/source-puller-pecos.ts | Weekly Sunday CMS PECOS PPEF pull — Medicare provider enrollment status. |
event-emitterevent: fonteum/source.snapshot_inserted | event | src/inngest/functions/event-emitter.ts | Fans source-snapshot-inserted events into downstream consumers (webhook-deliverer, methodology-publisher). |
refresh-manual-triggerevent: source.refresh.manual_triggered | event | src/inngest/functions/source-refresh-reminders.ts | Operator-fired manual refresh of a source family — re-runs the puller out-of-cadence. |
webhook-delivererevent: webhook.delivery.queued | event | src/inngest/functions/webhook-deliverer.ts | Per-recipient webhook delivery with backoff retry; consumes events emitted by the source-snapshot pipeline. |
dataset-snapshot-webhook-fanoutevent: fonteum/source.snapshot_inserted | event | src/inngest/functions/dataset-snapshot-webhook-fanout.ts | Pillar 5 dataset webhooks — fans each new source snapshot to one delivery event per active dataset.snapshot_published subscriber. |
compliance-feed-delivererevent: fonteum/compliance.change_detected | event | src/inngest/functions/compliance-feed-deliverer.ts | §pillar5-compliance-change-feed — HMAC-signed POST of each detected compliance change to active compliance_feed_subscriptions matching the event_type; logs every attempt to compliance_feed_deliveries with 6-retry exponential backoff. |
dataset-webhook-delivererevent: fonteum/dataset.delivery_requested | event | src/inngest/functions/dataset-webhook-deliverer.ts | Pillar 5 dataset webhooks — delivers one Ed25519-signed snapshot-published POST to one subscriber with Inngest backoff retry. |
fhir-bulk-export-workerevent: fhir.bulk.export.requested | event | src/inngest/functions/fhir-bulk-export-worker.ts | Processes FHIR R4 Bulk Data Access ($export) job requests; writes NDJSON output, updates job status. |
nsa-compliance-quarterly | 0 9 15 3,6,9,12 * | src/inngest/functions/nsa-compliance-quarterly.ts | Quarterly NSA/surprise-billing compliance score computation across IDR + MRF datasets. |
real-act-compliance-quarterly | 0 9 15 3,6,9,12 * | src/inngest/functions/real-act-compliance-quarterly.ts | Quarterly REAL Act network-adequacy compliance scoring for health plans. |
provider-directory-accuracy-quarterly | 0 9 15 3,6,9,12 * | src/inngest/functions/provider-directory-accuracy-quarterly.ts | Quarterly Provider Directory Accuracy Index (PDAI) computation across all 51 jurisdictions. |
hospital-margin-annual | 0 9 1 12 * | src/inngest/functions/hospital-margin-annual.ts | Annual hospital financial margin computation from HCRIS cost reports; runs each December 1. |
chain-extender | */5 * * * * | src/inngest/functions/chain-extender.ts | Polls snapshot_attestations for unchained rows; links previous_link_hash to extend the attestation chain. |
endpoint-uptime-monitor | */5 * * * * | src/inngest/functions/endpoint-uptime-monitor.ts | 5-min /api/health ping; records result in endpoint_uptime_checks for rolling 24h/30d uptime % shown on /status dashboard. |
freshness-watchdog | 0 14 * * * | src/inngest/functions/freshness-watchdog.ts | Daily dataset freshness audit: fetches /api/freshness, compares last_updated against declared cadence, emails operator when any dataset exceeds its threshold or endpoint uptime < 99% over 24h. |
snapshot-archive | 0 3 * * * | src/inngest/functions/snapshot-archive.ts | Daily 03:00 UTC content-addressed snapshot of NPPES + PECOS source datasets to S3 (fonteum-snapshots). Deduped by SHA-256; indexes captured_at in dataset_snapshots for /status Last-snapshot column and 36h freshness gate. |
risk-signal-refresh | 0 4 * * * | src/inngest/functions/risk-signal-refresh.ts | Daily 04:00 UTC recompute of risk signals for up to 10K NPIs in provider_risk_signals (stalest first). Fires 1h after snapshot-archive so fresh NPPES/PECOS data is captured first. Upserts via ON CONFLICT (npi, signal_type). |
risk-signal-refresh-error-alertevent: inngest/function.failed | event | src/inngest/functions/risk-signal-refresh.ts | Event-triggered: listens for inngest/function.failed scoped to risk-signal-refresh and sends a Resend operator alert. |
daily-dataset-snapshotter | 15 6 * * * | src/inngest/functions/daily-dataset-snapshotter.ts | Daily 06:15 UTC row-count snapshot for 7 core dataset families (NPPES, OIG LEIE, PECOS, QPP MIPS, POS, Care Compare NH, source manifest). Upserts source_snapshot rows and inserts snapshot_attestation rows so the chain-extender can sign them. Supports the Wave 6Z W1.1 chain bootstrap goal of ≥7 daily signed links. |
moat-m12-sitemap-drift | 0 */12 * * * | src/inngest/functions/moat-m12-sitemap-drift.ts | Every-12-hours sitemap drift detector: fetches sitemap-index recursively, HEAD-checks all URLs (10s/10-worker), diffs vs prior run url_set, writes sitemap_drift row, fires alert if broken>0 or dropped>5. |
moat-m14-cms-freshness | 0 3 * * * | src/inngest/functions/moat-m14-cms-freshness.ts | Daily 03:00 UTC CMS data freshness check — fetches upstream modified date from data.cms.gov API for 5 datasets, compares to our source_snapshots, computes lag_days, emails operator per stale source (lag > 14 days). |
journorequest-monitor | */30 * * * * | src/inngest/functions/journorequest-monitor.ts | Every-30-min scraper of Twitter #journorequest (via Nitter) and Qwoted public opportunities; keyword-matches against tier config; stores in journalist_requests table; sends Tier 1 matches via Resend immediately. |
journorequest-digest | 0 1 * * 1-5 | src/inngest/functions/journorequest-monitor.ts | Mon-Fri 01:00 UTC (09:00 PHT) Tier 2 daily digest email bundling all unnotified Tier 2 journalist request matches from the prior 24h; silent on zero matches. |
bulk-snapshot-on-demandevent: fonteum/bulk.snapshot.requested | event | src/inngest/functions/bulk-snapshot-on-demand.ts | On-demand source puller for bootstrapping source_cache_log. Triggered by POST /api/admin/bulk/trigger-seed; runs runSourcePullerJob for the requested source_id. Requires AWS_S3_* env vars. Fixes C-1 bulk-download-routing — seeds latest.csv.gz endpoints after first deploy. |
Lightweight HTTP-only ticks — fire-and-forget acceptable.
Vercel cron owns work that completes fast, has no external dependencies that fail interestingly, and doesn’t need step-orchestration. Defined in vercel.json crons[]; each entry maps to a src/app/api/cron/<name>/route.ts handler.
| Job ID | Schedule (UTC) | Source file | Purpose |
|---|---|---|---|
ai-citation-sampler | 0 6 * * * | src/app/api/cron/ai-citation-sampler/route.ts | Samples AI assistants for citations of Fonteum data; logs to ai_citations. |
archive-events | 0 4 * * * | src/app/api/cron/archive-events/route.ts | Daily housekeeping — archives old page_views + claim_funnel_events to keep hot tables small. |
audit-deploy | 0 8 * * * | src/app/api/cron/audit-deploy/route.ts | Daily post-deploy audit — checks recent deploys against schema-validation + launch-gate baselines. |
partner-reconciliation | 0 9 * * 1 | src/app/api/cron/partner-reconciliation/route.ts | Weekly Monday partner-attribution reconciliation — matches partner_clicks to landed conversions. |
ping-new-urls | 17 * * * * | src/app/api/cron/ping-new-urls/route.ts | Hourly IndexNow ping for newly-published URLs (claim_drafts → published listings, new research studies). |
ping-sitemaps | 30 2 * * * | src/app/api/cron/ping-sitemaps/route.ts | Daily Google + Bing sitemap-ping notification. |
provenance-audit | 0 7 * * * | src/app/api/cron/provenance-audit/route.ts | Nightly 07:00 UTC provenance source health check — HEAD/GETs every cited source_url, logs reachability + latency + content-SHA drift to provenance_audit_log; surfaces on /admin/provenance-audit. |
revalidate-stats | 0 * * * * | src/app/api/revalidate-stats/route.ts | Hourly ISR cache revalidation for /coverage + per-vertical stat pages. |
schema-audit | 0 6 * * 0 | src/app/api/cron/schema-audit/route.ts | Weekly Sunday rich-results / Schema.org test against every public surface; logs to schema_audit_reports. |
schema-validate | 30 3 * * * | src/app/api/cron/schema-validate/route.ts | Daily JSON-LD validity scan; logs to schema_validation_runs. |
submit-gsc-sitemaps | 15 3 * * * | src/app/api/cron/submit-gsc-sitemaps/route.ts | Daily Google Search Console sitemap submission across the 40-domain network. |
Decision tree per AGENTS.md §cron-doctrine.
- Does the job need step-level retries, idempotency, or step-orchestration? → Inngest.
- Does the job emit events that downstream Inngest functions consume? → Inngest.
- Does the job need observability beyond simple HTTP-200/non-200? → Inngest.
- Lightweight HTTP-only operation that completes in seconds with no external failure modes? → Vercel cron.
When unclear, default to Inngest — it is strictly more capable. The tools/cron-ownership-check.shCI gate blocks any job that lands in both systems and any job that is missing from this page’s registry.