| 2026-07-30 |

Author the per-DC MAAS region VM into both substrate roots (D-132 addendum)
...
vr1-dc0-maas-01 and vr1-dc1-maas-01: 4 vCPU / 8 GiB / 150 GiB, macs = []
for first apply. Additive on a for_each-keyed caller, so each plans
1 add / 0 change / 0 destroy.
Sizing is the shape the capacity gate actually modelled
(dc-dc-whole-host-budget.py --containment-overhead-mem-gib 32
--containment-overhead-vcpu 12 -> RAM 870/1024 = 85 pct, FIT, 154 GiB
headroom). Disk is 150 not 100 because this VM stores the region's
PostgreSQL AND its boot-image set.
Both entries carry the carve requirement in the comment: metal-admin AND
provider-public at enlistment. Carving metal-admin alone is exactly the
under-carve that cost three bootstrap attempts on the juju controller VM
today -- no default route, no image sync.
MACs deliberately empty, to be pinned from measurement immediately after
first apply, per the same rule that the 2026-07-20 MAC regeneration
established.
opentofu-validate: root + 12 modules + both extra roots all PASS.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

voffice1 reconcile: a gate that was RED on the only host that deploys
...
Operator asked whether the headend clone was fully reconciled. It was not, and running the
gauntlet there -- which had never actually been done -- found a real host-dependent gate defect.
RECONCILE. The headend was 1 commit behind with 0 local commits, now at HEAD, tfstate sha256
byte-identical before and after. No stale remote-tracking refs. One asymmetry found and fixed:
opentofu/vr1-dc1-substrate/.terraform.lock.hcl was UNTRACKED and not gitignored, while dc0's
equivalent IS tracked. Same provider version (0.9.8), so a content divergence was ruled out by
measurement, but a fresh clone could not reproduce dc1's provider resolution the way it can
dc0's. Landed, byte-identical to the headend copy.
THE GATE DEFECT. The gauntlet read ALL GREEN (89) on the jumphost and 1/89 FAILED on the headend,
on opentofu-validate. Cause: `tofu fmt -recursive` walks EVERY .tf/.tfvars under the tree,
including GITIGNORED local files. The sole flagged file was
opentofu/vr1-dc0-substrate/d124-inner.auto.tfvars -- gitignored operator input that exists only
on the host which runs the applies. So the gate was RED ON THE ONLY HOST THAT DEPLOYS and green
where it did not matter, the same host-dependent-verdict class as the LC_ALL manifest sort.
Ruled out first: both hosts run tofu 1.12.4, so this was not version drift.
The fmt check is now scoped to repo content, and a gitignored file is SKIPPED with the reason
printed rather than silently. Proven both ways: a badly-formatted TRACKED file still FAILS (T16),
a gitignored local tfvars is skipped and does not fail (T17). T17 also fails loudly if the ignore
rule ever stops covering per-DC tfvars, so the case cannot silently stop testing what it claims.
Owned: my first T16 read as a failure because `bash "$SCRIPT" | grep -q` inherits the gate's
correct exit 1 under `set -o pipefail`, even though grep matched -- a passing assertion reading as
a failure. Same strict-bash family as the IFS and inherit_errexit traps this repo has hit before.
Captured first, then grepped.
opentofu-validate harness 16/16; repo-lint 0 fail.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|
| 2026-07-29 |

Pin juju-01 MACs, add both controllers to lib-hosts at the ruled .5
...
Twelve measured MACs (six per DC, virsh domiflist) pinned into both
substrate roots; <dc>-juju-01 added to lib-hosts.sh with HOST_OCTET=5 per
the D-134 amendment and its measured boot MAC. Done now because both VMs are
ENLISTED -- the boundary modules/node-vm warns about, past which an in-place
apply can regenerate unpinned MACs and strand the node, as happened to the
nine role nodes on 2026-07-21.
No race with the running agents: they operate on the voffice1 clone; this
edit is on vcloud's, and nothing reaches their tree until someone pulls
there.
Recorded rather than smoothed over: dc1's juju-01 MACs are libvirt-generated
52:54:00: values, not dc1's schematic 52:54:01:d1: scheme -- a direct
consequence of the deliberate macs = [] at first apply.
Three exact-count assertions re-pointed to the new invariant and kept EXACT
rather than relaxed: dc-selector fleet 9 -> 10 (label corrected, since Option
C is a 9-node ruling and the 10th is D-104's), node-vm T8 9 -> 10 and T9
54 -> 60.
A real harness defect surfaced doing it: T8's grep -c 'macs = [' counts
COMMENTS, and my own comment explaining the deliberate macs = [] inflated the
count to 11 -- which reads exactly like a spurious extra node. Fixed to strip
comment lines. Same class as the ledger-scan next-free defect where a doc
merely quoting a token inflated the counter.
maas-role-tags.sh taught the utility band: adding juju-01 to HOSTS made it
refuse, because .5 is in no ROLE band -- correct behaviour meeting a new
fact. Per the amendment a utility-band host with no role token is now SKIPPED
and REPORTED, while the refusal keeps its teeth for genuine disagreement.
New cases T10 and T11; harness 9 -> 11.
Gauntlet ALL GREEN (87) on vcloud; opentofu-validate PASS; repo-lint 0 fail.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

Author both Stage-5 blockers (NOT applied); Octavia merge question resolved
...
Octavia RESOLVED as a clean negative. The chain audit flagged that
octavia-pki.yaml lands last and writes the same applications.octavia.options
map as the vips overlay, so under replace semantics octavia would lose its
vip and prefer-ipv6 with every offline gate still green. Researched against
source: juju 3.6 pins charm v12.1.1, and mergeStructs does
dstMap.SetMapIndex(srcKey, srcMapVal) per key for map-kind fields.
ApplicationSpec.Options is a Go map, so it deep-merges -- both overlays' keys
survive. The merge path is byte-identical between 2.9 and 3.6. The checker's
"MIRRORS juju's documented merge" comment is now sourced rather than assumed.
Logged: LP #2002371 (Triaged/High, unfixed) -- an EMPTY/null options: key
WIPES the base map rather than merging. Our overlays lack that shape and
nothing gates against acquiring it.
R1 AUTHORED. modules/node-vm gains osd_disk_size_bytes, default 0 = creates
nothing; the volume is count-gated and the disk entry appended via concat, so
an opted-out node has no extra resource and no plan diff -- precondition 4
verbatim. Four storage nodes per DC set osd_gib = 500: 8 volumes, not 18.
500 GiB is D-121's own budgeted figure (4x500Gi/DC = PASS, 5.31 TiB margin),
and D-121 records that footprint as an assumption pending an OSD-sizing
decision, so it is evidenced but not separately ruled. Headroom caveat
surfaced: dc0 has 2.0T available against 2.0 TiB nominal -- thin-provisioned,
so creation is cheap, but there is no room for those OSDs to fill.
D-104 AUTHORED. A 10th keyed entry per root, <dc>-juju-01, planning 1 add /
0 change / 0 destroy. The nine role nodes are untouched. 8 GiB / 4 vCPU are
the values the capacity gate actually modelled; disk 100 GiB is the authoring
value the amendment left open. MACs deliberately empty -- correct only before
enlistment, and they must be pinned from measurement after the first apply or
this reproduces the 2026-07-21 MAC-regeneration trap.
NEITHER IS APPLIED. opentofu-validate PASS on both roots; no apply run. Both
are live substrate mutations and individually operator-gated.
R1 precondition 3 is NOT satisfied and I am not treating it as such: the
amendment requires verifying BEFORE the apply that re-commissioning preserves
the D-134 statics and pinned MACs, and that needs live MAAS, absent here.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|
| 2026-07-22 |
G12 dc1: item-3 substrate landed + harness reconcile (gauntlet 76 ALL GREEN)
...
Lands the disconnected session's authored tree (vr1_dc1 vars, vvr1-dc1 +
uplink modules, inner root vr1-dc1-substrate/ with 54 pre-pinned MACs,
lib-net dc1 arm + one-selection guard) and delivers changelog item 4:
six harnesses reconciled to the ratified dc1 selector arm, phase-00
PLANES/lib-net parity guard (exit 2, refuses cross-DC planning),
rbd-mirror + radosgw parent-shell selection (dc1 reminder now shows
10.12.84.0/22, not dc0's). Gauntlet ALL GREEN 76
(docs/audit/gauntlet-20260722-g12-reconcile.txt); repo-lint 0-fail.
G12 next gated step unchanged: operator-gated apex --commit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|