The composite-action pivot was based on a false negative — reusable workflows DO work on Forgejo 11 (caller needs `runs-on`; short cross-repo ref). Correct the SESSION_002 + HANDOVER ecosystem-CI sections, the next-steps Forgejo-upgrade note, and point the required-reads at .forgejo/workflows/README.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.4 KiB
HANDOVER — next-session prompt (paste into a fresh context)
Living doc: overwritten each handover. The durable record is the dated
SESSION_*files. Latest state =SESSION_2026-07-01_002.md.
Continue the olsitec-foundation build. You are the Lead Agent, HIGH-RISK / INFRA mode.
Required reads (in ~/work/olsitec-foundation/foundation/)
documentation/sessions/SESSION_2026-07-01_002.md← current state + known gaps + next stepsdocumentation/sessions/SESSION_2026-07-01_001.md← the prior session (gaps closed, T11/T13/T14-core)documentation/contracts/CONTRACT_001–004+decisions/ADR_004,005,006,007(ADR-007 is the control-plane mechanism the whole egg runs on — read it first).forgejo/workflows/README.md← the ecosystem-CI reusable-workflow contract + the Forgejo-11 caller quirkdocumentation/999_testing.md← the operator's acceptance-test plan (now implemented)
Where things stand
The egg is LIVE; T11/T13/T14 are DONE; the ecosystem CI (999_testing) is built and validated.
Six containers on foundation-net (postgres/rustfs/vault/caddy/forgejo/runner), all healthy.
https://forge.olsitec.net=200; git clone git@git.olsitec.net:olsitec/foundation.git works; origin is
Forgejo (master default). Backups age-encrypted + restore-verified (RustFS + offsite); DR scripted (dr/).
Working tree clean on master.
CI on the runner, all green:
ci.yml(preflight + typecheck),pulumi-preview.yml(read-only drift/PR check),backup-verify.yml(weekly + dispatch; RESTORE VERIFY PASS from offsite).ecosystem-selftest.yml— semantic-release bump sequence (1.0.0→1.1.0→1.1.1→2.0.0→3.0.0) + eslint/yamllint non-zero-exit gates..forgejo/workflows/reusable-*.yml(node-build, docker-build, lint, semantic-release) — the ecosystem-CI reuse layer. Downstream repos call them asuses: olsitec/foundation/.forgejo/workflows/<x>.yml@master. Forgejo-11 quirk: the calling job MUST setruns-on(omitting it → silently zero runs; removed by a v15 upgrade) and use the SHORT cross-repo ref (not a full URL). See.forgejo/workflows/README.md.
cd bootstrap && ./run.sh up is idempotent and now also publishes pulumi stack export to RustFS
(bootstrap/state-publish.sh) so the state-dependent CI has Pulumi state.
Operating essentials
- VM:
204.168.234.72, admin SSH :222, key~/.ssh/foundation-test_ed25519(also the Forgejo operator key). Git endpoint :22 (scp-form) + :2222. - Deploy:
cd bootstrap && ./run.sh up. Master passphrase:pass olsitec-foundation/PULUMI_CONFIG_PASSPHRASE. - Vault reboot:
bootstrap/vault-unseal.sh. Backup:backup/backup.sh [ts]; restore-verify:backup/restore.sh <ts> [rfs|off]. DR:dr/restore-to-fresh-vm.sh(+dr/RUNBOOK.md). - Forge admin:
platform-admin/ Vaultfoundation/forgejo/service-credentials:forgejoAdminPassword. (If you change the admin password in the UI, the API steps that set CI secrets need the new value.) - CI image: built on the VM (
/tmp/ci-image, fromcontainers/ci-image/Dockerfile), tagfoundation-ci:latest, used locally by the runner (force_pull:false). Rebuild on toolchain change:scpthe Dockerfile +docker build -t foundation-ci:latest .on the VM. - CI secrets (repo-scoped on
olsitec/foundation, set via the admin API):PULUMI_CONFIG_PASSPHRASE,SSH_PRIVATE_KEY,RUSTFS_ACCESS_KEY,RUSTFS_SECRET_KEY.
Watchouts (HIGH-RISK)
pulumi-previewshows a benign perpetual~sshOptsdiff (the operator vs CI key path differ in the docker provider) — informational; preview exits 0 on diffs by design. Don't add--expect-no-changes.up --refreshshows pessimistic~triggersreplaces on the vault command chain (a preview artifact, idempotent if applied). The VM sshd throttles bursts of docker-over-SSH → use--parallel 1for refresh, or raise MaxStartups before wiring refresh into CI.- Never print/commit the passphrase, Vault root token, or unseal keys (D2). Don't
pulumi upthe prodolsicloud4-*stacks, and don'tuptheprovisionstack against the LIVE VM (it would recreate it). - The runner holds the host Docker socket (root-equivalent). R5 is deferred (operator OK'd trusted first-party CI on it) — fence it to a separate VM before any UNTRUSTED workflow. Commit atomically per task.
Next work (pick up here)
- Package registry (Stage-2) — populate the Forgejo package registry so cross-repo
@olsitecdeps resolve: publisholsicrypto,svelte-common, … Then validatedocker-buildend-to-end for the two registry-blocked candidates (C1 seaspots-homepage, C5 token-service) — pass an npmrc via the action'sbuild-args. (C2/C3/C4 already validated.) - R5 fence — separate privileged runner VM (or socket-less DinD), labelled, before untrusted repos.
- T15 —
index.tsorchestration polish (phase marker stillT10-runner) + Gate A/B comments +docs/DAY-ZERO-TIMELINE.md. - Hardening — pin floating refs (
IMAGE_REGISTRYPIN_DIGEST,IMAGE_RUSTFSlatest,IMAGE_CItag); pre-bake pulumi plugins intofoundation-ci(drop preview's per-run auto-install); register in Olsitec MCP (D6); a Forgejo v15 upgrade would drop the reusable-workflow callerruns-on/short-ref quirks.
Validate each task live (VM ./run.sh up + the runner for CI) and commit per task.