Skip to content

feat: demo mode for a public demonstration (spec 003) - #12

Draft
AnaLauraFFerraz wants to merge 29 commits into
mainfrom
003-demo-mode
Draft

AnaLauraFFerraz wants to merge 29 commits into
mainfrom
003-demo-mode

Conversation

@AnaLauraFFerraz

Copy link
Copy Markdown
Owner

Summary

Spec 003 adds a demo mode to the API, selected with DEMO_MODE=true and off by default, so the API can run as a self-contained public demonstration on a free web service (one port, 0.1 CPU, 512 MB, temporary disk, sleep after 15 minutes, 5 GB of outbound bandwidth a month). Local mode stays as it is.

In demo mode the server will verify the published recording, build the whole session in memory before answering, use the recording's capture times, seed the coach cache from a versioned file, switch the database to read-only, and replay the recording at 1x in a loop on the single port, sending only the player's car, compressed, to at most 5 connections of at most 5 minutes each. It never makes a paid call: it refuses to start with an Anthropic key.

This is a draft: the work lands phase by phase, following the tasks.

Done so far

  • A compiled build (npm run build, its own tsconfig.build.json) and npm start; paths resolved from the project root, so the compiled server uses data/telemetry.db and not dist/data/.
  • The demo-mode configuration and its fail-fast checks (PORT, DEMO_ALLOWED_ORIGIN, limits, DEMO_WS_COMPRESSION; refuses ANTHROPIC_API_KEY and DB_PATH). With a valid configuration the server still stops: the demo itself is not wired yet.
  • persistTelemetry returns the lap a packet completed (used later for the capture times).

Changes the frontend sees (for the frontend's spec 003)

None of these exist yet in this draft; they are what the finished feature will expose, from plan.md:

  1. REST and WebSocket on one host and port (demo mode).
  2. WebSocket data holds only the player's car (a contract change with the same shape).
  3. playerCarIndex is always 0 (read the car through it, as today).
  4. Messages compressed with per-message deflate (transparent to the browser).
  5. Close codes 4001 "demo full" and 4002 "time limit" (after 5 minutes); reconnect only on the visitor's action.
  6. The WebSocket handshake refused with 403 for a foreign origin.
  7. CORS only for the configured frontend origin.
  8. Cache-Control: no-cache plus the ETag on reads (304 on revalidation); no-store on the coach and on health.
  9. Session dates are the recording's capture times (2026-10-16, displayed as 4 min); session id 1.
  10. New GET /health, in both modes.
  11. No 429: the per-IP limit is not adopted.
  12. The coach's 503 body is unchanged and still mentions ANTHROPIC_API_KEY.
  13. Only (8, 6) and (8, 7) are reachable with today's fixed primary lap; all six ordered pairs are seeded.
  14. Hosting the frontend in the same account as the API would spend the same 5 GB monthly allowance.

Out of scope

The deploy itself, a build check in the CI (a separate small spec), and any frontend change.

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