foundation/documentation/agents/task_001_preflight/000_subtask_outline.md
Andreas Niemann edc708b826 feat(preflight): host/toolchain validation + VERSIONS pin-file — T01
- VERSIONS: 7 container images (CONTRACT_003 §3.2) + 13 host tools, KEY=value,
  source-able+greppable; images carry :PIN_DIGEST placeholders with a documented
  pin-digests procedure (D5 determinism — no real deploy until pinned).
- preflight.sh: fails closed (non-zero on any required check), bash-3.2 safe,
  composable checks/ (versions,tools,env,docker) + gated (ssh,dns) that WARN-skip
  until the stack is configured.
- env check honors D2 (passphrase presence only, never printed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 18:00:26 +02:00

3.3 KiB

Task T01 — Pre-flight tooling + VERSIONS pin-file — Subtask Outline

Mode: BUILD (scaffolding only; no live VM touched — not HIGH-RISK/INFRA). Realizes: PLAN-002 §10 T01, §9.1 (binary installation / host validation), baseline D5 (determinism). Contracts read: CONTRACT_001 (config schema §1.1/§1.3), CONTRACT_003 (container/DNS §3.2).

Restated task

Build the pre-flight validation tooling and the VERSIONS determinism pin-file for olsitec-foundation:

  1. foundation/VERSIONS — pin every CONTRACT_003 §3.2 container image + every required host tool; KEY=value, source-able + greppable; digest-pin form image:tag@sha256:<digest> with a documented pin-digests procedure and a PIN_DIGEST placeholder where digests can't be resolved offline.
  2. foundation/preflight/preflight.sh — orchestrates checks, PASS/FAIL summary, exits non-zero on any failure; set -euo pipefail; macOS bash 3.2 + Linux compatible.
  3. foundation/preflight/checks/*.sh — one composable script per concern.

Checks implemented (one file per concern)

Check Concern Gates exit code?
versions.sh VERSIONS present, source-able, all required keys present; WARN on PIN_DIGEST yes
tools.sh every required tool present + version ≥ VERSIONS pin yes
env.sh PULUMI_CONFIG_PASSPHRASE set/non-empty (presence only, never printed — D2); SSH_PRIVATE_KEY_PATH (default ~/.ssh/id_rsa) exists yes
docker.sh docker info succeeds (daemon reachable) yes
ssh.sh OPTIONAL/GATED: SSH reachability to foundation:vm.host — WARN-skip if no stack config no
dns.sh OPTIONAL/GATED: resolves foundation:hosts.* — WARN-skip if no stack config no

Shared helpers live in preflight/lib/common.sh (PASS/FAIL/WARN reporters, bash-3.2-safe numeric version compare pf_vercmp/pf_ge, pf_versions_get).

Assumptions

  • Tool list is taken from the task scope: pulumi, bun, node, docker, git, age, zstd, jq, vault CLI, postgresql client (psql + pg_dump), openssh client, S3/RustFS client (mc). CONTRACT_001/003 name the artifacts but not an explicit tool floor list, so this scope list is authoritative (no contract conflict).
  • Tool minimums in VERSIONS are conservative real-world floors (not exact host versions), so the file is portable across operator workstation + CI without pinning to whatever happens to be installed here.
  • Image digests cannot be resolved offline in this environment → every image carries the stable tag and the @sha256:PIN_DIGEST placeholder. This is a WARNING, not a failure, at scaffold stage (honesty / PD-5).
  • Gated checks depend on Pulumi stack config (bootstrap/) that does not meaningfully exist yet → they detect absence and WARN-skip rather than fail (per task spec).
  • Image tags chosen: caddy 2.10, forgejo codeberg.org/forgejo/forgejo:11, postgres 17, hashicorp/vault 1.18, rustfs rustfs/rustfs:latest (no stable semver — must digest-pin), act_runner code.forgejo.org/forgejo/runner:6, registry:2. These are the pinnable identities; the binding determinism guarantee is the digest, added by the pin-digests procedure when online.

Out of scope (not touched)

bootstrap/, packages/, other components, any pulumi up, any secret material, git add/commit.