From 4ce80f87514a1b02c6cedc5a3d5cfcc69b9560c2 Mon Sep 17 00:00:00 2001 From: autonomic-bot Date: Fri, 29 May 2026 02:23:22 +0100 Subject: [PATCH] =?UTF-8?q?claim(2w):=20W1=20gate=20WC2+WC3=20CLAIMED=20?= =?UTF-8?q?=E2=80=94=20data-warm=20canonical=20proven=20(custom-html=20rou?= =?UTF-8?q?nd-trip:=20undeploy-keep-volume=20=E2=86=92=20reattach=20?= =?UTF-8?q?=E2=86=92=20data=20survives)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit W1.2: enrolled custom-html (recipe_meta.WARM_CANONICAL); live proof ALL PASS (seed canonical → idle-with-volume-retained → re-warm → marker survived). WC2 (registry+data-warm model) + WC3 (snapshot+restore) proven. 61 unit pass. custom-html now the first real data-warm canonical (idle). Co-Authored-By: Claude Opus 4.8 (1M context) --- machine-docs/JOURNAL-2w.md | 17 ++++++++++++ machine-docs/STATUS-2w.md | 44 +++++++++++++++++++++++++++++--- tests/custom-html/recipe_meta.py | 7 +++++ 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 tests/custom-html/recipe_meta.py diff --git a/machine-docs/JOURNAL-2w.md b/machine-docs/JOURNAL-2w.md index 9c4c79e..5ffc17e 100644 --- a/machine-docs/JOURNAL-2w.md +++ b/machine-docs/JOURNAL-2w.md @@ -233,3 +233,20 @@ restore. Need to decide: registry format/location (in-repo declarative) + the da builds the registry + data-warm reconcile; WC5/WC6 (promote-on-green-cold + nightly) come in W3. traefik W0.10 + alert-relay deferred to a quiet window before DONE (traefik is critical TLS infra). + +## 2026-05-29 — W1.2 data-warm canonical PROVEN (WC2+WC3); claiming W1 gate + +Enrolled custom-html (`recipe_meta.WARM_CANONICAL=True`) and ran the live data-warm proof +(/tmp/wc2_proof.py): deploy warm-custom-html @ 1.11.0+1.29.0 → write marker into the content volume → +undeploy → seed_canonical (registry + snapshot while undeployed) → confirm app UNDEPLOYED but volume +RETAINED → deploy_canonical reattach → **marker SURVIVED**. ALL PASS. custom-html is now the first +real data-warm canonical, left idle (undeployed, volume retained, registry status=idle). Disk 49% +(custom-html canonical 32K; keycloak snapshot 318M = the one-per-app DB snapshot, WC8 budget). + +WC2 (registry + data-warm model) + WC3 (snapshot tied to canonical; restore proven in W0.5) are +proven. Claimed the WC2+WC3 gate for Adversary cold-verify. One canonical (custom-html) demonstrates +the model; the nightly sweep (WC6/W3) populates more over time — not re-warming all here (plan §4 +bounded). Did NOT enroll a 2nd recipe yet (custom-html suffices for W2 --quick + the model proof). + +Parked at the W1 gate. While awaiting: will do non-disruptive W0.10b (alert-relay) — NOT the traefik +W0.10a migration (it disrupts TLS the Adversary needs to verify the data-warm round-trip through). diff --git a/machine-docs/STATUS-2w.md b/machine-docs/STATUS-2w.md index 354d9ee..106f7f7 100644 --- a/machine-docs/STATUS-2w.md +++ b/machine-docs/STATUS-2w.md @@ -20,10 +20,13 @@ nightly full-cold sweep. Definition of Done = WC1–WC9 (plan §1), each Adversa before Phase-2w DONE (Adversary will require a cold proof). - [x] **WC1.2** — Pre-deploy safety gate (major / manual-migration → hold + alert with notes, no churn, short-circuits before WC1.1). **Adversary PASS @2026-05-29**. -- [ ] **WC2** — Data-warm canonical model: per-recipe canonical at a stable domain, declarative - registry tracking recipe→known-good commit; re-warmable from scratch. -- [ ] **WC3** — Known-good snapshots: raw volume copy taken while undeployed under stable path; one - last-known-good per app, atomic replace; restore proven to round-trip data. +- [x] **WC2** — Data-warm canonical model: per-recipe canonical at stable domain `warm-`, + declarative registry (canonical.json + recipe_meta.WARM_CANONICAL) tracking recipe→known-good + version/commit; data-warm (undeployed-when-idle, volume retained); re-warmable via seed_canonical. + Proven on custom-html (W1.2). **CLAIMED — see Gate below.** +- [x] **WC3** — Known-good snapshots: raw per-volume tar taken while undeployed under + `/var/lib/ci-warm//snapshot/`; one last-good per app, atomic subdir swap; restore + round-trips data (W0.5 mutate→restore proof + W1.2 data-warm reattach). **CLAIMED — see Gate.** - [ ] **WC4** — `--quick` mode: reattach canonical → upgrade to PR head → generic+custom asserts; PASS→undeploy keep volume (known-good unchanged); FAIL→restore snapshot then undeploy; never promotes. - [ ] **WC5** — Canonical advancement via cold only (promote-on-green-cold; seeds on first green cold). @@ -116,6 +119,39 @@ headline e2e is green (below). No recipe/harness change needed. ## Gate +### Gate: WC2 + WC3 — CLAIMED, awaiting Adversary (@2026-05-29, HEAD = see `git log -1`) + +**WHAT.** The data-warm canonical model (W1): a declarative per-recipe canonical at the stable domain +`warm-.ci.commoninternet.net`, kept **data-warm** (undeployed-when-idle, data volume +retained), tracked by a registry; **known-good snapshots** (raw per-volume tar while undeployed, one +last-good per app, restore round-trips data). + +**WHERE (code).** `runner/harness/canonical.py` (registry + data-warm lifecycle), `runner/harness/ +warmsnap.py` (snapshot/restore), enrollment `tests/custom-html/recipe_meta.py: WARM_CANONICAL=True`. +State on cc-ci under `/var/lib/ci-warm//` (`canonical.json`, `snapshot/`, retained volume). + +**HOW + EXPECTED (cold, from your own clone on cc-ci):** +1. **Units:** `cc-ci-run -m pytest tests/unit -q` → **61 passed** (incl. test_canonical, test_warmsnap). +2. **WC2/WC3 data-warm round-trip** (custom-html canonical exists idle now): reproduce with a driver + that uses `runner/harness/canonical.py` — deploy `warm-custom-html.ci.commoninternet.net` @ + `1.11.0+1.29.0`, write a marker file into `/usr/share/nginx/html/`, undeploy, `seed_canonical` + (writes `/var/lib/ci-warm/custom-html/canonical.json` + a `snapshot/` while undeployed); confirm + **app UNDEPLOYED but the `content` volume RETAINED** (`docker volume ls | grep warm-custom-html`); + then `deploy_canonical('custom-html')` → the marker **survives** (data-warm reattach). Builder ran + this live: **ALL PASS** (marker `WC2-DATA-MARKER-7f3a9c` survived; registry version=1.11.0+1.29.0; + snapshot present). Current live state: `cat /var/lib/ci-warm/custom-html/canonical.json` → + status=idle, version=1.11.0+1.29.0; `docker volume ls` shows + `warm-custom-html_ci_commoninternet_net_content` retained with NO custom-html service running. +3. **WC3 restore round-trip** already cold-verified in the W0.9/W0.5 keycloak proof (snapshot → + mutate DB → restore → data back); same `warmsnap` helper. +4. **D8/WC8:** `/var/lib/ci-warm/` is cache, NOT in the nix closure (no module references it as a + source); re-seeded by cold runs, not restored on rebuild. + +**Builder will NOT advance into W2 (`--quick`, which consumes the canonical) past this gate** until +REVIEW-2w shows PASS — but will do non-disruptive W0.10 follow-ups (alert relay) meanwhile. + +--- + ### Gate: WC1 + WC1.2 + WC1.1(keycloak) — ✅ Adversary PASS @2026-05-29 (REVIEW-2w 31ac86d, gate 985686f) All 6 checks cold-verified from the Adversary's own clone. Builder may proceed to W1. **Tracked open (must close before Phase-2w DONE, not a blocker now): traefik WC1.1 (W0.10)** — stateless diff --git a/tests/custom-html/recipe_meta.py b/tests/custom-html/recipe_meta.py new file mode 100644 index 0000000..8ce953a --- /dev/null +++ b/tests/custom-html/recipe_meta.py @@ -0,0 +1,7 @@ +# Per-recipe harness config for custom-html. (Previously none — all defaults; still all defaults +# except the Phase-2w enrollment flag below.) +# +# Phase 2w / WC2: enroll custom-html as a DATA-WARM canonical (simplest stateful recipe: nginx serving +# a single `content` volume, no external DB). The canonical lives at warm-custom-html.ci...; idle = +# undeployed with its content volume retained, re-warmed on demand. See runner/harness/canonical.py. +WARM_CANONICAL = True