Session scope (GA-R2, one changelog per session). Picks up the durability debt the 2026-08-05 (part 2) close left explicitly open: three uncommitted files on the vcloud working tree (the RULED-but-uncommitted D-020 vault-metal-only amendment) plus a RED provider-bundle-check harness (6 fail) and repo-lint L10. All offline; no live-cloud mutation this session. Advisor-reviewed before commit.
Branch: dc-dc-stage5-preconditions. Stage 5 dc0 remains OPEN.
a5cf01a did NOT contain the D-020 2026-08-05 amendment despite its commit message naming "vault metal-only" -- the work was uncommitted on disk. Verified: git show HEAD:docs/design-decisions.md | grep -c "D-020 -- AMENDMENT (2026-08-05)" = 0.ae06c72) folded the FULL 13-subordinate HA chain (vault-hacluster included) and num_units: 3 into bundle.yaml. Confirmed: 13 :ha relations + 13 hacluster subordinates in bundle.yaml; num_units: 3 on mysql/ovn-central/ceph-mon (so the harness rolesep builder must be num_units-aware).12 clustered VIP(s) ... (0 dual-family), 13 hacluster principal(s) all carry a VIP, vault excluded from the triple count via its own metal-only [ok] line. Dual fixture: 12 ... (12 dual-family). These are the numbers the harness assertions were re-pointed to.scripts/provider-bundle-check.py -- vault metal-only exception, HARDENED (DOCFIX-210)--dc PROVIDER/ADMIN/INTERNAL bands -- replacing the first draft's hardcoded 10.12.4. literal (which was blind to dc1's 10.12.64.x provider). The metal pair is STILL band-checked (50-99) and STILL registers in octet_owner for uniqueness. Docstring invariant 2 records the exception.continue ran BEFORE the band check and octet_owner[h] = n, silently disarming octet-uniqueness for .61 -- a second app given .61 would collide with nothing and pass (a gate that cannot fail; this repo's named failure mode). PROVEN: the reconstructed draft returns rc=0 on a glance-takes-vault's-.61 input (gap); the fixed checker returns rc=1 VIP last octet .61 shared by glance and vault (caught).git checkout HEAD -- scripts/provider-bundle-check.py restores the no-vault-exception version (vault treated as a normal triple; the live metal-only overlay would then FAIL the check -- so revert the overlays in item 3 together).tests/provider-bundle-check/run-tests.sh -- harness reconciled to 58/0SystemExit if any to: app has num_units>3 (only 3 control machines exist). Fixes T9, broken by BUNDLEFIX-053's num_units: 3 against the old to:[lxd:0] pin. (b) Count assertions re-pointed to the measured values: T16 12 -> 13 hacluster principals (vault-hacluster now in the BASE bundle, dissolving the old T16/T17 pre/post-overlay ordering distinction -- comment re-pointed; the dc-ha-scaleup.yaml-now-redundant question LOGGED as a Task #1 finding, not fixed here per hard rule 1); T19 13 -> 12 clustered VIPs; T21/T45 13 -> 12 clustered + 13 -> 12 dual-family (vault leaves the triple count). (c) NEW failing-direction fixtures T54 (provider leg on vault FAILS), T55 (triple FAILS), T56 (another app taking vault's .61 octet FAILS -- guards the item-1 defect). Result 49/6 -> 58/0 ALL PASS.git checkout HEAD -- tests/provider-bundle-check/run-tests.sh.overlays/vr1-dc0-vips.yaml + overlays/vr1-dc1-vips.yaml -- vault metal pair, RE-RENDERED"10.12.8.61 10.12.12.61"; dc1 vault vip the dual-family sextet -> the dc1 metal pair "10.12.68.61 10.12.72.61" (provider leg + the D-141-deprecated fd50: ULA metal v6 legs dropped). Both stay a v4 metal pair THROUGH a future D-141 rule-3 promotion until a new amendment. These overlays are GENERATED by render-dc-overlays.py from render/values/*.yaml (D-136), NOT hand-editable -- see the FINDING below. Both files were re-rendered from the values files (items 6-7); the diff vs HEAD is EXACTLY the one vault line in each, no other drift.git checkout HEAD -- overlays/vr1-dc*-vips.yaml.scripts/render-dc-overlays.py -- vault metal-only render exception (DOCFIX-210)render() gains a name == "vault" branch that drops the provider-public leg AND forces v4 (no v6 append) so vault renders exactly the 2-leg metal pair in BOTH v4 and dual-family DCs. Named exception, mirroring provider-bundle-check.py + pre-flight-checks.sh -- fires for every DC's values file (the ruled Roosevelt delta), not a per-DC flag a new DC could omit.git checkout HEAD -- scripts/render-dc-overlays.py (then vault re-renders as a triple).render/values/vr1-dc0-vips.yaml + render/values/vr1-dc1-vips.yaml -- vault commentcomment: field updated (dc0) / added (dc1) to the D-020 metal-only note. The comment is part of the rendered bytes, so it belongs in the values file, not the overlay. Octet 61 unchanged; vault stays in the apps list (T12 count still 13).git checkout HEAD -- render/values/vr1-dc0-vips.yaml render/values/vr1-dc1-vips.yaml.scripts/pre-flight-checks.sh -- CHECK 1 vault metal-only exceptionname == "vault" branch accepting exactly the metal PAIR (metal-admin + metal-internal, octet-aligned, in-band, no provider column) as OK. VIP_COUNT_EXPECT stays 13 (vault still joins the OK count). Without this, vault's 2-leg pair was reported MALFORMED (not 3/6 IPs).git checkout HEAD -- scripts/pre-flight-checks.sh.render/values/*.yaml; tests/render-drift byte-compares every values file against its overlay and FAILS with "re-render, do not hand-edit the overlay." Task #2's guidance ("edit overlays/vr1-dc1-vips.yaml vault->metal pair") and the part-2 session's dc0 hand-edit BOTH violated this. render-drift + render-dc-overlays + pre-flight-checks were red at the part-2 close but NOT in its "RED AT CLOSE" list (which named only repo-lint L10
tests/render-dc-overlays: T15 count 13->12 dual-family (vault excluded) + vault metal-only [ok]; NEW T15b proof-of-teeth (renaming vault restores the 6-leg sextet -- the exception is name-keyed). T3b/T14 heal on re-render. 20/3 -> 24/0.tests/render-drift: heals on re-render (2/2 -> 4/0).tests/pre-flight-checks: T27/T28 heal; NEW T28b proof-of-teeth (vault as a triple FAILS CHECK 1). 29/2 -> 32/0.docs/design-decisions.md -- D-020 amendment text finalizedgit checkout HEAD -- docs/design-decisions.md.docs/CURRENT-STATE.md -- D-121 12/14 -> 14/14 + D-020 amendment; L10 satisfiedjuju status capture -- flagged OWED, riding the F4 live-verify sweep. Not papered over.git checkout HEAD -- docs/CURRENT-STATE.md.provider-bundle-check 58/0; render-dc-overlays 24/0; render-drift 4/0; pre-flight-checks 32/0. Full gauntlet re-run after the renderer work.scripts/repo-lint.sh -> 0 fail (1 pre-existing L1 non-ASCII warn, unchanged).juju status -m vr1-dc0 capture backing 14/14 (F4 sweep, next live step).