| 2026-07-29 |

Per-DC Octavia PKI generated: independence proven, identity unverified, 12 real findings
...
The mint was operator-executed on the headend; the session guard hard-blocks it and that was
not worked around.
PER-DC INDEPENDENCE PROVEN, which is the whole point of F1. Both DCs hold 12 files across 3
dirs, and sha256 DIFFERS between DCs for both encrypted CA keys, the controller cert and the
overlay. Before F1 those columns would have been identical, because the second generation would
have overwritten the first. Both overlays are mode 600, carry exactly five lb-mgmt-* keys, are
ASCII clean and are gitignored -- the F4 gate held.
NOT CLAIMED AS DONE: the four CA subjects, the controller SAN sets and the chain verifications
are unread, because the guard blocks openssl against those paths. Recorded as structurally
complete with identity unverified. A cert can be well-formed and name the wrong DC.
P5 on the headend went 6 -> 18 findings and all 12 new ones are genuine.
E2 x4: the CA certificates are mode 664. This session had explicitly called that harmless "for
public certs", reasoning only about confidentiality. That was wrong -- 664 is group-WRITABLE, so
a group member can replace a trust anchor. Integrity, not secrecy, is the exposure.
E3 x8: four generator outputs per DC (the controller certificate, the CA serial file, the
openssl config and the signing request) exist with no matrix row. The 18-row set landed earlier
today was incomplete -- "enumerate what exists, not only what is declared", applied to this
session's own work.
Validation worth recording: all 12 would have been INVISIBLE before today's F2 and F6 fixes,
since the rows were singleton and the locations resolved on the jumphost. The register found
real defects in exactly the mint it was repaired to observe.
F8: the controller-cert step's heredoc is a live paste hazard -- the operator hit it. An
indented terminator can yield a config with no alt_names section, producing a certificate with
NO SANs while every step still reports OK, and nothing asserts the SAN set.
F9: the controller certificate's DNS SANs are coupled to D-106 and nothing recorded it. They
are inert only because os-public-hostname is set nowhere (B5 IP-ONLY; R5 refused setting it at
Stage 5 as a D-019 repeat). When Stage 7 turns FQDN endpoints on, both DCs' certificates
carrying dc0.vr0 becomes wrong exactly when it starts mattering; likely disposition is reissue
inside D-106's own FQDN-SAN step.
Remediation logged not executed: tighten the six certificate modes; and for E3 either declare
all four artifacts per DC or have the generator drop the two build intermediates and declare the
two that must persist.
repo-lint 0 fail.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

F7: office1-tailscale is labelled a subnet router and advertises no routes
...
Raised from an operator report of Permission denied (publickey) reaching voffice1 "from my
workstation via tailscale". Measured rather than assumed, and the premise did not survive.
tailscale is absent from BOTH voffice1 and vcloud -- no binary in any standard location, no
state dir, no interface, service not running. Checked with explicit path probes after an
initial `command -v`, because tool-absent-from-PATH reported as feature-absent is a trap this
repo has hit repeatedly.
The tailnet node is a separate LXD guest INSIDE voffice1: office1-tailscale, RUNNING,
100.64.0.53, site leg 10.10.1.11. Its tailscale status reports AdvertisedRoutes: <none>. So
nothing on the tailnet can reach 10.10.0.20 -- there is no route and there never was.
Two records made the false belief look supported: the ssh stanza labels it "Office1 subnet
router (D-107)", and the operating skill's routing table says the workstation reaches voffice1
over the tailnet, citing D-107 -- which is titled "Airgap posture, per-DC artifact mirror, and
NTP (VR1)" and rules nothing of the sort. A real citation that does not support its claim.
RULED (operator): option (a), ProxyJump through vcloud. Option (b), advertising 10.10.0.0/24
onto the tailnet, was presented and not taken -- it exposes the isolated site net, a posture
change against the airgap subject D-107 actually governs.
Fixed operationally outside the repo: vcloud's ssh config now matches Host voffice1 10.10.0.20,
so the raw IP resolves to the office1 service key with IdentitiesOnly yes instead of falling
through to the id_* defaults, which was the actual cause. Both forms verified, with a negative
control proving the key is not offered to unrelated hosts.
Third wrong record this session, after D-124's MAC-sourcing instruction and the skill citation.
Two of the three surfaced only because something adjacent was being fixed; nothing here gates
prose, so no check could have caught them.
repo-lint 0 fail.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

Five Stage-5 findings raised, none executed: R7's per-DC Octavia PKI is half built
...
F1 (HIGH): the D-109 amendment rules per-DC independent Octavia CAs, and the
2026-07-29 work correctly made the CA subject and the VIP gate per-DC -- but $DC
appears in no PATH. phase-01-bundle-deploy.md:293 is a fixed $HOME/octavia-pki and
:473 writes a fixed overlays/octavia-pki.yaml, so generating dc1 after dc0
overwrites dc0's issuing-CA key, controller-CA key and both passphrases, and a
later dc0 redeploy reads the fixed overlay name and applies dc1's CA to dc0 -- the
cross-DC shared amphora root R7 explicitly refused. The existence checks at
phase-01:86 and pre-flight-checks.sh:65 cannot detect it: they ask whether the file
exists, never whose CA it is. The gap is in R7's own "Work implied" list.
F2: creds-matrix.tsv:103-111 declares all nine Octavia credentials `singleton`,
while creds-matrix.py:368-398 enforces both-DC existence only for `per-DC` rows --
so the register behind the BLOCKING P5 gate is structurally blind to a missing
second PKI set. Baseline captured (82 rows, 7 findings, exit 1) so the delta is
attributable. Must land before generation.
F3: both ~/octavia-pki/ and overlays/octavia-pki.yaml are ABSENT (existence only,
no contents read), so F1/F2 are fixable at zero risk right now; the window closes
when the first DC's PKI is generated.
F4: .gitignore:40 is an exact path, so a per-DC overlay rename would un-ignore a
file holding CA key blobs plus a plaintext passphrase, in a repo SEC-004 records as
PUBLIC. The F1 fix must widen the glob in the same commit.
F5: preflight.sh:99 sets DC without exporting it and pre-flight-checks.sh never
reads DC at all, so a dc1 invocation runs a DC-aware P2 beside a dc0-frozen P4
under one combined verdict.
Logged not executed per hard rule 1. repo-lint 0 fail / 615 files.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|