diff --git a/DEPLOYMENT_PROFILES.md b/DEPLOYMENT_PROFILES.md index 4d40dba..3268f9a 100644 --- a/DEPLOYMENT_PROFILES.md +++ b/DEPLOYMENT_PROFILES.md @@ -249,6 +249,43 @@ racing on one service make deploy history impossible to read. > for roughly 100 days: the ritual below is easy to forget and nothing failed > loudly when it was. Prefer the workflow. +### Moving the demo to a new service (cutover checklist) + +Standing up a replacement service and retiring the old one has ordering +traps. Work through these in sequence; every step is verifiable before the +next one starts. + +1. **Set `REGENGINE_CORS_ORIGINS` to the NEW service's own origin — change + it, never copy or reference it.** This value names the host, so a Railway + reference variable (`${{old-service.REGENGINE_CORS_ORIGINS}}`) carries the + *old* URL and fails in two ways at once: browser requests lose their CORS + headers, and every state-changing request is rejected as an untrusted + origin (`app/auth_middleware.py` gates writes on the same list). + Verify: `curl -sD - -o /dev/null -H "Origin: https://" https:///api/healthz` + must echo the origin back in `access-control-allow-origin`. +2. **Replace secret reference variables with concrete values.** + `REGENGINE_BASIC_AUTH_USERNAME`, `REGENGINE_BASIC_AUTH_PASSWORD`, and + `REGENGINE_WEBHOOK_HMAC_SECRET` may reference the old service. Deleting + the old service while references remain breaks auth on the new one. +3. **Retarget every consumer of the old URL.** In this repo that is the + smoke workflows (`remote-smoke.yml`, `remote-browser-smoke.yml`, + `smoke-failure-issue.yml`) and the docs. Outside this repo, the RegEngine + dashboard reaches the demo through a Next.js proxy route **hosted on + Vercel**, so `INFLOW_LAB_SERVICE_URL` (fallback + `NEXT_PUBLIC_INFLOW_LAB_SERVICE_URL`) is a *Vercel* env var — it is not + on any Railway service, and Vercel bakes env at build, so the change is + inert until production is redeployed. + Verify: `https:///api/inflow-lab/api/healthz` reports the + new commit with `commit_source: RAILWAY_GIT_COMMIT_SHA`. +4. **Only then retire the old service.** Until step 3 lands everywhere, the + old service is the live backend for whatever still points at it. + +> Steps 1–2 are exactly what the GitHub-connected cutover missed in August +> 2026: the new service referenced the old one's variables, the URL-bearing +> CORS value came across stale, and both nightly smokes stayed red for three +> days after the cutover PR merged — with the failure attributed to the wrong +> cause until the allowlist was probed directly. + ### Manual CLI deploy (fallback) When deploying from the CLI, update the non-secret build variables before `railway up` so health checks can identify stale deployments: