# Changelog 2026-08-02 (part 3) -- the Stage-5 deploy input is corrected before the deploy

Session changelog (GA-R2/D1: ONE per session). Branch `dc-dc-stage5-preconditions`.
Session open reconciled at HEAD `c620f99`: repo-lint 0 fail / 1 legacy warn,
`ledger-scan` 3 open decisions / 28 open SEC / next-free D-141, DOCFIX-208,
BUNDLEFIX-053. Status claims live in `docs/CURRENT-STATE.md` ONLY.

Scope: the item both the 2026-08-02 (part 2) close and `docs/CURRENT-STATE.md`
name as the next session's FIRST item -- the preflight-P2 / phase-4
machines-overlay asymmetry -- worked to completion ahead of the bundle deploy.

---

## Item 1 -- DOCFIX-208: the phase-4 dc0 deploy command was missing a load-bearing overlay

**WHAT WAS WRONG.** `runbooks/dc-dc-phase4-juju-bundle-per-dc.md` told the operator
to deploy `vr1-dc0` as `bundle.yaml` + `vr1-dc0-vips.yaml` +
`vr1-dc0-octavia-pki.yaml`, omitting `overlays/vr1-dc0-machines.yaml`. Its stated
reason -- "there is no `overlays/vr1-dc0-machines.yaml`" (`:527-528`) -- had been
FALSE since 2026-07-29, when that file was created (changelog-20260729 item 3.8).
`scripts/preflight.sh:144-145` folds the file into the merged input that gate P2
validates, so **P2 was grading an input the deploy would not have passed.**

**WHY IT WAS NOT HYGIENE.** The classification carried into this session was
"DOCFIX-shaped ... likely bundles with the outstanding D-138 run-location DOCFIX"
(changelog-20260802-queued-items item 5, finding 2). That is too low: the disputed
artifact is the argument list of the very next live mutation. Executed as written,
a dc0 deploy would have taken TWO independent injuries, neither of which surfaces
as a deploy error:

1. **No provider bridge mapping.** `bundle.yaml:494` states
   `bridge-interface-mappings` "IS NOT IN THIS FILE, and must never be re-added
   here" -- the overlay is its ONLY source. `ovn-chassis` would deploy with no
   `br-ex` mapping and tenant networks would come up with no external path. This
   is exactly the defect the 2026-07-29 move out of the base bundle was made to
   fix, reintroduced by stale prose.
2. **15 unreachable package sources.** Per the 2026-07-31 GA-R5 ruling ("Point
   origin/source at the mirrored UCA, per-DC overlay") the same overlay repoints
   12 `openstack-origin` + 3 ceph `source` at the in-DC mirror. Without it those
   charms fetch `ubuntu-cloud.archive.canonical.com`, MEASURED UNREACHABLE from a
   node (000) under the D-107 airgap -- a failure at package-install time.

**MEASURED, NOT REASONED.** Deep-merging `bundle.yaml` against the overlay:

```
overlay top-level keys: ['applications']        <- NO machines: block at all
apps in overlay: 16
  ovn-chassis.bridge-interface-mappings: ADDS
  barbican / magnum / octavia / ceph-mon / ceph-osd / ceph-radosgw : OVERRIDES  (6)
  cinder, designate, glance, keystone, neutron-api, nova-cloud-controller,
  nova-compute, openstack-dashboard, placement                    : ADDS      (9)
base ovn-chassis options: {'ovn-bridge-mappings': 'physnet1:br-ex',
                           'prefer-chassis-as-gw': True}
```

**THIS CORRECTS THIS REPO'S OWN EARLIER FINDING (GA-R1 C2).**
`docs/CURRENT-STATE.md` recorded 2026-07-31 that "the only delta it makes to the
merged input is `ovn-chassis.options.bridge-interface-mappings`". That was TRUE
WHEN TAKEN and was overtaken HOURS LATER IN THE SAME SESSION by the UCA build.
Sixteen applications, not one. The correcting capture is folded into the same
CURRENT-STATE entry rather than replacing it.

**THE FILE NAME IS WHAT MISLED THE RUNBOOK.** dc0 genuinely needs no machines
RETAG -- `bundle.yaml`'s machines block already reads
`tags=openstack-vr1-dc0,<role>` -- and the old table row said so correctly. The
error was concluding from that true fact that the FILE is unnecessary. The overlay
is the per-DC HAND-MAINTAINED overlay and its `applications:` half is load-bearing;
its own header says so and says not to add a `machines:` block for symmetry.

**WHAT CHANGED** (`runbooks/dc-dc-phase4-juju-bundle-per-dc.md`, 6 sites):

- **4.1 table** -- the "machines retag" row becomes `overlays/${DC}-machines.yaml`,
  REQUIRED for BOTH DCs, with the measured 16-app delta and the reason the old
  reading was wrong.
- **4.1 prose** -- the "Do not interpolate a machines overlay path for `vr1-dc0`"
  paragraph replaced. The never-silently-skip-an-overlay rule is KEPT (it is right,
  and it is why a dc1 deploy cannot merge dc0 tags); only its dc0 exemption goes.
- **4.2 dry-run block (dc0)** -- machines overlay added, order vips -> machines -> pki.
- **4.3 deploy block (dc0)** -- same, so 4.2 and 4.3 remain identical but for `--dry-run`.
- **Step 7 dry-run block (dc0)** -- same. This block CONTRADICTED ITS OWN paragraph
  four lines above ("dropping the VIP or machines overlay here would present juju with
  an input that contradicts the running model"), and the "Same overlay-set rules"
  sentence beneath it repeated the dc0 exemption; both fixed.
- **4.2 preamble** -- the VERIFY-LIVE pointer was dc1-only; now names both halves
  (dc1's machines-block retag, BOTH DCs' `applications.options` merge).

**NOT CHANGED, because it was already right:** `scripts/preflight.sh` P2 and
`runbooks/phase-01-bundle-deploy.md:199-201` both assemble the three-overlay set
behind a `[ -f ]` guard. This was one wrong surface, not two disagreeing.

- **Revert:** `git revert` this commit. The runbook returns to a dc0 command that
  omits a required overlay -- do not revert without also re-opening the finding in
  `docs/CURRENT-STATE.md`.

## Item 2 -- the 4.2 gate could not have caught it, so it gained two assertions

The standing rule that a checker which cannot fail is not a gate applies to the
gate as much as the command. Step 4.2's four gate items read the machines block,
the machine count, the VIP prefixes, and overlay-path errors. **The machines
overlay's entire payload is under `applications:`, so all four would have passed a
dc0 deploy with no provider bridge mapping and 15 unreachable package sources.**
Two added:

- **Item 5 -- `ovn-chassis` shows THREE options, not one.** `bridge-interface-mappings`
  must appear ALONGSIDE `ovn-bridge-mappings: physnet1:br-ex` and
  `prefer-chassis-as-gw: true`. This is the VERIFY-LIVE assertion both overlays'
  headers demand and that NO offline check can make: `provider-bundle-check.py`'s
  `_deep_merge` merges key-by-key BY CONSTRUCTION, so validating through it cannot
  distinguish a key-by-key merge from a map REPLACE. Only the live dry-run can. If
  only the new key appears, the physnet mapping and the B2 gateway-chassis election
  are both gone from the deploy input and provider egress dies by a different route
  than the defect item 1 fixes. Also: exactly TWO MACs, a third means a wrong node.
- **Item 6 -- every `openstack-origin` / ceph `source` resolves to an address this
  DC's nodes can reach.** Names dc1's deliberate absence of the block as D-135's
  experiment RESULT, so a later reader does not "fix" the asymmetry.

- **Revert:** delete gate items 5 and 6. Not recommended -- they are the only
  assertions in the chain that can see this overlay's payload.

## Item 3 -- LOGGED, NOT FIXED (hard rule 1)

`runbooks/phase-00-teardown-maas-reset.md:233` runs `provider-bundle-check.py` with
the vips overlay ONLY, so it grades a narrower input than either preflight P2 or the
deploy command. Not deploy-blocking (teardown-time check), DOCFIX material for the
same fold. Recorded in `docs/CURRENT-STATE.md`, not actioned here.

---

**Gates at delivery:** `bash scripts/repo-lint.sh` -- 0 fail, 1 warn (the legacy
D-001..018 ASCII carve-out), 658 files. No script changed, so no harness is
implicated; the gauntlet's last full run stands at ALL GREEN (98) from the
2026-08-02 (part 2) close.
