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.
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.
modules/dc-site (new composing IaC module) -- owed artifact #12What 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.
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.
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.
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.
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.
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).
| # | 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.
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 |
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.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.SCOPE-AND-EXECUTION-PLAN.md Section 4; only this worker's per-new-module dimension is covered here.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.