138 lines
5.5 KiB
Markdown
138 lines
5.5 KiB
Markdown
# GCP leoclean no-send service package
|
|
|
|
## Outcome
|
|
|
|
This slice packages the revision-bound Hermes/leoclean no-send artifact and one
|
|
explicit identity bundle as an immutable OCI image for a separate
|
|
`leoclean-gcp-nosend.service` on `teleo-staging-1`.
|
|
|
|
It is target-architecture staging work, not a production cutover. The image is
|
|
the atomic compatibility boundary because Python, the locked Hermes virtual
|
|
environment, PostgreSQL client, Cloud SQL CA, runtime artifact, identity files,
|
|
and container entrypoint must move and roll back together.
|
|
|
|
## Exact target and authority boundary
|
|
|
|
- project: `teleo-501523`
|
|
- zone: `europe-west6-a`
|
|
- instance: `teleo-staging-1`
|
|
- service account:
|
|
`sa-teleo-staging-vm@teleo-501523.iam.gserviceaccount.com`
|
|
- service: `leoclean-gcp-nosend.service`
|
|
- platform: `linux/amd64`
|
|
- image repository:
|
|
`europe-west6-docker.pkg.dev/teleo-501523/teleo/leoclean-nosend-staging`
|
|
|
|
The package adds only a deployable, digest-addressed staging service surface.
|
|
It does not add IAM, Secret Manager, database-role, proposal-approval,
|
|
canonical-apply, transport, production, or VPS authority.
|
|
|
|
The service has no provider credential in this slice. It can prove the gateway
|
|
and database-tool boundary, but paid model calls require a separately reviewed
|
|
internal no-send ingress and credential-delivery design during the parity
|
|
slice.
|
|
|
|
## Immutable closure
|
|
|
|
The dedicated Dockerfile uses only digest-pinned base images:
|
|
|
|
- Python `3.11.9`;
|
|
- uv `0.9.30`;
|
|
- PostgreSQL client `16.14` on Bookworm.
|
|
|
|
There is no `apt-get`, floating `pip install`, editable install, or image tag in
|
|
the closure. The final image also binds:
|
|
|
|
- the exact Teleo Git revision and release-pass artifact receipt;
|
|
- Hermes commit and source-tree hash;
|
|
- the artifact content and manifest hashes;
|
|
- the exact uv lock;
|
|
- the identity manifest, lock, `SOUL.md`, and bundle hashes;
|
|
- the Cloud SQL server CA hash;
|
|
- the Dockerfile, entrypoint, and package-contract hashes.
|
|
|
|
The runtime image starts with a capability-limited bootstrap that creates a
|
|
fresh tmpfs profile, then drops all groups, UID/GID to `65532`, and all Linux
|
|
capability bounding sets before executing Hermes. The gateway readiness receipt
|
|
is written only after the real zero-adapter runner starts and its sealed tool
|
|
registry is rechecked.
|
|
|
|
The PostgreSQL base image's inherited data-volume path is explicitly shadowed
|
|
by a tiny read-only, non-executable, mode-`0000` tmpfs. This prevents Docker
|
|
from exposing an unused writable database directory to the runtime.
|
|
|
|
## Prepare a build context
|
|
|
|
First compile and release-verify the no-send artifact from the exact clean
|
|
revision. Separately provide a reviewed identity directory containing exactly:
|
|
|
|
- `SOUL.md`
|
|
- `identity-lock.json`
|
|
- `identity-manifest.json`
|
|
|
|
Then run:
|
|
|
|
```bash
|
|
python3 ops/gcp_leoclean_nosend_package.py prepare \
|
|
--artifact /path/to/artifact \
|
|
--receipt /path/to/leoclean-nosend-runtime.json \
|
|
--identity /path/to/identity-bundle \
|
|
--output /tmp/leoclean-nosend-image-context
|
|
```
|
|
|
|
The command fails closed on a development receipt, revision drift, content or
|
|
mode drift, unsafe links, an inconsistent identity lock, a changed CA, a
|
|
non-staging target, or an existing output directory. The resulting context is
|
|
secret-free.
|
|
|
|
Use the exact values in `build-args.json` as Docker build arguments. The image
|
|
build itself revalidates that those values equal `image-input.json`.
|
|
|
|
## Finalize one digest-bound release
|
|
|
|
After an authorized build and Artifact Registry push returns the immutable
|
|
image digest:
|
|
|
|
```bash
|
|
python3 ops/gcp_leoclean_nosend_package.py finalize \
|
|
--image-input /tmp/leoclean-nosend-image-context/image-input.json \
|
|
--image-reference \
|
|
europe-west6-docker.pkg.dev/teleo-501523/teleo/leoclean-nosend-staging@sha256:<64-hex-digest> \
|
|
--output-release /tmp/leoclean-nosend-release.json \
|
|
--output-unit /tmp/leoclean-gcp-nosend.service
|
|
```
|
|
|
|
Tags, alternate repositories, alternate projects/instances/service accounts,
|
|
extra descriptor fields, and mismatched labels are rejected.
|
|
|
|
## Offline evidence and live gate
|
|
|
|
Offline tests prove descriptor strictness, artifact and identity binding,
|
|
digest-only images, pinned runtime versions, a secret-free context, the
|
|
capability-drop contract, no published ports, no Docker-socket mount, no
|
|
environment file, and no production/VPS/Telegram target.
|
|
|
|
They do not prove that `teleo-staging-1` currently has a compatible container
|
|
engine, enough disk, the expected architecture, the expected service account,
|
|
or an unused unit name. Those are the next read-only live preflight. If the
|
|
engine is absent, installation is separate infrastructure work; the deploy must
|
|
stop instead of falling back to the production sync script or a mutable host
|
|
virtual environment.
|
|
|
|
Publishing the draft branch and stacked PR is only a review handoff. Live
|
|
installation, Artifact Registry publication, service restart, IAM/secret
|
|
changes, Cloud SQL access, and proposal staging remain separate approvals.
|
|
|
|
## Rollback and sunset
|
|
|
|
The rollback boundary is one release descriptor, one image digest, and the
|
|
dedicated no-send unit. Rollback restores the prior descriptor/unit and prior
|
|
digest; it must never restart or edit the production Leo, Telegram, or VPS
|
|
services.
|
|
|
|
The fresh tmpfs profile intentionally has no session continuity. That is
|
|
appropriate for isolated gateway/database and fresh-turn parity proof, but it
|
|
is not the production state design. Before traffic cutover, a separate reviewed
|
|
slice must bind durable noncanonical session state without making it identity or
|
|
knowledge authority. The tmpfs-only state contract sunsets when that cutover
|
|
candidate is proven.
|