# Changelog 2026-07-09 -- Office1-local network + Office1 OPNsense edge ownership (DOCFIX-163)

No live infrastructure touched -- OpenTofu module/wiring additions, runbook
updates, and documentation only (prep-only session; no `tofu` binary
available, same UNVALIDATED status as every other OpenTofu module in this
repo). Closes tooling gap register items #12 and #16 in
`docs/dc-dc-deployment-workflow.md`; surfaces a new item, #17, found while
closing #16.

## Items

### 1. DOCFIX-163 -- `opentofu/modules/office1-network` (closes gap #12)

FILES: `opentofu/modules/office1-network/main.tf`,
`opentofu/modules/office1-network/variables.tf`,
`opentofu/modules/office1-network/outputs.tf`, `opentofu/main.tf` (new
`module "office1_network"` block, instantiated for real), `opentofu/README.md`.

WHAT: a new module, shaped exactly like `modules/dc-planes` (isolated
`libvirt_network`, no `forward`/DHCP block, attribute-style nested-object
syntax per this provider's confirmed schema convention) but sized for ONE
network instead of six planes -- Office1 is a headend, not a per-DC
OpenStack cloud, so the six-plane D-052/D-100 template does not apply to it.
This is the shared L2 segment the three Office1 service VMs (MAAS-region,
NetBox, GitBucket), the vcloud host's own management interface, and Office1's
own OPNsense edge's LAN side all attach to -- previously modeled nowhere in
`opentofu/` (gap #12, found 2026-07-09 while drafting
`runbooks/dc-dc-phase1-office1-standup.md`).

DESIGN DECISION: a NEW module, not a reused host bridge (the runbook's own
"Open questions" section had left this as a genuine, undecided fork).
Reasoning, in full in the module's own header comment and in
`runbooks/dc-dc-phase1-office1-standup.md`'s Open question #1:
- D-103 already establishes that OpenTofu owns create/destroy of every
  virtual network in this topology. A hand-configured host bridge would be
  the one network living outside that inventory -- exactly the
  not-reproducible, not-versioned debt D-103 exists to eliminate, and the
  same class of debt this repo already logs explicitly (as a DOCFIX
  candidate) whenever Option B (manual VM creation) is used elsewhere in the
  same runbook.
- This repo's own CHECK steps (`virsh net-list --all`, used throughout the
  Stage 1/2 runbooks) implicitly assume that command is a COMPLETE inventory
  of what exists on vcloud. A pre-existing, OpenTofu-invisible bridge would
  silently break that assumption, and Stage 0's teardown path (D-061) would
  never reach it.
Instantiated for REAL in root `main.tf` (`module "office1_network"`), unlike
most of the other still-scaffolded modules in this repo -- it needs no
unmeasured value beyond `domain_suffix`/`underlay_mtu`, both already real,
already-required inputs elsewhere in the same file (the identical reasoning
that already lets the three `mesh-link` legs be instantiated today).

VERIFIED:
- `bash scripts/repo-lint.sh`: 0 fail, 1 documented legacy WARN (unchanged).
- **UNVALIDATED against a real provider** -- no `tofu` binary was available
  this session (same status as every other module in `opentofu/`; see
  `opentofu/README.md`'s top-level status line). Run
  `bash scripts/opentofu-validate.sh` on a connected machine before trusting
  the schema.

REVERT: `git checkout HEAD~ -- opentofu/main.tf opentofu/README.md && rm -rf
opentofu/modules/office1-network` (safe -- nothing else references this
module yet).

### 2. DOCFIX-163 -- Office1 OPNsense edge ownership decision (closes gap #16)

FILES: `opentofu/main.tf` (new, commented-out `module "office1_opnsense"`
skeleton), `opentofu/README.md`,
`runbooks/dc-dc-phase1-office1-standup.md` (new Step 4b, updated Open
questions/Sequence/GATE/delivery-checklist sections).

WHAT: the buildout design's topology (Section 1) is explicit -- "full
dark-fiber triangle... plus a **per-site** OPNsense simulated ISP edge,"
three sites, three edges. Stage 3's Build list already covered DC1/DC2's
edges (`modules/opnsense-edge` per DC); neither Stage 2's nor Stage 3's
runbook instantiated one for Office1 (gap #16, found 2026-07-09 during final
consolidation of the DC-DC runbook set).

DECISION: **YES, Office1 gets its own `modules/opnsense-edge` call, a fourth
site alongside DC1/DC2 -- and Stage 2's own runbook
(`runbooks/dc-dc-phase1-office1-standup.md`) owns creating it**, via a new
Step 4b (CHECK-before-MUTATION shape, its own GATE bullet, matching the
runbook's existing style exactly). Rationale: Stage 2's entire scope is
already "Office1 headend standup" -- the OPNsense edge is part of that
headend's own boundary, not DC substrate -- and Stage 1 already creates the
mesh-link networks this edge's neighbors depend on; Stage 3 has no reason to
reach back into Office1's own infrastructure to build a piece of it.

The new `module "office1_opnsense"` skeleton in `main.tf` mirrors Stage 3's
`dc1_opnsense` template shape exactly (same module, same variable names).
Its `lan_network_name` resolves cleanly to Item 1's new network
(`module.office1_network.network_name`). Its `wan_network_name` does NOT --
see Item 3 below. The block stays commented out, same as DC1/DC2's own
not-yet-instantiated edges (neither is real either, per
`opentofu/README.md`), pending real `memory_mib`/`vcpu`/`disk_size_bytes`/
`base_volume_path`/`config_iso_path` values plus gap #17's resolution.

VERIFIED: `bash scripts/repo-lint.sh`: 0 fail (module block is commented
out; nothing new to `tofu validate` here that Item 1 didn't already cover).

REVERT: `git checkout HEAD~ -- opentofu/main.tf opentofu/README.md
runbooks/dc-dc-phase1-office1-standup.md` (safe -- Step 4b's module call was
never uncommented/applied).

### 3. Gap register item #17 (NEW) -- no per-site ISP-uplink/WAN network exists yet, for any site

Investigated per this task's own instruction to check before inventing a
WAN-side network for Office1's edge: read
`runbooks/dc-dc-phase2-tofu-dc-substrate.md` Step 5 directly. Its own
`dc1_opnsense` template carries an IDENTICAL, still-unresolved placeholder:
```
wan_network_name = module.mesh_dc1_office1... # or a dedicated per-site ISP-uplink segment -- confirm which, do not assume
```
This confirms the WAN-side network question is NOT Office1-specific -- it is
a genuinely deeper, cross-site gap that also blocks DC1's and DC2's own
edges, not something this delivery could resolve alone without inventing a
value or (worse) defaulting Office1's WAN side to a mesh-link network, which
would directly contradict D-100's own sub-item ruling that the three
dark-fiber mesh legs carry MANAGEMENT TRAFFIC ONLY (Office1<->DC = MAAS/
Juju/operator), not a simulated ISP uplink. Logged as new tooling gap
register item #17 in `docs/dc-dc-deployment-workflow.md`, cross-referenced
from gaps #4/#12/#16 and from both new module headers -- flagged rather than
invented, per this task's own instruction.

## Next actionable step

Tooling gap register items #12 and #16 CLOSED. Gap #17 (NEW) is now the
blocking dependency for instantiating ANY of the three sites'
`opnsense-edge` calls end-to-end -- needs a decision on the WAN-side network
shape (most likely a fourth per-site `libvirt_network`, analogous to
`office1-network`/`mesh-link`/`dc-planes`) before `dc1_opnsense`,
`dc2_opnsense`, or `office1_opnsense` can be uncommented for real. Designing
the three Office1 service VMs' actual `cloudinit-vm` `network_config`
content against the now-real `office1-local` network remains separate,
un-actioned work (unchanged by this delivery).
