# Changelog 2026-07-09 -- Stage 4 runbook: MAAS enlist/commission/deploy per DC (DOCFIX-157)

No live infrastructure touched -- new runbook document only. Authored by a
delegated subagent (general-purpose, briefed with this repo's discipline,
D-103/D-100/D-107, the tooling gap register, `phase-00-teardown-maas-
reset.md` and `scripts/lib-net.sh`/`lib-hosts.sh` as primary sources),
reviewed before this commit -- repo-lint was clean on the first pass.

## Item

### 1. DOCFIX-157 -- `runbooks/dc-dc-phase3-maas-enlist-deploy.md`
FILES: `runbooks/dc-dc-phase3-maas-enlist-deploy.md` (new), `docs/dc-dc-
deployment-workflow.md` (Stage 4 row updated, tooling gap register items
11/12/13/14/15 added or corrected).

WHAT: adapts `phase-00-teardown-maas-reset.md`'s validated single-rack
MAAS commission/deploy/carve sequence to VR1's multi-rack, per-DC shape.
Run once per `$DC` (dc1/dc2), explicitly not mixed in one shell session.

**Mandates the `$DC` selector convention as its first real step** --
`lib_net_select_dc "$DC"` (a documented no-op for dc1, fail-loud for dc2)
followed HONESTLY by `lib_hosts_select_dc "$DC"`, which the runbook states
is EXPECTED TO FAIL for both DCs right now: no per-DC host data exists in
`scripts/lib-hosts.sh` yet, and populating it from THIS stage's own real
enrollment is exactly the follow-up delivery that lets the selector start
passing. This is documented as a deliberate chicken-and-egg, not a bug to
route around -- every step in the runbook resolves host identity LIVE from
MAAS instead.

**Seven real gaps found and named in a dedicated section, each logged as a
finding rather than silently worked around:**
1. No OpenTofu module stands up a per-DC MAAS rack controller VM itself --
   only registration (`modules/maas-vm-host`) exists.
2. `reenroll-hosts.sh`, `carve-host-interfaces.sh`, and `phase-00-maas-
   standup.sh` do not accept a `$DC` argument or call the new selector
   functions -- only `lib-net.sh`/`lib-hosts.sh` themselves gained them
   (DOCFIX-151). The runbook describes adapting each script's MECHANICS by
   hand rather than inventing a `--dc` flag those scripts don't have.
3. Per-DC node count/sizing is an unmade Phase-0 decision -- the runbook
   discovers however many nodes actually exist live (Step 2), never
   assuming DC0's four hosts carry over.
4. DC2 is additionally blocked at the `lib_net_select_dc` layer (no NetBox
   literals yet).
5. The per-DC artifact mirror (D-107) has no identified owning stage/
   module anywhere in this repo as surveyed -- flagged before Step 7's
   reachability check assumes one exists.
6. The MAAS status a VM-host-DISCOVERED (vs. PXE-enlisted) pre-existing
   domain lands in has never been observed in this repo -- Step 2 measures
   it live rather than assuming `New` or an auto-`Ready` per phase-00's
   different code path.
7. `lib-hosts.sh`'s `HOST_TAG`/boot-fabric-name literals (`openstack`,
   `2_metal`) are DC0-specific -- confirmed live per DC, not assumed reused.

**A real sequencing subtlety flagged, not glossed over:** phase-00's own
precedent carves interfaces BEFORE deploy (Ready-only); if Stage 3's
discovery+commission flow for a DC leaves nodes at `Ready` before this
stage's carve step, the runbook instructs reordering Steps 4/5 to match
phase-00's actual order and recording which order was used, rather than
blindly following this document's own numbering against contradicting live
machine states.

VERIFIED: `bash scripts/repo-lint.sh` 0 fail, 1 documented legacy warn (no
fixes needed). NOT YET EXECUTED.

REVERT: `rm runbooks/dc-dc-phase3-maas-enlist-deploy.md && git checkout
HEAD~ -- docs/dc-dc-deployment-workflow.md` (safe).

## Next actionable step

This stage's own delivery checklist requires populating `scripts/lib-
hosts.sh` with real per-DC host data once it actually runs -- that follow-
up unblocks `lib_hosts_select_dc` for the DC it ran against and is a
prerequisite named explicitly in Stage 5's own runbook.
