133 lines
7.9 KiB
Markdown
133 lines
7.9 KiB
Markdown
# GCP leoclean migration goal
|
|
|
|
## Objective
|
|
|
|
Deploy and prove Leo's least-privilege Hermes/leoclean runtime in GCP staging
|
|
against canonical Cloud SQL, establish behavioral and database parity, connect
|
|
the protected Observatory to canonical/proposal/vector/runtime receipts, then
|
|
cut over safely and retire the VPS after soak.
|
|
|
|
## Architecture baseline
|
|
|
|
- Hermes with the `leoclean` profile remains Leo's intended runtime.
|
|
- Cloud SQL is canonical PostgreSQL authority.
|
|
- The protected Observatory is a separate frontend surface.
|
|
- The VPS remains untouched until an explicitly approved, parity-proven
|
|
cutover and retirement sequence.
|
|
|
|
## Current state
|
|
|
|
- Complete: PR #179 least-privilege PostgreSQL authority is merged on main.
|
|
- Complete: the revision-bound, structurally no-send runtime from PR #183 is
|
|
merged into `main` at `2d88c9765bd9b43641d1efb04a1118c5ce0bce39`.
|
|
- Complete: PR #182 head
|
|
`3e59845454f5315e955734db7fe598ec4ba4cf70` was merged with merge commit
|
|
`94a8160ceeb6821fd113f4c843f024d5de99939a` after all five checks passed.
|
|
- Complete: PR #202 remained the exact reviewed three-file QEMU/PID-1
|
|
correction at `ffe170007d0e20d77a5208263e5b33fc999139fc` after retargeting
|
|
to `main`, then merged with merge commit
|
|
`383996a43beebef57cf84a2ced53213e28a41dca` after all five checks passed.
|
|
- PR #193 is source material only. It must not be merged wholesale; only the
|
|
required identity-binding and OCI-lifecycle corrections belong in the narrow
|
|
#182/#183 stack.
|
|
- Complete through PR #182 head `3e59845`: the narrow package
|
|
correction binds every packaged and synthetic-identity source byte to its
|
|
reviewed Git blob; container health binds the packaged/live config plus the
|
|
exact sealed no-send tool and plugin surface; and the disposable image smoke
|
|
also binds the implicit root bootstrap user, entrypoint, command, healthcheck,
|
|
and stop signal. The focused package/runtime/identity/OCI suite passed 204
|
|
tests, the repository suite passed 2,338 with 3 skips, and one exact-revision
|
|
synthetic `linux/amd64` OCI lifecycle proved UID/GID `65532`, zero runtime
|
|
capabilities, no-send health, and complete candidate cleanup on the arm64 Mac
|
|
Docker daemon. No GCP or live service was contacted.
|
|
- PR #206 at exact head `e42d635523fcb90ecdd504b0f0290df7015991e7`
|
|
makes release finalization pull and inspect the exact immutable staging
|
|
digest. Its five checks pass, but it must not merge unchanged: PR #209's
|
|
final repair at `d2ad4f7c964ff70f01be65ad57290b1346153f95` is the required
|
|
corrective layer that prevents finalization from deleting daemon-global
|
|
digest references a Docker-config lock cannot exclusively own.
|
|
- Published as draft PR #210: one structured, self-hashed build/push receipt
|
|
producer. It derives the content-bound candidate tag, manifest digest, and
|
|
config binding from validated pre/post-push daemon state; finalization
|
|
consumes that receipt instead of caller-supplied digest/config values. The
|
|
branch has been rebuilt directly on PR #209's final repair and carries the
|
|
same retained-digest rule through both build/push and finalization. No
|
|
daemon-global build tag, candidate tag, immutable digest reference, or
|
|
receipt pathname is removed automatically. The receipt is published and
|
|
consumed only through a private operator-owned directory with a retained
|
|
two-link, stable-inode contract; remote candidates are retained. The exact
|
|
#210 head belongs in the mutable PR evidence, not recursively inside its own
|
|
commit.
|
|
- Current exact-head validation: 206 focused package/OCI tests and the full
|
|
repository suite at 2,480 passed with 3 expected skips; Ruff, Python compile,
|
|
and diff checks pass. Three independent advisory exact-head reviews approved
|
|
the receipt deletion/identity boundary. Tests mock Docker and perform no
|
|
registry push.
|
|
- Current gate: human exact-head review remains pending on #206 and #210. PR
|
|
#209 must first correct #206's feature branch; corrected #206 must be
|
|
re-reviewed and merged before #210 is retargeted to `main` for its own human
|
|
review and merge.
|
|
- In progress offline: a separate GCP staging preflight rebuilt on the final
|
|
#210 head. It checks exact control-plane and host prerequisites without
|
|
reading secrets, logging into PostgreSQL, deploying, or restarting. Its
|
|
bounded IAP/SSH path uses a fixed remote command and a maximum five-minute
|
|
key lifetime. Receipt publication now requires a pre-existing private
|
|
operator-owned directory, creates one mode-`0600` no-clobber/no-symlink
|
|
staged inode through a held directory descriptor, fsyncs it before a
|
|
no-clobber canonical hard link, and retains both links without automatic
|
|
cleanup. The host probe proves Docker loaded/active/running before its first
|
|
client call and unchanged service state, `MainPID`, and restart count after
|
|
the last, preventing socket activation from changing runtime state. No live
|
|
run is currently authorized.
|
|
- Artifact Registry cleanup policy is not an additional hard gate for the
|
|
package: immutable tags prevent deletion of the retained tagged candidate.
|
|
The post-push/finalization path must still re-prove the exact retained
|
|
candidate tag-to-digest binding immediately before deployment.
|
|
- Current offline evidence for the preflight extraction: 250 focused
|
|
preflight/package/OCI tests pass; Ruff, Python compilation, formatting, and
|
|
diff checks pass. The repository suite produced 2,504 passes and 5 expected
|
|
skips inside the desktop sandbox; all 18 sandbox-denied Docker, loopback, and
|
|
Swift-cache cases passed in a separately authorized 59-test local rerun,
|
|
reconciling the suite to 2,522 passes and 5 skips. No cloud or registry
|
|
endpoint was contacted.
|
|
- Historical only: the superseded preflight branch records an earlier live
|
|
observation of `e2-standard-4` on `teleo-staging-europe-west6`
|
|
(`10.60.0.0/20`) with an external IPv4 attachment. That observation is not
|
|
current-revision proof and has not been refreshed in this slice. The checker
|
|
intentionally fails while any public attachment remains.
|
|
- The older provisioning baseline names `e2-standard-2` and
|
|
`teleo-staging-subnet`; reconciling that declarative baseline is a separate
|
|
infrastructure change, not part of this preflight implementation.
|
|
- Not yet live-proven: staging VM/container engine, IAM/Secret Manager, Cloud
|
|
SQL effective identity, restart behavior, or model/database parity.
|
|
|
|
## Remaining order
|
|
|
|
1. Merge PR #209 into PR #206's feature branch, rerun exact-head checks, obtain
|
|
human review, and merge the corrected PR #206.
|
|
2. Update, review, retarget, and merge draft PR #210's structured build/push
|
|
receipt producer and receipt-bound release-v3 finalizer.
|
|
3. Review and merge the bounded staging preflight; under separate live
|
|
authorization, run its control-plane and IAP/SSH observations and verify the
|
|
staging repository/tag policy.
|
|
4. Under explicit live authorization, build and push one candidate, publish
|
|
its receipt, and independently finalize the exact digest.
|
|
5. Add the separate fail-closed installer/restart/verification/rollback slice
|
|
that consumes the exact inspection-bound release bundle.
|
|
6. Provision the scoped Cloud SQL role/secret and deploy the separate staging
|
|
service.
|
|
7. Prove effective identity, reads, function-only proposal staging, denied
|
|
writes/escalation, receipts, restart stability, and rollback.
|
|
8. Run behavioral and database parity backtesting.
|
|
9. Connect the protected Observatory to canonical claims, proposals, pgvector
|
|
projection, and runtime receipts.
|
|
10. Cut over, soak, restore-test, revoke VPS credentials, and retire the VPS.
|
|
|
|
## Current live-action boundary
|
|
|
|
No merge without explicit human approval, Artifact Registry push,
|
|
GCP control-plane or IAP/SSH access, Cloud SQL/Secret Manager mutation,
|
|
service deployment/restart, Telegram change, production promotion, canonical
|
|
proposal apply, or VPS access is part of the current offline corrective slice.
|
|
Any later authorization for the bounded preflight must explicitly accept that
|
|
the SSH access path may register a key with a maximum five-minute lifetime.
|