diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 61174b2..32926b6 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -753,7 +753,23 @@ **R10 confirmed:** P3 and P4-MAAS clear by running preflight on voffice1; octavia-pki and the 7 credential findings do not. Preflight cannot usefully be RUN there yet -- that clone is 105 commits stale. - Remaining: R9-R10 blocking, R12-R15 standing; G18 deferred-and-gated. + **R9 RULED 2026-07-27 -- exact utterance "Derive lib-net's dc1 arm from the overlay, with a + drift check (Recommended)"**, recorded as a **D-119 AMENDMENT (2026-07-27)**. + `scripts/lib-net.sh`'s `vr1-dc1` arm becomes GENERATED from `overlays/vr1-dc1-vips.yaml` + with a render-drift check that fails the gauntlet on divergence -- consumers keep sourcing + lib-net unchanged, and there is exactly ONE authored copy. **Mirrors D-137 sub-ruling 2** + (creds-manifests derived from creds-matrix.tsv with a drift gate), a pattern already ruled, + built and proven here. **Deliberately does NOT pre-empt the UNRULED D-136**: if that renderer + is later adopted, the apex becomes the source and both the overlay and this derived arm + become generated -- this is a sub-case, not a competitor. **GUARD carried from R11: the arm + unsets NINE variables for TWO reasons -- `METAL_INTERNAL_VID`/`IFACE` are CORRECTLY unset per + D-133 and must STAY unset; only the VIP/FIP/keystone group is derivable.** A generator that + populated all nine would silently reintroduce a stack D-133 retired. Coupled: R2 makes the + derivation dual-family; R11 moves `VIP_COUNT_EXPECT` 11->13 and widens the band, and the two + band constants are separately named in two files. **STILL OWED, not covered by this ruling: + the CONSUMER SWEEP** -- 20 of 28 scripts never call the selector; Stage-5 exposure is TWO of + them (`phase-03-core-verify.sh`, `deploy-watch.sh`), the rest bite at Stages 6-7. + Remaining: R10 blocking, R12-R15 standing; G18 deferred-and-gated. - Position inside Stage 3: deploy step A EXECUTED 2026-07-19 (6/0/6 exact; convergence zero -- `docs/audit/outer-plan-20260719-postA-converged.txt`). **Deploy step B diff --git a/docs/design-decisions.md b/docs/design-decisions.md index 7c8b5be..2876e0a 100644 --- a/docs/design-decisions.md +++ b/docs/design-decisions.md @@ -3753,6 +3753,66 @@ in a repo that operates more than one cloud is a latent off-by-one waiting for a reader who does not know which cloud the sentence is about. +## D-119 -- AMENDMENT (2026-07-27): the dc1 arm's OpenStack-layer literals are DERIVED from the overlay, not authored twice + +**Status:** RULED 2026-07-27 (operator, GA-R5). Question as presented, verbatim: "R9 -- dc1's +OpenStack-layer literals (VIP bands, FIP pool, keystone VIP). They are ratified in +`overlays/vr1-dc1-vips.yaml` but `lib-net.sh`'s dc1 arm unsets them, and 20 of 28 consumers +never call the selector so they silently get dc0 values. R2 made these dual-family. Where +should the authority live?" Options presented: (a) derive lib-net's dc1 arm from the overlay +with a drift check; (b) hand-populate the dc1 arm from the ratified values; (c) re-point the +`phase-0*` scripts at the overlay as authority. Operator selection, exact utterance: +**"Derive lib-net's dc1 arm from the overlay, with a drift check (Recommended)"**. + +**RULED SHAPE.** `scripts/lib-net.sh`'s `vr1-dc1` arm is GENERATED from +`overlays/vr1-dc1-vips.yaml` (the ratified, deploy-input copy), with a render-drift check +that FAILS the gauntlet when the checked-in arm and a fresh render diverge. Consumers keep +sourcing `lib-net.sh` unchanged -- no script learns to parse YAML -- and there is exactly ONE +AUTHORED copy of the values. + +**PRECEDENT, and why this is not new machinery.** D-137 sub-ruling 2 already ruled and built +exactly this shape for credentials: `creds-manifests/*` are DERIVED from `creds-matrix.tsv`, +`--render` regenerates them, and the gauntlet fails on rendered-vs-checked-in drift. This +amendment applies the proven pattern to network literals. + +**IT DOES NOT PRE-EMPT D-136.** D-136 (NetBox-coupled per-DC render pipeline) is PROPOSED and +UNRULED. This ruling is deliberately the smaller, compatible step: it makes the overlay the +single authored source for the SCRIPT-facing values. If D-136 is later adopted, the apex +becomes the source and BOTH the overlay and this derived arm become generated -- this +amendment is a sub-case of that, not a competitor to it. + +**MEASURED BASIS.** `lib-net.sh:76-79` states the backward-compatibility design in terms: +sourcing without the selector "continues to populate PLANE_CIDRS ... exactly as above +(VR0/DC0's real, measured values) -- every existing script that sources lib-net.sh keeps +working completely unchanged." Consequence, and it inverts the intuitive reading: the `unset` +block fires ONLY for selector-CALLERS, so the 8 correctly-updated scripts break LOUDLY under +`set -u` while the 20 that were never updated fail SILENTLY on dc0's `10.12.4/8/12` literals. +The silent half is the dangerous half. + +**GUARD, carried from R11 -- do NOT let the derivation touch these.** The dc1 arm unsets NINE +variables for TWO different reasons. `METAL_INTERNAL_VID` and `METAL_INTERNAL_IFACE` are +**correctly** unset: D-133 abolished the VLAN-103 / `br-internal` stack for VR1 and those +facts genuinely do not exist. ONLY the VIP/FIP/keystone group +(`VIP_PREFIX_PROVIDER`/`ADMIN`/`INTERNAL`, `VIP_COUNT_EXPECT`, `FIP_POOL_START`/`END`, +`KEYSTONE_VIP_DEFAULT`) is superseded and derivable. A generator that populates all nine would +silently reintroduce a stack D-133 retired. + +**COUPLED RULINGS.** R2 made these DUAL-FAMILY, so the derivation must carry both families, +not v4 only. R11 moved `VIP_COUNT_EXPECT` 11 -> 13 (vault `.61`, designate `.62`) and widened +the octet band to `.99`, so the generator and the checker constants must agree on the same +band -- note `OCTET_LO/HI` in `provider-bundle-check.py` and `VIP_OCTET_MAX` in `lib-net.sh` +are SEPARATELY NAMED, a two-file change (L3-7). + +**STILL OWED AND NOT COVERED BY THIS RULING:** the CONSUMER SWEEP. This decides where the +values live; it does not make the 20 non-selector scripts call `lib_net_select_dc`. Measured +Stage-5 exposure is TWO of them (`phase-03-core-verify.sh`, `deploy-watch.sh`); the rest bite +at Stages 6-7. `scripts/carve-host-interfaces.sh:48-67` (DOCFIX-166) is the in-repo precedent +for how a consumer is correctly wired. + +**Execution is a SEPARATE gated step.** Standard delivery discipline: generator + drift check +ship with a harness green, gauntlet ALL GREEN, repo-lint 0-fail, and a changelog entry +carrying a revert. + ## D-120: static-services addressing convention for the MAAS-managed compose /24s (ADOPTED) **Status:** **ADOPTED 2026-07-15 -- option (a), EXECUTED.** Operator endorsed the direction (static