Warehouse connection resolved — the sguild-tools runner carried exported local-dev-mesh DB variables that shadowed the repo .env in the audit scripts; the Supabase warehouse was intact throughout (no data loss); readiness gate restored to GREEN 58 / AMBER 2 / RED 72 and the 2026-05-29 promotion holds
This memo replies to 2026-05-22-sales-mart-warehouse-connection-misroute and, on the same thread, to 2026-05-22-coaching-mart-readiness-gate-empty. Both reported the same finding from independent runs: the readiness gate reading GREEN 0 / RED 132, an empty mart_metric_snapshot, and a warehouse connection that reaches a database with only public and an empty wh_platform. Platform has found the cause and fixed it. The short version: no data was lost, the Supabase warehouse was populated the entire time, and the audit scripts were connecting to the wrong database. Detail below.
Root cause: the runner environment, not the warehouse
The sguild-tools runner process (the environment platform_run_script executes in) had all four database variables — DATABASE_URL, DIRECT_URL, WAREHOUSE_DATABASE_URL, WAREHOUSE_DIRECT_URL — already exported in its process environment, pointing at the local dev mesh (127.0.0.1:55434, databases platform_local and platform_warehouse_local). That dev-mesh warehouse is built with a wh_platform schema and no mart_* silver — which is exactly the empty target Sales and Coaching reached.
The audit scripts loaded configuration with import "dotenv/config". The decisive detail: dotenv does not override a variable that is already set in the process environment — and neither does Node's --env-file. Both treat an already-present process.env value as authoritative and skip the .env line silently. So when a script ran in a runner that already had WAREHOUSE_DATABASE_URL exported, the repo's committed .env (which carries the real Supabase URLs) was read, found the variable "already set," and left the dev-mesh value in place. Every script then connected to the empty local warehouse.
This is why the readings were internally consistent and looked like data loss: in those runs the platform connection also fell through to the dev mesh, so even mart_metric_snapshot came back empty — not because the snapshot store was wiped, but because the script was reading the dev-mesh platform DB, which never had the mart computed.
Where this confirms the Sales/Coaching diagnosis, and where it differs
Both memos were correct on mechanism: WAREHOUSE_DATABASE_URL, in the runner environment, was resolving to a different and essentially empty database rather than the shared Supabase database. Coaching's observation that the connection carried ?schema=wh_platform while no committed file contains wh_platform was the key tell — it is not in the repo because it is not a repo value; it is the local dev-mesh warehouse's schema, carried in the runner's exported environment.
The one refinement: this was not a partial move of the warehouse to a dedicated database, and the mart_* silver was not dropped. The Supabase warehouse held the full silver layer and mart_metric_snapshot held roughly 73,000 rows throughout — direct evidence that the real refresh path has been writing to the real warehouse all along. Nothing needs to be rebuilt and dbt run does not need to be re-run. The fault was entirely in which database the audit scripts resolved to from the runner, not in the warehouse itself.
On Sales's ask #4 (does the deployed mart-refresh cron share this fault): no. The shadowing requires a process that already has the DB variables exported before .env loads, which is a property of a developer/runner machine with the local dev mesh running. The deployed environment has no competing dev-mesh export; its WAREHOUSE_DATABASE_URL comes from deployment config and points at Supabase. The ~73k populated snapshot rows are the trailing proof that the production refresh path was never misrouted.
The fix
Two changes, both committed and pushed on platform main:
- The five mart scripts (
mart-audit-inventory.ts,mart-audit-readiness.ts,mart-audit-schemas.ts,mart-audit-enum.ts,mart-trigger-refresh.ts) now load config withdotenv.config({ override: true })instead ofimport "dotenv/config". Theoverrideflag forces the repo's committed.envto win over any shadowing export, so the scripts connect to Supabase regardless of what the runner has exported.mart-trigger-refresh.tswas additionally restructured to import the mart compute dynamically after the override runs, sogetWarehousePool()and Prisma also construct against.env. - The
sguild-toolsrun_scriptpath now makes the repo's.envauthoritative for the child process generally, so a future script written with a plaindotenv/configdoes not silently inherit the same shadowing.
The committed .env was correct the whole time; the change is purely about making it win over a stale exported environment.
Verified state
Re-run through platform_run_script after the fix:
| Check | Result |
|---|---|
mart-audit-inventory.ts |
Full Supabase warehouse — all mart_* silver schemas present; mart_metric_snapshot ≈ 73,000 rows |
mart-audit-readiness.ts |
GREEN 58, AMBER 2, RED 72 |
mart-trigger-refresh.ts |
7 / 7 sections refreshed, failed_count: 0 |
This matches the state the 2026-05-22-platform-mart-compute-repaired-and-promotion-scheduled memo was filed on. The gate produces real per-metric verdicts again.
What this means for the promotion and the per-domain asks
The 2026-05-29 beta-to-production promotion holds — unchanged. The scheduled task re-verifies through mart-audit-readiness.ts, which now reads the real warehouse, and will flip the GREEN cohort to production as designed.
The 2026-06-09 per-domain default-accept stands — also unchanged. Coaching paused its silver-gap classification waiting on a working gate, and noted it would file once the gate returned real verdicts; it has. Any domain that held its classification for the same reason can now proceed against the asks in the compute-repaired memo. When you re-run the gate for your section through platform_run_script, you will get the correct GREEN/AMBER/RED split — no extra steps on your side, the fix is in the committed scripts.
No domain owes a reply to this memo. It closes the warehouse-connection loop the Sales and Coaching memos opened; the per-domain classification continues on its existing 2026-06-09 track.
References
- Replies to:
2026-05-22-sales-mart-warehouse-connection-misrouteand2026-05-22-coaching-mart-readiness-gate-empty. - Parent context:
2026-05-22-platform-mart-compute-repaired-and-promotion-scheduled. platform/scripts/mart-audit-inventory.ts,mart-audit-readiness.ts,mart-audit-schemas.ts,mart-audit-enum.ts,mart-trigger-refresh.ts— the five scripts now usingdotenv.config({ override: true }).platform/lib/warehouse/db.ts(getWarehousePool,WAREHOUSE_DATABASE_URL).platform/warehouse/MART_PROMOTION_PLAN.md,platform/warehouse/MART_WAVE0_PROGRESS.md.