| 2026-07-26 |

D-137 tier 3 (VALIDITY) BUILT: cross-copy sha256 provenance
...
Closes the gap the plan names: creds-audit PARSES declared provenance and
never verifies it, so SEC-020's stale-trap warning has been unchecked prose
and its sha256 equality was a ONE-TIME manual act on 2026-07-25.
sha256sum runs as an EXTERNAL command on both sides so only a 64-hex digest
enters the checker -- hashing bytes in Python would meet the letter of "never
transfer content" and not the spirit.
RESULT: 4 groups compared, all byte-identical, INCLUDING the SEC-020 pair
(maas-region-admin, region source-of-record vs jumphost copy). Now
machine-verified instead of remembered. The [ok] line names the groups.
TWO FALSE POSITIVES IN MY OWN DRAFT, caught by verifying before reporting.
Keying digests by (role, site) let an identity's DISTINCT artifacts at one
scope overwrite each other, so it compared unrelated files and reported drift
on maas-region-admin and dc1-svc-key. Manual sha256sum showed both IDENTICAL.
Reporting that would have raised a false credential-rotation alarm.
Root cause was a schema gap: nothing expressed which rows are byte-copies.
custody gains `verbatim-copy` [OPS]. V1 now compares only rows sharing
(id, filename) across scopes, or a source-of-record row against declared
verbatim-copy rows -- SEC-020's exact shape. Everything else is skipped with
a reason: a pair we cannot justify comparing is not a pair we may report
drift on. verbatim-copy is manifest-bearing; it asserts byte-identity, it
does not move the file.
Harness 44 -> 52: T47/T48 regression-lock both false positives; T49 keeps
SEC-020's case from falling into T48's skip; T51 asserts the digest path uses
sha256sum and that no content-transfer verb exists anywhere in the checker.
NOT built: tier 3's behavioural probes. Liveness, expiry, revocation state
and grant/scope drift remain unverified.
Gauntlet ALL GREEN (80), repo-lint 0-fail, finding-class baseline unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

D-137 ruling 1 EXECUTED: tier 1 wired as the blocking preflight P5
...
Operator answer, exact utterance: "wire tier 1 as the blocking preflight Pn"
(2026-07-26), resolving the open sequencing question. Recorded on D-137.
preflight.sh gains P5: credential matrix (D-137 tier 1), blocking, with
worst-exit aggregation, placed AHEAD of the stage-2 reminders block (now P6)
so its verdict participates in the deploy decision. Tier 1 only -- it is
offline and its findings ARE the three ruled failure classes. Tier 2 needs
--remote/--privileged and a caller-supplied --pending-stage, which do not
belong in an unattended gate; that stays an open decision.
FAIL-OPEN in my own wiring, caught by the new test: a missing creds-matrix.py
makes python3 exit 2, which `note` maps to WARN -- so deleting the gate would
have downgraded it to a warning rather than stopping the deploy. P4 already
guarded this class; P5 did not until T9 failed. Now guarded explicitly.
tests/preflight 7 -> 10: T8 a red register FAILS the deploy (blocking, not
advisory); T9 fails closed when the checker is absent; T10 the gate runs
before the reminders block.
CONSEQUENCE, not overclaimed: preflight exits 1 with P5 among the reasons,
but preflight was ALREADY exiting 1 before this change (P4: octavia-pki.yaml
absent, MAAS unreachable from the jumphost). P5 adds a fifth reason to an
already-red gate; it flipped nothing and closes no open deploy path.
Verified by stashing the change and re-running.
Gauntlet ALL GREEN (80), repo-lint 0-fail.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

D-137 phase 3: re-measure the register; SEC-024 opened
...
~21 inferred filenames corrected against their own mint-refs. The session had
owned six; those were only the rows the first sweep physically touched.
Octavia's 8 real basenames plus its THREE SUBDIRECTORIES (the bare
~/octavia-pki/* pattern matched ZERO of the 8 artifacts, two of them CA
private keys); vault's init.txt; the tenant rows' <client>- instance prefix,
with a placeholder matcher so they can match a real basename at all;
kube-config -> config; .maas.cli -> .maascli.db (measured: ~/.maas.cli does
not exist).
sec-ref mis-attribution corrected: both juju-maas-user rows cited SEC-020;
the on-subject rows are SEC-018/-019. This is the SEC-015 class recurring --
one instance was fixed by hand earlier without checking whether it was
systemic. It was.
mint-ref corrected: admin.pass cited a CONSUMER (:452), not the mint (:450);
the RGW key cites a line that takes it as INPUT, so it is operator-terminal.
Rows added: the libvirt SSH power password (standing rotation obligation from
a 2026-06-26 plaintext exposure, in neither the matrix nor the exclusions),
vault-ca-root, and the tfstate siblings. ~/as-executed/ deliberately NOT
declared, reason recorded: it holds session logs, so declaring it made every
log a false UNDECLARED.
Four further defects in my own phase-2 changes, found by RUNNING the sweep:
shlex.quote broke ~ expansion; a non-existent parent read as unreadable
rather than absent; site-key `-` needed shared-location semantics; the
tfstate siblings needed rows.
SEC-024 OPENED -- new exposure found by the fixed checker on its first clean
run: opentofu/terraform.tfstate.backup is mode 0664 and carries the MAAS API
key in plaintext (DOCFIX-175); the live state file is 0600. Invisible to
every prior control because the world-readable check was custody-gated and
the siblings were undeclared. LOGGED, NOT ACTIONED (hard rule 1).
Findings 35 -> 13, all true. Matrix 81 rows. Harness 44/44, creds-audit
15/15, gauntlet ALL GREEN (80), repo-lint 0-fail.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

D-137 phase 2: fix the eight confirmed false-greens, regression-lock each
...
Tier 2 is now scoped by (host-role, SITE-KEY). Keying on role alone merged
all three jumphost creds folders into one basename namespace, so a credential
present at ANY site satisfied the row for EVERY site -- how SEC-021's dc0
opnsense-api.txt absence passed a green sweep while tier 1 flagged it. Four
committee lenses converged on this. vm-secret-locations gains a site column.
Also fixed, each reproduced by the committee and each now regression-locked:
- probe_remote called a successfully-read location UNREACHABLE when its glob
matched nothing, gating the role and turning every absence FAIL there into
an [ok]; a __DONE__ liveness marker now separates "ran, found nothing" from
"could not reach".
- literal-file locations skipped absent/unreadable detection entirely (the
T33 false green surviving in the other path form).
- an EMPTY locations list bypassed ruling 3's refusal.
- a zero-row matrix reported clean over the empty set.
- a mint-ref pointing at a directory crashed with exit 1 -- indistinguishable
from findings -- and skipped S5/S6/S7, silently dropping the conflation and
asymmetry findings.
- mode enforcement was custody-gated, leaving 43 of 77 rows unchecked
including the SEC-020 and SEC-022 stores; a world-readable check now
applies at any custody.
- S5's dc1->dc0 direction was untested; deleting it left the harness green.
- rows with no declared location for their scope are disclosed, not skipped.
- declared paths/targets are charset-validated and shell-quoted: an
unvalidated `;` reached a remote shell, under sudo when --privileged.
- creds-audit sprawl globs now cover dotfiles; the prior widening could not
see .admin.pass, the dotfile sibling of its own motivating secret.
T24 replaced with a checked-in finding-CLASS baseline. The old form grepped
for the literal "IDENTITY CONFLATION", so REMEDIATING that defect would have
turned the gauntlet red for whoever did the right thing -- making "edit the
test" the cheapest response exactly when the guard mattered.
Harness 35 -> 43, creds-audit 13 -> 15, gauntlet ALL GREEN (80), lint 0-fail.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

D-137 tier 2: live read-only sweep + two probe false-greens it exposed
...
SEC-021's ON-DISK half REPRODUCED: vr1-dc0-maas-power_ed25519{,.pub} are
genuinely absent from the dc0 jumphost creds folder, not merely undeclared.
Capture: docs/audit/d137-tier2-sweep-20260726.txt (read-only, no sudo,
stat-over-ssh metadata only; jumphost + voffice1 + office1-netbox).
Running it against real hosts exposed two false-greens in the probe:
1. "absent" vs "could not look". /root/maas-secrets and /root/netbox-secrets
reported "does not exist" -- they exist; SEC-020 is precisely about
admin.pass living in the first. An unprivileged [ -d ] on a root-owned
parent is indistinguishable from a missing directory. The probe now tests
parent traversability and reports UNREADABLE as a FAIL, not a skip.
2. Role-level aggregation manufactured false absences: skipping one location
let a role's other locations cover it, so credentials in the unprobed
location reported EXPECTED-BUT-ABSENT. Absence is now asserted only over
fully-probed roles (14 rows report NOT JUDGED). Refinement: "absent" is a
conclusive observation and does not gate a role; only unreadable and
unreachable do.
Harness 33 -> 35 (T33 unreadable location, T34 absent location).
Gauntlet ALL GREEN (80), repo-lint 0-fail.
OUTSTANDING: the two root-owned dirs need a privileged read, so SEC-022's
shadow-store contents and the SEC-020 region secrets stay UNCONFIRMED. That
is a remote-sudo shape and was not run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

D-137 tier 2 (EXISTENCE): declared-location bound, existence checks, widened globs
...
Tooling only -- the LIVE three-site sweep has NOT run, so SEC-021's on-disk
half, SEC-022 and SEC-023 are not yet reproduced as live findings.
creds-manifests/vm-secret-locations (ruling 3): the absolute bound on
discovery. Covers the jumphost creds folders, the SEC-022 headend shadow
stores, the SEC-020 region secrets dir, the three dirs outside the SEC-009
convention, plus two the ruling's note did not name -- the in-clone PKI
overlay and the DOCFIX-175 plaintext tfstate. Tenant dirs are LOCAL-only:
no tenant VM/project/host is reachable from this file, so D-069 holds by
construction rather than by good behaviour. `<repo>` is substituted at
runtime (D-110: the repo name is never hardcoded).
creds-matrix.py --tier2 [--remote]: E1 expected-but-absent, E2 mode, E3
undeclared-at-a-declared-location. Probes are `stat` over ssh -- metadata
only, never content. An unreachable host SKIPS with an explicit [ok],
because "could not look" must never read as "nothing there".
--pending-stage is supplied by the CALLER so a not-yet-reached mint stage
defers instead of failing; encoding which stages have run would put a
status claim in code, and GA-R1 puts status in CURRENT-STATE only.
creds-audit.sh sprawl globs widened for the SEC-023 blind spots
(admin.pass, *.apikey, *.key, *.pem, *_ed25519, *_rsa, *openrc*). The old
six patterns could not have matched the SEC-020 secret that sat undetected
12 days, any bare SSH key or PEM, or the predicted Stage-5 ~/admin-openrc.
Harnesses: creds-matrix 33/33 (8 new tier-2 cases), creds-audit 13/13
(was 7; five blind-spot fixtures plus T13 asserting the widening did NOT
become trigger-happy). Gauntlet ALL GREEN (80), repo-lint 0-fail.
FLAGGED DIVERGENCE from the plan's Files list: --remote is implemented in
creds-matrix.py, not creds-audit.sh. Tier 2 IS the preflight Pn and the
matrix plus locations list both live there; splitting it would mean two
implementations of one bounded walk. Ruling 3 names a bound, not a script.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

D-137 tier 1 (STATIC): credential matrix, checker, harness -- RED by design
...
Schema amended 10 -> 12 columns (operator-ruled 2026-07-26, "go with the
12-column amendment"): adds `custody` + `notes-ref` and re-keys a row to one
(credential, location) pair. A read-first round-trip check of the three
manifests proved the 10-column form could not carry what D-137 ruling 2
forbids dropping -- and ruling 3 puts four deliberate credential copies inside
--remote's declared locations, where creds-audit.sh:63-67 would report each as
UNDECLARED. Implements ruling 2 ("prose must become MATRIX FIELDS"); OPS under
GA-R3, the five sub-rulings untouched.
Ships: creds-matrix.tsv (72 rows), creds-matrix-notes.md (32 keys),
scripts/creds-matrix.py (S1 schema / S2 both-bounds manifest coverage / S3
render drift / S4 mint-ref resolution / S5 per-DC symmetry / S6 ruling-5
principal invariant / S7 notes integrity), tests/creds-matrix 24/24.
Gauntlet ALL GREEN (80, was 79); repo-lint 0-fail.
RED BY DESIGN, 5 findings -- do not go green by deleting rows: the ruling-5
identity conflation on maas-region-admin (the live SEC-020 defect), 3x
EXPECTED-BUT-ABSENT for SEC-021's declaration half, and the S5 asymmetry on
dc0's divergently-named headend power key. 27 operator-terminal rows are the
FINDING 1 reproducibility debt, counted not faulted.
Two self-inflicted false-greens found and closed during the build: S2
enumerated only matrix-mentioned sites (an empty matrix read CLEAN -- the
sandbox-fidelity-check.py:131-143 defect one level up; now the union of both
sides, regression-locked by T9), and the uniqueness key false-failed two
identities sharing one file (T6).
NOT done, stated so the boundary is unambiguous: tiers 2-3, vm-secret-locations,
the SEC-009 demotion, and the ruling-1 preflight Pn -- whose blocking-vs-deferred
sequencing is an OPEN operator question. No manifest rewritten; no cloud state
touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|
| 2026-07-25 |

netbox: office1-record dumper (source separation) + current apex snapshot
...
Operator-directed: one dump script per SOURCE so a credential/URL can never be
confused (the token never travels -- read from env).
- netbox/office1-record-dump.py (NEW): READ-ONLY dumper for the office1-netbox
RECORD -- the VR1 working apex (10.10.1.10:8000, 4.6.4, v2 token). This is what
every VR1 system actually consumes (DOCFIX-195) and what the dc0/dc1 buildout
edited -- i.e. the CURRENT in-cloud NetBox state.
- netbox/prod-draft-dump.py: docstring clarified -- it pulls ONLY the FROZEN v1
reference (netbox.baldurkeep.com), not the working apex.
- tests/office1-record-dump/run-tests.sh (NEW): offline harness 5/5 (slim /
prefix-scope rewrite / range key / source-target).
- netbox/draft/vr1-office1-current-20260725.json (NEW): the current snapshot --
139 prefixes / 11 sites (incl. vr1-dc0/dc1/off1), dc1 bands 10.12.64/68/72.0/22
present; differs from the 90-prefix frozen reference. For the Chat design
session (NetBox->deploy coupling) which has no live infra.
READ-ONLY: nothing written to NetBox. repo-lint 0-fail.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|
| 2026-07-24 |

provider-bundle-check: overlay merge + per-DC VIP bands + placement invariants
...
The committee's non-negotiable placement "spine" so the vr1-dc1 render is
machine-checked, not eyeballed. The checker was placement-blind (D-052 bindings
+ mysql=3 only), so any render could silently ship decorative HA.
- --overlay FILE: juju-like merge -> validates the EFFECTIVE deploy input
- --dc vr1-dc0|vr1-dc1: per-DC VIP bands (default dc0 = base; un-param run
byte-identical to before). Closes the dc1-VIP-outside-the-check gap.
- placement invariants (fire only on a role-separated machines block, self-skip
on the base bundle): no dangling to:; LXD->control, ceph-osd->storage,
nova-compute->compute; num_units>=2 spread across that many DISTINCT machines
(anti-affinity); ceph-osd==storage count, nova-compute==compute count.
Harness 15/15 (7 new behavioral cases); gauntlet ALL GREEN (78); repo-lint 0 fail.
Machines-block overlay merge is confirmed at `juju deploy --dry-run` (VERIFY-LIVE).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|

D-135 amendment: DC1 interim apt caching proxy (dc-cache-proxy.sh)
...
Operator-ruled 2026-07-24 (GA-R5, utterance quoted in D-135): DC1 gets an
interim apt caching proxy (apt-cacher-ng) to unblock its build without waiting
on the full ~950 GiB debmirror; DC0 stays the full-mirror deployment under test;
DC1 proxy is replaced by a full mirror afterward. Both artifact-delivery models
thus get exercised this rehearsal (Roosevelt input, D-132/D-133).
- scripts/dc-cache-proxy.sh: site-keyed check/install; apt-cacher-ng proxy mode
at the D-134 utility .4:3142; reuses the <site>-mirror-net layer (fails loud if
absent); caches archive/security/UCA, consumed via juju apt-http-proxy.
- tests/dc-cache-proxy/run-tests.sh: 15 static cases, 15/15 PASS.
- D-135 AMENDED (design-decisions.md) + CURRENT-STATE Stage-4 DC0/DC1 split.
- DC1 debmirror PAUSED at ~330 GiB (kept dormant as fallback); measured that the
vcloud uplink was NOT the shared bottleneck (pausing dc1 did not speed dc0).
Feasibility recon'd read-only first (apt-cacher-ng installable, upstreams 200 via
edge, port free). Live install on the DC1 rack is the separately-gated mutation.
repo-lint 0 fail; gauntlet ALL GREEN (78).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|

caveman: disable on live host + SEC-017 + fail-closed compress guardrails
...
Council-reviewed follow-through on the caveman plugin (operator accepted the
recommendations). Three gated deliverables:
1. DISABLED on the live host: enabledPlugins."caveman@caveman"=false at user
(~/.claude, uncommitted) + committed repo scope; env CAVEMAN_DEFAULT_MODE=off
retained; marketplace kept for deliberate re-enable. Stops the per-turn
third-party hook execution (which ran regardless of mode=off) at next
session start.
2. SEC-017 opened (docs/security-ledger.md): supply-chain re-verify obligation
pinning SHA 0d95a81 + self-remeasured baseline hashes; register = OPS (no
D-number per GA-R3; precedent D-129). Open SEC 12->13, reconciled at Stage 4
close (not an L10 trigger; CURRENT-STATE untouched).
3. Guardrails: repo-lint L11 FAILs on any *.original.md (caveman-compress
residue), opt-out marker + harness T42-T44 (45/45 PASS); .claude/settings.json
deny on Bash(*python3 -m scripts*)+Bash(*caveman-compress*); CLAUDE.md
"Tooling guardrails" prohibiting the compressor against any repo-tracked
prose. Rejected the proposed plugin-hash-baseline-in-repo-lint (layering
violation; drift belongs in the SEC-017 re-verify duty).
Harness-config + governance only; no cloud mutation. repo-lint 0 fail;
gauntlet ALL GREEN (77). Changelog: docs/changelog-20260724-caveman-disable.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|
| 2026-07-23 |
Delivery batch: lib-hosts VR1 arms, D-133 guards, appendix-A pf entry, DoD 8-9 (gauntlet 77 GREEN)
...
lib-hosts vr1-dc0/vr1-dc1 populated from the measured identity table
(tofu-name keys, pinned boot MACs, D-134 octets, per-DC power URIs +
tags) + host_sysid_by_bootmac (the VR1 resolver) + one-selection guard;
dc-selector rewritten, 48 PASS. reenroll-hosts + carve-host-interfaces
gain explicit vr1-* refusals (VR0 flows superseded by D-133 -- populated
arms must not enable them). lib-net vr1-dc0 VID caveat. Appendix-A:
edge pf-never-regenerated symptom (masking trap named). Phase-2 DoD:
items 8 (filter reload + LAN egress probe) + 9 (dc-mirror), item 4
range corrected to D-134 .201-.254. CURRENT-STATE same-commit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|
Mirrors installed both racks, syncs RUNNING; dc1 edge pf incident resolved; HOME fix (harness 19)
...
Item 9: fresh dc1 edge passed no LAN traffic -- pf ruleset never
regenerated after v4 addressing (set-interface reloads the interface,
not the filter; dc0 masked by 07-20 plugin work). configctl filter
reload -> egress 0%/301. Appendix-A + standup-DoD + script amendment
queued to stage close. Item 10: installs PASS 15/15 both racks, first
sync HOME-under-systemd failure fixed in the unit (T19), reinstalls +
syncs running (dc0 400M/dc1 343M in the first minute). Ledger in-flight
entry added; CURRENT-STATE same-commit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|
dc-mirror.sh shipped (D-135 item 1): per-DC apt+UCA mirror, harness 18/18, gauntlet 77 ALL GREEN
...
Site-keyed (dc0/dc1 MEASURED rows), check/install/sync; net layer = D-134
utility .4 alias + default route via the DC edge (egress path MEASURED
working; edge DNS answers). debmirror GPG-verified jammy triple + UCA
caracal, nginx on the utility address, daily timer, niced/idle-IO. Install
fails loud on missing packages with the exact apt line (net-first ordering
resolves the no-egress chicken-and-egg). Gauntlet capture + CURRENT-STATE
same-commit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|
Session bookend: queue-pass CLOSED (ledger summary, changelog archived, scan fix)
...
Bounded GA-R4 close entry; changelog-20260723-queue-pass.md -> docs/archive/
changelogs/; as-executed index row broadened to the window's full scope.
AT CLOSE: ledger-scan false-close defect (detached-amendment status hijack,
D-132 dropped) found by the close reconciliation itself -- fixed number-keyed
with regression cases (48/48; gauntlet 76 ALL GREEN), machine block re-seeded,
scan re-verified truthful. GA-R7 memory review: no changes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|

Queue pass: post-G12 queued findings delivered (5 script/harness fixes + DOCFIX-198/-199)
...
- opnsense-prep-image.sh: survives bash -s (BASH_SOURCE unbound fix; T3b)
- site-headend-install.sh: version/site-neutral hints; nftables-sec010
idempotent reload preamble; serial-log staging dir in --host-nodes (+check)
- opnsense-bootstrap-apikey.sh: sshd readiness wait + first-scp retry +
ssh -n stdin guard + minter-beside-script usage note (T9/T10)
- DOCFIX-198: phase2 runbook Steps 9-10 SUPERSEDED banners (pod route refuted,
D-103/D-123 amendments) + DC standup definition-of-done section (lands the
staging-dir + SEC-016 snap-refresh re-assert DoD obligations)
- DOCFIX-199: D-112(c) console-bootstrap payload requirements (util.inc et al)
Gauntlet ALL GREEN (76); repo-lint 0 fail. Per-item reverts in
docs/changelog-20260723-queue-pass.md. No cloud mutation this session;
queued: gated live re-assert of the nftables-sec010 files on all three hosts.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|
G12 dc1: dc-rack-net.sh dc1 site-table arm + harness (D-131 sub-1)
...
Adds the dc1 arm to the standing per-DC rack-legs + node-DNS forwarder
pattern. MEASURED/apex-committed values, network-name keyed (no virbrN):
- vr1-dc1-metal-admin 10.12.68.2/22 (rack MAAS/DHCP; apex-committed rack IP)
- vr1-dc1-metal-admin 10.12.68.3/22 (forwarder listen alias; D-120 static)
- vr1-dc1-provider-public 10.12.64.2/22 (edge-LAN; measured live 2026-07-23)
- upstream region BIND 10.10.0.20 over transit
Harness T15-T18 added; dc-rack-net 18/18, gauntlet ALL GREEN (76),
repo-lint 0-fail. The forwarder pre-empts dc0's commissioning SERVFAIL.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|
| 2026-07-22 |
G12 dc1 step B COMPLETE: transit live, rack enrolled, SEC-010 both ends, 26.7 staged
...
cloudinit-vm gains interface_macs (node-vm port; harness 10/10) -- voffice1
NIC3 + full MAC pins, vvr1-dc1 pin-adoption, 0/2/0 exact, post-bounce
battery ALL PASS, converged zero diff. Transit .5<->.6 proven with the dc1
key. Rack bootstrap dc1-parameterized via existing flags (dry-run caught the
dc0-flavored defaults); first run exit 4 on stale apt index, re-run exit 0;
region lists vvr1-dc1 (nmpcq4). SEC-010 region end extended to enp3s0.
OPNsense 26.7 base = hash-verified copy of dc0's proven artifact. Named
gate EXIT 0 (docs/audit/dc1-stepB-check-20260722-final.txt). Three queued
findings logged (changelog item 7).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|
G12 dc1: item-3 substrate landed + harness reconcile (gauntlet 76 ALL GREEN)
...
Lands the disconnected session's authored tree (vr1_dc1 vars, vvr1-dc1 +
uplink modules, inner root vr1-dc1-substrate/ with 54 pre-pinned MACs,
lib-net dc1 arm + one-selection guard) and delivers changelog item 4:
six harnesses reconciled to the ratified dc1 selector arm, phase-00
PLANES/lib-net parity guard (exit 2, refuses cross-DC planning),
rbd-mirror + radosgw parent-shell selection (dc1 reminder now shows
10.12.84.0/22, not dc0's). Gauntlet ALL GREEN 76
(docs/audit/gauntlet-20260722-g12-reconcile.txt); repo-lint 0-fail.
G12 next gated step unchanged: operator-gated apex --commit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUjEb7onHpdqFHUnio6iVw
|
| 2026-07-21 |
G12 dc1: apex confirm-free captured; dc-rack-mgmt-import gains per-site (--site) dc1 support
...
Confirm-free vs live apex (read-only): dc1 planes already assigned+consistent,
transit 172.31.0.4/30 + rack 10.12.68.2 free, uplink 172.30.3.0/24 registered.
Importer harness 117/117; live dc1 dry-run preflight PASS (captures committed).
The apex --commit remains an operator-gated step.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VifVpH3XQQxQz8NQ1VxNau
|
cloud-assert A9: vault-kv consumer AppRole auth probe (D-068 item 3 delivery)
...
Delegates to vault-kv-health.sh; skips gracefully pre-Stage-5 (no vault
app). Harness +3 cases (15/15); gauntlet 76 ALL GREEN.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aLU6j24tjquxgYQaAHgsV
|
Stage-close batch: ledger-scan PARTIAL fix; DOCFIX-197; D-103/D-123 pod-refutation amendments; GA-R7 memory review
...
- scripts/ledger-scan.sh: PARTIALLY-RULED decisions now surface (D-131
blind spot); harness regression fixture, 46 checks ALL PASS
- DOCFIX-197: phase2 runbook Step 11 leg selection corrected to executed
reality (dc0<->dc1 leg; office1 leg carries live transit)
- D-103/D-123 amendments + modules/maas-vm-host header: 2026-07-20
measured pod refutation + per-machine-virsh ruling RECORDED (cited to
captures; no new ruling made)
- GA-R7 memory review DONE: no memory-only facts remain
- Read-only: stale MAAS pod object confirmed (id=4 vr1-dc0-inner, virsh)
for the pending retire-or-keep ruling
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013XRtm5sDQgUsZyTJk3k7dz
|

Step E netem DONE -- G10 CLOSED; netem-link local mode; G16 opened (office1 channels residual)
...
- modules/netem-link: optional local execution (empty ssh target -> bare
sudo tc; D-128 outer root runs ON vcloud); NEW tests/netem-link harness
(12 cases); gauntlet 76 ALL GREEN
- outer root: module netem_vr1_dc0_vr1_dc1 wired -- virbr5 (measured at
wire time), placeholder profile 'delay 3ms 1ms loss 0.01%' (S6 lean,
PROVISIONAL; D-100 gap #11 unruled); runbook Step-11 leg divergence
flagged, DOCFIX queued
- 1/1/0 STOP honored; operator RULED 'Targeted netem apply (Recommended)';
saved -target plan exact 1/0/0, applied; qdisc live on virbr5,
virbr7/virbr3 untouched (docs/audit/stepE-netem-20260721.txt +
outer-{plan,apply}-20260721-netem*.txt)
- Convergence 0/1/0 = office1 channels=[] residual only
(outer-plan-20260721-postE-residual.txt) -> split per E3 into NEW gate
G16; CURRENT-STATE section 5 expected plan re-recorded 0/1/0 (GA-R1 C1)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013XRtm5sDQgUsZyTJk3k7dz
|
Step-E netem sudo: scoped NOPASSWD fragment shipped (operator-ruled)
...
scripts/sudoers.d/netem-tc grants exactly the netem-link module's two tc
verbs per measured mesh bridge (virbr5/7/3, re-measured this session;
drifting-ID caveat + fail-closed property documented). 9-case harness;
gauntlet 75 ALL GREEN. Install is operator-only (visudo-checked) and
pending; then the gated placeholder netem run closes G10 step E.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STHXiHfoxHqq8fGRVvb66G
|
dc-rack-net.sh: D-131 sub-1 delivery -- rack legs + node-DNS forwarder, repo-carried
...
Site-keyed (dc0 rows measured 2026-07-21), runs on the rack via piped
ssh. Legs move from reboot-lost bare `ip addr` into a oneshot unit;
bridges resolved from libvirt NET NAMES at runtime (dc-planes does not
pin bridge names -- virbrN is a drifting ID); dns unit Requires the legs
unit. 14-case harness; gauntlet 74 ALL GREEN. Rack install stays gated.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STHXiHfoxHqq8fGRVvb66G
|
node-vm: MAAS owns node power -- ignore_changes on running (operator-ruled)
...
The MAC-pin verification plan (docs/audit/inner-plan-20260721-macpin.txt,
0/9/0, 54 mac adoptions, zero replaces) exposed 9 entangled out-of-band
power-ons: the module re-asserts running=true against nodes MAAS holds
OFF. Operator-ruled: guard first, then apply.
- lifecycle ignore_changes = [running]: create still boots (PXE
enlistment); afterwards MAAS owns power (virsh here, Roosevelt IPMI).
- tests/node-vm +3 cases (guard present, no scope creep, cites MAAS);
15/15 green, gauntlet 73 ALL GREEN, repo-lint 0 fail.
- CURRENT-STATE: MAC-pinning delivery status + pending gated apply.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STHXiHfoxHqq8fGRVvb66G
|
node-vm: pin NIC MACs (54 measured) -- in-place applies can no longer drift them
...
Queued delivery item from the 2026-07-21 commissioning diagnosis: an
"in-place" apply (0/9/0) regenerated all 9 unpinned boot MACs on
2026-07-20 and stranded the fleet in MAAS.
- modules/node-vm: optional interface_macs (all-or-nothing + format
validations); mac = { address = ... } shape verified against the
dmacvicar/libvirt 0.9.8 schema dump this session.
- vr1-dc0-substrate: all 9 nodes x 6 planes pinned to values MEASURED
this session (virsh domiflist on vvr1-dc0); metal-admin entries
cross-checked vs MAAS boot-interface records 9/9.
- NEW tests/node-vm harness (12 cases). Gauntlet 72 -> 73 ALL GREEN;
repo-lint 0 fail; opentofu-validate PASS.
NOT YET APPLIED on voffice1 (inner root state) -- the gated apply's plan
must show NO replace; any replace is a STOP.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STHXiHfoxHqq8fGRVvb66G
|
| 2026-07-20 |
NEW: maas-node-power.sh (+harness 24/24) -- per-machine virsh power, MAC-matched
...
Operator-ruled 2026-07-20 over the pod route. Sets power_type=virsh +
power_address/power_id on already-enlisted machines, matching domains BY MAC
(MAAS renames machines at enlistment, so name matching would map nothing or
the wrong node). Dry by default; every write verified by an actual
query-power-state, since a stored parameter proves nothing about reachability.
Carries the measured reasoning: pods fail on node-vm's pool+volume disks
(domblkinfo 'missing storage backend', reproduced locally), the pod's
discovery role was already done by PXE, and per-node power is the Roosevelt
(IPMI) shape. Gauntlet 72 harnesses ALL GREEN.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KiUu1oqt76tWvV4vEC3NAr
|
FIX false-success: opnsense-plugins.sh apply ALWAYS dry-ran (DRY_RUN:+ expands on 0)
...
Found on the first-ever live run (vr1-dc0 edge, 2026-07-20): ${DRY_RUN:+--dry-run}
expands whenever the var is set and NON-EMPTY, and DRY_RUN=0 is non-empty -- so
every apply silently dry-ran while printing 'OK: profile applied'. Nothing was
ever installed by this script. The harness missed it because every test drove
--dry-run, leaving the live path with zero coverage. Fix tests the VALUE; harness
gains two live-path tests via a stub api client (verified to FAIL 2/2 against the
buggy version before restoring). 20/20.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KiUu1oqt76tWvV4vEC3NAr
|
NEW: opnsense-set-interface-v4 pair (+harness 53/53) -- IPv4 + WAN gateway via the vendor config model
...
Operator-ruled mechanism 2026-07-20 ('Build the v4 setter pair'). Mirrors
the proven v6 sibling: vendor Config singleton (never a config.xml push),
dry-by-default, interface-count guard, fresh read-back verify, sh -s for
the tcsh trap, kernel ground truth. Adds the gateway half (at most ONE
gateway_item, count-guarded) and MEASURES the interface's device from the
edge's own config instead of hardcoding lan->vtnet0 like the v6 sibling.
D-113 amendment RE-MEASURED on 26.7: interfaces/settings/get carries only
offload flags; interfaces/overview/list and interfaces/<if>/get both 404 --
so the amendment holds on two majors. Gauntlet 71 harnesses ALL GREEN.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KiUu1oqt76tWvV4vEC3NAr
|