Skip to content

Tier 4 Onset T-4 Prep Report — T4-0 through T4-3 (STOP before DNS)

Status: STOP — ready for Ryan T4-4 DNS cutover (Sun 03:00–07:00 PDT)
Date: 2026-08-30
Authorization: Ryan T-4 go (prep phases only)
Plan: TIER_4_ONSET_T4_EXECUTION_PLAN.md


Executive summary

T4-0 pre-cutover remediation is green on R940: 3 cron jobs, 20 storage objects (metadata + files), vault aligned to LAN clinic, all 3 cron routes HTTP 200 against http://192.168.1.101:3000. /patients/new migrated off client supabase.auth.getUser() and redeployed on VM 118.

T4-1/T4-2: onset-edge tunnel created and cloudflared active on VM 118 with ingress validated. No DNS changes.

T4-3: Vault + BWS edge keys aligned to live R940 state. Railway + hosted Supabase remain rollback net.

Hard stop: T4-4 DNS cutover is Ryan-only in the Sun window.


T4-0 — Pre-cutover remediation

T4-0a — pg_cron (PASS)

Check Result
SELECT COUNT(*) FROM cron.job 3
Jobs clinic_weekly_summary, clinic_protocol_deliveries, clinic_fullscript_sync
Vault decrypt clinic_cron_secret, clinic_portal_base_url = http://192.168.1.101:3000
Manual triggers → R940 clinic HTTP 200 (all 3 routes)

Actions taken:

  1. Restored cron.job rows from Gate B dump (pg_restore as supabase_admin).
  2. Recreated vault secrets (hosted dump ciphertext not decryptable on R940 pgsodium).
  3. Refactored trigger_clinic_weekly_summary() to use trigger_clinic_cron_route('/api/cron/weekly-summary').

Scripts: scripts/onset/t4-0-vault-align.py, scripts/onset/t4-0-smoke-pre-cutover.sh

T4-0b — storage.objects (PASS)

Check Result
Metadata storage.objects 20
Buckets templates (18), clinic-support-attachments (2)
Schema align Added versioning_status, archived_at, is_delete_marker, is_versioned
File migration 19 files API-migrated from hosted prod (~3.2 MB on disk)
Public URL http://192.168.1.102:8000/storage/v1/object/public/templates/posts/1.png → 200
Private signed URL clinic-support-attachments/...png → sign OK

Note: Hosted file download used Railway prod SUPABASE_SERVICE_ROLE_KEY (sb_secret_…, ref emxrmjysvxeboavhatry), not BWS legacy SUPABASE_SERVICE_ROLE_KEY (staging lzpyfohgfdohrtlamzek). RealOutcomes lesson applied: validate against live Railway, not stale BWS copy.

Script: scripts/onset/t4-0-migrate-storage-files.py

T4-0c — /patients/new bootstrap (PASS)

Check Result
Client supabase.auth.getUser() Removed
Pattern Server getClinicPortalContext() → NewPatientClient props
Deploy VM 118 container recreated (onset-clinic-app)
Repo Branch t4-0-patients-new-bootstrap on clinic.theonset.app

Ryan device verify: Load /patients/new with Last1 session after Gate E login (LAN http://192.168.1.101:3000/patients/new).


T4-1 — onset-edge tunnel (PASS)

Item Value
Tunnel name onset-edge
Tunnel UUID fe2fa2de-d776-485f-85ed-84415f0c3493
CNAME target fe2fa2de-d776-485f-85ed-84415f0c3493.cfargotunnel.com
Connector VM 118 onset-app — active (1 connector, 3 edge connections)
BWS ONSET_APP_PROD_EDGE_CLOUDFLARED_TUNNEL_ID, _TUNNEL_CNAME, _TUNNEL_CREDENTIALS

T4-2 — Ingress config (PASS, no DNS)

/etc/cloudflared/config.yml on VM 118:

tunnel: onset-edge
credentials-file: /etc/cloudflared/fe2fa2de-d776-485f-85ed-84415f0c3493.json

ingress:
  - hostname: clinic.theonset.app
    service: http://192.168.1.101:3000
  - service: http_status:404
Check Result
cloudflared tunnel ingress validate OK
systemctl is-active cloudflared active
Clinic LAN http://192.168.1.101:3000/ → 200

Fix applied: Origin must be 192.168.1.101:3000 (Docker binds LAN IP, not 127.0.0.1).

Script: scripts/onset/install-onset-edge-cloudflared.sh


T4-3 — Vault + env alignment (PASS)

Item R940 live value
clinic_portal_base_url (vault) http://192.168.1.101:3000
clinic_cron_secret (vault) Matches ONSET_APP_PROD_CRON_SECRET (BWS ↔ VM 118 .env)
VM 118 DATABASE_URL host 192.168.1.102 (not hosted)
VM 118 NEXT_PUBLIC_SUPABASE_URL http://192.168.1.102:8000
Edge tunnel BWS Created (see T4-1)

At T4-4 DNS: Update vault clinic_portal_base_url to https://clinic.theonset.app before first post-cutover cron fire.

Rollback net unchanged: Railway clinic origin + hosted Supabase (emxrmjysvxeboavhatry, lzpyfohgfdohrtlamzek) remain live. iOS Release xcconfig untouched.


BWS legacy keys aligned (T4-3 closeout)

Legacy unprefixed SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY / SUPABASE_ANON_KEY updated to match ONSET_DB_PROD_* (R940). Clinic render path (render-onset-env-app.sh) already used prefixed keys only; legacy keys were a script/human landmine (RealOutcomes pattern).


Ready for T4-4 (Ryan — Sun 03:00–07:00 PDT)

  1. Update vault clinic_portal_base_url → https://clinic.theonset.app
  2. CNAME clinic.theonset.app → fe2fa2de-d776-485f-85ed-84415f0c3493.cfargotunnel.com (proxied)
  3. Run T4-R clinic E2E on prod hostname
  4. Reply T-4 pass or share failure detail

Do not merge clinic /patients/new PR or cut DNS until Ryan reviews this report.


Scripts added (lastvet-gates)

Script Purpose
t4-0-vault-align.py Recreate vault secrets + weekly summary refactor
t4-0-migrate-storage-files.py Hosted → R940 storage file API migration
t4-0-smoke-pre-cutover.sh Cron + storage count verification
install-onset-edge-cloudflared.sh T4-1/T4-2 tunnel install on VM 118

END T-4 prep report (STOP before DNS)