diff --git a/src/app/products/[slug]/page.tsx b/src/app/products/[slug]/page.tsx index 42fb1756..898678be 100644 --- a/src/app/products/[slug]/page.tsx +++ b/src/app/products/[slug]/page.tsx @@ -182,21 +182,23 @@ export default async function ProviderPage({ // Vercel keeps serving the last good render instead of caching a page // full of "data warming up" for the next 5 minutes. // - // Exception: providers whose endpoint is legitimately broken (Cloudflare - // returns -32046 on most RPC methods, permissioned-mode gateways refuse - // reads, etc.) show up with `unresponsive: true` or `availability: - // "unavailable"` on every appearance. That's real data, not a store - // read failure, and firing the tripwire on it blocks every prod deploy - // because the sitemap smoke test catches the 500 and auto-rollbacks. - const allUnresponsive = p.appearances.every( + // Tightened gate: only fire when EVERY appearance claims availability + // "live" yet none of them ranked. That is the true store-read-failure + // signature (data present but ranking silently failed). Any appearance + // with `unresponsive: true` or `availability: "unavailable"` — or the + // mixed shape Cloudflare produces (some benches live-but-broken with + // rank=0, others outright unavailable) — is real provider data, not a + // store fault, so we render the page as-is instead of 500ing the smoke + // test into a rollback loop. + const allClaimLive = p.appearances.every( (a) => - a.result.unresponsive === true || - a.result.availability === "unavailable", + a.result.availability === "live" && + a.result.unresponsive !== true, ); if ( p.appearances.length >= 3 && p.appearances.every((a) => a.rank === 0) && - !allUnresponsive + allClaimLive ) { throw new Error(`degraded store read for /products/${slug}: ${p.appearances.length} appearances, all unranked`); }