Close the RLS/auth hard gate: runbook, web spec, and the session's evidence (#24)
The Dad-onboarding hard gate in tasks/phase2-onboarding-runbook.md and item 2 of tasks/web-overhaul-spec.md's STATUS block both pointed at "no authentication, RLS disabled". Both are closed by PR #21, and both now carry the red baseline
The Dad-onboarding hard gate in tasks/phase2-onboarding-runbook.md and item 2 of tasks/web-overhaul-spec.md's STATUS block both pointed at "no authentication, RLS disabled". Both are closed by PR #21, and both now carry the red baseline next to the green result so a later reader can tell the difference between a claim and a demonstration.
The numbers that matter, all against production: /api/holdings unauthenticated 200 with holdings JSON -> 401 every page 200 -> 307 to /login plain http:// 200, served the portfolio -> 308 to https anon INSERT into trades 201 -> 401 anon DELETE from trades 204 -> 401 old CRON_SECRET worked -> 401
Exactly 6 of the instance's 93 tables changed; 87 unchanged, verified by a full before/after diff of relrowsecurity rather than by assertion. Control tables belonging to other apps returned identical anon status codes on both sides. Row counts are unchanged except monitor_heartbeats, which grew by the monitor runs that happened during the work.
Consumers are verified from the data, not from exit codes: heartbeat rows written AFTER RLS was enabled by both github-actions/primary (15:48, 15:50) and hetzner-cron/chain1 (15:55), all ok=t.
docs/crons.md is deliberately untouched -- the how-it-works session is rewriting its Hetzner and Cloudflare sections in #23, including an enumeration of all six CRON_SECRET consumers with today's drift as the worked example. Editing it here would collide with better information.
Five carried risks are recorded rather than quietly dropped, the sharpest being that eight further tables this app writes still carry full anon grants -- predictions, iv_snapshots and overrides among them, which feed the recommendation engine. That is an integrity exposure on trade inputs and was outside this session's six-table scope.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>