| 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
|
| 2026-07-28 |
dc1 FIP pool RULED 10.12.65.0-10.12.67.254 (GA-R5); lib-net dc1 arm + assertions re-pointed
...
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|
| 2026-07-23 |
Delivery batch: lib-hosts VR1 arms, D-133 guards, appendix-A pf entry, DoD 8-9 (gauntlet 77 GREEN)
...
lib-hosts vr1-dc0/vr1-dc1 populated from the measured identity table
(tofu-name keys, pinned boot MACs, D-134 octets, per-DC power URIs +
tags) + host_sysid_by_bootmac (the VR1 resolver) + one-selection guard;
dc-selector rewritten, 48 PASS. reenroll-hosts + carve-host-interfaces
gain explicit vr1-* refusals (VR0 flows superseded by D-133 -- populated
arms must not enable them). lib-net vr1-dc0 VID caveat. Appendix-A:
edge pf-never-regenerated symptom (masking trap named). Phase-2 DoD:
items 8 (filter reload + LAN egress probe) + 9 (dc-mirror), item 4
range corrected to D-134 .201-.254. CURRENT-STATE same-commit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|
| 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
|
| 2026-07-14 |

D-119: region-qualify the VR1 DC namespace -- C3 / gap #19 CLOSED (Stage 3 unblocked)
...
THE BUG: the token `dc0` meant TWO DIFFERENT CLOUDS depending on the file --
VR0's LIVE testcloud in scripts/lib-net.sh, VR1's FIRST DC in the NetBox
importer. One string, two clouds, one of them in production.
THE RULING (operator): the repo adopts the apex's names verbatim.
vr0-dc0 VR0's DC0 the LIVE testcloud (a DIFFERENT region)
vr1-dc0 VR1's FIRST DC GUA 2602:f3e2:f02::/48
vr1-dc1 VR1's SECOND DC GUA 2602:f3e2:f03::/48
Bare dc0/dc1/dc2 are now REJECTED LOUDLY everywhere.
D-119 COMPLETES D-117, it does not reverse it: it executes D-117's own amendment
across the three surfaces D-117 never touched. ZERO NetBox writes -- the apex was
already correct and self-consistent (MEASURED: f02::/48 -> vr1-dc0, f03::/48 ->
vr1-dc1); the REPO was the only surface out of step. Renaming the apex to match
the repo was considered and REJECTED (production IPAM write; VR1 would become the
only 1-indexed region; and vr1-dc1 would mean VR1's FIRST DC while vr0-dc1 means
VR0's SECOND).
THE PRIZE: the importer's DC->site map is now an IDENTITY -- there is no offset
table left to get wrong, and an assert enforces it. The original defect was
precisely a WRONG LOOKUP TABLE. The bug class is deleted, not defended.
TWO REAL BUGS the naming fix ALONE would NOT have closed (found by review sweep):
- BREAK-1: descriptions were built with f"VR1 {dc.upper()} ..." -- under D-119 that
renders "VR1 VR1-DC0 provider-public" on all 36 prefixes. Same class as the
original bug (deriving a label by munging a token), hidden in the description
field where slug-focused review missed it. Now looked up from SITES[name].
- BREAK-2 (the important one): DC_GUA_PREFIX was NEVER cross-checked against --dc.
`--dc vr1-dc0 DC_GUA_PREFIX=<f03>` was ACCEPTED: it writes the SECOND DC's GUA,
carved with the FIRST DC's ULA nibble, scoped to the FIRST DC's site -- a
silently mis-bound datacenter assembled from two disagreeing sources. Identity-
mapping the slug leaves the ADDRESSING free-floating. Now guarded by EXPECTED_GUA.
ALSO: vdc1/vdc2 -> vvr1-dc0/vvr1-dc1 (D-114 amendment). D-114's own DR primitive is
`virsh destroy vdc1`, which read as "destroy VR1 DC1" while MEANING "destroy VR1
DC0". A mislabelled destroy command in a DR drill is not cosmetic. Neither VM is
built, so it is free. voffice1/Office1 KEEP their number (operator ruling).
Env var: DC1_/DC2_V4_SUPERNET -> VR1_DC1_V4_SUPERNET (both old names rejected).
rbd-mirror's --site-name aligned: `--dc vr1-dc0 --site-name dc1` was a re-created
two-namespace collision on one command line.
TESTS: dc-selector 21->30, prefixes-import 40->82 (identity invariant; EXPECTED_GUA
in BOTH mismatch directions; mismatched run writes NOTHING; matching pair still
succeeds; no munged description). GAUNTLET ALL GREEN (57). repo-lint 0 fail.
The old harnesses PINNED THE WRONG MAPPING -- they would have gone green while
enforcing the bug.
THE tofu apply IS NOT DONE -- IT IS GATED. Plan: 11 to add, 0 to change, 11 to
destroy (libvirt object names are ForceNew; moved{} makes the plan reviewable but
cannot suppress a replace). MEASURED SAFE: all 11 are EMPTY -- no guests, no
volumes, Stage 3 hasn't run. Office1's live objects are not in the plan.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
| 2026-07-10 |
DOCFIX-151: $DC selector convention for lib-net.sh/lib-hosts.sh (gap #1 closed)
...
Adds lib_net_select_dc() (dc0/dc1 no-op per D-101 inherited-layout ruling,
dc2 fails loud pending NetBox) and lib_hosts_select_dc() (dc0 no-op, dc1+dc2
both fail loud -- no per-DC host enrollment exists yet). Backward compatible;
21/21 new harness tests green; full gauntlet unaffected (A/B via git stash).
Unblocks the Stage 5 runbook's "high reuse" claim in the DC-DC deployment
workflow.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QrcJx8TUar7pYAvpGJw57A
|