foundation/documentation/sessions/SESSION_2026-06-30_001.md
Andreas Niemann 1d2462ddaf docs(session): SESSION_2026-06-30_001 — state + Wave 2 handoff
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 20:48:35 +02:00

49 lines
3.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Session 2026-06-30 #001 — Foundation bootstrap: contracts → live VM + DNS + offsite backup
## What was done
- **T00** contracts CONTRACT_001004 (+ amendment for `hosts.git`, `vm.sshPort`, `cloudflare.zoneId`).
- **T01** `preflight/` + `VERSIONS` (images carry `:PIN_DIGEST` placeholders — see gotchas).
- **T02** Bun-workspace + typed `config.ts` + vendored `@olsitec/pulumi-{docker,vault}`.
- **ADR-006 precursor**: shared Docker-over-SSH provider + `foundation-net` (`lib/context.ts`,
`components/network.ts`, phase-slotted `index.ts`). Composition = per-component factories, gates via `dependsOn`.
- **Phase-0 VM**: vendored `@olsitec/pulumi-hetzner`; `provision/` stack. Live: **cx33 Helsinki,
`204.168.234.72`**, Docker 29.6.1, **SSH port 222**, key `~/.ssh/foundation-test_ed25519`, firewall 222/80/443/2222.
- **Offsite backup**: `offsite-backup/` stack — bucket **`olsitec-foundation`** + scoped service account
on `minio.wob.olsitec.de:19000` (home Synology). Verified scoped (cross-bucket denied).
- **Steps 1+2**: real `olsitec.net` config + **DNS** `forge/vault/s3/git.olsitec.net → 204.168.234.72`
(verified authoritative; explicit A shadows the `*.olsitec.net` wildcard). `foundation-net` live on VM.
## Current state
- Repo: `~/work/olsitec-foundation/foundation`. Latest commit `185be52`. Working tree clean.
- **Master passphrase** (the one external secret): `pass olsitec-foundation/PULUMI_CONFIG_PASSPHRASE`.
- Deploy the foundation: `cd bootstrap && ./run.sh up` (sets passphrase + `SSH_PRIVATE_KEY_PATH`).
- Stacks (all local file backends): `bootstrap` stack **foundation** (real passphrase); `provision`
stack **foundation-test** + `offsite-backup` stack **prod** (throwaway passphrase `dev-validation-throwaway`).
- Other creds: `pass olsicloud4/{HCLOUD_TOKEN,CLOUDFLARE_MASTER_TOKEN}`; MinIO admin via the
`wob-admin-external` mc alias (accessKey `admin`, NOT `pass MINIO_BACKUP_*` which is a different instance).
## Next steps (Wave 2 → the goal: `git clone git@git.olsitec.net`)
Validate each live on the VM via `bootstrap/run.sh up` (images still unpinned → `FOUNDATION_ALLOW_UNPINNED=1`
or pin digests per `VERSIONS` header). Each component is a factory `components/<svc>.ts`, wired into the
`index.ts` phase slots (ADR-006).
1. **T03 postgres** · **T04 rustfs** (+ buckets) — data plane.
2. **T05 vault** — sealed container + init-capture (reuse `olsitec-core/run.sh` pattern → unseal keys to
`vaultCredentials:*` encrypted config) + passphrase-gated unseal helper (ADR-004). The hard one.
3. **T06 credentials**`@pulumi/random` → Vault (CONTRACT_002 paths).
4. **T07 Caddy** — DNS-01 TLS; needs a **Cloudflare-enabled Caddy image** (build via xcaddy; standard
`caddy:2` lacks the DNS plugin). Token already in `foundation:cloudflareApiToken`.
5. **T08 Forgejo** — app.ini ← Postgres/RustFS/Vault; first admin headless; **org + repo** so
`git clone git@git.olsitec.net:olsitec/...` works (forgeSshPort 2222, published).
6. **T10 runner** · **T12 backup** (RustFS → replicate to the offsite `olsitec-foundation` bucket;
scoped creds already in `foundation:backup.offsite*`).
## Risks / watchouts
- `Pulumi.foundation.yaml` self-quotes scalars + `encryptionsalt` is now **load-bearing** (decrypts 3
committed secrets) — keep it committed; don't strip the salt anymore.
- VM SSH is **port 222**; the eventual real VM would be 22 (`vm.sshPort` handles it).
- `VERSIONS` images are `:PIN_DIGEST` + RustFS is `latest` — pin before treating as production.
- Don't run `pulumi up` against the production `olsicloud4-*` stacks. The home MinIO `.local` name is
LAN-only; the VM must use the public `minio.wob.olsitec.de:19000`.
- Everything is destroyable: `provision` (VM), `offsite-backup` (bucket+creds) via `pulumi destroy`.
## Operating mode for next session: HIGH-RISK / INFRA (remote VM, Docker, secrets).