Skip to content

fix(demo): fail closed if synthetic demo data would reach live production#378

Merged
BigSimmo merged 1 commit into
mainfrom
claude/beautiful-hugle-dd3fb8
Jul 8, 2026
Merged

fix(demo): fail closed if synthetic demo data would reach live production#378
BigSimmo merged 1 commit into
mainfrom
claude/beautiful-hugle-dd3fb8

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up hardening to #373 (which stopped /api/search/universal serving demo docs to live public users). #373 fixed the one route; this closes the whole demo-served-live class so it can't recur through a new route.

demoSearch() — the single choke point for synthetic document search (demoAnswer routes through it too) — now fails closed: it throws in a production request unless NEXT_PUBLIC_DEMO_MODE=true. In production the Supabase-config demo fallback (nonProductionSupabaseDemoFallbackReason returns null) and isLocalNoAuthMode are already disabled, so an explicit demo deploy is the only legitimate case.

Key design point: the guard reads process.env directly (not isDemoMode) so it cannot be silently disabled by a test that mocks @/lib/env, and so every current and future caller is covered — a new route that hard-codes demo:true (the exact #373 mistake) would now surface a loud 500 instead of quietly serving fabricated clinical documents. Mirrors the existing fail-closed requireOwnerScope retrieval guard.

Verification

  • npx tsc --noEmit — clean
  • npx eslint + npx prettier --check on changed files — clean
  • npx vitest run across demo/answer/access suites (demo-data, private-access-routes, private-rag-access, public-access-deep, setup-status-route, supabase-errors, owner-scope, api-rate-limit-fallback, rag-answer-fallback, rag-offline-answer, universal-search) — all green, incl. the non-production Supabase-failure fallback paths (guard is inert outside production)
  • npm run verify:cheap / check:production-readiness — not run here (partial node_modules, no live keys); CI + a maintainer with live keys should run these

Clinical Governance Preflight

  • Demo/synthetic content remains clearly separated from real clinical sources — this PR enforces it at the data layer: synthetic search can no longer reach a live production request
  • No change to real retrieval, answer generation, ranking, or source rendering (guard is a no-op outside production / explicit demo mode)
  • Supabase target, service-role handling, and private document access unchanged
  • No patient-identifiable workflow introduced; no clinical decision-support behavior change (TGA SaMD impact n/a)

Notes

  • Regression tests: demoSearch throws in a production request; still serves fixtures under an explicit NEXT_PUBLIC_DEMO_MODE=true deploy.

🤖 Generated with Claude Code

…uction

Structural guard so the /api/search/universal leak class cannot recur:
demoSearch() — the single choke point for synthetic document search (demoAnswer
routes through it too) — now throws in a production request unless
NEXT_PUBLIC_DEMO_MODE=true. In production the Supabase-config demo fallback and
isLocalNoAuthMode are already disabled, so an explicit demo deploy is the only
legitimate case. The guard reads process.env directly (not isDemoMode) so it
cannot be silently disabled by a test that mocks @/lib/env, and so every current
and future caller is covered — not just the routes audited today.

Adds 2 regression tests (throws in production; allowed under explicit demo mode).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@supabase

supabase Bot commented Jul 8, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@BigSimmo
BigSimmo enabled auto-merge (squash) July 8, 2026 06:56
@BigSimmo
BigSimmo merged commit 01a13e9 into main Jul 8, 2026
5 checks passed
@BigSimmo
BigSimmo deleted the claude/beautiful-hugle-dd3fb8 branch July 9, 2026 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant