CRITICAL production fix: the validate-key cloud edge function returned HTTP 500 on every real API key (deploy drift), silently downgrading every Enterprise/Pro customer to Free (plan-2026-07-06-validate-key-deploy-drift). The DEPLOYED validate-key Supabase edge function was a stale bundle that never received the 2026-05-31 compareSync fix — it still called the async bcrypt compare(), which spawns a Web Worker the Supabase Edge Runtime forbids, so it threw → HTTP 500 on every real ms_live_ key. @massu/core's license path (validateLicense) treated the 500 as "Free", so every paid key silently resolved to Free (surfaced during git-safe-api-key dogfooding, 2026-07-05). The repo source was already correct; the fix redeploys it (wrong-key probe now returns 401, not 500) — no customer key changes, no re-hashing, no bcrypt/WebCrypto re-engineering (the cause was a missed deploy, not a library bug). Patch per semver: a bug fix with no API change. Incident: docs/incidents/2026-07-06-validate-key-deploy-drift-500.md.
Fixed
validate-keyedge function 500'd on every real API key (deploy drift). The live bundle (version 8, 2026-05-31) still imported the asynccompare()(Web-Worker → forbidden in the Supabase Edge Runtime → throw → HTTP 500) five weeks aftere7d67f6fixed the repo source to route throughverifyApiKeyHash/compareSync; the validate-key redeploy of that fix never actually landed. Verified from the deployed bundle viasupabase functions download; blast radius confirmed = validate-key only (the other 6 API-key edge functions were already correct). Redeployed the correct source.massu login/massu doctorreported "Free" when the license server had errored or was unreachable.validateLicensenow returns aLicenseValidationOutcome(validated/rejected/server_error/network_error/grace/cache_fresh/no_endpoint/no_key);loginanddoctordistinguish an authoritative Free from a "could not validate (server error / offline) — tier UNKNOWN" state, so a server 500 is never misreported as a Free downgrade (this masking is why the outage looked like "Free").
Added
- CR-60: API-key edge functions MUST be deploy-verified (three-layer structural drift-prevention). (1) A source drift-guard (
website/src/tests/edge-async-bcrypt-compare-drift.test.ts, vitest, CI + pre-push) fails if any edge function imports or calls the async bcryptcompare(— hashing must route throughverifyApiKeyHash/compareSync; catches a function bypassing the shared helper (which the Deno helper test cannot). (2) A canonical edge-deploy + post-deploy real-key smoke test (scripts/massu-deploy-edge-functions.sh) fails the deploy unless a known-good key validates (HTTP 200 + expected tier) and a wrong key returns 401 (scripts/massu-deploy.shdeploys only Vercel, so it could never have caught this). (3) A Guardian readiness watcher (massu_validate_key_readiness_watcher, hourly) POSTs a known-good key to the live gateway and fires CRITICAL on any 500 / non-200 / wrong tier — this class had zero alerting.