Skip to content

fix(free-tier): never serve a Radar overlay older than the shipped catalog - #12215

Merged
diegosouzapw merged 2 commits into
diegosouzapw:release/v3.8.51from
maxmad64bis:fix/free-tier-overlay-freshness
Sep 1, 2026
Merged

diegosouzapw merged 2 commits into
diegosouzapw:release/v3.8.51from
maxmad64bis:fix/free-tier-overlay-freshness

Conversation

@maxmad64bis

@maxmad64bis maxmad64bis commented Aug 31, 2026 •

Copy link
Copy Markdown
Contributor

Summary

GET /api/free-tier/summary could still answer from a Radar overlay built 2026-08-02 while this release ships a catalog curated 2026-08-30 (FREE_CATALOG_CURATED_AT). Totals were computed from older data and still tagged catalogSource: radar-overlay. This PR refuses any overlay built before the shipped catalog and, when stale, answers from that catalog through the operator's local state.

Related Issues

Validation

  • Change type: provider / routing / UI / i18n / CLI / DB / build-deploy / other
    • actual: other — free-tier route + Radar catalog resolution
  • Focused tests and category gates from the golden path
  • npm run lint
    • exits 0 on touched files; check:cycles/check:changelog-integrity/prettier --check also green (~500 suppressed pre-existing violations on the base)
  • Reconciled with the current active release base; focused checks rerun afterward
    • release/v3.8.51@63e4afa
  • Production-code changes include a new or updated automated test in this PR
npx cross-env DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm \
  --import ./open-sse/utils/setupPolyfill.ts --import ./tests/_setup/isolateDataDir.ts \
  --test tests/unit/free-tier-summary-radar-overlay.test.ts
# 15/15 pass

Tests Added Or Updated

  • tests/unit/free-tier-summary-radar-overlay.test.ts (9 → 15):
    • GEN_AT/FETCHED_AT anchored on FREE_CATALOG_CURATED_AT (+ STALE_GEN_AT); pre-migration (generatedAt: undefined) updated from radar-overlay/null to baseline/FREE_CATALOG_CURATED_AT (still asserts fetchedAt not substituted).
    • 4 freshness: older → baseline, null → baseline, same-day 00:30Z → overlay, newer → overlay.
    • 2 operator-state on stale overlay (naive computeFreeModelTotals({excludeTosAvoid}) fallback fails red, getCatalogWithoutOverlay() passes green):
      not ok 14 — a tombstoned model must never come back … · not ok 15 — a locally disabled model must not be counted …

Coverage Notes

Touches src/app/api/free-tier/summary/route.ts, src/lib/radar/index.ts, src/lib/radar/applyFeed.ts — all covered by the 15 tests above (focused file per plan; full suite + 60% gate run in CI). No touched file loses coverage. Guard is meta.generatedAt.slice(0,10) >= FREE_CATALOG_CURATED_AT (day-level, lexically safe even for +HH:MM); fallback exercises the empty-feed applyFeed path that now honours localOverrides for baseline-only entries.

Reviewer Notes

  • Not touched: GET /api/radar/catalog keeps its own contract ("this feed" + its date).
  • Guard: overlayIsFresh = meta!==null && meta.generatedAt!==null && slice(0,10) >= FREE_CATALOG_CURATED_AT — unknown is stale, same-day is fresh.
  • Fallback: getCatalogWithoutOverlay() = applyFeed({ baseline, feed: [], localOverrides, tombstones }); flag-off path unchanged.
  • When stale, isAuthenticated() is short-circuited (read-only, no known side effect).

@maxmad64bis
maxmad64bis force-pushed the fix/free-tier-overlay-freshness branch from 11faafb to 0c78567 Compare August 31, 2026 18:08
@maxmad64bis
maxmad64bis force-pushed the fix/free-tier-overlay-freshness branch from 0c78567 to d3f4f1c Compare August 31, 2026 18:27
…plyFeed under the cognitive ratchet

Behaviour-preserving extraction of the baseline-only local-override branch
added for the overlay-freshness fix; applyFeed drops back below the
cognitive-complexity threshold (file back to the base's 3 violations).
@diegosouzapw
diegosouzapw merged commit 33bdc38 into diegosouzapw:release/v3.8.51 Sep 1, 2026
15 of 16 checks passed
@maxmad64bis
maxmad64bis deleted the fix/free-tier-overlay-freshness branch September 24, 2026 21:13
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…talog (diegosouzapw#12215)

GET /api/free-tier/summary could answer from a Radar overlay built 2026-08-02 while the release ships a catalog curated 2026-08-30 (FREE_CATALOG_CURATED_AT) — totals computed from older data, still tagged catalogSource: radar-overlay. The route now refuses any overlay built before the shipped catalog and falls back to that catalog through the operator's local state.

Tightens diegosouzapw#11550 using the generatedAt persisted by diegosouzapw#11435.

Verified in a combined batch worktree: 174/174 focused tests across all 11 PRs of this batch (this PR's free-tier-summary-radar-overlay suite included), typecheck:core clean, check-file-size, check-changelog-integrity, check:cycles and check:docs-counts green.

Thanks @maxmad64bis.
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.

2 participants