# Changelog 2026-07-15 -- D-120 ADOPTED: Office1 service re-IP into the static band

## What changed

Adopted **D-120** (static-services addressing convention for MAAS-managed compose /24s) as
**option (a), executed**, and re-IP'd Office1's two running services out of the MAAS node band into
the `.2-.49` static band:

    office1-netbox     10.10.1.201 -> 10.10.1.10
    office1-tailscale  10.10.1.202 -> 10.10.1.11

No wipe. Both services verified on the wire:
- NetBox: HTTP 200 at `http://10.10.1.10:8000/login/`, reachable vcloud-side; old `.201` dead.
- Tailscale: `BackendState=Running`, `PrimaryRoutes=["10.10.0.0/22"]` unchanged, tailnet
  `100.64.0.53` unchanged; old `.202` dead.

## How (method, for the DC replication that reuses this)

- **MAAS could NOT be updated** -- it refuses interface edits on a **Deployed** machine ("Cannot
  unlink subnet interface because the machine is not New, Ready, Allocated, or Broken"). The only
  lift is Release->redeploy = WIPE (forbidden; destroys the seeded sandbox). So MAAS-model drift is
  ACCEPTED: MAAS still shows `.201`/`.202` `mode=auto`. It reconciles for free at the next
  teardown/redeploy. No collision: MAAS auto-assigns nodes from `.201+` upward (observed -- the two
  services themselves landed at `.201`/`.202`), so the low `.2-.49` band is off its allocation path.
  (Being outside the dynamic range is NOT the guarantee; the whole non-dynamic space is the static pool.)
- The live address was set on each **guest** via BOTH `/etc/netplan/50-cloud-init.yaml` and
  `/etc/cloud/cloud.cfg.d/50-curtin-networking.cfg` (the latter so it survives a reboot /
  cloud-init re-render), then `netplan apply`. Backups saved on each guest: `.bak-reip201` /
  `.bak-reip202`.
- Driven over **`lxc exec` from voffice1**, NOT SSH-to-the-guest-IP -- the LXD socket is immune to
  the `netplan apply` that swaps the address, so the control channel never dropped. `lxc exec`/
  `console` was also confirmed as the recovery backstop BEFORE the first apply.
- NetBox `ALLOWED_HOSTS` is `*` (config default, not overridden in `env/netbox.env`), so it served
  at `.10` with no restart. Tailscale re-asserted automatically (no `tailscale up` needed).

## Repo references swept (`.201->.10`, `.202->.11`)

- **Code:** `SANDBOX_HOSTS` allowlist in `netbox/dc-dc-prefixes-import.py`,
  `netbox/roles-aggregates-import.py`, `netbox/d115-office-carve.py`;
  `tests/dc-dc-prefixes-import/test_logic.py` (both sandbox-URL hosts). The on-box working copy
  `/home/ubuntu/nbimport/netbox/d115-office-carve.py` was updated too (else a `--commit` against the
  now-`.10` sandbox would be REFUSED as non-sandbox).
- **Docs:** `docs/vr1-office1-as-built.md` (+ a MAAS-model-drift caveat), `docs/session-ledger.md`,
  `docs/dc-dc-netbox-buildout-scope.md`, `docs/dc-dc-deployment-workflow.md`,
  `runbooks/dc-dc-phase1-office1-standup.md`, `docs/design-decisions.md` (D-120 flip + Execution),
  `runbooks/dc-dc-office1-service-reip.md` (PENDING markers resolved to the measured method).
- Dated changelogs left as historical snapshots (they record the deploy-time `.201`/`.202`).

## Gauntlet

`bash scripts/run-tests-all.sh` -> ALL GREEN (58 harnesses). `bash scripts/repo-lint.sh` -> 0 fail,
1 documented legacy WARN (design-decisions non-ASCII carve-out; my additions are ASCII-clean).

## Still owed (NOT done here)

- **D-120 Step 6 / C2:** register the `10.10.1.0/24` child ranges (static `.2-.49` / dynamic
  `.100-.200` / node `.201-.254`) and the two service IPs IN the sandbox NetBox, then feed upstream.
  Rides with C2.

## Revert

- **Repo:** `git revert <this commit>` restores the `.201`/`.202` references.
- **Live services:** on each guest via `lxc exec`, restore `/etc/netplan/50-cloud-init.yaml` and
  `/etc/cloud/cloud.cfg.d/50-curtin-networking.cfg` from the `.bak-reip201` / `.bak-reip202` backups,
  then `netplan apply`. MAAS needs no rollback (its model was never changed). The on-box importer
  copy reverts with `sed -i s#10.10.1.10#10.10.1.201#g /home/ubuntu/nbimport/netbox/d115-office-carve.py`.
