Print the private VPS operator path before anyone starts improvising.
The deployment rehearsal plan is a secret-free CLI checklist that stitches together VPS bootstrap, compose validation, production preflight, external edge smoke, disposable member smoke, owner dashboard visual review evidence, payment-provider review evidence, backup manifest/custody metadata, restore-drill planning, and the private VPS readiness gate. Run it first for a disposable/private test-VPS-like rehearsal host; passing it proves a transplantable container/edge/runtime shape, not the official long-lived VPS cutover.
Generate the rehearsal plan
cargo run -- deployment-rehearsal-plan \
--origin https://members.final-domain.example \
--backup-id backup-YYYYMMDD \
--app-commit 15496a9 \
--proxy nginx \
--env-file .env.production
The alias vps-rehearsal-plan prints the same report. The command validates that the selected rehearsal origin is HTTPS, the backup ID is concrete, runtime ledger paths are separated from source/runtime artifacts, the env path is not the committed example, and the gitignore still protects deployment evidence, backup artifacts, manifest, and custody roots. nginx is the safe default label; plain caddy warns and cannot satisfy widening evidence, while caddy-trusted-edge or trusted-edge must be used only after separately validating that control.
What the plan ties together
| Phase | Operator action | Evidence posture |
|---|---|---|
| Bootstrap | Run vps-bootstrap-plan and Docker compose config against the private env on the disposable rehearsal host. | No evidence record yet; this prevents bad inputs before services start and verifies compose persistence for backup, manifest, and custody volumes. |
| Private services | Start the VPS compose stack only after bootstrap passes and host ports remain private. | Still no public edge; failures are local/test-VPS-only and the proven shape can later be transplanted to the official VPS. |
| Preflight | Run production-preflight on the target runtime. | Record production_preflight with a sanitized artifact hash. |
| External edge | Attach the selected edge, validate nginx's memory-only sensitive-POST limits or a separately reviewed stock-Caddy trusted-edge throttle, then run scripts/external-edge-smoke.sh from outside the VPS network. | Record external_edge_smoke and controlled aggregate 429 behavior without retaining raw source identifiers. |
| Disposable member | Provision a recovery-confirmed smoke member using an operator recovery-key file. | Record smoke_member_provision without storing the recovery key. |
| Authenticated smoke | Run scripts/external-member-smoke.sh with the disposable member and recovery-key file. | Record external_member_smoke after login, library, media, download, checkout-return, owner-gate, and logout checks pass. |
| Cleanup | Revoke disposable member access/sessions and expire stale checkout state. | Record smoke_member_cleanup. |
| Owner visual review | Run the owner dashboard browser checklist after the dashboard is reachable in the private environment, then write the result with owner-dashboard-review-plan --artifact-file ... --review-result passed and verify it with owner-dashboard-review-artifact-check --artifact-file .... | Record advisory owner_dashboard_visual_review evidence with the verified artifact hash instead of pasted browser notes. |
| Payment provider review | After written adult/AI-adult processor evidence exists, write the result with payment-provider-review-plan --artifact-file ... --provider manual --review-result passed and verify it with payment-provider-review-artifact-check --artifact-file .... | Record advisory payment_provider_review evidence with the verified artifact hash instead of pasted contracts, dashboards, approval emails, or provider logs. |
| Backup metadata | Record sealed dump/media hashes and encrypted/offsite custody metadata. | Use backup-manifest-* and backup-custody-*; never store backup contents. |
| Restore drill | Use restore-drill-plan --backup-id ... --manifest-file ... --custody-file ... to prepare the isolated restore checklist for the selected sealed backup pair. | Only record backup_restore_drill after manifest/custody preflights and a real isolated drill pass. |
| Operational summary | Run owner-operational-summary --artifact-file ... against the selected rehearsal origin and backup ID. | Exports one sanitized owner-facing readiness snapshot with artifact hash evidence posture. |
| Readiness | Run private-vps-readiness against the selected rehearsal origin and backup ID. | Blocks widening private testing if any required evidence or backup/custody metadata is missing. |
Optional path overrides
cargo run -- deployment-rehearsal-plan \
--origin https://members.final-domain.example \
--backup-id backup-YYYYMMDD \
--artifact-dir /secure/operator/nocturne-evidence \
--recovery-key-file /secure/operator/nocturne-smoke-recovery-key.txt \
--evidence-file deployment_evidence/evidence.log \
--manifest-file backup_manifests/manifest.log \
--custody-file backup_custody/custody.log
--artifact-diris where the operator stores raw command output outside git. The rehearsal plan only references the path.--recovery-key-fileis the temporary smoke-member key path. The plan reminds the operator to destroy it through an approved process after cleanup.--evidence-file,--manifest-file, and--custody-filedefault to git-ignored local ledgers and must remain separate.- If
--app-commitis omitted, the printed plan derivesAPP_COMMITwithgit rev-parse --short HEADat rehearsal time.
Do not widen private testing when any stop condition fires
- The rehearsal plan reports failed checks, including missing backup, manifest, or custody persistence in the VPS compose shape.
- The private env is still an example file, group/world-readable, or placeholder-filled.
- Bootstrap, compose config, production preflight, edge smoke, member smoke, cleanup, provider-review artifact check, evidence check, backup manifest check, custody check, or private readiness fails.
- The selected edge has no validated sensitive-POST throttle, throttle testing exposes raw source identifiers, or legitimate shared-NAT traffic is unacceptably blocked.
- Any raw secret, recovery key, owner key, database URL, payment/customer identity, provider URL, raw IP, user-agent, or access log would need to be pasted into git or chat to proceed.
- The operator is drifting from disposable test-VPS validation into official long-lived VPS cutover or public-launch claims.