# Pass 3 -- W3.3: new per-module test-harness requirements (container-layer elimination)

**Worker:** W3.3 (Phase 3, container-layer-elimination pass, `SCOPE-AND-EXECUTION-PLAN.md`
Section 4). **Date:** 2026-08-09. **Scope:** READ-ONLY -- specifies what harness each OWED
new/changed artifact must ship; writes and runs nothing. Baseline consumed: `pass0-admin-report.md`
Section 7a (Option 1 CONFIRMED; cross-DC handling (a) CONFIRMED), `pass1-admin-report.md`
Sections 3/5/6 (the (a)-control spec, the layer model, the owed-artifacts seed list),
`pass1-w4-module-planning.md` (layer model + design principles), `pass2-admin-report.md`
Sections 2/4/5 (the three isolation concerns separated; the 13 owed artifacts) and
`pass2-w4-module-decomposition.md` (the procedure-module contract, Section 3; the IaC<->procedure
boundary, Section 4). Harness-pattern precedent read live this session:
`tests/geneve-encap-assert/run-tests.sh`, `tests/site-headend-install/run-tests.sh`,
`tests/phase-00-teardown-d061/run-tests.sh`, `tests/dc-egress-check/run-tests.sh`,
`tests/dc-node-v6-verify/run-tests.sh`, `tests/opentofu-validate/run-tests.sh`,
`scripts/lib-validate.sh`, `docs/security-ledger.md:21` (SEC-010), `docs/changelog-20260730-
octavia-reissue-tool.md:158-167` (the stage-assert-promote / join-workspace-to-deploy-input
vocabulary), `opentofu/modules/node-vm/variables.tf:38-62` (MAC-pinning validation, reused not
reinvented). No inferred values; every invariant below cites the source line that establishes it.

---

## 0. Method

This pass does not design the mechanisms (nftables rule sets, wrapper shapes, dig-test
fixtures) -- several are explicitly OPEN pending Phase-4 ratification (`pass2-admin-report.md`
Section 6). It specifies, for each of the 13 owed artifacts (`pass2-admin-report.md` Section 5),
**what its harness must assert and, critically, the fixture that proves each assertion can turn
red** -- so that whichever mechanism Phase 4 picks, the harness's job is already scoped and the
delivery session cannot ship a checker that cannot fail (this repo's own recorded failure mode,
`instrument-currency-before-negatives` memory #13/#14/#16, and the D-061 pair's "a host that does
not resolve is a `note`, not a `fail`" defect, `docs/tool-index.md`). Six artifacts get full specs
(Section 2, the pass's assigned dimension); the remaining seven get a shorter table (Section 3)
so all 13 are accounted for and none is silently left harness-less. Section 4 is the general
contract every one of these harnesses -- and by extension every future module harness -- follows.

---

## 2. Full harness specs -- the six artifacts named in this worker's charter

### 2.1 `modules/dc-site` (new composing IaC module) -- owed artifact #12

**What it composes** (`pass2-admin-report.md` Section 3.1): storage pool + six planes + edge +
12 node VMs (9 D-121 role nodes + `juju-01`/`maas-01`/`tailscale-01`, `pass0-admin-report.md`
Section 1.1) + the new `vr1-dcN-client` VM (`.8`, `pass2-admin-report.md` Section 4.3) -- 13
L1/L2 compute objects + 6 plane networks per DC, replacing the ~230-266-line copy-pasted
per-DC inner-root bodies.

| Invariant | Source of truth | Failing-direction fixture |
|---|---|---|
| **Plane count = 6** per DC | `pass0-admin-report.md` Section 1.1 ("the SIX planes"); D-134 | a fixture module tree with a plane call REMOVED (5 planes) -> count assertion FAILS |
| **Node roster = 12** (9 role + 3 utility), correctly classed | `pass0-admin-report.md` Section 1.1 exact roster | a fixture with a role node dropped (11) OR a utility node duplicated (13 with 2x `maas-01`) -> roster assertion FAILS |
| **Client-VM presence = exactly 1** per DC | Option-1 gate confirmation, `pass0-admin-report.md` Section 7a | a fixture module tree with the `client_vm` call commented out -> presence assertion FAILS; a fixture with 2 client-VM calls -> also FAILS (exactly-one, not at-least-one) |
| **MAC pinning**: every `node-vm` (and the client-VM) call supplies non-empty `interface_macs`, one per NIC | `opentofu/modules/node-vm/variables.tf:38-62` -- the module ALREADY enforces "empty or exactly one MAC per network_names entry" and rejects partial pinning; `dc-site` must not construct a call that leaves this empty post-provisioning (VR-only trap noted at `:50`) | a fixture `dc-site` call passing `interface_macs = []` for one node (the pre-carve default, `variables.tf:39-40` -- "acceptable ONLY before a node is enlisted anywhere") on a tree tagged post-apply -> assertion FAILS; reuses `node-vm`'s own `error_message` string (`:57,:62`) rather than re-deriving the rule |
| **CIDR / address family** matches the ruled posture per plane (D-139 IPv6-primary, `ipv6-primary-posture` memory; D-143 octet-preserving 10.12->10.13) | D-139, D-143 | a fixture plane input carrying a v4-only CIDR on a plane D-139 rules v6 -> family assertion FAILS |
| **MTU**: `underlay_mtu=9000` threaded unchanged into every plane/edge input (`pass0-admin-report.md` Section 1.4: "removing [the containment hop] changes no byte budget -- do not let later phases imply an MTU benefit") | `variables.tf` `underlay_mtu`; D-101 | a fixture with `mtu=1500` on a plane call (silently regressing the jumbo budget) -> MTU assertion FAILS |
| **Site-token parameterization** -- no DC identity hardcoded in the module body (design principle 1, `pass1-w4-module-planning.md` Section 4 item 1) | existing repo norm, all 12 current modules | a fixture instantiating the SAME module body for `dc0` and `dc1` with only the `$DC` input changed must produce disjoint object names/addressing -- a hardcoded literal inside the body that fails to vary -> FAILS |

**Ships-where:** `tests/dc-site/run-tests.sh`, offline/static, mirroring `tests/opentofu-
validate/run-tests.sh`'s `--static-only` fixture pattern (T3-T7: fixture `.tf` trees under
`tests/opentofu-validate/fixtures/`, no live provider dial). `dc-site` also automatically rides
the ONE shared IaC gate (`scripts/opentofu-validate.sh`, "validates EVERY module standalone",
`opentofu/README.md:5-6,40-41`, restated `pass1-w4-module-planning.md` Section 1.3) for its own
S1/S2 static guards (memory_unit/ACPI) at zero extra cost -- the dedicated harness above is for
`dc-site`'s OWN composition invariants (count/roster/MAC/family/MTU), which S1-S3 do not cover.
A live `tofu plan`-based resource-count assertion is a stretch addition, flagged OWED-AT-BUILD,
not specified here as fact -- `dc-site` does not exist yet and this pass does not infer its exact
resource graph (hard rule 2). **Dependency, not double-build:** the FIT-calculator extension
(owed #7) should consume `dc-site`'s node-class list once built, rather than re-deriving it.

### 2.2 The (a) cross-DC host-isolation control -- owed artifact #2 (concern i)

Spec settled at pass1 Section 3 / pass2 Section 2.1: a vcloud-level nftables artifact,
`--check` gate, own harness, SEC-NNN row, Stage-1 home, installed+verified before ANY flat
substrate apply. Mechanism (exact rule set) NOT yet designed -- specified here mechanism-agnostic.

| Invariant | Failing-direction fixture |
|---|---|
| No FORWARD rule permits traffic between any two DC plane bridges (dc0<->dc1) | a fixture `nft list ruleset`-style capture WITH a forward-accept rule naming both a dc0 plane bridge and a dc1 plane bridge -> `--check` must FAIL, mirroring `tests/geneve-encap-assert/run-tests.sh`'s C1-family-split fixture shape (fixture text files fed via flags, no live `nft` call) |
| **No host address exists on any plane bridge** (the literal fixture named in this worker's charter) | a fixture `ip addr show`-style capture where a plane bridge (e.g. `br-vr1-dc0-metal-admin`) carries an assigned IP (not merely tap-enslaved interfaces) -> `--check` must FAIL -- this is a DISTINCT failure mode from the forward-rule case: an address ON the bridge lets the HOST itself route between planes even with FORWARD correctly scoped |
| Fail-closed on an absent/unloaded control (never silently PASS) | an EMPTY or missing ruleset capture -> `--check` must FAIL (rc != 0), not report clean -- mirrors `geneve-encap-assert.sh` T11/T12 "refuse-not-pass on empty inputs" |
| No fail-open via an interface-name mismatch (SEC-010's own recorded lesson) | a fixture where the rule's `oifname`/`iifname` targets an interface NAME that does not exist on the host -> `--check` must FAIL, per `docs/security-ledger.md:21`'s own hardening note ("hardened 2026-07-16 -- if the keyed transit interface does not EXIST, since an nftables oifname on an absent iface loads clean but matches nothing = fail-open") and `tests/site-headend-install/run-tests.sh`'s existing assertion of the same class (`ip link show "$TRANSIT_IF"` must be verified, not merely referenced) |
| The control does not globalize (does not break the DC edges' legitimate WAN/uplink egress) | a fixture ruleset using a bare `policy drop` on the whole FORWARD chain (not interface-scoped) -> a "does-not-globalize" assertion must FAIL, per D-125's br_netfilter constraint already recorded for SEC-010 (`site-headend-install.sh` comments ~`:273-296`) -- the SAME class of regression one layer up |

**Ships-where:** `tests/<name>/run-tests.sh` (name minted with the SEC-NNN row), offline
fixture-file harness on the exact `geneve-encap-assert.sh` model (pre-captured text fed via
flags; `PASS=0; FAIL=0; run()` helper). **Two verification tiers, not one** (per `stage-assert-
then-promote`, Section 4): this offline harness proves the SCRIPT's logic; a SEPARATE live
`--check` re-run at B.3 (before any flat apply) and B.7 (once both DCs' planes are actually
co-resident, `pass1-admin-report.md` Part B.7) is the deploy-time gate proving the DEPLOYED
state, not this harness's job to fake.

### 2.3 The teardown-primitive (module-scoped group-destroy) -- owed artifact #1 (+ #6)

Re-earns D-122's one-command site-down for the flat shape (`pass1-admin-report.md` Section 6
item 1). Root-topology (B) recommended -- shared-outer + per-DC-flat roots (`pass2-admin-report.md`
Section 4.1) -- so the primary primitive is a gated `cd <dc-root> && tofu destroy`; the emergency
lever (#6) is a scripted `virsh destroy` loop over that DC's domain set, roster-derived from
`lib-hosts.sh` (`pass1-admin-report.md` Section 6 item 6). Both share one failing-fixture class.

| Invariant | Failing-direction fixture (the one named in this worker's charter) |
|---|---|
| The derived target/domain set for DC0's destroy contains **zero DC1 objects**, and vice versa | a fixture roster/state-list that (wrongly) includes **a domain from the other DC** (e.g. `vr1-dc1-node-05` appearing in a dc0-targeted destroy's resolved set) -> the target-set assertion must FAIL before any destroy call fires |
| The set also contains **zero non-DC objects** (voffice1, mesh legs, outer pools) under the recommended per-DC-flat root shape | a fixture where a shared-outer object (e.g. `office1_network`) leaks into a per-DC target list -> FAILS |
| The set is COMPLETE for that DC (no legitimate domain silently dropped -- the D-061 pair's own recorded defect: "a host that does not resolve is a `note`, not a `fail`", `docs/tool-index.md`) | a fixture roster missing one of the 13 expected objects for that DC -> a completeness assertion must FAIL, not silently proceed with a partial set |
| Refuses (rc=2), never destroys, against an EMPTY resolved target set (unreachable state/MAAS) | a fixture where the state-list/roster source returns nothing -> the primitive must REFUSE rather than report "nothing to do" as success, mirroring `tests/phase-00-teardown-d061/run-tests.sh`'s decompose-detection FAIL-LOUD pattern (`R3`: post-remove state dropping an expected host FAILS loud and blocks the destructive step) |
| A single-domain canary precedes the group destroy (D-061 precedent) | a fixture where the canary domain fails to actually stop/undefine -> the group destroy must NOT proceed, mirroring `phase-00-teardown-release.sh`'s `--canary` + decompose-check shape |

**Ships-where:** `tests/<name>/run-tests.sh`, stateful-fakebin harness on the exact
`tests/phase-00-teardown-d061/run-tests.sh` model: a fake `tofu`/`virsh` served by fixture
JSON/text selected by a phase-state file; mutating subcommands LOG rather than execute; the
post-mutation re-read is asserted against fixture state, not live. **Note (not yet resolvable):**
the harness's exact fixture SHAPE (root-scoped `tofu state list` vs. `lib-hosts.sh`-derived
domain roster) depends on the still-OPEN root-topology fork (`pass1-admin-report.md` Section 7
item 1, ratified Phase 4) -- flagged as a dependency, not guessed here (hard rule 2). Emergency
lever (#6) reuses the SAME fixture library/failing-direction class as a second entry point
(scripted `virsh destroy` vs. `tofu destroy`) -- not double-built, per `pass1-admin-report.md`
Section 6 item 6's own "distinct from #1 (emergency vs gated path)" framing.

### 2.4 The power-key blast-radius mitigation -- owed artifact #11 (concern iii)

**Verified real this session by pass2** (Section 2.3): each `vr1-dcN-maas-01` region VM holds a
live qemu+ssh virsh credential (`scripts/maas-region-power-key.sh`, SEC-012/SEC-016) that, once
re-pointed at vcloud's own `qemu:///system`, has NO per-domain scoping -- one connection reaches
every domain vcloud manages (both DCs' fleets + voffice1). Mechanism NOT yet chosen (`pass2-
admin-report.md` Section 2.3: "restricted key / wrapper / libvirt polkit ACL -- Phase-4 choice").

| Invariant | Failing-direction fixture (the one named in this worker's charter) |
|---|---|
| dc0's power key CANNOT reach any dc1 domain | a fixture allow-list/ACL/`command=`-restriction string that (wrongly) includes **a reachable dc1 domain name** -> the scope assertion must FAIL |
| dc0's power key CANNOT reach `voffice1` | a fixture allow-list including `voffice1` by name/UUID -> FAILS (this is the SECOND half of the named fixture -- "or voffice1" in the charter, not optional) |
| Symmetric for dc1's key against dc0 + voffice1 | mirror fixtures, both directions -- a mitigation validated in only one direction is unproven for the other (SEC-012/SEC-016 are explicitly per-DC, separate keys, `pass2-admin-report.md` Section 2.3 item 1) |
| **Positive coverage, not just absence-of-violation** -- the checker must enumerate what IS reachable and diff it against the DC's OWN roster (`lib-hosts.sh`-derived), not merely grep for known-bad names | a fixture allow-list using a WILDCARD/pattern that silently matches nothing (e.g. a typo'd site-token glob) -> the checker must FAIL this as under-specified/unverifiable, not pass it as "no bad match found" -- the exact fail-open shape SEC-010's own history warns against (`docs/security-ledger.md:21`, `site-headend-install.sh` harness item requiring the transit interface's EXISTENCE be checked, not just its rule) |
| **Negative control -- must NOT over-restrict.** dc0's key must still reach dc0's OWN roster (MAAS enlistment depends on this) | a fixture allow-list that (wrongly) excludes one of dc0's OWN domains -> a same-DC-reachability assertion must FAIL, catching a mitigation that breaks MAAS power control for its own fleet |

**Ships-where:** `tests/<name>/run-tests.sh` (new SEC-NNN, `pass2-admin-report.md` Section 2.3),
offline fixture-file harness parsing a rendered ACL/`authorized_keys`/polkit-rule artifact against
known-good/known-bad domain-name fixtures -- no live libvirt/SSH dial, same shape as `tests/
site-headend-install/run-tests.sh`'s grep-the-rendered-artifact pattern. **Blocking dependency,
stated in the harness's own header** (repo convention -- every gate names the root cause it
exists for, e.g. `geneve-encap-assert.sh`'s header): this harness's completion is a precondition
for the `lib-hosts.sh` `VIRSH_POWER_ADDRESS_FROM_OFFICE1`/`_FROM_DCREGION` re-derivation and
every `maas-node-power.sh` call-site literal (`pass2-admin-report.md` Section 3.2) -- the
mitigation's chosen mechanism determines the URI/key shape those edits need, so this harness
(and the artifact it tests) must land BEFORE those edits are written, not concurrently.

### 2.5 SEC-010-successor consolidated installer -- owed artifact #3 (concern ii)

Endpoints resolved: client VM (DC side) + voffice1 (Office1 side), `pass2-admin-report.md`
Section 2.2 / 4.4. Implementation shape: extract the SEC-010 nftables writer out of
`site-headend-install.sh`'s `node_host_setup()` (`:273-320`) into one role-agnostic subcommand
that installs BOTH ends, closing today's hand-mirrored voffice1 install.

| Invariant | Failing-direction fixture |
|---|---|
| **FORWARD-drop lands on the client VM's transit leg**, scoped, not global | reuse `tests/site-headend-install/run-tests.sh`'s EXISTING `--transit-if` override + `ip link show "$TRANSIT_IF"` existence-check assertions (already proven failable there) -- must MIGRATE, not be dropped, when the code is extracted |
| **FORWARD-drop lands on voffice1's transit leg too** (the "right legs" invariant named in this worker's charter -- both ends, not one) | a fixture invoking the new subcommand in `voffice1` role mode -> assert a transit-scoped rule is emitted for voffice1's OWN interface, not a copy of the client VM's; a fixture invoking it with the WRONG role's default interface name (e.g. client-VM role using voffice1's leg name) -> the "right legs" assertion must FAIL |
| Never lands on a non-transit leg (metal-admin, WAN/uplink) | a fixture forcing the subcommand to target the client VM's metal-admin interface name -> the emitted ruleset must NOT scope FORWARD-drop to it; a positive check that metal-admin traffic is unaffected must FAIL if it is |
| Never globalizes (D-125 br_netfilter constraint, verbatim requirement already enforced for the OLD SEC-010 writer) | reuse `tests/site-headend-install/run-tests.sh`'s existing `br_netfilter`/"never global" grep assertion against the new extraction target -- migration-completeness, not a new invariant |
| Idempotent reload (declare-then-delete preamble; `nft -f` on a live table APPENDS otherwise) | reuse the existing `delete table inet sec010` presence assertion against the new location |

**Ships-where:** if the extraction stays a subcommand of `site-headend-install.sh`, extends
`tests/site-headend-install/run-tests.sh`; if it becomes its own script, a new `tests/<name>/
run-tests.sh` inheriting EVERY SEC-010-related assertion already proven in the current harness
(item 8 in that file: transit-if override, node-host-mode presence, br_netfilter constraint,
idempotent-reload preamble) -- a **migration-completeness check** (grep the new location for
every trap-string the old harness asserted) is itself a required test, so the extraction cannot
silently drop a proven guard.

### 2.6 D-131 retire-with-evidence step -- owed artifact #13

Retirement is the ruled 10.13 end state for BOTH DCs once D-132's per-DC regions remove the
forwarder's precondition (`pass2-admin-report.md` Section 4.2(ii)). dc0 already proves the end
state (dig-verified, `docs/changelog-20260730-dc0-region-migration.md` Item 9); **dc1's
forwarder is CURRENTLY load-bearing** (`docs/changelog-20260807-dc1-region-sequence.md:80-89`,
config "replicated verbatim", `dns_servers=10.12.68.3` the forwarder alias) -- this asymmetry
must not be assumed equal (`pass2-admin-report.md` check 4).

| Invariant | Failing-direction fixture (the dc0/dc1 asymmetry named in this worker's charter) |
|---|---|
| Nodes resolve via the DC's OWN region BIND **directly**, not via the D-131 forwarder alias | a fixture `dig` capture that SUCCEEDS (answers correctly) but whose ANSWERING SERVER is the forwarder alias IP (`10.12.68.3`-class), not the region's own BIND (`10.12.68.6`-class per dc1's `.6` region VM) -> the checker must FAIL this, because a "did resolution succeed" test alone would PASS on dc1's still-load-bearing forwarder and falsely report retirement complete |
| dc0 passes (already the proven end state) | a fixture matching dc0's actual measured dig evidence (`dns_servers=10.12.8.6`, `flags: qr rd ra`, ANSWER: 9, `docs/changelog-20260730-dc0-region-migration.md` Item 9) -> must PASS, proving the checker is not just tuned to fail everything |
| **dc1 must be explicitly closed, not silently inherited as passing** | a fixture reproducing dc1's CURRENT (unretired) config verbatim (`docs/changelog-20260807-dc1-region-sequence.md:80-89`) -> the checker must FAIL dc1 today, and the harness's own dc1 test case must be RED until the live retirement actually happens -- this is the asymmetry as a standing red case, not a hypothetical |
| The checker asserts the resolver's IDENTITY, not merely that a name resolved | same fixture pair as row 1 -- restated because it is the entire point: a checker that only checks "resolution worked" is provably insufficient here and must not be shipped |

**Ships-where:** `tests/<name>/run-tests.sh`, offline, fixture = captured `dig +short`/`dig
+stats`-style text comparing the answering resolver's IP against the DC's own region IP (read
from `lib-hosts.sh`/`lib-net.sh`, never a duplicated literal). Small, single-purpose L3 gate;
invoked per-DC at the retirement decision point and again at B.5's placement close-out
(`pass1-admin-report.md` Part B.5).

---

## 3. The remaining seven owed artifacts -- harness coverage, concise

| # | Artifact | Harness disposition |
|---|---|---|
| 4 | R7 credential-revocation checklist | NEW gate, offline: fixture `vm-secret-locations` register rows (mock) keyed to the retiring rack host class; asserts EVERY matching row is enumerated. Failing fixture: an unlisted/orphan row for that host class the enumeration misses -- the exact defect class SEC-027's ledger row names verbatim ("an unlisted location is not audited," `docs/security-ledger.md:80`) |
| 5 | MAAS machine-record release/delete step (+ rack-controller decommission) | NEW gate, fakebin `maas` on the `tests/dc-egress-check` / `tests/phase-00-teardown-d061` model; asserts post-release re-read (LENS-2) reaches zero AND the region-side rack-controller + `primary_rack`/DHCP reference are cleared. Failing fixture: a post-release fixture where one machine record OR the rack-controller record survives -- must not report clean |
| 6 | Emergency site-down lever (`virsh destroy` loop) | Shares Section 2.3's harness/fixture library (same cross-DC-domain failing fixture) -- explicitly not double-built (`pass1-admin-report.md` Section 6 item 6) |
| 7 | FIT-calculator extension + fresh capacity measure | EXTENDS the existing `tests/dc-dc-whole-host-budget/` harness (already YES, `pass2-w4-module-decomposition.md` Section 2) with the 3 utility-node classes + the artifact-service disk-sizing branch. Failing fixture: a roster total EXCEEDING the measured host budget must FAIL the calculator, not silently round or omit a class |
| 8 | MAC re-measurement pass (post-apply) | No new dedicated harness -- rides `dc-site`'s own MAC-pinning invariant (Section 2.1 row 4) once that module is built and applied; cross-reference only |
| 9 | NetBox DCIM migration (decommission `vvr1-dcN`; register client VM + roster) | EXTENDS the existing `netbox/dc-rack-mgmt-import.py` harness (`pass0-admin-report.md` row 11) with a new failing fixture: a stale `vvr1-dcN` device record surviving import must FAIL a decommission-completeness assertion. Not a new module |
| 10 | Post-build live asserts (geneve/jumbo re-verify; gap-#20 re-verify) | Rides the EXISTING `tests/geneve-encap-assert/run-tests.sh` verbatim (already fully fixture-proven, Section 2.2 confirms its shape) -- no new harness; only a new invocation point (post-flatten, vcloud-level planes) belongs in the runbook, not the test suite |

All 13 owed artifacts are accounted for: 6 with full new-harness specs above, 5 extending an
existing harness with a new failing-direction fixture, 2 riding an existing invariant/harness
with no new build.

---

## 4. The per-module harness CONTRACT -- the template every one of these follows

Grounded entirely in patterns already proven in this repo (cited per row), not invented for
this pass -- consistent with `pass2-w4-module-decomposition.md` Section 3's procedure-module
contract and this pass's own charter (`SCOPE-AND-EXECUTION-PLAN.md` RULES).

| Principle | What it requires | Repo precedent |
|---|---|---|
| **Prove-it-can-fail** | Every assertion ships with a fixture engineered to make it FAIL; a mutation pass that deletes the assertion must turn the suite red. A clean PASS with no paired failing fixture is not a gate. | `geneve-encap-assert`'s T5/T6/T11/T12 (family-split, ofport -1, empty-input refuse); `phase-00-teardown-d061`'s R3 decompose-detection; the repo's own named failure mode, `docs/tool-index.md`'s D-061 "note not a fail" defect |
| **Assert the ARTIFACT, not the config/intent** | Check the INSTALLED rule, the DEPLOYED overlay value, the RENDERED file -- never a comment, a doc string, or a generator's self-report of what it meant to do. | `docs/changelog-20260730-octavia-reissue-tool.md:158-167`, A17: "graded the workspace copy... the charm gets this one ($OVLCMP)" -- the consumed copy is what's graded |
| **Stage-assert-then-promote** | Any harness whose subject WRITES material (mints a credential, renders a config, applies an nftables table) writes to a STAGING path first, asserts the STAGED artifact, and only then promotes/applies -- never assert an in-place mutation after the fact with no rollback point. | `docs/changelog-20260730-octavia-reissue-tool.md:158-167` (four cited properties incl. stage-assert-promote); `scripts/octavia-pki.sh` staging-dir promotion flow |
| **Join the workspace to the deploy input** | When a generated artifact is separately CONSUMED downstream (an overlay literal, a `lib-hosts.sh` value, a bundle var), assert BYTE/VALUE EQUALITY between the generator's output and what the consumer actually reads -- not just that each was independently produced correctly. | `docs/changelog-20260730-octavia-reissue-tool.md:158-167`; `scripts/octavia-pki.sh` A17 (the exact defect: two things independently graded correct, nothing joined them, and the deployed copy diverged) |
| **Fail-closed on absent/empty/unreachable input** | An empty, missing, or unresolvable input REFUSES or FAILS -- it never reports a clean PASS by default. Includes the interface-name fail-open class: a rule referencing an absent name loads clean and matches nothing. | `docs/security-ledger.md:21` SEC-010's own 2026-07-16 hardening; `geneve-encap-assert` T11/T12; `site-headend-install`'s transit-interface-existence check |
| **Offline/fixture-driven by default** | No live cloud dependency in the harness itself -- a stateful fakebin or captured-text fixture stands in for the live system. A SEPARATE, explicitly-named live gate re-run (not this harness) proves the deployed artifact. | Every harness surveyed this session (`geneve-encap-assert`, `site-headend-install`, `phase-00-teardown-d061`, `dc-egress-check`, `dc-node-v6-verify`); `dc-node-v6-verify`'s own disclaimer: "WHAT THE GREEN BELOW DOES NOT PROVE: no node has ever been asserted by it" |
| **`$SITE`/`$DC`-parameterized, never hardcoded** | A fixture exercises BOTH dc0 and dc1 (or a synthetic third site) to prove the checker generalizes -- not that it happens to pass against dc0's literals. | `pass1-w4-module-planning.md` Section 4 item 1 (design principle 1); DOCFIX-151 `lib_net_select_dc`/`lib_hosts_select_dc` |
| **Standard exit contract** | Adopt `lib-validate.sh`'s 0/1/2/3/4 PASS/FAIL/HOLD/PASS_PENDING_MANUAL/SKIPPED vocabulary for any verify-mode gate, so it composes into the existing G-series/preflight aggregation. | `scripts/lib-validate.sh:16-24` |
| **Delivery discipline** | Ships with its own `tests/<name>/run-tests.sh`, a changelog entry with a revert, and is `repo-lint` clean -- no exception for a "new" module. | CLAUDE.md "Delivery"; `pass2-w4-module-decomposition.md` Section 3 item 7 |

---

## 5. Open items (not resolved by this worker; feed the Phase-3 administrator / Phase 4)

1. Four of the six full-spec harnesses (2.2 isolation control, 2.3 teardown primitive, 2.4
   power-key mitigation, 2.5 SEC-010 successor) specify invariants and failing fixtures
   MECHANISM-AGNOSTICALLY because their underlying mechanism is still OPEN (`pass2-admin-report.md`
   Section 6) -- the harness SHAPE (offline fixture-file, on the `geneve-encap-assert.sh`/`site-
   headend-install.sh` model) is fixed; the exact fixture CONTENT is not writable until the
   mechanism is ruled.
2. `modules/dc-site`'s live `tofu plan`-based resource-count check (Section 2.1) is a stretch
   item flagged OWED-AT-BUILD, not specified as fact -- the module does not exist yet.
3. The teardown-primitive's fixture shape (Section 2.3) is explicitly contingent on the
   root-topology fork ratification (Phase 4).
4. This worker did not review W3.1 (existing harnesses assuming the container layer) or W3.2
   (preflight/cloud-assert/stage gates for a flat topology) -- those are sibling workers' domains
   per `SCOPE-AND-EXECUTION-PLAN.md` Section 4; only this worker's per-new-module dimension is
   covered here.

---

## 6. Verification note

Author = the W3.3 worker (no model name asserted). Direct reads this session: the five admin/
worker documents named in the header, in full; six existing `tests/*/run-tests.sh` harnesses
read in full or substantially; `scripts/lib-validate.sh` header; `docs/security-ledger.md:21`
(SEC-010) and `:79-80` (SEC-026/SEC-027) read directly; `docs/changelog-20260730-octavia-
reissue-tool.md:140-167` read directly for the stage-assert-promote / join-workspace vocabulary;
`opentofu/modules/node-vm/variables.tf:38-62` read directly for the MAC-pinning validation this
spec reuses. READ-ONLY; nothing executed; findings and specs are LOGGED only, per the pass's
charter.
