decisions(2w): W1 canonical registry design (recipe_meta.WARM_CANONICAL enrollment, warm-<recipe> data-warm lifecycle, canonical.json registry)

This commit is contained in:
2026-05-29 02:11:58 +01:00
parent 56a95c68ef
commit 563156ae7e

View File

@ -642,3 +642,31 @@ component of the pre-`+` recipe semver (e.g. 3.x→4.0 = held). Secondary signal
**Scope order for W0.6:** keycloak first (the W0 focus, stateful → snapshot path); apply the same
health-gated + safety-gate pattern to traefik (stateless, version-rollback-only) afterward by
migrating proxy.nix onto the shared reconcile entrypoint.
## Phase 2w — W1 canonical registry design (WC2/WC3) (2026-05-29)
**Enrollment is declarative per-recipe via `recipe_meta.WARM_CANONICAL = True`** (consistent with how
DEPS/EXTRA_ENV are declared — enrolling a recipe stays a `tests/<recipe>/` change, D5). A recipe so
flagged gets a DATA-WARM canonical. Prove the model on a couple of recipes (custom-html simplest:
stateful, no external DB), NOT all (the nightly sweep populates the rest over time).
**Stable domain `warm-<recipe>.ci.commoninternet.net`** (already decided for keycloak; same scheme for
canonicals). Distinct from cold `<recipe[:4]>-<6hex>`. Watch the swarm 64-char secret-name limit
per recipe on first deploy.
**Known-good state per canonical, under `/var/lib/ci-warm/<recipe>/`:** `last_good` (version string,
already written by warm_reconcile), `snapshot/` (warmsnap, W0.5), and a small `canonical.json`
registry record `{recipe, domain, version, commit, status, ts}`. The DATA VOLUME is retained while
the app is undeployed (data-warm). These are cache (excluded from D8, WC8).
**Data-warm lifecycle (new `runner/harness/canonical.py`):** `is_enrolled(recipe)` (reads
WARM_CANONICAL), `canonical_domain(recipe)`, `read/write_registry(recipe)`, `deploy_canonical(recipe)`
(deploy `warm-<recipe>` at last_good, reattaching the retained volume → warm boot), `undeploy_keep_
volume(recipe)` (undeploy, volume retained = idle data-warm), `seed_canonical(recipe, version, commit)`
(record + snapshot; the volume becomes the canonical). LIVE-warm (keycloak, always up) vs DATA-warm
(canonicals, undeployed when idle) both use `warm-<recipe>` + warmsnap.
**W1 scope vs W3:** W1 builds the registry + data-warm lifecycle and proves it (seed a custom-html
canonical → undeploy keep volume → redeploy reattach → data survives; re-warmable from scratch).
**Automatic promote-on-green-cold (WC5) + nightly (WC6) are W3** — for W1 the canonical is seeded
programmatically to prove the model; the cold-advances-canonical wiring comes later.