From 39c07a03b98f82446beb8fe8eeaece999831f04c Mon Sep 17 00:00:00 2001 From: Kev Date: Sat, 18 Jul 2026 13:57:45 -0400 Subject: [PATCH] STATE.md: security + plumbing follow-up (items 0-7) Co-Authored-By: Claude Opus 4.8 (1M context) --- specs/STATE.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/specs/STATE.md b/specs/STATE.md index 2eae595..52d9f9b 100644 --- a/specs/STATE.md +++ b/specs/STATE.md @@ -1,6 +1,14 @@ # VYNDR — STATE OF THE WORLD ### As of `a8e383e` (main, deployed + fingerprint-verified live), 2026-07-18. This file opens every future session. Update it when a train ships. +## SECURITY + PLUMBING FOLLOW-UP (2026-07-18, on main) — code shipped, migrations authored +Chrome ops session findings (Supabase advisor + Stripe). Code items shipped + fingerprinted; DB migrations authored for Kev to apply (no DB access from the box). +- **Item 0 (SHIPPED, fingerprinted)** `3b12c6c`: founder count = real active Stripe subs (`stripeService.countFounderSeats`), not DB tier fields. Phantom 1 (a comped profile) gone → prod now `available:false` (founder price IDs unset in prod env — set `STRIPE_PRICE_*_FOUNDER` to show the real 0). +- **Items 1,3,4,5 (AUTHORED — Kev applies in Supabase)** `78c1929`: `migrations/023_security_hardening.sql` (founder_pricing_seats → security_invoker; waitlist anon-INSERT-only; function search_path) + `migrations/024_anon_revoke_discoverability.sql` (revoke anon SELECT). Fingerprint = re-run Security Advisor. +- **Item 2 (SHIPPED — Kev sets env + cron)** `5f5c004`: `scripts/backup-db.sh` + `docs/BACKUP-RUNBOOK.md`. Needs `SUPABASE_DB_URL` (direct :5432 URI) in Coolify + the cron on the Hetzner box. Fingerprint = restore a dump + count ledger_entries. +- **Item 6 (SHIPPED — Kev activates portal in Stripe)** `889e862`: portal proxy + "Manage billing" button. Dunning verified: cancel-on-exhaustion → subscription.deleted → 48h grace → `gracePeriod.checkGracePeriod` revokes to free. Nuance: 48h grace on first payment_failed < Stripe's 2-week retry window (self-correcting). +- **Item 7 (SHIPPED)** `ae3cff9`: ESPN BET → theScore Bet (PENN) in books.js + ALLOWED_BOOKS; design HANDOFF flagged for the BookChip swap. + ## TRUTH-EVERYWHERE PART 2 — COMPLETE (2026-07-18, on main, all 8 items fingerprinted) Standing law: NO FABRICATED DATA ANYWHERE (UI, marketing, demos, examples). If it renders a number, it's from the DB or it doesn't render. Live data IS the better demo. - **Item 1 — Verb law** (`66d52a9`): one verb, READ (never SCAN), swept every user-visible surface (FAB/nav/tier/ticker/upgrade). `tests/unit/verbLaw.test.js` enforces. Ticker "slate read" text flips at the next snapshot cron.