# Installation preflight and release manifest The native operator protocol is version 1. `installation preflight` is the independent step-3 host check. `installation plan` repeats document validation, performs step-5 live checks and writes an owner-only JSON plan plus a separate owner-only `.key` file. Neither command creates containers, imports bindings, modifies a database or invokes model generation. Exit codes are 0 (checks passed), 1 (blocking error), and 2 (usage). JSON stdout contains only the report. Checks carry stable `id`, `outcome`, `field` and `action`; outcomes are `passed`, `error`, `warning`, `deferred-to-runtime`. ## Release manifest schema 1 The manifest is a local JSON file shipped with the verified operator/release bundle. Required keys: | Key | Contract | | --- | --- | | `schema_version` | `1` | | `version` | Semantic release version, optionally prerelease | | `revision` | 40 lowercase hexadecimal Git commit characters | | `validator_protocol` | `1`; incompatible consumers refuse the manifest | | `requirements` | `cpus`, `memory_bytes`, `disk_bytes`; at least 2 CPUs, 4 GiB Docker memory and 10 GiB installation filesystem space | | `components` | Includes `pi`, `catalog-migrations`, `workspace-maintenance` | | `images` | Exactly `core`, `frontend`, `catalog`, `qdrant`, `embedding`; each maps `linux/amd64` and/or `linux/arm64` to a `docker.io/...@sha256:...` **single-platform image digest** | | `files` | Relative packaged resource paths to SHA-256; no traversal, links or absolute paths; maximum 256 files, 32 MiB per resource | | `compose` | Ordered relative Compose file paths present in `files` for this release configuration | Include the selected `deploy/compose.git-https.yaml` or `deploy/compose.git-ssh.yaml` transport overlay in `files`. Standard transport overlays are resolved from the release while absent in the installation directory; existing authored overrides remain input files. Compose must resolve all eight services: core, frontend, catalog-db, catalog-migrate, workspace-maintenance, qdrant, embedding and embedding-model-init. The two maintenance services share the core digest; embedding initialization shares the embedding digest. Source builds and undeclared services are rejected in this prebuilt path. The explicit source path is a separate ticket. `docker manifest inspect --verbose` checks each selected immutable image and its platform without pulling layers. `docker compose config --format json` checks the effective service configuration. Compose receives only Docker connection/trust, proxy and executable-discovery host variables; application parameters come from the prepared environment file. Raw Docker output is never copied into reports. Each Docker command has a 15-second bound. No release is currently certified merely because controlled manifest tests pass: publication and real pull acceptance belong to the publication/execution tickets. ## External checks and bounds - Git HTTPS: authenticated `GET /info/refs?service=git-upload-pack`, configured CA, no redirects, selected branch advertised, 1 MiB response and 5-second bound. Git SSH uses its prepared key/known-hosts and `git-upload-pack --advertise-refs` with the same response/time bounds; no checkout or push occurs. - PostgreSQL: the existing Catalog diagnostic adapter authenticates and reads `current_database()` plus schema `USAGE`; no user tables are modified. - REST database transport: existing Catalog diagnostic `GET` with the configured bearer/API-key header and status validation. SSH database bindings cannot pass this NL-to-SQL installation plan because runtime sessions do not support them. - Evidence: local paths were already validated. HTTP performs bounded GET requests and cancels response bodies; signed URL identities must match authored provenance. S3 performs one `ListObjectsV2` request with `MaxKeys: 1`, no retries, explicit file credentials and the canonical Evidence egress policy. These metadata requests can incur normal remote-service request charges; they do not run LLM generation. Each external request has a 5-second bound; the native database/Evidence helper has a 60-second aggregate bound. Correct unavailable services before repeating. - Explicit model endpoints: DNS/TCP/TLS origin reachability, without generating tokens. Built-in endpoint resolution, provider authentication and model smoke operations use the bundled Pi SDK at runtime; the report never claims those operations have already passed. No unreachable configured external dependency is converted to a deferred success. Runtime obligations have explicit identities: `container-network`, `catalog-initialization`, `pi-operation`, `local-embedding`, `workspace-preprocessing`, `workspace-readiness`. These must be discharged by the execution/readiness tickets before final success. Host disk inspection cannot prove Docker Desktop VM free storage; its separate storage warning remains explicit. ## Input identity and freshness The plan records normalized installation configuration, release digests, validator build identity, verified input paths, local workspace content and its Git HEAD when available (otherwise a content snapshot). Files are bounded to 32 MiB each and 256 MiB total; workspace/auth trees to 10,000 entries, without links or special files. Credential contents are never serialized. An HMAC covers the private inputs and plan using a separate random 32-byte owner-only key; no public unkeyed secret hash is generated. Credential rotation invalidates the plan. Added/deleted/changed workspace files invalidate it as well. Changes during the checks abort publication. Plan output never overwrites an existing plan or key. Execution and resumption must call `VerifyPlanInputs` **and repeat live checks and credential reads before mutations**. A valid seal alone does not certify current network availability, Docker state or runtime readiness. Keep both plan files private and outside the workspace repository; they are installation-local artifacts.