Package leoclean no-send GCP staging service

This commit is contained in:
fwazb 2026-07-20 16:12:01 -07:00
parent 2d88c9765b
commit 1e5c67738f
13 changed files with 1787 additions and 20 deletions

View file

@ -42,6 +42,7 @@ jobs:
lib/evaluate.py \
lib/llm.py \
lib/post_extract.py \
docker/leoclean-nosend/entrypoint.py \
ops/apply_gcp_iam_split.py \
ops/attest_gcp_reasoning_compute.py \
ops/capture_vps_canonical_postgres_snapshot.py \
@ -50,6 +51,7 @@ jobs:
ops/apply_gcp_runtime_baseline.py \
ops/check_gcp_service_communications.py \
ops/derive_leoclean_runtime_query_contract.py \
ops/gcp_leoclean_nosend_package.py \
ops/plan_gcp_iam_split.py \
ops/private_receipt_io.py \
ops/run_local_canonical_postgres_rebuild.py \
@ -63,8 +65,13 @@ jobs:
ops/verify_postgres_parity_manifest.py \
ops/verify_vps_canonical_snapshot_delta.py \
telegram/approvals.py \
hermes-agent/patches/enforce_leoclean_learning_policy.py \
hermes-agent/leoclean-bin/kb_tool.py \
hermes-agent/leoclean-bin/cloudsql_memory_tool.py \
hermes-agent/runtime/leoclean-nosend/bootstrap.py \
hermes-agent/runtime/leoclean-nosend/profile-sources/cloudsql_memory_runtime.py \
hermes-agent/runtime/leoclean-nosend/profile-sources/leo_db_context.py \
hermes-agent/runtime/leoclean-nosend/profile-sources/operational_contracts.py \
scripts/check_crabbox_ci_contract.py \
scripts/check_llm_refinement_contract.py \
scripts/build_working_leo_m3taversal_outcome_sandbox.py \
@ -94,6 +101,7 @@ jobs:
tests/test_gcp_infra_execute_canary.py \
tests/test_gcp_infra_readiness_checker.py \
tests/test_gcp_leoclean_runtime_permissions.py \
tests/test_gcp_leoclean_nosend_package.py \
tests/test_gcp_leoclean_service_environment.py \
tests/test_gcp_runtime_baseline_apply.py \
tests/test_gcp_service_communications.py \

View file

@ -0,0 +1,78 @@
# syntax=docker/dockerfile:1.7
FROM ghcr.io/astral-sh/uv:0.9.30@sha256:538e0b39736e7feae937a65983e49d2ab75e1559d35041f9878b7b7e51de91e4 AS uv
FROM docker.io/library/python:3.11.9-slim-bookworm@sha256:8fb099199b9f2d70342674bd9dbccd3ed03a258f26bbd1d556822c6dfc60c317 AS python-build
COPY --from=uv /uv /usr/local/bin/uv
COPY artifact/hermes-agent /opt/livingip/leoclean-nosend/artifact/hermes-agent
RUN /usr/local/bin/uv venv \
--python /usr/local/bin/python3.11 \
--no-project \
/opt/livingip/leoclean-nosend/venv \
&& VIRTUAL_ENV=/opt/livingip/leoclean-nosend/venv /usr/local/bin/uv sync \
--directory /opt/livingip/leoclean-nosend/artifact/hermes-agent \
--active \
--frozen \
--no-dev \
--extra cron \
--no-editable \
&& /usr/local/bin/uv pip check --python /opt/livingip/leoclean-nosend/venv/bin/python
FROM docker.io/library/postgres:16.14-bookworm@sha256:92620daddcd947f8d5ab5ba66e848702fe443d87fed30c4cea8e389fd78dfc55
ARG TELEO_REVISION
ARG ARTIFACT_SHA256
ARG IDENTITY_SHA256
ARG INPUT_SHA256
LABEL org.opencontainers.image.source="https://github.com/living-ip/teleo-infrastructure" \
org.opencontainers.image.revision="${TELEO_REVISION}" \
livingip.artifact.sha256="${ARTIFACT_SHA256}" \
livingip.identity.sha256="${IDENTITY_SHA256}" \
livingip.input.sha256="${INPUT_SHA256}" \
livingip.runtime="leoclean-nosend" \
livingip.target="gcp-staging"
COPY --from=python-build /usr/local /usr/local
COPY --from=python-build /opt/livingip/leoclean-nosend/venv /opt/livingip/leoclean-nosend/venv
COPY artifact /opt/livingip/leoclean-nosend/artifact
COPY identity /opt/livingip/leoclean-nosend/identity
COPY entrypoint.py /opt/livingip/leoclean-nosend/entrypoint.py
COPY package_contract.py /opt/livingip/leoclean-nosend/package_contract.py
COPY artifact-receipt.json /opt/livingip/leoclean-nosend/metadata/artifact-receipt.json
COPY image-input.json /opt/livingip/leoclean-nosend/metadata/image-input.json
COPY Dockerfile /opt/livingip/leoclean-nosend/metadata/Dockerfile
COPY cloudsql-server-ca.pem /usr/local/libexec/livingip/leoclean-kb/cloudsql-server-ca.pem
RUN ln -s /usr/local/bin/python3.11 /usr/bin/python3 \
&& mkdir -p /usr/local/libexec/livingip/leoclean-kb/gcloud-config \
&& chmod 0755 /usr/local/libexec/livingip/leoclean-kb \
&& chmod 0555 /usr/local/libexec/livingip/leoclean-kb/gcloud-config \
&& chmod 0444 /usr/local/libexec/livingip/leoclean-kb/cloudsql-server-ca.pem \
&& chmod 0555 /opt/livingip/leoclean-nosend/entrypoint.py \
&& chmod 0444 /opt/livingip/leoclean-nosend/package_contract.py \
&& case "$TELEO_REVISION" in (*[!0-9a-f]*|'') exit 65;; esac \
&& test "${#TELEO_REVISION}" -eq 40 \
&& for digest in "$ARTIFACT_SHA256" "$IDENTITY_SHA256" "$INPUT_SHA256"; do \
case "$digest" in (*[!0-9a-f]*|'') exit 65;; esac; \
test "${#digest}" -eq 64; \
done \
&& test "$(/usr/local/bin/python3.11 -c 'import platform; print(platform.python_version())')" = "3.11.9" \
&& /usr/bin/psql --version | grep -Eq '^psql \(PostgreSQL\) 16[.]14([[:space:]]|$)' \
&& test "$(sha256sum /usr/local/libexec/livingip/leoclean-kb/cloudsql-server-ca.pem | cut -d ' ' -f 1)" = "80701e768f0e1f6b9d621aa0b53f6e851daaa276c6d9a8e51a300fbc015539cb" \
&& /opt/livingip/leoclean-nosend/venv/bin/python /opt/livingip/leoclean-nosend/entrypoint.py \
verify-build "$TELEO_REVISION" "$ARTIFACT_SHA256" "$IDENTITY_SHA256" "$INPUT_SHA256"
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONNOUSERSITE=1 \
PYTHONSAFEPATH=1
STOPSIGNAL SIGTERM
HEALTHCHECK --interval=15s --timeout=10s --start-period=30s --retries=4 \
CMD ["/opt/livingip/leoclean-nosend/venv/bin/python", "/opt/livingip/leoclean-nosend/entrypoint.py", "health"]
ENTRYPOINT ["/opt/livingip/leoclean-nosend/venv/bin/python", "/opt/livingip/leoclean-nosend/entrypoint.py"]
CMD ["service"]

View file

@ -0,0 +1,295 @@
#!/usr/bin/env python3
"""Validate and launch the immutable leoclean no-send container."""
from __future__ import annotations
import ctypes
import importlib.util
import json
import os
import platform
import shutil
import stat
import subprocess
import sys
from pathlib import Path
from typing import Any
def _load_adjacent_contract() -> Any:
path = Path(__file__).resolve().with_name("package_contract.py")
spec = importlib.util.spec_from_file_location("livingip_leoclean_nosend_package_contract", path)
if spec is None or spec.loader is None:
raise ImportError("the adjacent package contract cannot be loaded")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
contract = _load_adjacent_contract()
ROOT = Path(contract.RUNTIME_ROOT)
ARTIFACT = ROOT / "artifact"
IDENTITY = ROOT / "identity"
PROFILE = Path(contract.PROFILE_ROOT)
RECEIPT = ROOT / "metadata" / "artifact-receipt.json"
IMAGE_INPUT = ROOT / "metadata" / "image-input.json"
DOCKERFILE = ROOT / "metadata" / "Dockerfile"
ENTRYPOINT = ROOT / "entrypoint.py"
PACKAGE_CONTRACT = ROOT / "package_contract.py"
CA = Path(contract.CA_DESTINATION)
READINESS = PROFILE / "state" / "readiness.json"
PSQL = Path("/usr/bin/psql")
RUNTIME_PYTHON = ROOT / "venv" / "bin" / "python"
BOOTSTRAP = ARTIFACT / "bootstrap.py"
STATE_DIRECTORIES = ("cache", "cron", "logs", "memories", "platforms", "sessions", "state")
class EntrypointError(RuntimeError):
"""The installed image or live process violates its release contract."""
def _require(condition: bool, message: str) -> None:
if not condition:
raise EntrypointError(message)
def _validate_installed() -> dict[str, Any]:
image_input = contract.load_json(IMAGE_INPUT, "installed image input")
contract.validate_image_input(image_input)
revision = image_input["runtime"]["teleo_git_head"]
runtime = contract.validate_artifact(ARTIFACT, RECEIPT, revision)
for field in (
"teleo_git_head",
"artifact_sha256",
"artifact_manifest_sha256",
"artifact_receipt_sha256",
"hermes_commit",
"hermes_source_sha256",
"uv_lock_sha256",
):
_require(runtime.get(field) == image_input["runtime"].get(field), f"installed runtime binding drifted: {field}")
identity = contract.validate_identity_bundle(IDENTITY)
_require(identity == image_input["identity"], "installed identity bundle drifted")
_require(contract.sha256_file(CA) == contract.CA_SHA256, "installed Cloud SQL CA drifted")
_require(platform.python_version() == contract.PYTHON_VERSION, "installed Python version drifted")
_require(Path("/usr/bin/python3").resolve() == Path("/usr/local/bin/python3.11"), "system Python binding drifted")
psql_version = subprocess.run(
[str(PSQL), "--version"],
check=True,
capture_output=True,
text=True,
timeout=10,
).stdout.strip()
_require(
psql_version.startswith(f"psql (PostgreSQL) {contract.POSTGRES_VERSION}"), "installed psql version drifted"
)
bindings = image_input["source_bindings"]
_require(contract.sha256_file(DOCKERFILE) == bindings["Dockerfile"], "installed Dockerfile binding drifted")
_require(contract.sha256_file(ENTRYPOINT) == bindings["entrypoint.py"], "installed entrypoint binding drifted")
_require(
contract.sha256_file(PACKAGE_CONTRACT) == bindings["package_contract.py"],
"installed package contract binding drifted",
)
return image_input
def _prepare_profile() -> None:
_require(os.geteuid() == 0, "profile preparation requires the capability-limited container bootstrap user")
_require(PROFILE.is_dir() and not PROFILE.is_symlink(), "runtime profile tmpfs is missing or unsafe")
_require(not any(PROFILE.iterdir()), "runtime profile tmpfs is not empty")
template = ARTIFACT / "profile-template"
for source in template.iterdir():
destination = PROFILE / source.name
if source.is_dir():
shutil.copytree(source, destination, symlinks=False)
else:
shutil.copy2(source, destination, follow_symlinks=False)
for name in contract.IDENTITY_FILES:
shutil.copy2(IDENTITY / name, PROFILE / name, follow_symlinks=False)
(PROFILE / name).chmod(0o600)
for name in STATE_DIRECTORIES:
path = PROFILE / name
path.mkdir(mode=0o700)
profile_entries = sorted(
PROFILE.rglob("*"),
key=lambda path: len(path.relative_to(PROFILE).parts),
reverse=True,
)
for path in profile_entries:
_require(not path.is_symlink(), "prepared runtime profile contains a symlink")
for path in profile_entries:
os.chown(path, contract.RUNTIME_UID, contract.RUNTIME_GID)
runtime_identity = PROFILE / "bin" / "gcp-runtime-identity.json"
os.chown(runtime_identity, 0, 0)
runtime_identity.chmod(0o644)
os.chown(PROFILE, contract.RUNTIME_UID, contract.RUNTIME_GID)
def _drop_privileges() -> None:
if os.geteuid() == contract.RUNTIME_UID and os.getegid() == contract.RUNTIME_GID:
return
_require(os.geteuid() == 0, "container bootstrap user is unexpected")
libc = ctypes.CDLL(None, use_errno=True)
pr_capbset_drop = 24
for capability in (0, 6, 7, 8): # CHOWN, SETGID, SETUID, SETPCAP (last)
if libc.prctl(pr_capbset_drop, capability, 0, 0, 0) != 0:
raise EntrypointError("container bootstrap capability drop failed")
os.setgroups([])
os.setgid(contract.RUNTIME_GID)
os.setuid(contract.RUNTIME_UID)
_require(os.geteuid() == contract.RUNTIME_UID and os.getegid() == contract.RUNTIME_GID, "privilege drop failed")
def _runtime_environment() -> dict[str, str]:
return {
"HOME": str(PROFILE / "state"),
"HERMES_HOME": str(PROFILE),
"LANG": "C",
"LC_ALL": "C",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"PYTHONDONTWRITEBYTECODE": "1",
"PYTHONNOUSERSITE": "1",
"PYTHONSAFEPATH": "1",
}
def _exec_runtime(command: str) -> None:
_prepare_profile()
_drop_privileges()
argv = [str(RUNTIME_PYTHON), str(BOOTSTRAP), command, "--profile", str(PROFILE)]
if command == "service":
argv.extend(["--readiness-file", str(READINESS)])
os.execve(str(RUNTIME_PYTHON), argv, _runtime_environment())
def _validate_zero_capabilities() -> None:
status = Path("/proc/1/status").read_text(encoding="utf-8")
fields = {}
for line in status.splitlines():
key, separator, value = line.partition(":")
if separator:
fields[key] = value.strip()
for name in ("CapInh", "CapPrm", "CapEff", "CapBnd", "CapAmb"):
_require(fields.get(name) == "0000000000000000", f"runtime process retains {name}")
_require(fields.get("NoNewPrivs") == "1", "runtime process does not enforce no-new-privileges")
_require(
fields.get("Uid")
== f"{contract.RUNTIME_UID}\t{contract.RUNTIME_UID}\t{contract.RUNTIME_UID}\t{contract.RUNTIME_UID}",
"runtime uid drifted",
)
_require(
fields.get("Gid")
== f"{contract.RUNTIME_GID}\t{contract.RUNTIME_GID}\t{contract.RUNTIME_GID}\t{contract.RUNTIME_GID}",
"runtime gid drifted",
)
def _health() -> dict[str, Any]:
_drop_privileges()
_validate_zero_capabilities()
_require(READINESS.is_file() and not READINESS.is_symlink(), "runtime readiness receipt is missing or unsafe")
_require(stat.S_IMODE(READINESS.stat().st_mode) == 0o600, "runtime readiness receipt mode drifted")
value = contract.load_json(READINESS, "runtime readiness receipt")
_require(
set(value)
== {
"schema",
"status",
"process_id",
"runtime_mode",
"config_sha256",
"gateway_adapter_count",
"connected_platforms",
"tool_surface",
"identity_sha256",
},
"runtime readiness fields are not exact",
)
_require(value.get("schema") == "livingip.leocleanNoSendServiceReadiness.v1", "runtime readiness schema drifted")
_require(
value.get("status") == "ready" and value.get("process_id") == 1, "runtime readiness process binding drifted"
)
_require(value.get("runtime_mode") == "gcp_staging_no_send", "runtime readiness mode drifted")
_require(
value.get("gateway_adapter_count") == 0 and value.get("connected_platforms") == [],
"runtime has a transport adapter",
)
surface = value.get("tool_surface")
_require(isinstance(surface, dict), "runtime tool surface is missing")
_require(surface.get("tools") == ["skill_view", "skills_list", "terminal"], "runtime tool surface drifted")
_require(surface.get("send_message_present") is False, "runtime send_message surface is present")
expected_identity = {name: contract.sha256_file(PROFILE / name) for name in contract.IDENTITY_FILES}
_require(value.get("identity_sha256") == expected_identity, "runtime readiness identity binding drifted")
cmdline = Path("/proc/1/cmdline").read_bytes().split(b"\0")
expected_native = [
str(RUNTIME_PYTHON).encode(),
str(BOOTSTRAP).encode(),
b"service",
b"--profile",
str(PROFILE).encode(),
b"--readiness-file",
str(READINESS).encode(),
b"",
]
expected_binfmt = [expected_native[0], *expected_native]
_require(cmdline in (expected_native, expected_binfmt), "runtime process command line drifted")
return {
"schema": "livingip.leocleanNoSendContainerHealth.v1",
"status": "pass",
"process_id": 1,
"gateway_adapter_count": 0,
"send_message_present": False,
}
def _verification_result(image_input: dict[str, Any]) -> dict[str, Any]:
return {
"schema": "livingip.leocleanNoSendContainerVerification.v1",
"status": "pass",
"teleo_git_head": image_input["runtime"]["teleo_git_head"],
"artifact_sha256": image_input["runtime"]["artifact_sha256"],
"identity_sha256": image_input["identity"]["bundle_sha256"],
"input_sha256": image_input["input_sha256"],
"python_version": contract.PYTHON_VERSION,
"postgres_version": contract.POSTGRES_VERSION,
"cloudsql_ca_sha256": contract.CA_SHA256,
}
def main(argv: list[str] | None = None) -> int:
arguments = argv if argv is not None else sys.argv[1:]
arguments = arguments or ["service"]
command = arguments[0]
try:
image_input = _validate_installed()
if command in {"probe", "service"}:
_require(len(arguments) == 1, "runtime command arguments are not exact")
_exec_runtime(command)
if command == "health":
_require(len(arguments) == 1, "health command arguments are not exact")
result = _health()
elif command == "verify":
_require(len(arguments) == 1, "verify command arguments are not exact")
result = _verification_result(image_input)
elif command == "verify-build":
_require(len(arguments) == 5, "build verification arguments are not exact")
expected = (
image_input["runtime"]["teleo_git_head"],
image_input["runtime"]["artifact_sha256"],
image_input["identity"]["bundle_sha256"],
image_input["input_sha256"],
)
_require(tuple(arguments[1:]) == expected, "image build arguments drifted from image input")
result = _verification_result(image_input)
else:
raise EntrypointError("unsupported container command")
print(json.dumps(result, separators=(",", ":"), sort_keys=True))
return 0
except (EntrypointError, contract.PackageError, OSError, subprocess.SubprocessError):
print(json.dumps({"status": "fail", "error": "container_contract_failed"}, sort_keys=True), file=sys.stderr)
return 65
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -94,3 +94,7 @@ Those remain separate rollback boundaries:
projection, and runtime receipts; and
6. cut over only after soak and restore testing, then revoke the VPS credentials
and retire the VPS.
The independently reversible OCI/systemd packaging contract for step 2 is
documented in `docs/gcp-leoclean-nosend-service-package.md`. Its offline proof
does not count as a live deployment or satisfy steps 1, 3, 4, 5, or 6.

View file

@ -0,0 +1,138 @@
# 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.

View file

@ -0,0 +1,50 @@
# 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`.
- Rebuilt for human review: isolated, digest-addressed GCP staging service
package with an independent rollback boundary, exact release receipt,
immutable image verification, and network-disabled service/readiness smoke
test, based directly on that merged `main` revision in PR #182.
- In progress: validate the rebuilt PR #182 revision and stop at the
exact-revision human review and merge gate.
- Not yet live-proven: staging VM/container engine, IAM/Secret Manager, Cloud
SQL effective identity, restart behavior, or model/database parity.
## Remaining order
1. Obtain exact-revision human review for the no-send service-package stack.
2. Run the read-only `teleo-staging-1` host/engine/service-account preflight.
3. Provision the scoped Cloud SQL role/secret and deploy the separate staging
service.
4. Prove effective identity, reads, function-only proposal staging, denied
writes/escalation, receipts, restart stability, and rollback.
5. Run behavioral and database parity backtesting.
6. Connect the protected Observatory to canonical claims, proposals, pgvector
projection, and runtime receipts.
7. Cut over, soak, restore-test, revoke VPS credentials, and retire the VPS.
## Current live-action boundary
Draft branch/PR publication is authorized only as a review handoff. No merge,
Artifact Registry push, GCP/Cloud SQL/Secret Manager mutation, service
deployment/restart, Telegram change, production promotion, canonical proposal
apply, or VPS access is part of the current offline slice.

View file

@ -15,9 +15,12 @@ import signal
import stat
import subprocess
import sys
import tempfile
from pathlib import Path
from typing import Any
READINESS_SCHEMA = "livingip.leocleanNoSendServiceReadiness.v1"
class NoSendContractError(RuntimeError):
"""The runtime does not satisfy its no-send contract."""
@ -738,7 +741,58 @@ def probe(profile: Path, *, template: bool) -> dict[str, Any]:
}
async def _run_service(profile: Path) -> bool:
def _write_readiness(
profile: Path,
readiness_file: Path,
contract: dict[str, Any],
runner: Any,
tool_surface: dict[str, Any],
) -> None:
state = profile / "state"
_require(state.is_dir() and not state.is_symlink(), "service state directory is missing or unsafe")
expected_parent = state.resolve(strict=True)
_require(
readiness_file.parent.resolve(strict=True) == expected_parent, "readiness file must be inside profile state"
)
_require(readiness_file.name == "readiness.json", "readiness file name is not exact")
_require(not readiness_file.is_symlink(), "readiness file cannot be a symlink")
identity_hashes = {}
for name in ("SOUL.md", "identity-lock.json", "identity-manifest.json"):
path = profile / name
_require(path.is_file() and not path.is_symlink(), f"runtime identity entry is unsafe: {name}")
identity_hashes[name] = _sha256(path)
payload = {
"schema": READINESS_SCHEMA,
"status": "ready",
"process_id": os.getpid(),
"runtime_mode": contract["runtime_mode"],
"config_sha256": _sha256(profile / "config.yaml"),
"gateway_adapter_count": len(runner.adapters),
"connected_platforms": [],
"tool_surface": tool_surface,
"identity_sha256": identity_hashes,
}
encoded = (json.dumps(payload, separators=(",", ":"), sort_keys=True) + "\n").encode("utf-8")
descriptor = None
temporary = None
try:
descriptor, temporary = tempfile.mkstemp(prefix=".readiness.", dir=expected_parent)
os.fchmod(descriptor, 0o600)
with os.fdopen(descriptor, "wb", closefd=True) as handle:
descriptor = None
handle.write(encoded)
handle.flush()
os.fsync(handle.fileno())
os.replace(temporary, readiness_file)
temporary = None
finally:
if descriptor is not None:
os.close(descriptor)
if temporary is not None:
Path(temporary).unlink(missing_ok=True)
async def _run_service(profile: Path, readiness_file: Path | None = None) -> bool:
contract, _config, _surface, _effective_policy = _prepare(profile, template=False)
from gateway.config import GatewayConfig
from gateway.run import GatewayRunner
@ -749,7 +803,7 @@ async def _run_service(profile: Path) -> bool:
_require(getattr(runner, "_smart_model_routing", None) == {}, "service retained smart-model routing")
_assert_tool_registry(profile, contract)
importlib.import_module("model_tools")
_assert_tool_registry(profile, contract)
tool_surface = _assert_tool_registry(profile, contract)
loop = asyncio.get_running_loop()
stop_tasks: set[asyncio.Task[Any]] = set()
@ -766,9 +820,15 @@ async def _run_service(profile: Path) -> bool:
pass
started = await runner.start()
_require(started, "Hermes no-send gateway did not start")
_assert_tool_registry(profile, contract)
await runner.wait_for_shutdown()
return True
tool_surface = _assert_tool_registry(profile, contract)
if readiness_file is not None:
_write_readiness(profile, readiness_file, contract, runner, tool_surface)
try:
await runner.wait_for_shutdown()
return True
finally:
if readiness_file is not None:
readiness_file.unlink(missing_ok=True)
def main() -> int:
@ -779,12 +839,15 @@ def main() -> int:
child.add_argument("--profile", required=True, type=Path)
if name == "probe":
child.add_argument("--template", action="store_true")
else:
child.add_argument("--readiness-file", type=Path)
args = parser.parse_args()
try:
if args.command == "probe":
print(json.dumps(probe(args.profile.resolve(), template=args.template), sort_keys=True))
return 0
return 0 if asyncio.run(_run_service(args.profile.resolve())) else 1
readiness_file = args.readiness_file.absolute() if args.readiness_file else None
return 0 if asyncio.run(_run_service(args.profile.resolve(), readiness_file)) else 1
except NoSendContractError as exc:
print(json.dumps({"status": "fail", "error": str(exc)}, sort_keys=True), file=sys.stderr)
return 65

View file

@ -34,7 +34,7 @@
{
"source": "hermes-agent/runtime/leoclean-nosend/profile-template/config.yaml",
"target": "config.yaml",
"mode": "0600"
"mode": "0444"
},
{
"source": "hermes-agent/leoclean-bin/teleo-kb-gcp",

View file

@ -0,0 +1,674 @@
#!/usr/bin/env python3
"""Build and validate the immutable GCP leoclean no-send service package."""
from __future__ import annotations
import argparse
import hashlib
import json
import re
import shutil
import stat
import subprocess
import sys
from collections.abc import Mapping
from pathlib import Path
from typing import Any
IMAGE_INPUT_SCHEMA = "livingip.leocleanNoSendImageInput.v1"
RELEASE_SCHEMA = "livingip.leocleanNoSendRelease.v1"
ARTIFACT_MANIFEST_SCHEMA = "livingip.leocleanNoSendArtifactManifest.v1"
ARTIFACT_RECEIPT_SCHEMA = "livingip.leocleanNoSendArtifactVerification.v1"
IDENTITY_MANIFEST_SCHEMA = "livingip.leoIdentityManifest.v1"
IDENTITY_LOCK_SCHEMA = "livingip.leoIdentityProfileLock.v1"
PROJECT = "teleo-501523"
ZONE = "europe-west6-a"
INSTANCE = "teleo-staging-1"
SERVICE = "leoclean-gcp-nosend.service"
SERVICE_ACCOUNT = "sa-teleo-staging-vm@teleo-501523.iam.gserviceaccount.com"
PLATFORM = "linux/amd64"
IMAGE_REPOSITORY = "europe-west6-docker.pkg.dev/teleo-501523/teleo/leoclean-nosend-staging"
CONTAINER_NAME = "livingip-leoclean-nosend"
HERMES_COMMIT = "b2f477a30b3c05d0f383c543af98496ae8a96070"
PYTHON_VERSION = "3.11.9"
UV_VERSION = "0.9.30"
POSTGRES_VERSION = "16.14"
PYTHON_IMAGE = (
"docker.io/library/python:3.11.9-slim-bookworm@"
"sha256:8fb099199b9f2d70342674bd9dbccd3ed03a258f26bbd1d556822c6dfc60c317"
)
UV_IMAGE = "ghcr.io/astral-sh/uv:0.9.30@sha256:538e0b39736e7feae937a65983e49d2ab75e1559d35041f9878b7b7e51de91e4"
POSTGRES_IMAGE = (
"docker.io/library/postgres:16.14-bookworm@sha256:92620daddcd947f8d5ab5ba66e848702fe443d87fed30c4cea8e389fd78dfc55"
)
CA_SHA256 = "80701e768f0e1f6b9d621aa0b53f6e851daaa276c6d9a8e51a300fbc015539cb"
CA_DESTINATION = "/usr/local/libexec/livingip/leoclean-kb/cloudsql-server-ca.pem"
RUNTIME_ROOT = "/opt/livingip/leoclean-nosend"
PROFILE_ROOT = "/run/leoclean-profile"
RUNTIME_UID = 65532
RUNTIME_GID = 65532
HEX_40 = re.compile(r"^[0-9a-f]{40}$")
HEX_64 = re.compile(r"^[0-9a-f]{64}$")
IMAGE_REFERENCE = re.compile(rf"^{re.escape(IMAGE_REPOSITORY)}@sha256:([0-9a-f]{{64}})$")
FORBIDDEN_DESCRIPTOR_MARKERS = (
"77.42.65.182",
"gcp-teleo-pgvector-standby-postgres-password",
"leoclean-gateway.service",
"sa-teleo-prod-vm",
"telegram_bot_token",
"teleo-prod-1",
)
IDENTITY_FILES = ("SOUL.md", "identity-lock.json", "identity-manifest.json")
class PackageError(RuntimeError):
"""The image or service package does not satisfy the staging contract."""
def _require(condition: bool, message: str) -> None:
if not condition:
raise PackageError(message)
def sha256_file(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def canonical_sha256(value: Any) -> str:
encoded = json.dumps(value, ensure_ascii=True, separators=(",", ":"), sort_keys=True).encode("utf-8")
return hashlib.sha256(encoded).hexdigest()
def load_json(path: Path, label: str) -> dict[str, Any]:
try:
value = json.loads(path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as exc:
raise PackageError(f"cannot read {label}: {type(exc).__name__}") from exc
_require(isinstance(value, dict), f"{label} must be a JSON object")
return value
def write_json(path: Path, value: Mapping[str, Any], mode: int = 0o644) -> None:
path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8")
path.chmod(mode)
def _is_sha256(value: Any) -> bool:
return isinstance(value, str) and bool(HEX_64.fullmatch(value))
def _is_revision(value: Any) -> bool:
return isinstance(value, str) and bool(HEX_40.fullmatch(value))
def _safe_tree(root: Path, label: str) -> None:
_require(root.is_dir() and not root.is_symlink(), f"{label} root is missing or unsafe")
for path in root.rglob("*"):
_require(not path.is_symlink(), f"{label} contains a symlink")
_require(path.is_dir() or path.is_file(), f"{label} contains an unsupported entry")
def tree_manifest(root: Path, *, excluded: frozenset[str] = frozenset()) -> dict[str, Any]:
_safe_tree(root, "tree")
files: list[dict[str, Any]] = []
for path in sorted(root.rglob("*"), key=lambda item: item.relative_to(root).as_posix()):
relative = path.relative_to(root).as_posix()
if relative in excluded or path.is_dir():
continue
mode = stat.S_IMODE(path.stat().st_mode)
files.append(
{
"path": relative,
"bytes": path.stat().st_size,
"mode": f"0o{mode:03o}",
"sha256": sha256_file(path),
}
)
stable = {"files": files, "file_count": len(files), "total_bytes": sum(item["bytes"] for item in files)}
return {**stable, "sha256": canonical_sha256(stable)}
def identity_bundle_manifest(root: Path) -> dict[str, Any]:
_safe_tree(root, "identity bundle")
actual = sorted(path.name for path in root.iterdir())
_require(actual == sorted(IDENTITY_FILES), "identity bundle entry set is not exact")
files = []
for name in IDENTITY_FILES:
path = root / name
_require(path.is_file() and not path.is_symlink(), f"identity file is unsafe: {name}")
_require(path.stat().st_size <= 1024 * 1024, f"identity file is too large: {name}")
_require(not stat.S_IMODE(path.stat().st_mode) & 0o022, f"identity file is group/world writable: {name}")
files.append({"path": name, "bytes": path.stat().st_size, "sha256": sha256_file(path)})
stable = {"files": files, "file_count": len(files), "total_bytes": sum(item["bytes"] for item in files)}
return {**stable, "sha256": canonical_sha256(stable)}
def validate_identity_bundle(root: Path) -> dict[str, Any]:
bundle = identity_bundle_manifest(root)
manifest = load_json(root / "identity-manifest.json", "identity manifest")
lock = load_json(root / "identity-lock.json", "identity lock")
_require(
set(manifest) == {"schema", "identity_inputs", "identity_inputs_sha256", "compiled_views", "manifest_sha256"},
"identity manifest fields are not exact",
)
_require(manifest.get("schema") == IDENTITY_MANIFEST_SCHEMA, "identity manifest schema is invalid")
_require(_is_sha256(manifest.get("manifest_sha256")), "identity manifest hash is invalid")
_require(_is_sha256(manifest.get("identity_inputs_sha256")), "identity input hash is invalid")
stable = {key: value for key, value in manifest.items() if key != "manifest_sha256"}
_require(canonical_sha256(stable) == manifest["manifest_sha256"], "identity manifest self-hash drifted")
views = manifest.get("compiled_views")
_require(
isinstance(views, dict) and set(views) == {"SOUL.md", "identity.json"}, "compiled identity views are incomplete"
)
soul = views["SOUL.md"] if isinstance(views, dict) else None
_require(isinstance(soul, dict) and _is_sha256(soul.get("sha256")), "SOUL identity binding is invalid")
_require(soul["sha256"] == sha256_file(root / "SOUL.md"), "SOUL content differs from identity manifest")
_require(
set(lock) == {"schema", "manifest_sha256", "identity_inputs_sha256", "compiled_views", "session_boundary"},
"identity lock fields are not exact",
)
_require(lock.get("schema") == IDENTITY_LOCK_SCHEMA, "identity lock schema is invalid")
_require(lock.get("manifest_sha256") == manifest["manifest_sha256"], "identity lock manifest binding drifted")
_require(
lock.get("identity_inputs_sha256") == manifest["identity_inputs_sha256"],
"identity lock input binding drifted",
)
_require(
isinstance(lock.get("compiled_views"), dict)
and (lock["compiled_views"].get("SOUL.md") or {}).get("sha256") == soul["sha256"],
"identity lock SOUL binding drifted",
)
inputs = manifest.get("identity_inputs")
database = inputs.get("canonical_database") if isinstance(inputs, dict) else None
_require(isinstance(database, dict), "identity database authority is missing")
authority = database.get("authority")
canonical = database.get("canonical_authority_granted")
_require(
(authority, canonical)
in {
("synthetic_noncanonical_fixture", False),
("canonical_database_same_transaction_export", True),
},
"identity database authority is invalid",
)
return {
"bundle_sha256": bundle["sha256"],
"manifest_sha256": manifest["manifest_sha256"],
"identity_inputs_sha256": manifest["identity_inputs_sha256"],
"soul_sha256": soul["sha256"],
"authority": authority,
"canonical_authority_granted": canonical,
}
def validate_artifact(artifact: Path, receipt_path: Path, expected_revision: str) -> dict[str, Any]:
_require(_is_revision(expected_revision), "expected Teleo revision is invalid")
_safe_tree(artifact, "runtime artifact")
manifest = load_json(artifact / "artifact-manifest.json", "artifact manifest")
receipt = load_json(receipt_path, "artifact verification receipt")
_require(manifest.get("schema") == ARTIFACT_MANIFEST_SCHEMA, "artifact manifest schema is invalid")
_require(receipt.get("schema") == ARTIFACT_RECEIPT_SCHEMA, "artifact receipt schema is invalid")
_require(receipt.get("status") == "pass", "artifact receipt did not pass")
_require(receipt.get("verification_mode") == "release", "artifact receipt is not release evidence")
_require(manifest.get("teleo_git_head") == expected_revision, "artifact revision differs from source revision")
_require(receipt.get("teleo_git_head") == expected_revision, "receipt revision differs from source revision")
content = tree_manifest(artifact, excluded=frozenset({"artifact-manifest.json"}))
_require(manifest.get("content") == content, "artifact content manifest drifted")
_require(receipt.get("artifact_sha256") == content["sha256"], "artifact receipt content hash drifted")
_require(manifest.get("hermes_commit") == HERMES_COMMIT, "artifact Hermes commit drifted")
_require(receipt.get("hermes_commit") == HERMES_COMMIT, "receipt Hermes commit drifted")
runtime_lock = load_json(artifact / "runtime-lock.json", "artifact runtime lock")
_require(
runtime_lock.get("base_images") == {"python": PYTHON_IMAGE.removeprefix("docker.io/library/"), "uv": UV_IMAGE},
"artifact base-image lock drifted",
)
hermes = runtime_lock.get("hermes")
_require(isinstance(hermes, dict) and hermes.get("commit") == HERMES_COMMIT, "artifact Hermes lock drifted")
claim_ceiling = manifest.get("claim_ceiling")
_require(isinstance(claim_ceiling, str) and claim_ceiling == receipt.get("claim_ceiling"), "claim ceiling drifted")
return {
"teleo_git_head": expected_revision,
"artifact_sha256": content["sha256"],
"artifact_manifest_sha256": sha256_file(artifact / "artifact-manifest.json"),
"artifact_receipt_sha256": sha256_file(receipt_path),
"hermes_commit": HERMES_COMMIT,
"hermes_source_sha256": receipt.get("hermes_source_sha256"),
"uv_lock_sha256": hermes.get("uv_lock_sha256"),
"claim_ceiling": claim_ceiling,
}
def _target() -> dict[str, str]:
return {
"project": PROJECT,
"zone": ZONE,
"instance": INSTANCE,
"service": SERVICE,
"service_account": SERVICE_ACCOUNT,
"platform": PLATFORM,
}
def _base_images() -> dict[str, str]:
return {"python": PYTHON_IMAGE, "uv": UV_IMAGE, "postgres": POSTGRES_IMAGE}
def _assert_no_forbidden_descriptor_markers(value: Mapping[str, Any]) -> None:
encoded = json.dumps(value, ensure_ascii=True, separators=(",", ":"), sort_keys=True).casefold()
for marker in FORBIDDEN_DESCRIPTOR_MARKERS:
_require(
marker.casefold() not in encoded, "release descriptor contains a forbidden production/transport marker"
)
def validate_image_input(value: dict[str, Any]) -> None:
_require(
set(value)
== {
"schema",
"target",
"runtime",
"identity",
"base_images",
"source_bindings",
"claim_ceiling",
"input_sha256",
},
"image input fields are not exact",
)
_require(value.get("schema") == IMAGE_INPUT_SCHEMA, "image input schema is invalid")
_require(value.get("target") == _target(), "image input target is not exact GCP staging")
_require(value.get("base_images") == _base_images(), "image input base-image closure drifted")
runtime = value.get("runtime")
_require(isinstance(runtime, dict), "image runtime binding is missing")
_require(
set(runtime)
== {
"teleo_git_head",
"artifact_sha256",
"artifact_manifest_sha256",
"artifact_receipt_sha256",
"hermes_commit",
"hermes_source_sha256",
"uv_lock_sha256",
"python_version",
"uv_version",
"postgres_version",
"cloudsql_ca_sha256",
},
"image runtime binding fields are not exact",
)
_require(_is_revision(runtime.get("teleo_git_head")), "image Teleo revision is invalid")
for field in (
"artifact_sha256",
"artifact_manifest_sha256",
"artifact_receipt_sha256",
"hermes_source_sha256",
"uv_lock_sha256",
"cloudsql_ca_sha256",
):
_require(_is_sha256(runtime.get(field)), f"image runtime {field} is invalid")
_require(runtime.get("hermes_commit") == HERMES_COMMIT, "image Hermes commit drifted")
_require(runtime.get("python_version") == PYTHON_VERSION, "image Python version drifted")
_require(runtime.get("uv_version") == UV_VERSION, "image uv version drifted")
_require(runtime.get("postgres_version") == POSTGRES_VERSION, "image PostgreSQL version drifted")
_require(runtime.get("cloudsql_ca_sha256") == CA_SHA256, "image Cloud SQL CA drifted")
identity = value.get("identity")
_require(
isinstance(identity, dict)
and set(identity)
== {
"bundle_sha256",
"manifest_sha256",
"identity_inputs_sha256",
"soul_sha256",
"authority",
"canonical_authority_granted",
},
"image identity binding fields are not exact",
)
for field in ("bundle_sha256", "manifest_sha256", "identity_inputs_sha256", "soul_sha256"):
_require(_is_sha256(identity.get(field)), f"image identity {field} is invalid")
_require(
(identity.get("authority"), identity.get("canonical_authority_granted"))
in {
("synthetic_noncanonical_fixture", False),
("canonical_database_same_transaction_export", True),
},
"image identity authority is invalid",
)
bindings = value.get("source_bindings")
_require(
isinstance(bindings, dict)
and set(bindings) == {"Dockerfile", "entrypoint.py", "package_contract.py"}
and all(_is_sha256(item) for item in bindings.values()),
"image packaging source bindings are invalid",
)
_require(
isinstance(value.get("claim_ceiling"), str) and bool(value["claim_ceiling"]), "image claim ceiling is missing"
)
stable = {key: item for key, item in value.items() if key != "input_sha256"}
_require(value.get("input_sha256") == canonical_sha256(stable), "image input self-hash drifted")
_assert_no_forbidden_descriptor_markers(value)
def build_image_input(
*,
artifact: Path,
receipt: Path,
identity: Path,
ca: Path,
source_revision: str,
dockerfile: Path,
entrypoint: Path,
package_contract: Path,
) -> dict[str, Any]:
_require(sha256_file(ca) == CA_SHA256, "Cloud SQL CA does not match the reviewed certificate")
runtime = validate_artifact(artifact, receipt, source_revision)
runtime.update(
{
"python_version": PYTHON_VERSION,
"uv_version": UV_VERSION,
"postgres_version": POSTGRES_VERSION,
"cloudsql_ca_sha256": CA_SHA256,
}
)
identity_binding = validate_identity_bundle(identity)
stable = {
"schema": IMAGE_INPUT_SCHEMA,
"target": _target(),
"runtime": {key: runtime[key] for key in runtime if key != "claim_ceiling"},
"identity": identity_binding,
"base_images": _base_images(),
"source_bindings": {
"Dockerfile": sha256_file(dockerfile),
"entrypoint.py": sha256_file(entrypoint),
"package_contract.py": sha256_file(package_contract),
},
"claim_ceiling": runtime["claim_ceiling"],
}
value = {**stable, "input_sha256": canonical_sha256(stable)}
validate_image_input(value)
return value
def prepare_context(
*,
repo_root: Path,
artifact: Path,
receipt: Path,
identity: Path,
output: Path,
source_revision: str,
) -> dict[str, Any]:
_require(not output.exists() and not output.is_symlink(), "output context already exists")
dockerfile = repo_root / "docker" / "leoclean-nosend" / "Dockerfile"
entrypoint = repo_root / "docker" / "leoclean-nosend" / "entrypoint.py"
package_contract = repo_root / "ops" / "gcp_leoclean_nosend_package.py"
ca = repo_root / "ops" / "gcp-teleo-pgvector-standby-server-ca.pem"
for path, label in (
(dockerfile, "Dockerfile"),
(entrypoint, "entrypoint"),
(package_contract, "package contract"),
(ca, "Cloud SQL CA"),
):
_require(path.is_file() and not path.is_symlink(), f"{label} source is missing or unsafe")
image_input = build_image_input(
artifact=artifact,
receipt=receipt,
identity=identity,
ca=ca,
source_revision=source_revision,
dockerfile=dockerfile,
entrypoint=entrypoint,
package_contract=package_contract,
)
output.mkdir(parents=True, mode=0o700)
try:
shutil.copytree(artifact, output / "artifact", symlinks=False)
shutil.copytree(identity, output / "identity", symlinks=False)
for name in IDENTITY_FILES:
(output / "identity" / name).chmod(0o600)
shutil.copyfile(receipt, output / "artifact-receipt.json")
shutil.copyfile(ca, output / "cloudsql-server-ca.pem")
shutil.copyfile(dockerfile, output / "Dockerfile")
shutil.copyfile(entrypoint, output / "entrypoint.py")
shutil.copyfile(package_contract, output / "package_contract.py")
for name in (
"artifact-receipt.json",
"cloudsql-server-ca.pem",
"Dockerfile",
"entrypoint.py",
"package_contract.py",
):
(output / name).chmod(0o644)
write_json(output / "image-input.json", image_input)
write_json(
output / "build-args.json",
{
"ARTIFACT_SHA256": image_input["runtime"]["artifact_sha256"],
"IDENTITY_SHA256": image_input["identity"]["bundle_sha256"],
"INPUT_SHA256": image_input["input_sha256"],
"TELEO_REVISION": source_revision,
},
)
_safe_tree(output, "prepared image context")
return image_input
except BaseException:
shutil.rmtree(output, ignore_errors=True)
raise
def build_release_descriptor(image_input: dict[str, Any], image_reference: str) -> dict[str, Any]:
validate_image_input(image_input)
match = IMAGE_REFERENCE.fullmatch(image_reference)
_require(match is not None, "release image must be the exact staging repository at a sha256 digest")
digest = f"sha256:{match.group(1)}"
labels = expected_image_labels(image_input)
stable = {
"schema": RELEASE_SCHEMA,
"target": _target(),
"image": {
"reference": image_reference,
"digest": digest,
"platform": PLATFORM,
"labels": labels,
"input_sha256": image_input["input_sha256"],
},
"image_input": image_input,
}
value = {**stable, "release_sha256": canonical_sha256(stable)}
validate_release_descriptor(value)
return value
def expected_image_labels(image_input: dict[str, Any]) -> dict[str, str]:
validate_image_input(image_input)
return {
"livingip.artifact.sha256": image_input["runtime"]["artifact_sha256"],
"livingip.identity.sha256": image_input["identity"]["bundle_sha256"],
"livingip.input.sha256": image_input["input_sha256"],
"livingip.runtime": "leoclean-nosend",
"livingip.target": "gcp-staging",
"org.opencontainers.image.revision": image_input["runtime"]["teleo_git_head"],
"org.opencontainers.image.source": "https://github.com/living-ip/teleo-infrastructure",
}
def validate_release_descriptor(value: dict[str, Any]) -> None:
_require(
set(value) == {"schema", "target", "image", "image_input", "release_sha256"},
"release descriptor fields are not exact",
)
_require(value.get("schema") == RELEASE_SCHEMA, "release descriptor schema is invalid")
_require(value.get("target") == _target(), "release target is not exact GCP staging")
image_input = value.get("image_input")
_require(isinstance(image_input, dict), "release image input is missing")
validate_image_input(image_input)
image = value.get("image")
_require(
isinstance(image, dict) and set(image) == {"reference", "digest", "platform", "labels", "input_sha256"},
"release image fields are not exact",
)
reference = image.get("reference")
match = IMAGE_REFERENCE.fullmatch(reference) if isinstance(reference, str) else None
_require(match is not None, "release image is not digest-pinned in the staging repository")
_require(image.get("digest") == f"sha256:{match.group(1)}", "release image digest differs from its reference")
_require(image.get("platform") == PLATFORM, "release platform is not exact")
_require(image.get("input_sha256") == image_input["input_sha256"], "release image input binding drifted")
_require(image.get("labels") == expected_image_labels(image_input), "release image labels are not exact")
stable = {key: item for key, item in value.items() if key != "release_sha256"}
_require(value.get("release_sha256") == canonical_sha256(stable), "release descriptor self-hash drifted")
_assert_no_forbidden_descriptor_markers(value)
def render_systemd_unit(release: dict[str, Any]) -> str:
validate_release_descriptor(release)
image = release["image"]["reference"]
release_sha = release["release_sha256"]
profile_tmpfs = f"{PROFILE_ROOT}:rw,noexec,nosuid,nodev,size=64m,uid=0,gid=0,mode=0700"
temp_tmpfs = f"/tmp:rw,noexec,nosuid,nodev,size=64m,uid={RUNTIME_UID},gid={RUNTIME_GID},mode=0700"
postgres_data_tmpfs = "/var/lib/postgresql/data:ro,noexec,nosuid,nodev,size=64k,uid=0,gid=0,mode=0000"
exec_start = " ".join(
[
"/usr/bin/docker run",
"--rm",
f"--name={CONTAINER_NAME}",
"--pull=never",
"--read-only",
"--cap-drop=ALL",
"--cap-add=CHOWN",
"--cap-add=SETGID",
"--cap-add=SETUID",
"--cap-add=SETPCAP",
"--security-opt=no-new-privileges:true",
"--pids-limit=512",
"--network=bridge",
"--stop-timeout=30",
f"--tmpfs={profile_tmpfs}",
f"--tmpfs={temp_tmpfs}",
f"--tmpfs={postgres_data_tmpfs}",
f"--label=livingip.release.sha256={release_sha}",
image,
"service",
]
)
unit = f"""[Unit]
Description=LivingIP leoclean-gcp-nosend staging
Documentation=https://github.com/living-ip/teleo-infrastructure
After=docker.service network-online.target
Requires=docker.service
Wants=network-online.target
[Service]
Type=simple
ExecStart={exec_start}
ExecStop=/usr/bin/docker stop --time=30 {CONTAINER_NAME}
ExecStopPost=-/usr/bin/docker rm --force {CONTAINER_NAME}
Restart=on-failure
RestartSec=5s
TimeoutStartSec=120s
TimeoutStopSec=45s
UMask=0077
NoNewPrivileges=yes
CapabilityBoundingSet=
AmbientCapabilities=
PrivateDevices=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectControlGroups=yes
LockPersonality=yes
RestrictSUIDSGID=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
SystemCallArchitectures=native
[Install]
WantedBy=multi-user.target
"""
_require("--publish" not in unit and " -p " not in unit, "service unit publishes a port")
_require("docker.sock" not in unit, "service unit mounts the Docker socket")
_require(
"EnvironmentFile" not in unit and "LoadCredential" not in unit,
"service unit adds an unreviewed credential source",
)
_require("telegram" not in unit.casefold(), "service unit contains a messaging marker")
return unit
def _git_head(repo_root: Path) -> str:
try:
return subprocess.run(
["git", "-C", str(repo_root), "rev-parse", "HEAD"],
check=True,
capture_output=True,
text=True,
).stdout.strip()
except (OSError, subprocess.CalledProcessError) as exc:
raise PackageError("cannot determine source revision") from exc
def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
subparsers = parser.add_subparsers(dest="command", required=True)
prepare = subparsers.add_parser("prepare")
prepare.add_argument("--repo-root", type=Path, default=Path(__file__).resolve().parents[1])
prepare.add_argument("--artifact", type=Path, required=True)
prepare.add_argument("--receipt", type=Path, required=True)
prepare.add_argument("--identity", type=Path, required=True)
prepare.add_argument("--output", type=Path, required=True)
finalize = subparsers.add_parser("finalize")
finalize.add_argument("--image-input", type=Path, required=True)
finalize.add_argument("--image-reference", required=True)
finalize.add_argument("--output-release", type=Path, required=True)
finalize.add_argument("--output-unit", type=Path, required=True)
validate = subparsers.add_parser("validate")
validate.add_argument("--release", type=Path, required=True)
return parser.parse_args(argv)
def main(argv: list[str] | None = None) -> int:
try:
args = _parse_args(argv)
if args.command == "prepare":
repo_root = args.repo_root.resolve()
result = prepare_context(
repo_root=repo_root,
artifact=args.artifact.resolve(),
receipt=args.receipt.resolve(),
identity=args.identity.resolve(),
output=args.output.absolute(),
source_revision=_git_head(repo_root),
)
elif args.command == "finalize":
image_input = load_json(args.image_input, "image input")
result = build_release_descriptor(image_input, args.image_reference)
for path in (args.output_release, args.output_unit):
_require(not path.exists() and not path.is_symlink(), "finalize output already exists")
path.parent.mkdir(parents=True, exist_ok=True)
write_json(args.output_release, result)
args.output_unit.write_text(render_systemd_unit(result), encoding="utf-8")
args.output_unit.chmod(0o644)
else:
result = load_json(args.release, "release descriptor")
validate_release_descriptor(result)
print(json.dumps({"status": "pass", "schema": result["schema"]}, sort_keys=True))
return 0
except PackageError as exc:
print(json.dumps({"status": "fail", "error": str(exc)}, sort_keys=True), file=sys.stderr)
return 65
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -46,11 +46,7 @@ def _canonical_sha256(value: Any) -> str:
def _is_sha256(value: Any) -> bool:
return (
isinstance(value, str)
and len(value) == 64
and all(character in "0123456789abcdef" for character in value)
)
return isinstance(value, str) and len(value) == 64 and all(character in "0123456789abcdef" for character in value)
def _safe_relative(value: Any, label: str) -> str:
@ -72,7 +68,10 @@ def _load_json(path: Path, label: str) -> dict[str, Any]:
def _validate_lock(value: dict[str, Any]) -> None:
_require(value.get("schema") == LOCK_SCHEMA, "unsupported runtime lock schema")
_require(set(value) == {"schema", "hermes", "base_images", "patches", "profile_sources"}, "runtime lock fields are invalid")
_require(
set(value) == {"schema", "hermes", "base_images", "patches", "profile_sources"},
"runtime lock fields are invalid",
)
hermes = value.get("hermes")
_require(isinstance(hermes, dict), "Hermes lock is missing")
_require(
@ -90,7 +89,10 @@ def _validate_lock(value: dict[str, Any]) -> None:
"Hermes lock fields are invalid",
)
commit = hermes.get("commit")
_require(isinstance(commit, str) and len(commit) == 40 and all(ch in "0123456789abcdef" for ch in commit), "Hermes commit must be an exact SHA")
_require(
isinstance(commit, str) and len(commit) == 40 and all(ch in "0123456789abcdef" for ch in commit),
"Hermes commit must be an exact SHA",
)
_require(hermes.get("repository") == "https://github.com/NousResearch/hermes-agent", "Hermes repository is invalid")
_require(
hermes.get("archive_url") == f"https://codeload.github.com/NousResearch/hermes-agent/tar.gz/{commit}",
@ -108,7 +110,10 @@ def _validate_lock(value: dict[str, Any]) -> None:
targets: set[str] = set()
for patch in patches:
_require(isinstance(patch, dict), "patch lock entry must be an object")
_require(set(patch) == {"source", "source_sha256", "target", "before_sha256", "after_sha256"}, "patch lock fields are invalid")
_require(
set(patch) == {"source", "source_sha256", "target", "before_sha256", "after_sha256"},
"patch lock fields are invalid",
)
_safe_relative(patch["source"], "patch source")
target = _safe_relative(patch["target"], "patch target")
_require(isinstance(target, str) and target not in targets, "patch targets must be unique")
@ -119,12 +124,15 @@ def _validate_lock(value: dict[str, Any]) -> None:
_require(isinstance(sources, list) and bool(sources), "profile sources are missing")
profile_targets: set[str] = set()
for source in sources:
_require(isinstance(source, dict) and set(source) == {"source", "target", "mode"}, "profile source fields are invalid")
_require(
isinstance(source, dict) and set(source) == {"source", "target", "mode"},
"profile source fields are invalid",
)
_safe_relative(source["source"], "profile source")
target = _safe_relative(source["target"], "profile target")
_require(target not in profile_targets, "duplicate profile target")
profile_targets.add(target)
_require(source["mode"] in {"0600", "0644", "0755"}, "profile mode is invalid")
_require(source["mode"] in {"0444", "0600", "0644", "0755"}, "profile mode is invalid")
def _download(url: str, target: Path, timeout: float) -> None:
@ -190,7 +198,9 @@ def _apply_patches(repo_root: Path, hermes_root: Path, lock: dict[str, Any]) ->
patcher = _bound_file(repo_root, entry["source"], f"managed patcher {entry['source']}")
target = _bound_file(hermes_root, entry["target"], f"Hermes patch target {entry['target']}")
_require(_sha256(patcher) == entry["source_sha256"], f"managed patcher drifted: {entry['source']}")
_require(_sha256(target) == entry["before_sha256"], f"Hermes patch target drifted before apply: {entry['target']}")
_require(
_sha256(target) == entry["before_sha256"], f"Hermes patch target drifted before apply: {entry['target']}"
)
module = _load_patcher(patcher)
result, code = module.install(target, check=False)
_require(code == 0, f"managed patch failed: {entry['source']}")
@ -219,6 +229,7 @@ def _copy_profile(repo_root: Path, artifact: Path, lock: dict[str, Any]) -> None
target.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(source, target)
target.chmod(int(entry["mode"], 8))
profile.chmod(0o555)
def _tree_manifest(root: Path, *, excluded: frozenset[str] = frozenset()) -> dict[str, Any]:
@ -304,8 +315,12 @@ def compile_artifact(
extracted = staging / "extracted"
extracted.mkdir()
hermes_source = _safe_extract(archive_path, extracted, lock["hermes"]["archive_root"])
_require(_sha256(hermes_source / "pyproject.toml") == lock["hermes"]["pyproject_sha256"], "Hermes pyproject drifted")
_require(_sha256(hermes_source / "uv.lock") == lock["hermes"]["uv_lock_sha256"], "Hermes dependency lock drifted")
_require(
_sha256(hermes_source / "pyproject.toml") == lock["hermes"]["pyproject_sha256"], "Hermes pyproject drifted"
)
_require(
_sha256(hermes_source / "uv.lock") == lock["hermes"]["uv_lock_sha256"], "Hermes dependency lock drifted"
)
patch_receipts = _apply_patches(repo_root, hermes_source, lock)
patched_source = _tree_manifest(hermes_source)
_require(

View file

@ -22,6 +22,7 @@ fi
temporary="$(mktemp -d "${TMPDIR:-/tmp}/livingip-nosend-runtime.XXXXXX")"
cleanup() {
chmod -R u+w "$temporary" 2>/dev/null || true
rm -rf "$temporary"
}
trap cleanup EXIT INT TERM

View file

@ -0,0 +1,362 @@
"""Offline contracts for the isolated GCP leoclean no-send service image."""
from __future__ import annotations
import copy
import json
import os
import shutil
import subprocess
import sys
from pathlib import Path
import pytest
from ops import gcp_leoclean_nosend_package as package
ROOT = Path(__file__).resolve().parents[1]
REVISION = "1" * 40
IMAGE_DIGEST = "2" * 64
CLAIM_CEILING = "Offline package proof only; live GCP identity, database access, restart, and parity remain unproven."
def write_json(path: Path, value: object, mode: int = 0o600) -> None:
path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8")
path.chmod(mode)
def artifact_fixture(tmp_path: Path) -> tuple[Path, Path]:
artifact = tmp_path / "artifact"
artifact.mkdir()
(artifact / "bootstrap.py").write_text("#!/usr/bin/env python3\n", encoding="utf-8")
(artifact / "bootstrap.py").chmod(0o755)
write_json(
artifact / "runtime-lock.json",
{
"base_images": {
"python": package.PYTHON_IMAGE.removeprefix("docker.io/library/"),
"uv": package.UV_IMAGE,
},
"hermes": {
"commit": package.HERMES_COMMIT,
"uv_lock_sha256": "3" * 64,
},
},
mode=0o644,
)
profile = artifact / "profile-template"
profile.mkdir()
(profile / "config.yaml").write_text("model: fixture\n", encoding="utf-8")
(profile / "config.yaml").chmod(0o600)
content = package.tree_manifest(artifact)
manifest = {
"schema": package.ARTIFACT_MANIFEST_SCHEMA,
"teleo_git_head": REVISION,
"hermes_commit": package.HERMES_COMMIT,
"claim_ceiling": CLAIM_CEILING,
"content": content,
}
write_json(artifact / "artifact-manifest.json", manifest, mode=0o644)
receipt = tmp_path / "receipt.json"
write_json(
receipt,
{
"schema": package.ARTIFACT_RECEIPT_SCHEMA,
"status": "pass",
"verification_mode": "release",
"teleo_git_head": REVISION,
"artifact_sha256": content["sha256"],
"hermes_commit": package.HERMES_COMMIT,
"hermes_source_sha256": "4" * 64,
"claim_ceiling": CLAIM_CEILING,
},
mode=0o644,
)
return artifact, receipt
def identity_fixture(tmp_path: Path) -> Path:
identity = tmp_path / "identity"
identity.mkdir(parents=True)
soul = identity / "SOUL.md"
soul.write_text("# Leo fixture\n", encoding="utf-8")
soul.chmod(0o600)
stable = {
"schema": package.IDENTITY_MANIFEST_SCHEMA,
"identity_inputs": {
"canonical_database": {
"authority": "synthetic_noncanonical_fixture",
"canonical_authority_granted": False,
}
},
"identity_inputs_sha256": "5" * 64,
"compiled_views": {
"SOUL.md": {"sha256": package.sha256_file(soul)},
"identity.json": {"sha256": "6" * 64},
},
}
manifest = {**stable, "manifest_sha256": package.canonical_sha256(stable)}
write_json(identity / "identity-manifest.json", manifest)
write_json(
identity / "identity-lock.json",
{
"schema": package.IDENTITY_LOCK_SCHEMA,
"manifest_sha256": manifest["manifest_sha256"],
"identity_inputs_sha256": manifest["identity_inputs_sha256"],
"compiled_views": {
"SOUL.md": {"sha256": package.sha256_file(soul)},
"identity.json": {"sha256": "6" * 64},
},
"session_boundary": {"classification": "temporary_noncanonical"},
},
)
return identity
def image_input_fixture(tmp_path: Path) -> dict[str, object]:
artifact, receipt = artifact_fixture(tmp_path)
identity = identity_fixture(tmp_path)
return package.build_image_input(
artifact=artifact,
receipt=receipt,
identity=identity,
ca=ROOT / "ops" / "gcp-teleo-pgvector-standby-server-ca.pem",
source_revision=REVISION,
dockerfile=ROOT / "docker" / "leoclean-nosend" / "Dockerfile",
entrypoint=ROOT / "docker" / "leoclean-nosend" / "entrypoint.py",
package_contract=ROOT / "ops" / "gcp_leoclean_nosend_package.py",
)
def test_image_input_binds_exact_runtime_identity_and_staging_target(tmp_path: Path) -> None:
value = image_input_fixture(tmp_path)
package.validate_image_input(value)
assert value["target"] == {
"project": "teleo-501523",
"zone": "europe-west6-a",
"instance": "teleo-staging-1",
"service": "leoclean-gcp-nosend.service",
"service_account": "sa-teleo-staging-vm@teleo-501523.iam.gserviceaccount.com",
"platform": "linux/amd64",
}
assert value["runtime"]["python_version"] == "3.11.9"
assert value["runtime"]["postgres_version"] == "16.14"
assert value["identity"]["canonical_authority_granted"] is False
assert value["base_images"]["postgres"].endswith(
"@sha256:92620daddcd947f8d5ab5ba66e848702fe443d87fed30c4cea8e389fd78dfc55"
)
def test_artifact_requires_release_receipt_exact_revision_and_unchanged_content(tmp_path: Path) -> None:
artifact, receipt = artifact_fixture(tmp_path)
package.validate_artifact(artifact, receipt, REVISION)
development = json.loads(receipt.read_text(encoding="utf-8"))
development["verification_mode"] = "development"
write_json(receipt, development, mode=0o644)
with pytest.raises(package.PackageError, match="not release"):
package.validate_artifact(artifact, receipt, REVISION)
development["verification_mode"] = "release"
write_json(receipt, development, mode=0o644)
(artifact / "bootstrap.py").write_text("mutated\n", encoding="utf-8")
(artifact / "bootstrap.py").chmod(0o755)
with pytest.raises(package.PackageError, match="content manifest drifted"):
package.validate_artifact(artifact, receipt, REVISION)
def test_identity_bundle_rejects_drift_extra_files_and_false_authority(tmp_path: Path) -> None:
identity = identity_fixture(tmp_path)
package.validate_identity_bundle(identity)
(identity / "SOUL.md").write_text("drift\n", encoding="utf-8")
(identity / "SOUL.md").chmod(0o600)
with pytest.raises(package.PackageError, match="SOUL content differs"):
package.validate_identity_bundle(identity)
identity = identity_fixture(tmp_path / "second")
(identity / "extra.txt").write_text("extra\n", encoding="utf-8")
with pytest.raises(package.PackageError, match="entry set"):
package.validate_identity_bundle(identity)
identity = identity_fixture(tmp_path / "third")
manifest_path = identity / "identity-manifest.json"
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
manifest["identity_inputs"]["canonical_database"] = {
"authority": "synthetic_noncanonical_fixture",
"canonical_authority_granted": True,
}
stable = {key: value for key, value in manifest.items() if key != "manifest_sha256"}
manifest["manifest_sha256"] = package.canonical_sha256(stable)
write_json(manifest_path, manifest)
lock_path = identity / "identity-lock.json"
lock = json.loads(lock_path.read_text(encoding="utf-8"))
lock["manifest_sha256"] = manifest["manifest_sha256"]
write_json(lock_path, lock)
with pytest.raises(package.PackageError, match="authority"):
package.validate_identity_bundle(identity)
def test_release_requires_exact_digest_repository_and_strict_schema(tmp_path: Path) -> None:
image_input = image_input_fixture(tmp_path)
reference = f"{package.IMAGE_REPOSITORY}@sha256:{IMAGE_DIGEST}"
release = package.build_release_descriptor(image_input, reference)
package.validate_release_descriptor(release)
assert release["image"]["reference"] == reference
assert release["image"]["digest"] == f"sha256:{IMAGE_DIGEST}"
assert release["image"]["platform"] == "linux/amd64"
with pytest.raises(package.PackageError, match="sha256 digest"):
package.build_release_descriptor(image_input, f"{package.IMAGE_REPOSITORY}:latest")
with pytest.raises(package.PackageError, match="staging repository"):
package.build_release_descriptor(
image_input,
f"europe-west6-docker.pkg.dev/teleo-501523/teleo/other@sha256:{IMAGE_DIGEST}",
)
extra = copy.deepcopy(release)
extra["unexpected"] = True
with pytest.raises(package.PackageError, match="fields are not exact"):
package.validate_release_descriptor(extra)
wrong_label = copy.deepcopy(release)
wrong_label["image"]["labels"]["livingip.artifact.sha256"] = "9" * 64
stable = {key: value for key, value in wrong_label.items() if key != "release_sha256"}
wrong_label["release_sha256"] = package.canonical_sha256(stable)
with pytest.raises(package.PackageError, match="labels are not exact"):
package.validate_release_descriptor(wrong_label)
def test_rendered_unit_is_isolated_digest_pinned_and_has_no_credential_or_transport_surface(tmp_path: Path) -> None:
image_input = image_input_fixture(tmp_path)
release = package.build_release_descriptor(
image_input,
f"{package.IMAGE_REPOSITORY}@sha256:{IMAGE_DIGEST}",
)
unit = package.render_systemd_unit(release)
assert "leoclean-gcp-nosend" in unit
assert f"@sha256:{IMAGE_DIGEST}" in unit
assert "--pull=never" in unit
assert "--read-only" in unit
assert "--cap-drop=ALL" in unit
assert "--cap-add=CHOWN" in unit
assert "--cap-add=SETGID" in unit
assert "--cap-add=SETUID" in unit
assert "--cap-add=SETPCAP" in unit
assert "--network=bridge" in unit
assert "--tmpfs=/run/leoclean-profile:" in unit
assert "--tmpfs=/var/lib/postgresql/data:ro,noexec,nosuid,nodev,size=64k,uid=0,gid=0,mode=0000" in unit
assert "NoNewPrivileges=yes" in unit
assert "EnvironmentFile" not in unit
assert "LoadCredential" not in unit
assert "docker.sock" not in unit
assert "--publish" not in unit
assert "teleo-prod-1" not in unit
assert "77.42.65.182" not in unit
assert "telegram" not in unit.casefold()
def test_prepare_context_is_secret_free_normalized_and_idempotently_refuses_overwrite(tmp_path: Path) -> None:
artifact, receipt = artifact_fixture(tmp_path)
identity = identity_fixture(tmp_path)
output = tmp_path / "context"
result = package.prepare_context(
repo_root=ROOT,
artifact=artifact,
receipt=receipt,
identity=identity,
output=output,
source_revision=REVISION,
)
package.validate_image_input(result)
assert sorted(path.name for path in output.iterdir()) == [
"Dockerfile",
"artifact",
"artifact-receipt.json",
"build-args.json",
"cloudsql-server-ca.pem",
"entrypoint.py",
"identity",
"image-input.json",
"package_contract.py",
]
assert all((output / "identity" / name).stat().st_mode & 0o777 == 0o600 for name in package.IDENTITY_FILES)
encoded = (output / "image-input.json").read_text(encoding="utf-8").casefold()
assert "telegram_bot_token" not in encoded
assert "postgres-password" not in encoded
with pytest.raises(package.PackageError, match="already exists"):
package.prepare_context(
repo_root=ROOT,
artifact=artifact,
receipt=receipt,
identity=identity,
output=output,
source_revision=REVISION,
)
def test_dockerfile_has_only_digest_pinned_bases_and_no_floating_package_install() -> None:
dockerfile = (ROOT / "docker" / "leoclean-nosend" / "Dockerfile").read_text(encoding="utf-8")
from_lines = [line for line in dockerfile.splitlines() if line.startswith("FROM ")]
assert len(from_lines) == 3
assert all("@sha256:" in line for line in from_lines)
assert "postgres:16.14-bookworm@sha256:92620d" in dockerfile
assert "python:3.11.9-slim-bookworm@sha256:8fb099" in dockerfile
assert "uv:0.9.30@sha256:538e0b" in dockerfile
assert "apt-get" not in dockerfile
assert "pip install" not in dockerfile
assert "uv sync" in dockerfile
assert "--frozen" in dockerfile
assert "--no-editable" in dockerfile
assert "HEALTHCHECK" in dockerfile
assert "verify-build" in dockerfile
def test_entrypoint_prepares_exact_profile_drops_privileges_and_health_checks_pid_one() -> None:
source = (ROOT / "docker" / "leoclean-nosend" / "entrypoint.py").read_text(encoding="utf-8")
assert "os.setgroups([])" in source
assert "os.setgid(contract.RUNTIME_GID)" in source
assert "os.setuid(contract.RUNTIME_UID)" in source
assert "pr_capbset_drop = 24" in source
assert "reverse=True" in source
assert source.index("os.chown(runtime_identity, 0, 0)") < source.index(
"os.chown(PROFILE, contract.RUNTIME_UID, contract.RUNTIME_GID)"
)
assert 'value.get("process_id") == 1' in source
assert "expected_binfmt = [expected_native[0], *expected_native]" in source
assert "cmdline in (expected_native, expected_binfmt)" in source
assert 'surface.get("send_message_present") is False' in source
assert "gateway_adapter_count" in source
assert "os.execve" in source
assert "OPENROUTER_API_KEY" not in source
assert "TELEGRAM_BOT_TOKEN" not in source
def test_entrypoint_loads_adjacent_contract_with_python_safe_path(tmp_path: Path) -> None:
image_root = tmp_path / "image"
image_root.mkdir()
entrypoint = image_root / "entrypoint.py"
shutil.copy2(ROOT / "docker" / "leoclean-nosend" / "entrypoint.py", entrypoint)
shutil.copy2(ROOT / "ops" / "gcp_leoclean_nosend_package.py", image_root / "package_contract.py")
environment = {**os.environ, "PYTHONSAFEPATH": "1"}
result = subprocess.run(
[sys.executable, "-P", str(entrypoint), "verify"],
cwd=tmp_path,
env=environment,
check=False,
capture_output=True,
text=True,
timeout=10,
)
assert result.returncode == 65
assert json.loads(result.stderr) == {"error": "container_contract_failed", "status": "fail"}
assert "Traceback" not in result.stderr

View file

@ -7,6 +7,7 @@ import copy
import importlib.util
import io
import json
import os
import re
import shutil
import subprocess
@ -52,6 +53,7 @@ def copy_profile(tmp_path: Path, bootstrap) -> Path:
bootstrap._runtime_root = lambda: runtime_root
profile = tmp_path / "profile"
shutil.copytree(runtime_root / "profile-template", profile)
profile.chmod(0o700)
return profile
@ -100,6 +102,19 @@ def test_committed_lock_and_contract_are_exactly_pinned() -> None:
}
def test_compiled_immutable_profile_is_readable_after_privilege_drop(tmp_path: Path) -> None:
runtime_root = tmp_path / "runtime"
runtime_root.mkdir()
compiler._copy_profile(ROOT, runtime_root, LOCK)
profile = runtime_root / "profile-template"
assert profile.stat().st_mode & 0o777 == 0o555
assert (profile / "config.yaml").stat().st_mode & 0o777 == 0o444
assert all(path.stat().st_mode & 0o004 for path in profile.rglob("*") if path.is_file())
assert all(path.stat().st_mode & 0o001 for path in profile.rglob("*") if path.is_dir())
def test_profile_sources_keep_gcp_adapters_out_of_vps_deploy_paths() -> None:
by_target = {entry["target"]: entry for entry in LOCK["profile_sources"]}
assert by_target["bin/cloudsql_memory_tool.py"]["source"] == (
@ -219,6 +234,67 @@ def test_profile_template_and_runtime_state_are_exact(tmp_path: Path) -> None:
bootstrap._validate_profile(profile, CONTRACT, template=False)
def test_service_readiness_is_atomic_sanitized_and_identity_bound(tmp_path: Path) -> None:
bootstrap = load_bootstrap()
profile = copy_profile(tmp_path, bootstrap)
for name in CONTRACT["profile"]["required_runtime_entries"]:
(profile / name).write_text(f"{name}\n", encoding="utf-8")
state = profile / "state"
state.mkdir()
readiness = state / "readiness.json"
tool_surface = {
"registry_sealed": True,
"send_message_present": False,
"tools": ["skill_view", "skills_list", "terminal"],
}
bootstrap._write_readiness(
profile,
readiness,
CONTRACT,
SimpleNamespace(adapters={}),
tool_surface,
)
payload = json.loads(readiness.read_text(encoding="utf-8"))
assert payload == {
"schema": bootstrap.READINESS_SCHEMA,
"status": "ready",
"process_id": os.getpid(),
"runtime_mode": "gcp_staging_no_send",
"config_sha256": bootstrap._sha256(profile / "config.yaml"),
"gateway_adapter_count": 0,
"connected_platforms": [],
"tool_surface": tool_surface,
"identity_sha256": {
name: bootstrap._sha256(profile / name)
for name in ("SOUL.md", "identity-lock.json", "identity-manifest.json")
},
}
assert readiness.stat().st_mode & 0o777 == 0o600
assert str(profile) not in readiness.read_text(encoding="utf-8")
def test_service_readiness_rejects_escape_and_symlink(tmp_path: Path) -> None:
bootstrap = load_bootstrap()
profile = copy_profile(tmp_path, bootstrap)
for name in CONTRACT["profile"]["required_runtime_entries"]:
(profile / name).write_text("{}\n", encoding="utf-8")
state = profile / "state"
state.mkdir()
runner = SimpleNamespace(adapters={})
with pytest.raises(bootstrap.NoSendContractError, match="inside profile state"):
bootstrap._write_readiness(profile, tmp_path / "readiness.json", CONTRACT, runner, {})
target = state / "target.json"
target.write_text("{}\n", encoding="utf-8")
linked = state / "readiness.json"
linked.symlink_to(target)
with pytest.raises(bootstrap.NoSendContractError, match="symlink"):
bootstrap._write_readiness(profile, linked, CONTRACT, runner, {})
@pytest.mark.parametrize(
("section", "field", "unsafe"),
[
@ -240,6 +316,7 @@ def test_profile_rejects_learning_policy_drift(
bootstrap = load_bootstrap()
profile = copy_profile(tmp_path, bootstrap)
config_path = profile / "config.yaml"
config_path.chmod(0o600)
config = yaml.safe_load(config_path.read_text(encoding="utf-8"))
config[section][field] = unsafe
config_path.write_text(yaml.safe_dump(config, sort_keys=False), encoding="utf-8")
@ -254,6 +331,7 @@ def test_profile_rejects_smart_model_routing(tmp_path: Path) -> None:
bootstrap = load_bootstrap()
profile = copy_profile(tmp_path, bootstrap)
config_path = profile / "config.yaml"
config_path.chmod(0o600)
config = yaml.safe_load(config_path.read_text(encoding="utf-8"))
config["smart_model_routing"] = {
"enabled": True,
@ -750,6 +828,7 @@ def test_ci_runs_the_release_canary_and_retains_its_receipt() -> None:
assert "--development" not in wrapper
assert "--allow-dirty" not in wrapper
assert 'rm -f "$receipt"' in wrapper
assert 'chmod -R u+w "$temporary"' in wrapper
assert 'repeat_artifact="$temporary/artifact-repeat"' in wrapper
assert "first != second" in wrapper
assert "compile-primary.json" in wrapper