| 2026-08-02 |

Close both egress gaps: dc-egress-check.sh + preflight P9, wired into restart + phase-4
...
Gap 1: nothing tested DC egress. dc-rack-net.sh check PASSED through a 19-hour outage
because it asserts legs and units -- a leg is not a path -- and the mirror answered 200
from its own nginx, which says nothing about upstream.
Gap 2: the post-reboot check set was my judgement, and it omitted egress.
New scripts/dc-egress-check.sh: site-keyed, runs on the rack, LAYERED (route -> edge
answers -> traffic leaves, ICMP and TCP -> the three upstreams), reporting the FIRST
failure as the cause while the rest SKIP. A4 asserts the UPSTREAM the local artifact
services sync FROM, which is independent of whether they serve.
Proven live on two different failure modes: dc0 fails at A2 naming the dead edge; dc1
passes A2 and fails A3/A4 -- traffic not leaving a healthy edge.
preflight P9 WARNs off-rack with the exact command, FAILs on the rack when broken, WARNs
if the checker is absent. Gap 2 is closed by the WIRING: restart procedure Stage 0
(before anything fetches) and phase-4 Step 3.9 (before the deploy), both stating P9 is
not a substitute for running it on the rack.
Mutation pass caught a decorative test of mine: T11 never reached A4's unrecognised-code
branch, so flipping it to ok() left the suite green. T14 added to exercise A4 alone.
tests/dc-egress-check 14/14; tests/preflight 39 -> 43/43; 5 mutations across both, each
killing a named case, scripts restored sha256-identical. Gauntlet ALL GREEN (97),
manifest 96 -> 97; repo-lint 0 fail / 1 warn.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

D-139 steps 2 and 3 EXECUTED for vr1-dc0: the nodes are on GUA
...
Step 2: dc-plane-ipam.sh carve-v6 --commit, applied=5, each GUA /64 on the same vlan as
its v4 twin and read back. 2 errors are correct refusals (lbaas-mgmt and oob have no v4
plane to pair with). Independent read: 11 v6 subnets, 6 GUA + 5 ULA, every GUA paired.
Step 3: dc-node-v6-carve.py replace --v6-family gua --commit, applied=45 skipped=9
errors=0, READ-BACK 45/45. Independent query: PRE 54 v6 links (GUA 9 / ULA 45) -> POST 54
(GUA 54 / ULA 0), and ZERO NICs carry more than one global v6, so G19's sole-global
predicate holds. v4 was not touched -- the ordering step 3 exists to enforce.
Gates after: dc-node-v6-carve check --v6-family gua PASS (54 correct, 0 missing, 0
errors); dc-plane-ipam check 29 pass / 2 fail, both expected absences and neither new
(lbaas-mgmt is step 5, oob has no MAAS plane). Was 7 fail before step 2.
Reversible: replace --v6-family ula --commit. Nothing was deleted; both families remain
in MAAS until step 6 retires the ULA rows. vr1-dc1 untouched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|
| 2026-08-01 |

D-139 step 2 (input half): VIP overlay onto GUA; both apex readers learn v6 FAMILY
...
overlays/vr1-dc0-vips.yaml is now fully GUA -- 39/39 v6 VIP legs, zero fd50:. The
renderer reproduces it byte-for-byte and provider-bundle-check PASSES with 13
dual-family VIPs.
Both apex readers had to learn family first. Step 1 creates GUA alongside ULA and step
6 retires ULA, so mid-transition every v6-only plane has two /64s under one (role,kind)
key and both readers could only REFUSE -- measured live: derive --dual-family rc 2, and
the gate "cannot evaluate barbican's dual-family vip". render-dc-overlays gains
--v6-family (refuse on ambiguity kept); provider-bundle-check resolves per application
AND per leg, needing no flag at any call site.
A lossy path was found and NOT taken: a full derive drops the 13 per-app comment fields
(4368 -> 3593 bytes). The values file was edited surgically instead: 26 changed overlay
lines, every comment intact. derive being lossy against its own values file is logged.
PROPERTY TRADED, recorded as a loss not a win: the gate no longer catches a wrong-FAMILY
leg -- a ULA leg in the GUA dc0 overlay now PASSES, graded against the ULA band that
exists until step 6. Necessary (dc1 is legitimately ULA) but it leaves D-139 family
conformance checked by nothing. A ruled-table conformance gate is OWED.
Two bugs I introduced were caught by the harness, not review: family inferred once from
the provider leg (GUA in both worlds -- 7 dc1 cases red), then bands resolved once per
bundle instead of per application.
tests/render-dc-overlays 18 -> 23/23 (3 mutations, restore sha256-identical);
tests/provider-bundle-check 55/55; gauntlet ALL GREEN (96); repo-lint 0 fail / 1 warn.
vr1-dc1 untouched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

P8 host guard: && -> || (live false FAIL on voffice1); dc0 MAAS path restored
...
P8's guard warned only when BOTH terraform.tfstate and opentofu/.terraform were
absent. voffice1 has no state file but does have .terraform -- D-128 has it run the
INNER tofu roots, and `tofu init` leaves a provider cache -- so neither warn branch
fired, P8 ran a real `tofu plan`, and it died on a gitignored tfvar -> exit 1 -> hard
FAIL on the very host the Stage-5 runbook designates for preflight. terraform.tfstate
is the OWNERSHIP marker; .terraform is only a cache. Both must be present to evaluate.
No test caught it because T38 removes the whole opentofu/ directory, so both markers
vanish together; the fixture itself sat in the defective state and passed only because
the && was wrong. Fixture now creates both markers; new T39 covers voffice1's real
shape (cache present, state absent -> WARN). Mutation: reverting || to && turns T39
and only T39 red; script restored sha256-identical.
Also: the dc0 MAAS path was down -- the vr1-dc0-region profile points at an SSH
forward (127.0.0.1:5241) that died with the 05:48 rack reboot. Restored and proven
(plan vr1-dc0 PASS exit 0, was REFUSE exit 3). Not an SEC-010 puncture: an SSH forward
originates on the rack. voffice1 pulled to HEAD. Preflight re-run: 12 [FAIL] lines,
11 = the ruled-accepted P5 set compared by identity, 1 = P8.
tests/preflight 38 -> 39/39; gauntlet ALL GREEN (96); repo-lint 0 fail / 1 warn.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|