# Complete VM Rehearsal and Production Cutover

You are working on StratoFusion. Complete the remaining OVH VM rehearsal, local VM rehearsal, and production cutover preparation without changing live apex production until explicit cutover approval is given.

## Required Context

Before acting, read:

- `AGENTS.md`
- `README.md`
- `public/docs/developer/AI_OPERATING_PROTOCOL.md`
- `docs/ai-skills/01-architecture.md`
- `docs/ai-skills/03-rclone-data-plane.md`
- `docs/ai-skills/08-testing.md`
- `docs/ai-skills/09-authentication-oauth.md`
- `docs/ai-skills/11-deployment.md`
- `docs/phase-b-checklist.md`
- `docs/local-vm-rehearsal.md`
- `public/docs/DEPLOYMENT.md`
- `public/docs/RCLONE_SERVICE.md`

Use PowerShell and PNPM on Windows. Do not use WSL. Use explicit Git Bash only for `.sh` scripts that require POSIX shell behavior.

## Current Known State

- Branch: `migrate/vm-consolidation`.
- Pushed commits:
  - `5feb92d7` - supports OVH `vm-*` and local `.test` rehearsal hostnames.
  - `39388f8b` - allows VM deploy job to log into GHCR before pulling images.
- GitHub `VM Deploy` rerun for `39388f8b` passed.
- OVH VM at `15.204.243.136` has healthy internal app and rclone services.
- OVH Caddy now serves only:
  - `vm-staging.stratofusion.io`
  - `vm-rclone.stratofusion.io`
  - `vm-grafana.stratofusion.io`
  - `vm-glitchtip.stratofusion.io`
- OVH VM runtime env has been updated to `vm-staging` / `vm-rclone` URLs.
- OAuth redirect env vars on the OVH VM have been updated to:
  - `https://vm-staging.stratofusion.io/api/google`
  - `https://vm-staging.stratofusion.io/api/onedrive`
  - `https://vm-staging.stratofusion.io/api/dropbox`
- `CRON_REPLICAS` must remain `0` and `AUTH_ACCESS_PAUSED` should remain `true` except during a controlled auth verification window.

## Remaining OVH Blocker

Public DNS for the `vm-*` hostnames still resolves to Vercel edge IPs, not the OVH VM. Create or update these DNS A records:

| Host | Type | Value |
| --- | --- | --- |
| `vm-staging.stratofusion.io` | A | `15.204.243.136` |
| `vm-rclone.stratofusion.io` | A | `15.204.243.136` |
| `vm-grafana.stratofusion.io` | A | `15.204.243.136` |
| `vm-glitchtip.stratofusion.io` | A | `15.204.243.136` |

Do not change apex, `www`, `rclone`, `grafana`, or `glitchtip` production records until Phase C cutover is explicitly approved.

After DNS changes propagate, verify:

```powershell
$names = @(
  "vm-staging.stratofusion.io",
  "vm-rclone.stratofusion.io",
  "vm-grafana.stratofusion.io",
  "vm-glitchtip.stratofusion.io"
)
foreach ($name in $names) {
  Resolve-DnsName $name -Type A | Select-Object @{Name="Name";Expression={$name}},IPAddress
}
```

Then verify real TLS and health:

```powershell
curl.exe -sSI https://vm-staging.stratofusion.io/api/health
curl.exe -sS https://vm-rclone.stratofusion.io/health
```

If certificates are still pending, inspect Caddy:

```powershell
ssh -i C:\Users\rhoun\.ssh\stratofusion-vm-deploy deploy@15.204.243.136 "cd /opt/stratofusion/deploy && docker compose -f docker-compose.prod.yml logs --tail=120 caddy"
```

## Third-Party Dashboard Requirements

Confirm these production-resource dashboard additions exist for the rehearsal host:

- Clerk production instance allowed origin/domain: `https://vm-staging.stratofusion.io`
- Google OAuth redirect URI: `https://vm-staging.stratofusion.io/api/google`
- Microsoft Entra redirect URI: `https://vm-staging.stratofusion.io/api/onedrive`
- Dropbox OAuth redirect URI: `https://vm-staging.stratofusion.io/api/dropbox`
- Stripe temporary webhook endpoint: `https://vm-staging.stratofusion.io/api/webhooks/stripe`

Do not remove apex production callbacks until Phase C cutover cleanup.

## Local VM Requirements

For a local VMware rehearsal, use the `local-vm.stratofusion.io` hostnames via
the Windows hosts file and Caddy internal TLS.

1. Add Windows hosts entries pointing to the local VM IP:

```text
LOCAL_VM_IP local-vm.stratofusion.io local-vm-rclone.stratofusion.io local-vm-grafana.stratofusion.io local-vm-glitchtip.stratofusion.io
```

2. On the local VM, configure:

```sh
cd /opt/stratofusion/deploy
cp Caddyfile.local.example Caddyfile.local
cp docker-compose.local.example.yml docker-compose.local.yml
```

3. Apply values from `deploy/local-vm.env.example` into the active `deploy/.env`, especially:

```env
DEPLOY_ENV=local-vm
NEXT_PUBLIC_SITE_URL=https://local-vm.stratofusion.io
NEXT_PUBLIC_APP_URL=https://local-vm.stratofusion.io
OAUTH_REHEARSAL_ORIGIN=https://local-vm.stratofusion.io
FLYIO_RCLONE_SERVICE_URL=https://local-vm-rclone.stratofusion.io
NEXT_PUBLIC_FLYIO_RCLONE_SERVICE_URL=https://local-vm-rclone.stratofusion.io
CRON_REPLICAS=0
AUTH_ACCESS_PAUSED=true
```

4. Trust Caddy's local root certificate on Windows as described in `docs/local-vm-rehearsal.md`.

5. Build or deploy an image whose public build-time URLs match the local `.test` origin if testing browser flows locally. Do not promote local `.test` images to OVH or production.

## Safety Rules

- Keep cron disabled during all rehearsals unless doing a short, explicit, user-approved cron test window.
- If a Neon production dump is restored to any VM, park all jobs except the operator's test jobs before enabling cron.
- Never run destructive rclone commands without explicit approval.
- Manual rclone commands must default to `--dry-run`.
- Do not print secrets, OAuth tokens, provider client secrets, webhook secrets, or complete `.env` contents.
- Do not change production apex DNS until the user explicitly approves Phase C cutover.

## Completion Criteria

OVH rehearsal is complete when:

- All four `vm-*` DNS records resolve to `15.204.243.136`.
- Caddy obtains valid public certificates for all four `vm-*` hosts.
- `https://vm-staging.stratofusion.io/api/health` returns healthy over real TLS.
- `https://vm-rclone.stratofusion.io/health` returns healthy over real TLS.
- Clerk sign-in, provider OAuth callbacks, upload/download, Grafana, GlitchTip, backup, and drain-gate checks from `docs/phase-b-checklist.md` are evidenced.
- `CRON_REPLICAS` is restored to `0` after any test window.

Local VM rehearsal is complete when:

- Windows hosts entries resolve all four `.test` names to the local VM.
- Browser TLS trusts the local Caddy root certificate.
- App and rclone health checks pass through the `.test` hostnames.
- Upload/download and optional restore/cron/drain rehearsals pass without affecting production jobs.

## Final Report

Report:

- DNS records changed and observed resolution.
- VM services and health check outputs.
- Caddy certificate status.
- Third-party dashboard items completed or still pending.
- Local VM setup status.
- Tests or manual checks run.
- Remaining risks and Phase C cutover blockers.
