# Changelog -- 2026-08-03: reconcile provider-bundle-check harness to D-141

Session scope: close the RED gauntlet the 2026-08-03 deploy session left at its bookend
(`docs/audit/queued-findings-20260803-stage5-deploy-ovn.txt` **sweep F1**) --
`run-tests-all` 1/98 FAIL on `provider-bundle-check`, 4 dual-family cases. Stage 5 remains
OPEN; nothing here opens or closes a stage. No change to `scripts/provider-bundle-check.py`
-- the checker is family-agnostic (a vip is a v4 triple OR a dual-family sextet); this is a
HARNESS reconcile only.

---

## Item 1 -- sweep F1: provider-bundle-check re-pointed to the v4-only deploy input (D-141)

**The defect.** On 2026-08-03 the dc0 VIP overlay was reverted to IPv4-only under **D-141**
(`3e691cd`, "revert dc0 VIP overlay to IPv4-only; v6 GUA block RETAINED as reserved") -- v6
GUA is now `reserved`-until-capable in the NetBox apex, not deployed. A built-surface change
shipped WITHOUT its companion harness update: four `tests/provider-bundle-check` cases still
asserted the REAL deploy input is dual-family, so `run-tests-all` closed the day RED at
`1/98 FAIL -- provider-bundle-check`. This is the repo's own "remediating a finding turns the
harness red -- REPLACE the assertion with the new invariant, never delete it to go green"
class.

The four cases (measured `RESULT: PASS=51 FAIL=4`):
- **T19** `13 clustered VIP(s) ... 13 dual-family` on `good.yaml` -- the checker now reports
  `(0 dual-family)` on the v4-only input.
- **T21**, **T45** the same `13 dual-family` PASS assertion on `good.yaml`.
- **T25** dual-family + unreadable apex REFUSES (rc=2) on `good.yaml` -- a v4-only bundle
  needs no apex, so it returned rc=0 (that path is T26).

**The reconcile (re-point, never delete -- the checker's dual-family logic is still live code
and D-141 rule 3 will promote v6, so its coverage MUST be preserved):**

- **New fixture `dual.yaml`** built in the fixture block: `good.yaml`'s v4 triples with the
  three v6 legs appended, the v6 host part textually mirroring the v4 octet. This is the
  shape D-141 rule-3 promotion RESTORES. The v6 prefixes are the **MEASURED all-GUA legs of
  the pre-revert dual-family deploy input** (`git show 3e691cd^:overlays/vr1-dc0-vips.yaml`):
  provider `2602:f3e2:f02:11::/64`, metal-admin `2602:f3e2:f02:20::/64`, metal-internal
  `2602:f3e2:f02:21::/64` -- all present in the current apex (D-139 step 6, 2026-08-02).
  **Deliberately NOT the module `DUAL6` constant**, whose `fd50:` admin/internal legs are the
  **ULA family D-139 DEPRECATED** (do-not-allocate under D-141) -- see Item 2.
- **T19 REPLACED** with the new invariant: the real dc0 deploy input is v4-only under D-141,
  asserting `13 clustered VIP(s) ... (0 dual-family)` on `good.yaml`. The comment records the
  re-point-back-to-dual-family instruction for when v6 is promoted.
- **T21, T45 RE-POINTED** to `dual.yaml` (assertion unchanged: `(13 dual-family)`), preserving
  the dual-family full-count PASS controls (9b absence / 9a declare positive controls) on the
  fixture promotion restores rather than on the now-v4-only real input.
- **T25 RE-POINTED** to `dual.yaml`, preserving the "could not look is never nothing there"
  apex-refusal control on a live dual-family input.

**Failing-direction proved** (repo rule: prove the assertion CAN fail, do not infer it): the
new T19 regex `13 clustered VIP\(s\).*\(0 dual-family\)` matches the v4-only `good.yaml` line
and does NOT match `dual.yaml`'s `(13 dual-family)` line. `dual.yaml` verified in both
directions before wiring: default apex -> rc=0 `(13 dual-family)`; `APEX_RECORD=/nonexistent`
-> rc=2 refusal.

**Case count unchanged: 55 -> 55** (pure re-point, no case added or dropped). Post-change:
`RESULT: PASS=55 FAIL=0 / ALL PASS`.

- Changed: `tests/provider-bundle-check/run-tests.sh` -- add the `dual.yaml` fixture builder
  (argv[6]); re-point T19 (assertion replaced), T21, T25, T45; correct the now-vacuous
  `v4only.yaml` comment (see Item 3).
- Verified: `bash tests/provider-bundle-check/run-tests.sh` -> **55/55 ALL PASS**; full
  `bash scripts/run-tests-all.sh` -> **ALL GREEN (98)** (captured; was `1/98 FAIL`);
  `repo-lint` 0 fail. ASCII/LF clean.
- **Revert:** `git checkout <this-commit>^ -- tests/provider-bundle-check/run-tests.sh`. The
  gate returns to RED against the current v4-only overlay, which is the pre-fix state.

## Item 2 -- LOGGED, not fixed: `DUAL6` grades T22/T23 against the DEPRECATED ULA family

The module constant `DUAL6` (`run-tests.sh:61`) uses `fd50:840e:74e2:220::` / `:221::` for
the metal-admin / metal-internal v6 legs. Those are the **ULA family D-139 step 6 DEPRECATED**
(2026-08-02; `deprecated` -> do-not-allocate under **D-141**'s status table). It still
validates only because step 6 deprecated rather than DELETED those prefixes and
`_apex_v6_bands` resolves per-leg family without reading NetBox status. So the negative
controls T22/T23 (wrong-`/64`, wrong host-part) are graded against a retired family, and with
Item 1's `dual.yaml` on GUA the harness now holds TWO notions of "valid dual-family vip".
**Not fixed here** (out of this reconcile's scope; would touch cases written for a different
invariant). Recommend re-pinning `DUAL6` to the GUA legs and asserting the apex marks the ULA
`/64`s `deprecated` -- operator to rule. Recorded on the close sweep as **FN1**
(`docs/audit/queued-findings-20260803-stage5-deploy-ovn.txt`, AMENDED block).

## Item 3 -- corrected comment: the `v4only.yaml` twin is byte-identical to `good.yaml` today

Under D-141 `good.yaml` is itself v4-only, so the `v4only.yaml` builder is a no-op TODAY and
the old comment's rationale ("mutate this instead of good.yaml so the v4-shaped cases do not
trip the prefer-ipv6 coupling check first") is vacuous. The comment is corrected to state the
current identity AND why the builder is RETAINED: if D-141 rule-3 promotion re-renders the
overlay dual-family, `good.yaml` becomes a sextet again and the twin AUTOMATICALLY re-diverges
to the v4 legs T5/T8/T26/T28 need. No case restructured -- comment only. Leaving a comment
asserting a distinction that no longer exists is a trap for the next session; this is D-141
fallout, so it belongs in this reconcile.

## Item 4 -- LOGGED, not fixed: generated overlay header still says "DUAL-FAMILY per R2"

`overlays/vr1-dc0-vips.yaml`'s GENERATED header block still describes dual-family legs
("each vip carries the three v4 legs THEN the three v6 legs") over v4-only VIP lines --
a renderer/values divergence from the D-141 revert. Out of scope (renderer + `render/values`
work, not the harness). Recorded on the close sweep as **FN2**.

## Item 5 -- LOGGED watch item (advisor-flagged): the `dual.yaml` builder can silently no-op

The `dual.yaml` builder skips any app whose vip is not exactly 3 tokens. That is correct today
(the overlay is v4-only), but if D-141 rule-3 promotion re-renders the overlay dual-family,
`good.yaml` is already a sextet and the builder yields it unchanged -- T21/T45 would keep
passing while asserting nothing new (the "clean zero deserves suspicion" shape). At promotion,
make the builder ASSERT it appended legs, or drive `dual.yaml` from the rendered dual overlay
directly. Paired with the re-point-back instruction already written into T19's comment.
Recorded on the close sweep as **FN3**.
