ANALYSIS + RECOMMENDATION PACKAGE, NOT A RULING. This file mutates no authoritative surface (no design-decisions.md, no security-ledger.md, no CURRENT-STATE.md, no live infra). It exists so the operator can see the entire open-item backlog in one place, judged against the project's current state and the hardened end goal, and rule/schedule from there. Every recommendation is a candidate for a gated exchange (GA-R5 for rulings, presented-and-approved for record edits).
docs/CURRENT-STATE.md (status authority, top section in full); docs/security-ledger.md (all 28 open rows in full); docs/design-decisions.md D-068/131/132/139/140/141/142 blocks + the D-134 amendment index; scripts/ledger-scan.sh (method); runbooks/dc-dc-teardown-rollback.md (credential-gate section C.5); docs/audit/reip-1013-ga-r5-ruling-prep-20260808.md (Section A).Two things define the yardstick for this review; nothing below is judged in the abstract.
The hardened end goal (from CURRENT-STATE section 1, the standing pivot).
10.13.0.0/16 because 10.12.0.0/16 collides with the live IPv4 cloud (vr0-dc0).The three horizons the open items actually retire against. Almost none of the backlog is "do it now." Reading every open row, each retires at one of:
Bottom line up front: the open-item backlog is overwhelmingly correctly deferred. The review's job is to confirm those deferrals still hold under the re-IP end goal, and to surface the small number of items that (a) genuinely gate the end goal, (b) become actionable because of the re-IP, or (c) are stale/superseded records that should be reconciled. Exactly one open item actually blocks the end goal: the re-IP GA-R5 ruling (Section 1). Everything else is schedule, hygiene, or Roosevelt.
This is not on the D/SEC/DOCFIX/BUNDLEFIX lists yet -- it is an owed ruling with no number -- but it is the item that gates the hardened end goal, so it leads.
10.12.0.0/16 to 10.13.0.0/16. It is a D-115 supersession (D-115 rejected 10.13 and set the Cloud role to 10.12) and it terminates D-101's "vr1-dc0 inherits vr0-dc0 v4 unchanged" clause. Ruling-prep package is complete and read-only: docs/audit/reip-1013-ga-r5-ruling-prep-20260808.md (decision reconciliation D-101/115/124/134, measured blast radius, the 3 owed live-free checks). Draft mapping: octet-preserving 10.12.a.b -> 10.13.a.b.RECOMMENDATION R1 (HIGH -- the gating action): complete the 3 live-free checks, then present the GA-R5 re-IP ruling as D-143 (grep next-free again at ruling time per the prep doc). Sequence it as: dc0 checkpoint wrap-gates complete -> re-IP ruling -> teardown (with the revocation checklist of R7) -> redeploy on 10.13.
LIVE STATUS OF THE 3 OWED CHECKS (measured this session, operator authorized live discovery -- full detail in the Appendix):
10.0.0.0/8 aggregate.office1-tailscale node): PASS. No approved subnet route overlaps 10.13.0.0/16 (only generic exit-node 0.0.0.0/0). Positive control is decisive: the run shows the exact 10.12 collision that caused the pivot -- vopenstack-jesse-tailscale (the live VR0 cloud) advertising 10.12.4.0/22 + 10.12.8.0/22. 10.13 is also clear of Roosevelt (10.17.x), willamette (10.1/10.16), and Office1 (10.10) on the shared tailnet. Blind spot: this is the approved (AllowedIPs) view from one node; an advertised-but-pending view needs the Headscale server itself.vopenstack, logxen's cloud) is a separate trust domain reachable only over the tailnet, which vcloud is deliberately not joined to (the STOPPED tailscale workstream -- installing it would be a mutation and is out of scope). Best available evidence: VR0 advertises nothing in 10.13 on the tailnet.All five open decisions are deferred by design; none is a defect and none blocks the checkpoint. Summary judgement per decision:
dc-rack-net.sh). sub-4 OPEN: Roosevelt shape (same forwarder / region-DNS-over-WAN+firewall exception / wait for the upstream MAAS fix + minimum version), gated on the Launchpad outcome; carries a PINNED architectural review (best-practice + security + vendor-config) for next-deployment design time.dc-rack-net.sh install re-runs as standup DoD on the 10.13 addresses (it is already in the standup definition-of-done, so this is a checklist confirmation, not new work)..6). q2 (rack-top controllers deferring to the site region) and q3 (cross-site backup custody) OPEN, pinned to Roosevelt.-m openstack targets a non-existent VR1 model; filed as F13).D-items NOT open but worth a note re: the end goal (no manufactured contradictions):
ipv6-primary-posture standing note). No change.overlay_ip_version=6) is an input to the 10.13 redeploy, tracked in the root-cause record -- not an open decision.The rows are not equally urgent; grouping them by what event closes them is the useful lens. The buckets below partition all 28: 3a=10, 3b=8, 3b'=3, 3c=3, 3d=3, 3e-watch=1 (SEC-024) = 28. (This partition was corrected after an advisor catch -- the first draft asserted "sums to 28" while only accounting for 24; SEC-003/015/016/024 were unplaced.)
These live on the Office1 headend / vcloud jumphost, which the DC redeploy does NOT tear down. They stay on the v1-close schedule and the re-IP changes nothing about them. (10 rows: SEC-001, 003, 004, 005, 006, 007, 008, 013, 020, 025.)
admin + operator) -- rotate both; stale-copy hazard between voffice1:/root/maas-secrets/admin.pass and the vcloud copy.These live on the dc0 rack / dc0 region VM / dc0 edge / dc0 node power path -- exactly the substrate being torn down and rebuilt on 10.13 (residency MEASURED live this session, Appendix item 5). Each is re-minted fresh at redeploy; the OLD material must be revoked as part of teardown. This is the review's key "superseded by project state" finding for SEC. (8 rows: SEC-012, 014, 018, 026, 027, 028, 029, 032 -- all dc0.)
opnsense-api.txt).runbooks/dc-dc-teardown-rollback.md has a credential gate (C.5, region-scoped) that ensures creds work for a rebuild -- it does not carry a revocation checklist for the material being abandoned at teardown. So today's teardown path would tear down the substrate and leave the old DC-resident keys/tokens live.Important scope boundary the advisor flagged: these are dc1 credentials, but dc1 was never built (0 machines in vr1-dc1-region, held) -- so there is no dc1 substrate to tear down, and R7's teardown-revocation does NOT cover them. They sit on persistent hosts (vcloud / voffice1 -- SEC-016's headend key was MEASURED at voffice1:~/vr1-dc1-creds/vr1-dc1_svc_ed25519 this session) and retire at v1 close. (3 rows: SEC-015, 016, 019.)
*-creds/ stores on voffice1, structurally invisible to creds-audit (no remote capability) -- coupled to the D-137 --remote fork (unruled).~/admin-openrc from phase-03-admin-openrc.sh, matches no sprawl glob) -- becomes live when Stage-5 phase-03 runs.~/admin-openrc exposure fires the moment phase-03 runs on the checkpoint (Stage-5 is open now). Two cheap, D-137-independent fixes: widen the sprawl globs to cover admin-openrc/*.apikey/*.pem/*_ed25519, and consolidate ~/admin-openrc by hand at mint time. Do the by-hand consolidation whenever phase-03 runs; schedule the glob widening + the D-137 --remote fork (SEC-022) as post-checkpoint hardening, not now.These are places where the record lags project state -- exactly the "superseded by project state" the operator asked for.
opnsense-api.txt now exists on both the jumphost and the dc0 rack (measured this session). BUT the live creds-matrix.py run shows S2 vr1-dc0 dc0-edge-api EXPECTED-BUT-ABSENT is STILL a FAIL -- the derived manifest (creds-manifests/ vr1-dc0.manifest) was never regenerated to declare it. (My first draft overstated this as "E1 now CLEAN / effectively resolved"; the measurement corrects it, and SEC-032 item (2) already flagged the manifest-regen as owed.) RECOMMENDATION R11 (revised): regenerate the dc0 manifest (creds-matrix.py --render) to declare the now-present opnsense-api.txt, which clears the S2 finding; and refresh SEC-021's text so (a) reads "access closed by SEC-032; manifest declaration owed," (b) still open.creds-matrix.tsv:76 note n-dc0-edge-api-absent + creds-matrix-notes.md:123 are factually STALE -- they assert the dc0 edge API cred is absent; it now exists (SEC-032). SEC-032 itself flags this. RECOMMENDATION R12: replace the note wording with the new invariant (never delete the row to go green -- the note says so).:3984, :4251-4253), and Stage 4 is long closed. The "reconciles at Stage 4 close" deferral in SEC-017/020/023 never happened as written and is now moot. RECOMMENDATION R13: drop the stale G14 count-note clauses from those SEC rows (the count now lives correctly in CURRENT-STATE per GA-R1). Pure hygiene..backup at 0664; the mode defect is fixed and retention was RULED "Keep both" (2026-07-27), so this is a WATCH, not an open remediation -- the umask cause was out of ruled scope, so a future tofu apply may rewrite 0664 and P5 is the detection. End-goal note: the 10.13 redeploy rebuilds the OpenTofu state from scratch, so the specific 0664 files retire then -- but the umask cause rides along unless fixed, so it will recur on 10.13. No action recommended now (ruled watch); worth a one-line umask check when the 10.13 tofu roots are first applied.Framing corrected after an advisor catch + re-measurement on the host that counts. The 2026-07-30 acceptance capture (stage5-preflight-dc0-20260730.txt, on voffice1) = 101 rows / 19 clean groups / 6 findings. The matrix then grew 101 -> 121 rows by design on the same day via the SEC-027/028/029 mint commits (c664f4f, 4a78a28, d870d76), which registered the new per-DC region/juju/PKI credentials. Re-running P5 exactly as preflight does (creds-matrix.py --tier2) on voffice1 this session (clone verified at 6aae475 == HEAD, not stale): FAIL, 121 rows, 19 clean groups, 11 findings. The delta vs the accepted 6 is +5, and all 5 are dc1 forward-register S2 rows (SEC-027 region-admin/api-key/db + SEC-028 juju-apikey/user). They FAIL by design -- dc1's region does not exist (dc1 held) -- and SEC-028 already records they are "NOT covered by the operator's 2026-07-30 P5 acceptance" and "must NOT be deleted to go green." They self-clear when dc1's region is built at the 10.13 redeploy. So the correct statement is "the matrix grew as designed; the gate expanded by 5 by-design forward-register rows," NOT "the gate silently grew and you now face 12."
opnsense-api-rebuild-20260807.txt (dc1 edge API token, 2026-08-07 rebuild) sitting in no matrix row. voffice1's P5 does NOT see it -- it correctly refuses to probe jumphost-local paths (E0 ... NOT PROBED), so this is not a P5-gate finding; it is a real jumphost-local hygiene item of exactly the class SEC-022/023 warn about (an undeclared secret the gate structurally cannot see without --remote).opnsense-api-rebuild-20260807.txt on the jumphost -- DECLARE it (one matrix/manifest row). Do NOT shred it without first proving it superseded. The filename and SEC-031's closure note (the 2026-08-07 dc1 edge rebuild sequence was "console bootstrap -> API mint -> addressing") indicate this is very likely the live dc1 edge API credential -- unlike SEC-032's dc0 case, where the rebuild destroyed the config.xml holding the old hash and made that file provably dead. If the operator wants it gone, the disambiguator is a live auth-test against the dc1 edge (status-only, secret never printed); shred only on a proven-dead result. Never weaken a row to green the gate (standing rule). None of this blocks the checkpoint.ledger-scan.sh): DOCFIX and BUNDLEFIX are applied-at-creation operational items (GA-R3 [OPS]: a runbook edit / session-changelog line / as-built row). There is no persistent open DOCFIX/BUNDLEFIX register -- the scan only computes next-free (DOCFIX-214, BUNDLEFIX-059). A DOCFIX/BUNDLEFIX is closed when written.docs/audit/queued-findings-*.txt F-registers. These carry items explicitly held for later (e.g. F13 = the D-142 R1 model-target defect; the phase-03/06 F-CV items were RESOLVED 2026-08-06 via BUNDLEFIX-056/057/058). Recent BUNDLEFIX activity (053-058) is all bundle binding/HA-chain corrections, applied and harness-covered.queued-findings-*.txt F-items to confirm none is a silent precondition for the redeploy (F13/D-142-R1 is the known live one; it is captured in Section 2 R6). No standalone DOCFIX/BUNDLEFIX item is open or superseded in a way that needs action now.netbox/README.md:49 -- stale importer default VR1_DC1_V4_SUPERNET=10.13.0.0/19 (pre-D-115; D-115 moved dc1 to 10.12.64.0/19). Confirmed present.tests/dc-rack-mgmt-import/test_logic.py:265 -- a LIVE test literal 10.13.0.5 (--rack-ip), mirrored in docs/archive/stage3-review-base.patch:3667. Confirmed present. The 10.13 subnetting draft MISSED this one.10.13.0.0/16 as the Cloud /16 gives 10.13 a THIRD in-repo meaning and puts a rack-IP test fixture INSIDE the new Cloud space. Reconcile both literals as part of the re-IP change (a DOCFIX folded into the D-143 work), so the three meanings do not confuse a future reader or a test.Consolidated answer to the operator's explicit ask:
n-dc0-edge-api-absent matrix note is stale (R12); the SEC "G14 reads 12" count-notes are stale (R13).| # | Priority | Item | Action | Horizon |
|---|---|---|---|---|
| R1 | HIGH (blocker) | re-IP ruling | 2/3 live-free checks now PASS; run VR0-internal or accept -> present GA-R5 as D-143 | before teardown |
| R7 | HIGH | teardown revocation gap | add DC-cred revocation checklist (residency measured this session) to teardown runbook | with re-IP |
| R15 | LOW/MED | P5 now 11 not 6 (LIVE, voffice1) | note the +5 as by-design (self-clear at dc1 redeploy); declare/shred the off-gate undeclared jumphost token | before citing P5 accepted |
| R16 | LOW | 10.13 naming collisions | fold netbox/README.md:49 + test literal 10.13.0.5 DOCFIX into the re-IP |
rides R1 |
| R8 | MEDIUM | SEC-006 burned token | present revoke-now vs keep completion-deferral | any time |
| R10 | MEDIUM | SEC-023 ~/admin-openrc |
by-hand consolidate at phase-03; widen sprawl globs | phase-03 run |
| R6 | LOW | D-142 R1 defect + R2 Q | fix -m model-target before next Vault init; put R2 to operator |
before 10.13 Vault |
| R11 | LOW (hygiene) | SEC-021(a) | regen dc0 manifest (S2 still RED -- measured); refresh SEC-021 text | batchable |
| R12 | LOW (hygiene) | stale matrix note | replace n-dc0-edge-api-absent wording |
batchable |
| R13 | LOW (hygiene) | stale G14 count-notes | drop from SEC-017/020/023 | batchable |
| R14 | LOW | F-register sweep | one pass before teardown | before teardown |
| R2/R3/R4/R5/R9 | DEFER | D-068/131/132/140 + accepted SEC postures | confirm deferral, no action | Roosevelt / v1-close |
Honest framing for the operator: the backlog looks large (5 open D + 28 SEC) but is almost entirely correctly deferred. The real content of this review is four things: the re-IP ruling (R1) is the only thing gating the end goal; the teardown revocation checklist (R7) is a genuine gap the re-IP makes actionable; a handful of near-term credential traps (R8, R10); and a small batch of stale-record hygiene (R11-R13). Everything else is "confirm the deferral holds."
All read-only. No live mutation. Credential dirs listed with ls only (contents never read -- the guard-hook rule). Captures in $CLAUDE_JOB_DIR/tmp/ (apex dump, tailnet json).
office1-record-dump.py, from vcloud, record env sourced (token never printed): 152 prefixes / 5 aggregates / 27 ranges / 194 IPs dumped. 10.13.0.0/16 = 0 objects; 10.12.0.0/16 = 149 (positive control). Aggregates present: 10.0.0.0/8, 172.16.0.0/12, 23.157.124.0/24, 2602:f3e2::/36, fd50:840e:74e2::/48 -- 10.13 nests under 10.0.0.0/8 with no collision.office1-tailscale (tailscale status --json, v1.98.9): 17 advertised/approved subnet routes. Overlapping 10.13.0.0/16: only 4x 0.0.0.0/0 exit-node adverts (not a subnet collision). Overlapping 10.12.0.0/16 (control): those 4 PLUS 10.12.4.0/22 + 10.12.8.0/22 from vopenstack-jesse-tailscale -- the live VR0 collision, reproduced. Other projects on the tailnet: Roosevelt 10.17.4.0/22/ 10.17.8.0/22/10.0.0.0/24, willamette 10.1.0.0/24/10.16.0.0/24, Office1 10.10.0.0/22. None touch 10.13.10.12.64.1:22 unreachable from vcloud; no VR0 openrc/juju/clouds.yaml on vcloud; juju/tailscale not installed on vcloud. VR0 is tailnet-only, separate trust domain -> check #3 deferred to an operator workstation run.6aae475 == HEAD; run as preflight does, creds-matrix.py --tier2): FAIL, 121 rows, 19 clean groups, 11 findings (6 accepted + 5 dc1 forward-register, all by-design; detail Section 3f). The 07-30 baseline capture was 101/19/6; the matrix grew 101->121 by design (SEC-027/028/029 commits). A separate vcloud run (--all --tier2) additionally surfaced the off-gate undeclared opnsense-api-rebuild-20260807.txt (jumphost-local; voffice1 does not probe it). Also corrects the draft's SEC-021(a) claim (Section 3e): S2 dc0-edge-api is still RED (host-independent matrix-vs-manifest check -- manifest regen owed).~/vr1-dc0-creds/: maas-virsh_ed25519, vr1-dc0_svc_ed25519{,.pub}; ~/vr1-dc1-creds/: vr1-dc1_svc_ed25519{,.pub} (SEC-022 shadow stores, confirmed).~/vr1-dc0-creds/: maas-juju-api-key.txt, maas-virsh_ed25519{,.pub}, opnsense-api.txt, vr1-dc0-edge_ed25519; ~/.local/share/juju/ full client store (credentials.yaml, accounts.yaml, ...); ~/repo-stage/overlays/vr1-dc0-octavia-pki.yaml (+ machines, vips). This is the DC-substrate material R7 must revoke at teardown./var/snap/maas/current/root/.ssh/: id_dc0_power, config (snap-side power key, SEC-016-class); ~/vr1-dc0-creds/ empty (region secrets were consolidated to the jumphost/rack, not kept on .6).juju from the dc0 rack, D-138): controller vr1-dc0-controller (3.6.27), model vr1-dc0 = 66 machines / 104 cores / 162 units, available -- matches CURRENT-STATE. The end-goal "checkpoint" frame is live-accurate.(Terminology note, RESOLVED 2026-08-09. The two advisory passes on this review used the advisor() tool, which was configured as Opus 5 at the time -- confirmed by the operator, who then moved the advisor to Fable 5 (/advisor output in-transcript). Earlier drafts mislabelled it "the fable advisor" following this repo's inherited memory convention; that was wrong (it was Opus 5). Do NOT retro-label these passes as Fable. "The advisor" = the advisor() tool; name a model only when its configuration is confirmed.)
The review ran two adversarial advisor passes over the same items. The value of the structure is that the corrections are RECORDED, not that the final list looks clean.
Pass 1 -- what the advisor caught, and what changed:
creds-matrix.py --all --tier2 run on vcloud. The accepted-6 baseline was measured on voffice1 (the D-128 host whose P5 reading counts) and without --remote. Re-measured on voffice1 (clone 6aae475 == HEAD): 11 findings, and the matrix grew 101->121 rows BY DESIGN (SEC-027/028/029 mint commits). The +5 are all dc1 forward-register rows that fail S2 by design. The framing inverted -- from "the gate silently grew" (which manufactures a decision, this project's named failure mode) to "the gate expanded by 5 by-design rows." The 12th item (the undeclared opnsense-api-rebuild token) is a vcloud-local, off-gate hygiene item, separated out.netbox/README.md:49, tests/dc-rack-mgmt-import/test_logic.py:265) were in the ruling-prep output but not carried forward -> added as R16, tied to R1.Pass 2 -- what the advisor caught on the corrected draft, and what changed:
CONSENSUS -- the agreed final position (both reviewers):
Standing-discipline note: every recommendation here is a candidate for a gated exchange (GA-R5 for the re-IP ruling and any SEC-row edit; presented-and-approved for the DOCFIX and manifest regenerations). This document rules nothing and mutates no authoritative surface; it is the decision package for the operator. It does not reopen the "proceed to deploy" directive -- it front-runs the re-IP that the checkpoint's own plan requires.