atlilith/@platform/docs/phase-5-gates.md
2026-05-16 22:44:19 -07:00

81 lines
6.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase 5 — Infrastructure Foundation Verification Gates
Phase 5 is the wall between scaffolding (Phases 14, done) and feature work (Phase 6+). When Phase 5 closes, `manage-apps start atlilith apricot` brings up an empty-but-functional platform, deploys can fire via `./run deploy:<service>`, and backups + tunnels run unattended. **No feature code lands until §5.8 below all green.**
Living checklist. Update statuses here, mirror to `../DESIGN.md §8 Phase 5` if you change scope.
## 5.1 — Port registry & env
- [ ] `infrastructure/ports.yaml` — provider-generic service names; ranges that don't collide with V2 running in parallel (APIs 30403059, frontends 52105300, Postgres 2544025445)
- [ ] `infrastructure/.env.ports` — committed, sourced by `manage-apps`, in sync with ports.yaml
- [ ] No hardcoded ports in code — use `$ATLILITH_*_PORT` env vars
## 5.2 — Databases
- [ ] `infrastructure/compose.platform-db.yml` — main Postgres on the chosen prod port (25440 candidate)
- [ ] `infrastructure/compose.platform-minio.yml` — MinIO for objects
- [ ] `infrastructure/pg-services.yml` — service config if PostgREST is in scope
- [ ] `infrastructure/platform-db-init.sql` — base schema adapted from V2's `quinn-db-init.sql`
- [ ] `infrastructure/sql/migrations/001_add_orgs.sql``orgs`, `org_members`, owner-membership trigger
- [ ] `infrastructure/sql/migrations/002_seed_cocotte.sql` — inaugural Cocotte Org, transquinnftw as owner
- [ ] pgBouncer compose (or compose extension) for transaction-mode pooling in front of the main DB
## 5.3 — Reverse proxy (Caddy)
- [ ] `infrastructure/Caddyfile.local` — dev TLS for `*.atlilith.apricot.lan` (or whichever dev TLD V3 chooses; consider reusing the `.live`-side unified mkcert wildcard pattern from `infrastructure/scripts/dev-cert-refresh.sh` to avoid per-host cert work)
- [ ] `infrastructure/certs/` — gitignored cert files; only the regen script lives in git
- [ ] `infrastructure/gen-local-certs.sh` (or `dev-cert-refresh.sh`) — regen script that auto-reloads Caddy
- [ ] Production: per-host Caddyfile / nginx templates under `deployments/@domains/<domain>/`
## 5.4 — DB connectivity between hosts
V3 authoritative Postgres lives on **black**, behind `platform.api`. vps-0 (V3 role) is web UI + public-info cache only. Private/authenticated data never leaves the LAN.
V2 and V3 run side by side. V2's `quinn-*-api` units and local Postgres `:5435` on vps-0 stay where they are, serving Quinn's existing traffic. V3 stands up a parallel stack — own ports (`DESIGN.md §8 Phase 5.1`: 30403059 APIs, 2544025445 PGs), own services, own tunnel. **No migration of V2 surfaces in Phase 5.**
- [ ] **Tunnel direction (V3):** initiated **from black**. Pattern reference: V2's `quinn-m-orchestrator-tunnel.service` on black. vps-0 reaches `platform.api` over the tunnel; vps-0 cannot initiate inbound to black (security: vps-0 compromise → no LAN pivot)
- [ ] `infrastructure/scripts/setup-tunnel.sh` — systemd `user@.service` + autossh for persistence + reconnect, originating on black
- [ ] Health check from vps-0: `curl -sf http://localhost:<tunneled-api-port>/health` should return 200
- [ ] Document in `../INFRA.md §5 Inter-host links` and lock it down before features arrive
## 5.5 — ACS integration
- [ ] `users/transquinnftw/app.manifest.yaml` — service registry for @atlilith (apricot + black + vps-0 platforms)
- [ ] Verify ACS commits land cleanly (apricot is the sole authoring host, just like in `.live`)
- [ ] Pre-commit hook for `bun run typecheck` / `bun lint` on changed files; block the commit on fail (no `--no-verify`)
## 5.6 — Backups & DR
- [ ] `infrastructure/scripts/backup-pg.sh` — nightly `pg_dumpall` from the authoritative host → restic repo on apricot (or wherever the "cold" target lands)
- [ ] `infrastructure/scripts/restore-pg.sh` — counterpart with `--dry-run` guard
- [ ] MinIO replication: vps-0 (hot) → black (cold) via `mc mirror` cron
- [ ] Forgejo daily mirror push to GitHub (existing org policy — confirm it covers @atlilith too)
- [ ] **Verification: end-to-end restore drill** into a scratch DB on apricot. A backup that hasn't been restored is not a backup.
## 5.7 — Build / deploy pipeline
- [ ] `run` shell entrypoint at repo root (`./run dev`, `./run dev:stop`, `./run dev:status`, `./run dev:logs`, `./run build`, `./run deploy:<service>`)
- [ ] `.forgejo/workflows/typecheck.yml``bun install && bun run typecheck` on every push
- [ ] `.forgejo/workflows/lint.yml` — on every push
- [ ] `.forgejo/workflows/deploy-template.yml` — reusable, parameterized by `with: service: <name>`
- [ ] Per-service `deployments/@domains/<svc>/deploy.sh` template (rsync to host, systemd reload, smoke test). **Must ship bundled artifacts; no remote `npm install` on the VPS.**
## 5.8 — Verification gates (ALL must pass before Phase 6 can start)
- [ ] `manage-apps start atlilith apricot` brings up DB + MinIO + mailpit (and pgBouncer if 5.2 includes it) cleanly
- [ ] `manage-apps status atlilith apricot` returns healthy for every service entry
- [ ] `psql -h <db-host> -p <db-port> -U platform -c "SELECT * FROM orgs WHERE slug='cocotte'"` returns 1 row (proves seed + connectivity)
- [ ] JWT-bearing `curl` through Caddy to a placeholder route succeeds (proves TLS + SSO scaffold + routing)
- [ ] If a cross-host tunnel is in scope: vps-0 can connect to the authoritative DB through it
- [ ] `backup-pg.sh && restore-pg.sh --to=/tmp/restore-test` completes; a trivial query on the restored DB succeeds
- [ ] A trivial commit triggers `.forgejo/workflows/typecheck.yml` and it passes
## Files to carry from V2
- `~/Code/@projects/@lilith/lilith-platform.live/infrastructure/{ports.yaml,.env.ports,Caddyfile.local,compose.*.yml,pg-services.yml,quinn-db-init.sql,gen-local-certs.sh,setup-*.sh,scripts/dev-cert-refresh.sh}`
- `~/Code/@projects/@lilith/lilith-platform.live/users/transquinnftw/app.manifest.yaml`
- `~/Code/@projects/@lilith/lilith-platform.live/run`
Adapt — don't copy blindly. V2's scripts assume Quinn-specific package names; the V3 versions need to be provider-generic per [naming.md](./naming.md).
Related: `../DESIGN.md §8`, `../INFRA.md §11`.