# Changelog 2026-07-09 -- OpenTofu network/pool scaffold (DOCFIX-142)

First OpenTofu content in the repo, addressing the largest item in the
tooling gap register (`docs/dc-dc-deployment-workflow.md` gap #2). Executed
under blanket approval; no live infrastructure touched -- this is unapplied
IaC source only, and no live cloud/vcloud-host mutation occurred or was
attempted. Ratification note: D-100..D-110 (which this code encodes the
mechanics of) remain ALL PROPOSED (Stage 0 of the workflow doc); nothing here
bakes in a specific unratified value as fact -- CIDRs/MTU/paths are either
required inputs with no default, or DC1's already-inherited-from-DC0 values
(D-101), never an invented DC2 or netem specific.

## Items

### 1. DOCFIX-142 -- `opentofu/` network + storage-pool scaffold
FILES (new): `opentofu/versions.tf`, `opentofu/variables.tf`, `opentofu/main.tf`,
`opentofu/README.md`, `opentofu/modules/dc-planes/*`,
`opentofu/modules/mesh-link/*`, `opentofu/modules/dc-storage-pool/*`.

WHAT: the six per-DC plane segments (D-052/D-100) and the D-100 dark-fiber
mesh triangle (DC1<->DC2, DC1<->Office1, DC2<->Office1), each as an isolated
`libvirt_network` resource (no `forward`/`ips`/`dhcp` block -- NetBox is the
IPAM apex per skill hard rule 3, not libvirt DHCP); plus a directory-backed
`libvirt_pool` per DC/Office1 for future node-VM disks. Root module wires DC1
(using its DC0-inherited CIDRs, D-101) and Office1; DC2 is written but
commented out pending its NetBox CIDR assignment (D-101 open sub-item).

WHY: `opentofu/` had zero files before this -- the single largest item in the
2026-07-09 tooling gap register, and a hard blocker for buildout-design
Stage 1-2 (vcloud host prep, Office1 headend, per-DC substrate creation).

SCHEMA VERIFICATION (read `opentofu/README.md` for the full account): the
`dmacvicar/libvirt` provider's current schema (confirmed against its actual
`docs/resources/*.md`, tag v0.9.8, fetched this session -- NOT taken from
training-data memory of older provider versions, which materially differs)
turned out to nest network isolation under `forward.mode` rather than a
top-level `mode` argument, and to have restructured `libvirt_domain` into a
~40-argument schema mirroring raw libvirt XML. The `forward.mode` accepted
value enum could not be confirmed from the reachable docs this session; this
scaffold sidesteps the ambiguity by omitting the `forward` block entirely
(documented native-libvirt isolated-network behavior) rather than guessing a
value. Flagged prominently in `opentofu/README.md` as the first thing to
re-check if `tofu validate` objects.

DELIBERATELY NOT BUILT, and why (see `opentofu/README.md` "Scope of this
delivery" for the full list): `libvirt_domain` (node VMs) and `libvirt_volume`
(disk images) -- the domain schema's nested `devices` block (disks,
interfaces, filesystems, graphics, etc.) could not be verified with enough
confidence this session to author safely; DC2's plane networks -- CIDRs not
yet assigned; `tc netem` WAN-simulation application -- an OS-level `tc qdisc`
setting with no equivalent `libvirt_network` argument, needing a provisioner
or companion script not yet written, and whose parameters are themselves a
Phase-0 open item (D-100); OPNsense/MAAS-region/NetBox/GitBucket service VMs
-- all depend on the deferred domain module.

HARNESS: `scripts/opentofu-validate.sh` (fmt-check + init + validate wrapper,
BASH_SOURCE-self-locating, no hardcoded repo name) + `tests/opentofu-validate/`
(2/2 green -- only the guard-clause paths this environment can exercise
without a `tofu` binary; the fmt/init/validate path itself is UNTESTED here,
logged not hidden). Also extended `scripts/repo_lint.py`'s L1 (ASCII/LF) file
extension set to include `.tf` (it did not cover Terraform/OpenTofu files at
all before this, since none existed) -- verified this introduces no new
findings (the new `.tf` files are plain ASCII/LF) and the 34/34 repo-lint
harness still passes.

REVERT: `git rm -r opentofu/ scripts/opentofu-validate.sh tests/opentofu-validate/`;
revert the one-line `exts` change in `scripts/repo_lint.py` and its harness
counterpart if reverting fully (not recommended -- `.tf` coverage is a real
gap otherwise, independent of whether this specific scaffold survives).

### 2. Workflow doc + visual tracker updated to match
FILES: `docs/dc-dc-deployment-workflow.md`, the companion Artifact (same URL,
redeployed) -- Stage 1/3 authoring-status notes, gap register item 2, and the
status summary table all updated to reflect the scaffold's existence and its
UNVALIDATED state, per the "update this as stages close" standing instruction
on that doc.

REVERT: `git checkout HEAD~ -- docs/dc-dc-deployment-workflow.md`.

## Next actionable step (logged, not actioned)

On a machine with the `tofu` binary and registry network access: run
`bash scripts/opentofu-validate.sh`, then `tofu providers schema -json` against
the initialized provider, and read the actual `libvirt_domain`/`libvirt_volume`
schema directly before authoring the node-VM module -- do not proceed from
memory or from a doc-summarization pass a second time.
