STAGE-5 PHASE 0 -- execution-environment preconditions: EXECUTED 2026-07-27
==========================================================================
Operator direction (GA-R5 not required -- OPS execution of the already-ruled
R10, plus readiness-doc Phase 0): "Merge to main, then start Phase 0", then
"Approve A, B, and C, and retire the audit branch".
Scope executed: readiness-doc preconditions 0.1, 0.2, 0.3
(docs/audit/stage5-readiness-20260727.md), plus retirement of the merged
audit branch. Host: voffice1 (the D-128 Plane-2 execution host).
Status authority for anything below is docs/CURRENT-STATE.md (GA-R1). This
file is a capture, not a status surface.
0. MERGE (prerequisite, done first)
-----------------------------------
merge commit 607813b 2 parents (NOT squashed), 33 commits from
dc-dc-stage5-grounding-audit
recorded by 6495cfb (a --no-ff merge cannot carry the doc edit;
same shape as Stage 4's 6f5701d / 1023596)
containment git branch --merged main -> listed, before deleting
ON main gauntlet ALL GREEN (81 harnesses); repo-lint 0 fail / 1 warn
branch RETIRED local + remote; git ls-remote --heads origin -> main only
NO STAGE OPENED OR CLOSED.
A. 0.1 -- ADVANCE THE voffice1 CLONE
------------------------------------
PRE (measured read-only, before touching anything):
HEAD 61c416e on dc-dc-g12-dc1-substrate (deleted upstream)
distance 105 0 vs its CACHED origin/main (itself pre-merge 71519a2)
dirty 1 untracked: opentofu/vr1-dc1-substrate/.terraform.lock.hcl
SAFETY CHECK RUN FIRST -- the inner tfstate for BOTH DCs lives INSIDE this
working tree (it is the state-of-record; CURRENT-STATE section 1 records the
location). A branch switch here is therefore not a routine checkout.
git check-ignore -> IGNORED, all of:
opentofu/vr1-dc0-substrate/terraform.tfstate
opentofu/vr1-dc0-substrate/terraform.tfstate.backup
opentofu/vr1-dc1-substrate/terraform.tfstate
opentofu/vr1-dc1-substrate/terraform.tfstate.backup
opentofu/vr1-dc{0,1}-substrate/d124-inner.auto.tfvars
git ls-tree origin/main -> tracks the SAME file set at those paths as the
outgoing branch, and does NOT track vr1-dc1-substrate/.terraform.lock.hcl,
so the one untracked-not-ignored file cannot collide.
=> the switch cannot touch the state-of-record. PROVEN, not assumed.
EXECUTED:
git fetch origin --prune
- [deleted] origin/dc-dc-g12-dc1-substrate
- [deleted] origin/dc-dc-stage3-phase2-dc-substrate
- [deleted] origin/dc-dc-stage5-grounding-audit
71519a2..6495cfb main -> origin/main
git switch main
(a plain `git pull` would NOT have worked -- the tracked branch is gone
upstream; recovery shape per finding L5-4)
POST -- ASSERTIONS:
HEAD 6495cfb
origin/main 6495cfb ASSERT PASS
tfstate sha256, dc0 2e140b74...894608c3 IDENTICAL to PRE
tfstate sha256, dc1 aa91f103...dc671645 IDENTICAL to PRE
overlays/vr1-dc1-vips.yaml NOW PRESENT (was ABSENT)
overlays/vr1-dc1-machines.yaml NOW PRESENT (was ABSENT)
bundle.yaml machines block NOW the VR1 9-node role-separated layout
(was VR0 4-node hyperconverged "8"-"11")
dirty 1 untracked (unchanged, as predicted)
=> readiness blocker 1 ("you would deploy the wrong topology") CLEARED.
B. 0.3 -- PRUNE STALE REFS
--------------------------
Remote-tracking refs: pruned by the fetch above (3 deleted).
Local branches: voffice1 carried TWO stale locals, not the one the record
named. Containment proven before deletion (`git rev-list --count
origin/main..<branch>` -> 0 for both; `-d` used, which refuses if unmerged).
Deleted dc-dc-g12-dc1-substrate (was 61c416e)
Deleted dc-dc-stage3-phase2-dc-substrate (was 57836b1)
FINAL: local `main` only; remotes/origin/main only.
Ordering note: the audit branch was retired on origin BEFORE this fetch, so
advancing the clone could not hand it a FRESH stale ref -- the exact condition
that produced the 105-commit problem.
C. 0.2 -- THE openstack CLIENT
------------------------------
MEASURED BEFORE PRESENTING (the options were not assumed):
snap `openstackclients` NO Caracal channel. Newest stable = zed (2023-03).
latest/stable = xena (2021). REFUTED for this
deployment. Corroborating in-repo prior art:
docs/design-decisions.md:638 records the snap's
home-only confinement (paths under /tmp unreadable).
apt noble/main python3-openstackclient 6.6.0-0ubuntu2 <-- MATCH
6.6.0 IS the Caracal 2024.1 client (verified
upstream, not from memory: Launchpad
python-openstackclient 6.6.0-0ubuntu1, packaged
for the 2024.1 coordinated release).
archive reachability http://archive.ubuntu.com/ubuntu/dists/noble/Release -> 200
simulated install 0 upgraded, 68 newly installed, 0 to remove
UCA not configured on this host (not needed -- noble's
native OpenStack release IS Caracal 2024.1)
EXECUTED: sudo apt-get install -y python3-openstackclient
POST -- VERIFIED BEHAVIOURALLY, not just by presence:
command -v openstack /usr/bin/openstack
openstack --version openstack 6.6.0
openstack --help exit 0
openstack server list "Missing value auth-url required for auth plugin
password" <- fails CLEANLY on absent config,
which is correct (no cloud configured yet); it
does not crash.
dpkg versions (the pin):
python3-openstackclient 6.6.0-0ubuntu2
python3-openstacksdk 3.0.0-0ubuntu2
python3-novaclient 2:18.5.0-0ubuntu1
=> readiness blocker 2 CLEARED. Pin recorded in CURRENT-STATE section 7.
D. THE PAYOFF RUNS (deliberately deferred until the clone was current)
----------------------------------------------------------------------
CURRENT-STATE recorded these as OWED; running them against a 105-commit-stale
tree would have measured nothing. All three run here for the first time.
D.1 repo-lint ON voffice1 0 fail / 1 warn (the standing legacy
D-001..018 non-ASCII carve-out). Matches
vcloud exactly.
D.2 gauntlet ON voffice1 *** 2/81 FAILED *** opentofu-validate,
site-headend-install
-- on the IDENTICAL commit that reports
ALL GREEN (81) on vcloud.
FINDING P0-1: "GAUNTLET ALL GREEN" IS A HOST-DEPENDENT CLAIM.
Both failures are host-portability defects, NOT tree defects. Every
GA-R6 stage close in this project's history has cited a gauntlet figure
measured on vcloud only.
(a) opentofu-validate -- every sub-check PASSES (root, 12 modules, both
extra roots) and the aggregate still reports FAIL. Cause:
`tofu fmt -check -recursive` walks the FILESYSTEM, not the git tree,
and trips on alignment drift in
opentofu/vr1-dc0-substrate/d124-inner.auto.tfvars
which is GITIGNORED and exists ONLY on voffice1 (it carries that
host's real deploy inputs). vcloud cannot see this file, so vcloud
can never fail on it -- and equally, vcloud's green can never
attest the fmt state of the inputs the deploy actually uses.
Verbatim drift: `opnsense_base_path = ` wants two more spaces to
align with `vvr1_dc0_ssh_keyfile`.
(b) site-headend-install -- tests/site-headend-install/run-tests.sh:36
if snap list lxd >/dev/null 2>&1 || snap list maas >/dev/null 2>&1; then
bad "--dry-run appears to have INSTALLED a snap on the test host"
The assertion takes an UNCONDITIONAL snapshot of the host and never
compares it to a pre-state. On voffice1 -- which IS the headend, where
lxd and maas are installed BY DESIGN -- it fires as a false positive.
It works only on a host that is not a headend. Same defect class the
R15 work names (an assertion that does not measure what it claims),
in its false-RED direction.
NEITHER is fixed here (hard rule 1 -- Phase 0's ruled scope is 0.1/0.2/0.3).
Both are logged for a ruling/OPS decision.
D.3 preflight ON voffice1 TRUE EXIT 1 ("PREFLIGHT: FAIL -- do NOT deploy")
(exit code read from the script itself, NOT through a pipe -- the 07-27
audit owned exactly that error by reading `tail`'s status instead.)
R10's RULED CONSEQUENCE IS DELIVERED, both halves:
P3 ALL 33 charm-channel pins now VERIFY [ok] -- 2024.1/stable,
squid/stable, 2.4/stable resolved against charmhub. Previously
ZERO of 33 were verified by any executable check, because `juju`
is absent on vcloud. This is the first executable confirmation of
the committed Caracal pins.
P4 "MAAS reachable (profile=admin)" PASS. The former "MAAS
unreachable" was the missing `maas` binary on vcloud, as ruled.
P4 residual FAILs -- and ONE OF THESE WAS INITIALLY MIS-FILED BY THIS
CAPTURE AS "already known". Corrected here by measurement:
- MISSING overlays/octavia-pki.yaml (deliberately absent; host-independent).
Genuinely known.
- metal-internal VID=0 (want 103) -> readiness item 3.7: pre-flight-checks.sh
is VR0-FROZEN and its VID-103 / br-internal assertions CONTRADICT D-133,
so they can never pass on either VR1 DC. Genuinely known.
- metal-admin gateway=none (want 10.12.8.1) -> **NOT item 3.7, and NOT
previously recorded anywhere.** Item 3.7 is specifically the VID-103 /
br-internal assertions; this is a separate expectation. See P0-5.
FINDING P0-5: lib-net DECLARES A metal-admin GATEWAY THAT HAS NEVER EXISTED.
scripts/lib-net.sh:37 (the DEFAULT / VR0-dc0 arm):
declare -A PLANE_GW=( ["10.12.4.0/22"]="10.12.4.1"
["10.12.8.0/22"]="10.12.8.1" )
so pre-flight-checks.sh CHECK 3 hard-FAILs metal-admin for having no
gateway. MEASURED from the dc0 rack (ssh -J voffice1, dc0 svc key):
ping 10.12.8.1 -> 2 transmitted, 0 received, 100% loss
ip neigh -> 10.12.8.1 dev virbr2 INCOMPLETE (ARP never
resolved -- nothing HOLDS the address; this is
not a device that is merely down)
rack legs on the plane: 10.12.8.2 (rack), .3 (D-131 DNS forwarder),
.4 (D-134 utility / mirror)
CONTROL: ping 10.12.4.1 (the edge, provider gw) -> 0% loss
The control proves the instrument. So MAAS is RIGHT to carry no gateway
on metal-admin and the CHECKER's expectation is the defect -- a VR0
inheritance. Consistent with the record of the D-134 carve, which ruled
`.1` gateways for the two PROVIDER subnets only; the 8 plane subnets were
created without them. Nothing routes off metal-admin (nodes reach the
mirror .4 and DNS .3 on-link), so no gateway is wanted.
Adjacent to item 3.7 -- same script, same VR0-frozen class -- but a
DISTINCT assertion that 3.7's remediation would not touch. Logged, not
fixed (hard rule 1). NOTE the dc1 arm (lib-net.sh:149) carries the same
shape at 10.12.68.1 and will fail identically.
FINDING P0-2: P5 IS HOST-BLIND, AND PREFLIGHT HAS NO CORRECT HOST.
P5 on voffice1 -> 34 findings
P5 on vcloud -> 7 findings (the known residual set)
SAME matrix (82 rows), SAME commit.
Cause, measured:
vcloud has ~/vr1-dc0-creds, ~/vr1-dc1-creds, ~/vr1-office1-creds
voffice1 has ~/vr1-dc0-creds, ~/vr1-dc1-creds and NO vr1-office1-creds
(its two ARE the SEC-022 shadow stores, not the jumphost set)
The matrix's `jumphost` role carries no assertion about WHICH host is the
jumphost, so every `jumphost/*` location silently re-points to whatever
host runs the checker. On voffice1 that manufactures ~27 spurious
EXPECTED-BUT-ABSENT findings against the headend's shadow stores.
This is the committee's "tier 2 is SITE-BLIND" defect one level up:
HOST-blind. Note the direction -- here it produces false RED, but the
same hole would produce false GREEN for any row whose credential happens
to exist on the wrong host under a matching name.
One finding in the voffice1 run is REAL and worth keeping:
E3 UNDECLARED: 'maas-virsh_ed25519' present at jumphost/vr1-dc0 but in
NO matrix row for that site
-- i.e. an undeclared file in the headend shadow store, the SEC-022 class.
CONSEQUENCE FOR R10: the ruling ("fix the stale commit issue and make sure
all working directories are current") is EXECUTED and its predicted
P3/P4 clearance is CONFIRMED. But the measurement also shows the reds are
not merely an artifact of the wrong host -- vcloud has the credentials and
not the clients; voffice1 has the clients and not the credentials. There
is NO single host on which preflight is currently correct. Not ruled here.
E. FINDINGS LOGGED, NOT ACTIONED (hard rule 1)
----------------------------------------------
P0-1 gauntlet is host-dependent; two harnesses encode "I am not the
headend" assumptions (detail in D.2). The stage-close citation
"gauntlet ALL GREEN (N)" should state the HOST it was measured on.
P0-2 creds-matrix `jumphost` role is host-blind; preflight has no
correct host (detail in D.3).
P0-3 opentofu/vr1-dc1-substrate/.terraform.lock.hcl is untracked on main
while its dc0 twin IS tracked -- an asymmetry, harmless today, but it
is why the dc1 root shows a permanent untracked file on every host.
P0-4 No logged window (scripts/run-logged.sh) was opened for this session;
it was offered and the operator approved the steps directly. Recorded
for the as-executed trail rather than left silent.
P0-5 lib-net declares a metal-admin gateway (.8.1 / dc1 .68.1) that no
device holds -- measured 100% loss + INCOMPLETE ARP against a working
control (detail in D.3). Both DC arms affected.
QUESTION QUEUED FOR THE OPERATOR (not a finding -- an interlock the R15
rulings do not currently reach; one GA-R5 exchange, no D-number self-assigned,
GA-R3 doubt resolves DOWN to OPS unless the A1 Roosevelt test is met):
WHICH HOST IS AUTHORITATIVE FOR THE GATES?
R10 ruled preflight belongs on voffice1; R15(3) rules preflight must stop
failing open. Executed together as ruled, and given P0-2, preflight on
voffice1 becomes PERMANENTLY UNPASSABLE -- its 34 findings are host
artifacts, not defects. Likewise R15(2) pins a harness MANIFEST, which
catches renames but does nothing about P0-1: `tofu fmt -check -recursive`
walks the filesystem, so implementing R15(2) exactly as ruled still leaves
voffice1 red. So the R15 execution scope needs to answer, first, which host
each gate is authoritative on -- and for the credential matrix, whether
`jumphost` is a ROLE that must be pinned to a named host.
STANDING CONSEQUENCE either way, worth stating plainly: STAGE 5 EXECUTES
FROM voffice1, and the gauntlet cannot be green there until P0-1 is
resolved. Every future GA-R6 close citing a gauntlet figure measured there
inherits a known red, so the citation must name its host.
Captured 2026-07-27 on branch dc-dc-stage5-preconditions.