Conversation
… so refresh runs Live log 2026-04-16 09:25 showed the bundle runner SKIPPING Resilience-Scores (last seeded 203min ago, interval 360min -> 288min skip threshold). Every Railway cron fire within the 4.8h skip window bypassed the section entirely, so refreshRankingAggregate() -- the whole point of the Slice B work merged in #3124 -- never ran. Ranking could then silently expire in the gap. Lower intervalMs to 2h. The bundle runner skip threshold becomes 96min; hourly Railway fires run the section about every 2h. Well within the 12h ranking TTL, and cheap per warm-path run: - computeAndWriteIntervals (~100ms local CPU + one pipeline write) - refreshRankingAggregate -> /api/resilience/v1/get-resilience-ranking?refresh=1 (handler recompute + 2-SET pipeline, ~2-5s) - STRLEN + GET-meta verify in parallel (~200ms) Total ~5-10s per warm-scores run. The expensive 222-country warm still only runs when scores are actually missing. Structural test pins intervalMs <= 2 hours so this doesn't silently regress. Full resilience suite: 378/378.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Greptile SummaryThis PR fixes a skip-logic bug in the Confidence Score: 5/5Safe to merge — the interval change is minimal, well-reasoned, and guarded by a new structural test. The only finding is a stale test name/comment (P2 style). The core fix is correct: 2 h interval → 96 min skip threshold → hourly cron runs the section every ~2 h, well inside the 12 h ranking TTL. The new regex test correctly guards against regression to a larger interval. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A([Railway hourly cron fire]) --> B[Bundle runner reads seed-meta:resilience:intervals]
B --> C{elapsed < intervalMs × 0.8?}
C -- "Old: 6 h interval\n skip window = 4.8 h\n(most hourly fires hit this)" --> D[SKIP — refreshRankingAggregate never runs]
C -- "New: 2 h interval\n skip window = 96 min\n(every other hourly fire passes)" --> E[RUN Resilience-Scores section]
E --> F[refreshRankingAggregate via ?refresh=1]
F --> G[Ranking key refreshed — 12 h TTL reset]
D --> H[Ranking TTL silently expires → EMPTY_ON_DEMAND]
|
Summary
Follow-up to the Slice B work merged in #3124. Live Railway log at 2026-04-16 09:25 UTC:
The bundle runner skips any section whose seed-meta is younger than
intervalMs * 0.8. WithintervalMs: 6 * HOURthe skip window is 4.8h. Every Railway cron fire inside that window bypassed the section entirely, which meansrefreshRankingAggregate(), the whole point of the Slice B work, never ran on those ticks. The ranking aggregate (12h TTL) could then expire silently before the next actual run.Fix
Drop
intervalMson Resilience-Scores from 6h to 2h. Skip threshold becomes ~96min, so hourly Railway fires run the section every 2h or so. Cheap on warm-path runs (~5-10s; only the light refresh + intervals recompute + verify, not the 222-country warm). Well within the 12h ranking TTL.Structural test pins
intervalMs <= 2 hoursso this doesn't silently regress later.Test plan
[Resilience-Scores] Refreshed resilience:ranking:v9 with 222 countries (scheduled cron refresh)in the log./api/healthresilienceRanking.statusshould stay OK across cron ticks instead of flipping to EMPTY_ON_DEMAND.