From 594824d9fea4aef9c8a3aba48da7fd20d6f4ce92 Mon Sep 17 00:00:00 2001 From: autonomic-bot Date: Thu, 9 Jul 2026 01:42:59 +0000 Subject: [PATCH] =?UTF-8?q?journal(redfix):=20wake=20#17=20=E2=80=94=20con?= =?UTF-8?q?sumed=20review(redfix)@32fefb2=20(re-confirmation=20#15);=20fix?= =?UTF-8?q?ed=20stale=20"15=20existing=20canonicals"=20in=20STATUS=20(real?= =?UTF-8?q?:=2017=20seeded,=20and=20the=20invariant=20is=20structural=20no?= =?UTF-8?q?t=20numeric=20=E2=80=94=20WARM=5FDOMAINS=20singleton=20?= =?UTF-8?q?=E2=87=92=20exactly=20one=20re-key,=2020=20of=2021=20enrolled?= =?UTF-8?q?=20unchanged);=20all=20figures=20re-derived=20first-hand=20off?= =?UTF-8?q?=20live=20disk=20+=20b5f2b10,=20not=20taken=20from=20the=20verd?= =?UTF-8?q?ict;=20filed=20B-redfix-6=20for=20the=20same=20stale=20count=20?= =?UTF-8?q?in=20canonical.py:52's=20docstring,=20deliberately=20NOT=20fixe?= =?UTF-8?q?d=20inline=20to=20avoid=20moving=20the=20branch=20off=20the=20M?= =?UTF-8?q?2-PASS-pinned=20b5f2b10;=20no=20verdict=20change,=20DONE=20stan?= =?UTF-8?q?ds,=20loop=20remains=20stopped?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machine-docs/BACKLOG-redfix.md | 12 ++++++++++++ machine-docs/JOURNAL-redfix.md | 33 +++++++++++++++++++++++++++++++++ machine-docs/STATUS-redfix.md | 6 +++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/machine-docs/BACKLOG-redfix.md b/machine-docs/BACKLOG-redfix.md index 786d54d..4e576e2 100644 --- a/machine-docs/BACKLOG-redfix.md +++ b/machine-docs/BACKLOG-redfix.md @@ -69,6 +69,18 @@ hold). Concrete fix designs from M1 evidence: `last_good` (or, if restoring data is judged mandatory before redeploy, alert loudly + leave a breadcrumb rather than dying mid-rollback). Needs a decision on which is safer for a DB-backed app after a forward migration — that trade-off is why this is filed, not fixed inline. +- [ ] **B-redfix-6 — `canonical_ns()` docstring says "the 15 existing canonicals"; the real number is 17, + and the invariant is not a count** (COSMETIC; docs-only; no behaviour change). At + `redfix-m2-harness`@`b5f2b10`, `runner/harness/canonical.py:52` reads "zero blast radius on the 15 + existing canonicals". Verified on live disk: `/var/lib/ci-warm/` has 20 slots, **17** carrying a + `canonical.json` (spared: `alerts`, `keycloak`, `traefik` — the reconciler dirs). More importantly the + guarantee is *structural*, not numeric: `WARM_DOMAINS` is a singleton (`{"keycloak"}`), 21 recipes are + enrolled, so exactly one re-keys (`keycloak -> canon-keycloak`) and the other 20 satisfy + `canonical_ns(r) == r`. The docstring's count will rot again on the next enrollment. + **Deliberately NOT fixed inline:** amending it would move the branch tip off `b5f2b10`, the exact sha + the M2 PASS was granted against and that every drift sweep pins. Fold into the next commit that moves + the branch for a substantive reason (e.g. B-redfix-5), rewording to the structural form. + Corrected in STATUS-redfix.md prose (which is not sha-pinned) as of wake #17. ## Adversary findings diff --git a/machine-docs/JOURNAL-redfix.md b/machine-docs/JOURNAL-redfix.md index 8b1f9f6..e522da8 100644 --- a/machine-docs/JOURNAL-redfix.md +++ b/machine-docs/JOURNAL-redfix.md @@ -1103,3 +1103,36 @@ has no go.mod and no tracked `.go` files. Git cannot propagate an untracked file actor outside the two loops wrote it to both. Inert: nothing listening on :8080, no go process. Left in place (I did not create it; not mine to delete) and surfaced to the operator. Invisible to the Adversary's cold clone, so no DoD item is affected. + +## Wake #17 — 2026-07-09T01:52Z — consumed review(redfix)@32fefb2 (re-confirmation #15); corrected a stale count in STATUS; filed B-redfix-6 + +Consumed the Adversary's re-confirmation #15 (`32fefb2`): "existing canonicals unchanged" verified +exhaustively rather than only at keycloak's slot. Verdict: no finding, DONE stands, no VETO. Terminal +condition therefore unchanged and the loop remains stopped. + +The verdict carried no finding, but it did expose a factual error in an artifact I own: STATUS-redfix.md +said "the 15 existing canonicals". I did not take the Adversary's replacement number on trust either — +re-derived every figure first-hand: + + ssh cc-ci: /var/lib/ci-warm/ slots=20 seeded(canonical.json)=17 + spared = alerts, keycloak, traefik (reconciler dirs, no canonical.json) + keycloak/ contains only `last_good` → migration-none holds + canon-keycloak/ absent → created on first post-merge run + git show b5f2b10:runner/harness/warm.py → WARM_DOMAINS = {"keycloak": ...} (singleton) + enrolled (WARM_CANONICAL=True) at b5f2b10 → 21, keycloak among them ⇒ 20 unchanged + +So "15" was wrong twice over: the count is 17, and the guarantee was never a count in the first place. It +is structural — `r not in warm.WARM_DOMAINS` — which is why a singleton `WARM_DOMAINS` makes the re-key +provably `keycloak -> canon-keycloak` and nothing else. Rewrote the STATUS line in the structural form, +with 17 as an observation rather than as the load-bearing fact. STATUS is not sha-pinned, so this is free. + +**WHY I did not fix the identical "15" in the `canonical_ns()` docstring** (`canonical.py:52` @ `b5f2b10`), +which is the actual origin of the error and the copy a future reader will hit: amending it moves the branch +tip off `b5f2b10` — the exact sha the M2 PASS was granted against, that STATUS pins, and that every drift +sweep re-checks (`tip == b5f2b10`). Trading a verified gate sha for a comment fix is a bad bargain, and it +would force a re-verification round for zero behaviour change. Filed as **B-redfix-6** (cosmetic, docs-only) +to be folded into the next commit that moves the branch for a substantive reason — B-redfix-5 being the +obvious candidate. Recording it beats both silently fixing it and silently dropping it. + +Node untouched (the only remote command was a read-only `ls`/`find` under /var/lib/ci-warm). Nothing +claimed, nothing pending, no ADVERSARY-INBOX written — this needs no verdict. DONE stands. diff --git a/machine-docs/STATUS-redfix.md b/machine-docs/STATUS-redfix.md index ae9f649..c243bbf 100644 --- a/machine-docs/STATUS-redfix.md +++ b/machine-docs/STATUS-redfix.md @@ -38,7 +38,11 @@ was given against). Warm state is now keyed by a **stack namespace**, not a bare `canonical.canonical_ns(r)` is the single source from which BOTH the canonical's domain and its warm-state slot derive. A live-warm provider (`r in warm.WARM_DOMAINS`) gets ns `canon-` → domain `warm-canon-keycloak.ci.commoninternet.net` (**unchanged**) + slot `/var/lib/ci-warm/canon-keycloak/`. -Every other recipe keeps ns `` → on-disk layout of the 15 existing canonicals unchanged. +Every other recipe keeps ns `` (the invariant is structural — `r not in warm.WARM_DOMAINS` — not a +property of any particular count). `WARM_DOMAINS == {"keycloak"}` is a singleton, so the re-key is provably +`keycloak -> canon-keycloak` and nothing else: of the 21 enrolled recipes the other 20 satisfy +`canonical_ns(r) == r`, so **zero existing canonical slots change**. On live disk that is 17 seeded +canonicals (those carrying a `canonical.json`), all of which remain in `prune_stale`'s `keep` set. Addresses all four consequences: (1)+(2) slots disjoint, neither deployment can replace the other's known-good; (3) the outage race is removed with the shared slot; (4) `prune_stale`'s reconciler-dir