Public: anyone can read this; the crew can change it.
Platform app move gap: Rehearsal mode: a preview seeded from a copy of production data #11714
Check · Review · Land · Live done — Landed and live in production.
mason/forge:mason/11702-platform-app-move-gap-rehearsal-mode-a-p → main 1 commit fork
2 files
changed +27
−1
docs/APPS.md +7
| @@ -386,6 +386,13 @@ around it. None is advisory. | ||
| 386 | 386 | `main` the pull's commit predates — is tried exactly once more on an |
| 387 | 387 | empty data directory before the deploy is failed; production is never |
| 388 | 388 | seeded from a copy, so this never applies to it. |
| 389 | **Rehearsal.** A preview of a moved app is a rehearsal: the copy above, | |
| 390 | plus variables set for scope `preview`, which win over `all` and | |
| 391 | `production` of the same name (`core/app_env.ts`). Set a payment key | |
| 392 | once for `production` (live) and once for `preview` (sandbox); a name | |
| 393 | left in `all` reaches previews too, so a live key must never be there. | |
| 394 | The forge does not know which names are payment keys and does not refuse | |
| 395 | one; the procedure is in `docs/features/platform-app-move.md`, step 4. | |
| 389 | 396 | 4. **A deployment is a check.** Every deploy is a run; the run's state is |
| 390 | 397 | what the pull shows. With `require_checks` on, `mergePull` refuses |
| 391 | 398 | `checks_required` until the head's deploy run is `ok`, read live inside |
docs/features/platform-app-move.md +20 −1
| @@ -35,6 +35,25 @@ Preview address, a copy of the data, the payment **sandbox** keys. The owner, | ||
| 35 | 35 | or the shop's owner, places an order and the webhook lands. No cut-over before |
| 36 | 36 | they say so in the issue. |
| 37 | 37 | |
| 38 | The forge already does the parts of this (`docs/APPS.md`, "Rehearsal"): a | |
| 39 | preview's data is a copy of production's taken when it is created, and a | |
| 40 | variable set for scope `preview` beats the same name set for `all` or | |
| 41 | `production`. So the rehearsal is a procedure, in this order: | |
| 42 | 1. In **Settings → App → Environment**, set each payment name (for example | |
| 43 | `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`) with scope `production` to | |
| 44 | the live value and with scope `preview` to the sandbox value. | |
| 45 | 2. **Never leave a payment name in scope `all`.** `all` reaches previews, so | |
| 46 | a live key there is a live key in the rehearsal. Move it to `production` | |
| 47 | before the pull is opened. | |
| 48 | 3. Open the pull; read the app's payment-mode indicator (the app should show | |
| 49 | `sandbox` on the preview) before anyone places an order. | |
| 50 | 4. The copy is disposable: it is gone with the pull, and nothing placed on it | |
| 51 | reaches production's data. | |
| 52 | ||
| 53 | What stays open: the forge cannot tell which names are payment keys, so | |
| 54 | nothing refuses a live key in `all` or in `preview`; the checks above are a | |
| 55 | person's. Webhooks reaching a preview's changing address are #11703. | |
| 56 | ||
| 38 | 57 | ## 5. Backup before anything is removed (person) |
| 39 | 58 | Encrypted dump and files archive (`age` or `gpg`, key held by the owner, not |
| 40 | 59 | on the node). Restore it into a scratch database and compare the step-3 |
| @@ -54,7 +73,7 @@ counts. The old copy stays until that has passed. | ||
| 54 | 73 | - A file and upload copy with a manifest compared on both ends. (#11699) |
| 55 | 74 | - A custom domain for an app with certificate issuance, and a one-step revert of it. (#11700) |
| 56 | 75 | - Per-app encrypted backup with a restore proof (`docs/features/backup-truth.md` covers the forge's own, not an app's). (#11701) |
| 57 | - A rehearsal mode: a preview seeded from a copy of production data, with payment sandbox keys only. (#11702) | |
| 76 | - A guard for rehearsal: data copy and `preview`-scoped sandbox keys exist and are the procedure in step 4; nothing yet refuses a payment name left in scope `all`. (#11702) | |
| 58 | 77 | - Inbound payment webhooks that survive a preview's changing address. (#11703) |
| 59 | 78 | - A read-only switch for the old side of a migration. (#11704) |
| 60 | 79 | - Importing an app's customer accounts (password-hash formats) without the owner reading them. (#11705) |
new above
offline