Skip to content

September 2026 Full Production Launch (SUPERSEDED — historical record)

📕 HISTORICAL — do not plan against this document. It is no longer active and parts of it are known to be false.

What it was: the plan for a September 2026 full production launch — real clinics, real patients, and the ~20k legacy migration, with the full clinic-operations stack (F1/F3/F4/F5/F6) built to a calendar date.

Status: superseded 2026-08-02 by platform-completion.md. The September date and the launch-date framing are both retired. Planning backwards from a date produced pressure to cut scope — a minimum clinic-ops slice, a "good enough for beta" appointments table — which is the failure mode the foundation discipline exists to prevent. The corrected order is: build every remaining feature properly → harden → then plan the migration against a complete, real schema. There is no target date.

Why it is kept: it is the record of what was scoped, decided, and in several cases shipped between 2026-06-19 and 2026-08-02 — the F9/F10 inheritance, the operational-hardening inventory, and the launch-gate reasoning that carried forward into Phase 2 of the active plan.

Known-false claims inside — corrected inline where they appear:

  • F5's "substrate columns already landed" (Stream C) is false. There is no appointments table in any migration; the cadence redesign designed those columns against a table that was never created. Building against that line produces a broken migration. See the ⚠️ note at that item.
  • Every checkbox reflects state as of 2026-06-19 at the latest. foundation.md is authoritative for foundation status; platform-completion.md is authoritative for what is and is not built.
  • Its scope table lists F2 clinical service catalog and F8 segments as "folding forward." Under the active plan F8 is out of scope, and F2 ships only as the F2.1 offerings stand-in (catalog identity + offering_specialists + offering_forms; no pricing, no plans, no products, no purchase path).

🕘 Original header, as written 2026-06-19. The "active" claim below was retired on 2026-08-02 — see the banner above.

ACTIVESeptember 2026 full production launch. This is the live plan for taking the platform from its current shipped state to real clinics + real patients at full clinic-operations scope. The narrow June-10 single-session demo — see june-demo.md, now an archived milestone — shipped on 2026-06-10 and stood up the production substrate this plan builds on. Inherited from that demo: the F9 patient slice, the F10 media half, the production AWS substrate, the Clerk production app, custom-hostname routing, the legacy→new handoff bridge, and Console platform-stats reads. This doc tracks only the remaining September delta on top of that.

Plan window: 2026-06-19 (current state: demo shipped, production live serving real patients) → September 2026 (full launch — real clinics, real patients, ~20k legacy-patient migration). Full clinic-operations stack (F1/F3/F4/F5/F6); 5k self-serve open signup; full guided programs + seeded platform catalog; counsel-signed legal text gating the migration.

Premise

  • Full clinic-operations launch. Real clinics run their own operations on the platform — F1 Specialists, F3 Forms, F4 Scheduling, F5 Appointments, F6 Documents are now in scope (the demo's single-tenant collapse no longer applies). The shipped F9 telerehab slice and everything that already folds forward (F2 clinical service catalog + F8 segments) ride on this stack.
  • Patient side already ships at 100% production quality, including observability — inherited from the demo. The September delta brings the staff/admin surfaces up to the same bar.
  • No foundation shortcuts. The ~20k legacy-patient migration (11k+ treatment plans, 5k+ subscriptions) lands on this substrate — this becomes the production data we never want to re-migrate. 50k+ session_completions + media telemetry continue from day one.
  • Permanent open access. Cannot roll back, cannot time-box. Anything "good enough for beta" becomes load-bearing on day 27.
  • Real data, real learning. Sentry, CloudWatch product dashboards, adherence monitoring are launch-blocking — not nice-to-have.
  • F12 billing engine and the F10 pose-ingest pipeline are deferred past September — launch on hand-cut FGO invoices (the shipped paid-self-enroll + expiry sweep stay; only the auto-renew/invoicing engine is deferred); keep the client-side skeleton preview only, no pose ingest, no MDR / IEC-62304 scope pulled in for September.

Headline user stories

  1. Real clinics run their own operations on the platform — specialists, scheduling, appointments, forms, documents (full clinic-ops stack), with telerehab as the shipped slice.
  2. 5k patients self-serve onboard via public sign-up (no invite); the ~20k legacy cohort migrates in (pre-launch task).
  3. Free guided program with 10 sessions; per-session adherence + VAS captured.
  4. Adherence telemetry: video watch %, session completion, drop-off observable platform-wide.
  5. Portal works on mobile, desktop, and cast-to-TV (Chromecast / AirPlay). 90% mobile.

In scope for September: phased programs (the program_phases substrate shipped — populate it) + a seeded platform catalog. Deferred past September: the F10 pose ingest pipeline (keep the client-side MediaPipe skeleton preview only — no MDR scope) and the F12 billing engine.

Scope at a glance

Already DONE (inherited from the June-10 demo — see june-demo.md): F9 patient slice (catalog, enrollment, execution, instruments), F10 media half (separate Go service), production AWS substrate, Clerk production app, custom-hostname routing, legacy→new handoff bridge, Console platform-stats reads. These are not re-scoped here.

The table below is the true remaining September delta:

In (September delta)Deferred past SeptemberOut
Full clinic-ops: F1 Specialists, F3 Forms, F4 Scheduling, F5 Appointments, F6 DocumentsF12 billing engine (hand-cut FGO invoices at launch)F7 automations
5k self-serve open signup (demo used legacy handoff only)F10 pose ingest pipeline (preview stays)MDR / IEC-62304 pose scope
Full 10-session + phased programs + seeded platform catalog~20k legacy migration tooling (pre-launch task, plan closer to launch)
v2 legal text + Romanian counsel sign-off (gates the migration)
DSAR / erasure end-to-end
Enable backup cron (prod has none today) + cross-region backup & restore drill
SES bounce/complaint handler + suppression
k6 5k-shape load gate
media-service + clinic app brought fully live in prod
Status page + on-call + support inbox
iOS-playback fix (Bunny token-auth signed URLs)

Locked decisions

  • F10 telemetry = separate Go service. No folding into API. Media half ingests + aggregates; pose half deferred. Decisions doc + foundation patterns require this shape; "fix it later" is the failure mode CLAUDE.md bans.
  • Pose telemetry tables land empty. pose_session_metrics + pose_rep_metrics migrate now with monthly partitioning per P41. Cheaper than retrofitting partitioned tables at scale post-launch.
  • TV scope = cast from phone. Chromecast + AirPlay via Bunny Stream HLS. No Smart TV native UI, no D-pad work.
  • F3 dynamic forms now in scope for September. The demo deferred F3 — end-of-program feedback was satisfied by per-session instrument columns. The full clinic-operations launch brings the real dynamic-forms framework (intake / surveys); the two-layer split below still holds (time-series clinical signal stays as columns on F9 tables; dynamic surveys live in F3).
  • Two-layer patient-input model. Adherence + clinical instruments (VAS, RPE, completion) live as columns on the F9 clinical tables (session_runs for per-run feedback; session_exercise_events + session_pain_events for per-exercise and per-set events) — they're time-series clinical signal, indexed and aggregated constantly. Dynamic surveys (post-program satisfaction, NPS, intake) live in F3 when F3 ships.
  • Column shape on session_runs / session_exercise_events / session_pain_events is settled — VAS pain (0–10), Borg RPE (1–5), exercise milestone events (started / completed / skipped / paused_for_pain / resumed), per-set pain events. Shipped with the sessions MVP. See features/programs-and-assignments/ for the canonical schema.

Wall-clock dependency; longest lead time on the September path. F11.0.5 counsel engagement is 2–3 weeks regardless of effort applied. v2 legal text + Romanian counsel sign-off gates the ~20k legacy-patient migration — the migration cannot proceed onto patients under un-reviewed templates.

  • [ ] Engage Romanian data-protection counsel (F11.0.5) — brief them on 1B.10 privacy notice seeds, 1B.9 consent purposes, F10 media telemetry consent gate, F9 telerehab Class I MDR posture, marketing copy
  • [ ] Law 190/2018 review (Romanian GDPR implementation, CNP handling, employment quirks)
  • [ ] Age of digital consent verification (Romania: 16; below = parental consent path)
  • [ ] Telemedicine framework review (Orders 1.589/2020 + 1.488/2020) — applies to F9 even without live appointments
  • [ ] Medical records retention (Law 95/2006) — codify in F11.1 erasure flow
  • [ ] Biometric data guidance (pose tracking deferred but tablet-signature surfaces may exist)
  • [ ] Cross-border transfer (Clerk in US; SCCs in DPA)
  • [ ] Recent ANSPDCP enforcement scan (last 12 months)
  • [ ] Apply findings to 1B.10 EN + RO templates; mark "production-ready"
  • [ ] DPA template revision (SCCs + sub-processor list)
  • [ ] DPA between RestartiX-clinic and RestartiX-platform (both sides are us; still required for clean controller/processor boundary)
  • [ ] Sub-processor list draft + publish to public-facing page (GDPR Art. 28 transparency): Clerk, Bunny, SES, Cloudflare, Sentry, AWS
  • [ ] Marketing copy MDR review — every claim on the public landing page reviewed against Class I MDR posture
  • [ ] AWS BAA accepted in AWS Artifact
  • [ ] Findings documented in decisions.md

Stream B — Production Infrastructure

Production AWS substrate is live since 2026-06-05 (Multi-AZ RDS + Redis + ECS Fargate, prod DB at schema v38) — stood up for the demo. The items below reconcile what already shipped against the remaining September delta. Verify each "done" against the deployed prod state before relying on it.

  • [x] infra/envs/production Terraform: Multi-AZ RDS, NAT Gateway, pgbouncer, Multi-AZ Redis, on-demand Fargate. Topology per iac-layout.md
  • [x] Telemetry/media service IaC — provisioned alongside API + Next.js apps + composer + pgbouncer (bring fully live in prod — see Stream E)
  • [x] Production KMS keys (API encryption envelope + S3 telemetry blobs)
  • [ ] Enable backup cron — prod has none today. Daily pg_dump to S3 with checksum + lifecycle (Glacier IA at 90d / Deep Archive at 365d). RDS PITR confirmed.
  • [ ] Cross-region backup replication to a second EU region + restore drill executed.
  • [x] Cloudflare for SaaS production custom-hostname routing live (custom-hostnames API token in Secrets Manager); end-to-end cert + custom-hostname proven on our own domain
  • [ ] WAF decision settled (zone-WAF-for-SaaS add-on vs. AWS WAF on ALB — production-launch-readiness.md L98)
  • [ ] CloudWatch alarms per monitoring.md, routing to SNS → Slack
  • [ ] AWS Budgets alarms at 50% / 80% / 100%
  • [ ] All scheduled jobs verified running in production: api-partition-roll, usage-quota-reset, usage-summary-rollup, check-providers (crons had a scheduler-tags bug — confirm the fix is applied on prod)
  • [ ] Fargate auto-scaling bounds tuned against production-shape load test
  • [ ] k6 5k-shape load gate against production environment; baseline p50/p95/p99 latency, error rate, DB connection saturation

Stream C — Feature Build

Full clinic-operations stack (September delta — the bulk of new build)

Now in scope — the demo's single-tenant collapse on F1/F4/F5/F6 no longer applies. These are scaffold-only / not-started today (verify current status against features.md and the code). Each follows the foundation checklist: permission seeding, role grants, RLS, route gating, audit, data-classification + SOUP in the same PR.

  • [ ] F1 Specialists — specialist accounts, profiles, scheduling availability, assignment to protocols
  • [ ] F3 Forms — dynamic forms framework (the demo satisfied feedback with per-session instrument columns; September brings the real form builder for intake / surveys)
  • [ ] F4 Scheduling — availability, slots, calendars
  • [ ] F5 Appointments — booking, confirmation, status lifecycle (substrate columns appointments.{channel, protocol_id, session_id} + patient/clinic status split already landed in the cadence redesign)

    ⚠️ The struck text is FALSE — verified against every migration on 2026-08-02. There is no appointments table in services/api/migrations/core/, and therefore no appointments.channel, no appointments.protocol_id, no appointments.session_id, and no patient/clinic status split. The 2026-05-28 cadence redesign designed those columns and referenced them in comments; it never created the table. Every mention of appointments in the shipped migrations is a forward-looking comment. appointments is created for the first time by F5 — see platform-completion.md → Phase 1 → F5 and leo-port-map.md §0.3, which lists four further defects in architecture/appointments-substrate.md that must be fixed before that migration is written.

  • [ ] F6 Documents — clinical document storage, generation, retrieval
  • [ ] F2 clinical service catalog + F8 segments fold forward on this stack (ride on the shipped substrate; build the surfaces they need)

F9 patient slice — DONE (shipped via the June-10 demo)

The patient-facing telerehab slice below shipped end-to-end with the demo and is live in production. Kept here for substrate-shape reference; the September delta is the seeded platform catalog + full 10-session / phased programs (last item below) plus the iOS-playback fix, tracked in Stream E.

  • [x] F9.1 Phase 2 patient-facing only: GET /v1/portal/exercises catalog endpoint
  • [x] Bunny iframe player integration (cast slice shipped)
  • [x] F9.1 Cat A providers resolver for Bunny credentials (gates production)
  • [x] F9.2 Phase 1 substrate (shipped, reshaped 2026-05-22): programs (with derived_from_program_id for org-tier variants), program_phases, program_assets, content_files, session_audio_items, session_assets; sessions.kind/ownership_kind/program_id/phase_id/order_in_phase (sessions point at parent program directly — no program_sessions junction); exercises dual-ownership. Per P49 catalog ownership pattern. The originally-planned program_versions + session_versions snapshot tables were retired by the three-tier copy-on-derive rework.
  • [x] F9.2 Phase 1 protocol substrate (shipped 2026-05-23, redesigned 2026-05-28): protocols (renamed from patient_assignments; the "assignment" framing was a relic of the shared-by-reference model), protocol_pauses, two-cadence engine (flexible | scheduled) with orthogonal supervision_mode (unsupervised | supervised) — see cadence & supervision. The planned session_runs.assignment_id FK was dropped — the protocol is derivable via sessions.program_id chain. The 2026-05-28 cadence/supervision redesign shipped (end-to-end functional for unsupervised + flexible/scheduled; only the mid-treatment exercise-edit workflow is intentionally deferred behind the clinic program-UI rework — verify substrate against cadence & supervision): supervision_mode rename, appointment_driven dropped from the cadence_kind CHECK, cadence_config (flexible) extended, session_exercises.deleted_at added, and the appointments.{channel, protocol_id, session_id} + status-enum split landedstruck 2026-08-02: same false claim as the F5 item above. The appointments columns were designed, not created; there is no appointments table.
  • [x] F9.3 Phase 2 patient-facing flows: portal pages render protocols + session player (live in prod).
  • [x] F9.4 Phase 2 stats slice — /patients/[id]/stats operational visibility (clinical vitals header + activity log + playback health).
  • [x] Portal pages: program landing, enrollment flow, session player, per-session instrument capture (on session_runs.feedback_* fields).
  • [x] Audit log + RLS + data classification entries on every shipped column — enforced by the CI gate.
  • [ ] September delta — full programs + seeded platform catalog: the demo seeded one curated session; September needs the full 10-session + phased programs (program_phases substrate shipped — populate it) and a seeded platform-tier catalog patients can self-enroll into. Uses the programs shape with sessions.program_id direct containment, NOT the old treatment_plans or the retired program_sessions junction. SOUP entries for any new direct deps — same PR.

F10 media half (separate service) — DONE (shipped via the June-10 demo)

The media/engagement telemetry half shipped with the demo. The pose ingest pipeline stays deferred past September (keep the client-side MediaPipe skeleton preview only — no MDR / IEC-62304 scope). September delta on this service is operational: bring the media service fully live in prod (Stream E) — verify against the deployed state, since "shipped to staging" is not "on prod" until promotion.

  • [x] services/telemetry/cmd/ Go service scaffold
  • [x] Cat F service-account principal for callback into API
  • [x] Signed-session-token verifier (HS256); issuer ships in API at session start
  • [x] Ingest endpoints: POST /v1/media/events, POST /v1/sessions/{id}/end
  • [x] In-flight buffer + session-end aggregation: per-session watch %, completion, duration written to media_session_metrics (telemetry-owned)
  • [x] PG tables: media_session_metrics, media_buffering_events — monthly partitioned per P41
  • [x] Empty pose-half migrations: pose_session_metrics + pose_rep_metrics partitioned now, populated only when pose ingest ships (deferred past September)
  • [x] F10.5 lawful-basis posture: media-events / library-views ingest is Art. 6(1)(f) legitimate interest — gated by signed-session-token audience + signature only, no consent flag, no 403-on-consent path. Art. 21 right to object honoured at the controller (clinic) tier. Pose ingest stays consent-gated (biometric flag). See decisions.md → Why engagement telemetry is legitimate interest, not consent.
  • [x] algorithm_version recorded on every metrics row; CI guard cmd/check-telemetry-bounds
  • [x] Events.Bus subscriber in API consumes session-aggregated event, writes rows
  • [x] Read endpoints: GET /v1/me/exercise-sessions, GET /v1/patients/{id}/exercise-sessions

Public self-signup (September delta — demo used legacy handoff only)

The demo onboarded patients exclusively through the legacy→new handoff bridge (shipped). September adds true open self-serve sign-up for the 5k expected.

  • [ ] Public landing page + open sign-up flow on portal
  • [ ] self_signup_disabled=false on the launching org(s)
  • [ ] Open-link onboarding (no invite required); reuses 1B.8 portal onboarding
  • [ ] Under-16 parental-consent path (Romania = 16) — counsel may dictate flow
  • [ ] Rate limit + bot protection on sign-up endpoint (anticipate abuse at 5k expected)

Thin Console reads (operator visibility) — DONE (Console platform-stats shipped via the demo)

  • [x] Console page reading adherence metrics (signups, sessions started, sessions completed, drop-off by session number)
  • [x] Console page reading individual patient sessions + playback health
  • [x] No CRUD UI on this slice; content seeding via migration

Stream D — Mobile UX + Cast

The mobile-first portal + Bunny player + TV/cast slice shipped via the demo and is live in prod (patient side at 100% production quality). The September delta is verification of the new September pages (open self-signup, full programs, clinic-ops patient touchpoints) against the same bar, plus the iOS-playback fix tracked in Stream E.

  • [ ] Mobile-first audit of the September-new portal pages (open sign-up, full program landing/enrollment, any clinic-ops patient touchpoints) — the demo pages already passed
  • [x] Cast/TV slice on Bunny player (Chromecast + AirPlay via HLS) — shipped, with the companion/TV-parity hardening wave on top
  • [ ] Tap-target audit (44pt minimum); virtual-keyboard handling on inputs; safe-area insets — for new pages
  • [ ] Test matrix: iOS Safari, Android Chrome, desktop Chrome — re-run including the iOS-playback fix
  • [ ] Slow-connection testing (mid-tier Android on throttled 3G)
  • [ ] P46 portal hybrid architecture conformance review (server shell + client for live bits)

Stream E — Pre-launch Operations

  • [x] Clerk production app/keys; production webhook endpoint verified (shipped via the demo)
  • [x] Bunny CDN production account wired (shipped via the demo); bandwidth contract sizing for 5k × 10 sessions still to confirm against the launch-month range (~1.25 TB)
  • [ ] iOS-playback fix — Bunny token-auth signed URLs. Known prod bug: Bunny hotlink protection → CoreMedia 403 on iOS (~30% completion). Tracked launch-gate item; do not ship the migration until this is closed.
  • [ ] Bring media-service + clinic app fully live in prod. Both are IaC-provisioned; the September delta is the operational cutover + verification under real-clinic load.
  • [ ] Sentry: org created, project per service (API + 3 Next.js + Telemetry); source-map upload in CI; release tracking by image SHA; alert routing to Slack
  • [ ] SES app-layer bounce/complaint handler (production-launch-readiness.md L65-70):
    • SNS topic restartix-prod-ses-feedback subscribed to SES bounce + complaint events
    • Migration: notification_suppression table (recipient, reason, suppressed_at, source event ID) + RLS restricting reads to platform-admin
    • Webhook: POST /v1/internal/ses-feedback with SNS signature verification
    • EmailChannel precheck: query suppression by recipient address; if present, mark dead-lettered with dead_letter_reason='suppressed'
  • [ ] CloudWatch product dashboards: signups/day, sessions started, sessions completed, drop-off by session number, video watch % distribution, time-to-first-session, p95 API latency, error rate, telemetry ingest lag
  • [ ] Status page (statuspage.io or similar) automated from CloudWatch
  • [ ] support@restartix.pro mailbox provisioned (referenced in break-glass templates); also noreply@restartix.pro for send-only
  • [ ] On-call rotation documented; synthetic incident drill against staging
  • [ ] DSAR / erasure end-to-end: DSAR export (single JSON dump per-patient), erasure (anonymise per Art. 17(3)(c) — keep audit trail)
  • [ ] Incident response playbook reviewed by on-call engineers
  • [ ] ~20k legacy migration tooling — pre-launch task (11k+ treatment plans, 5k+ subscriptions). Plan closer to launch; tracked launch-gate item, not an active current workstream. Gated by Stream A counsel sign-off on v2 legal text.

Milestones (June → September, guide not contract)

Ordered by dependency, not calendar week — the September window is the outer bound, and the critical path runs through Stream A counsel sign-off (longest lead) and the clinic-ops build.

  1. Engage Romanian counsel immediately (Stream A). 2–3 week lead regardless of effort; v2 legal text + sign-off gates the migration. Start before anything else on the path.
  2. Close the iOS-playback bug (Bunny token-auth signed URLs) — known prod regression at ~30% completion; launch-gate item.
  3. Build the clinic-ops stack (F1/F3/F4/F5/F6) — the bulk of new feature work; each follows the foundation checklist.
  4. Open self-serve signup + full 10-session / phased programs + seeded platform catalog (the demo only did legacy handoff + one curated session).
  5. Operational hardening (Stream E + Stream B delta): enable backup cron, SES bounce/complaint handler, Sentry, status page, on-call, support inbox; bring media-service + clinic app fully live in prod.
  6. Load + resilience gates: k6 5k-shape load test; cross-region backup + restore drill.
  7. DSAR / erasure end-to-end; counsel-reviewed templates locked; marketing copy MDR review.
  8. Pre-launch — ~20k legacy migration tooling (planned closer to launch, gated by counsel sign-off), then the migration + September launch.

Critical-path callouts

  1. F11.0.5 counsel gates the migration. v2 legal text + sign-off is the longest-lead item and blocks the ~20k migration. Engage immediately; if review slips, the choice is delay launch or launch onto migrated patients under un-reviewed templates (not acceptable). Decide contingency early.
  2. iOS-playback fix is launch-blocking. Bunny hotlink → CoreMedia 403 at ~30% completion; the token-auth signed-URL fix must land before the migration brings real patients onto iOS at scale.
  3. Clinic-ops build is the bulk of new work. F1/F3/F4/F5/F6 are scaffold-only today; budget the largest share of feature engineering here.
  4. 5k self-serve = no human in loop. Edge cases (under-16, abandoned onboarding, expired Clerk verification email, DSAR with no operator support) must work autonomously.
  5. The shipped substrate is the foundation — don't re-migrate it. Programs / protocols / cadence engine / content_files / exercise dual-ownership are live in prod. Build September features against this shape, not the old patient_assigned_sessions. See programs-and-assignments.

Open decisions

DecisionWhereWhen to resolve
Per-exercise programs containing audio sessions in addition to exercise sessions for launch (Phase 1 supports it; Phase 2 decides whether to expose)F9.3 (clinic builder UI)Only if first audio content is curated in time
WAF for clinic custom hostnames: Cloudflare WAF-for-SaaS add-on vs. AWS WAF on ALBStream BBefore WAF/Cloudflare contract locks
Public landing page URL: restartix.pro root vs. portal.restartix.pro/join vs. dedicated /programs pageStream CLocks marketing copy review scope
Under-16 parental consent flow: block at signup, parent email verification, or skip launch (require 16+)Stream A + CDriven by counsel finding

What this rules out

  • "Migrate the ~20k onto un-reviewed legal text and fix it later." The migration is gated by counsel sign-off on v2 templates — once real patients are migrated under a privacy notice, consent re-collection is a permanent shape, not a temporary hole.
  • "Patch the schema later." The live session_runs rows + partitioned event tables already in prod make column-add migrations heavy at scale. Build September features against the shipped substrate — no ALTER TABLE after rows accumulate.
  • "Add pose ingest the week after launch." Pose tables are pre-partitioned, but the pose-ingest pipeline + MediaPipe SOUP + biometric consent surface + MDR scope land separately when pose ships (deferred past September; the client-side preview stays).
  • "Skip Sentry to ship faster." Permanent open access without error observability is a permanent unknown-unknowns liability.