| 2026-07-19 |

Batch 4 C6: docs disposition -- 24 history docs archived, 16 retained, refs rewritten
...
DISPOSITION MANIFEST (archive, one-line justifications): clientdocs-
workflow-review (v1 tenant-docs era) / D-057-DECIDED-append +
D-057-REVIEW-ITEMS + README-D057-PACK + D-058-renumber (executed v1
decision packs) / D-068-openbao-assessment-DRAFT (supplementary; the
cited analysis retained) / DOCFIX-064-phase08-changelist + docfix-draft-
20260702 (executed/draft) / handoff-20260703 + handoff-20260705
(superseded handoffs) / incident-20260712-triplefault (trap routed to
platform-traps 1b/1c long ago) / netbox-vip-queue + phase-00-maas-
standup-notes + script-quality-findings + session-findings-2026-07-02 +
tenant-cidr-overlap-PLAN + v1-pre-deploy-fixes (v1-era executed/dated) /
repo-lint-nextfree-bug-FINDING (absorbed DOCFIX-105/107; repo_lint.py
pointer updated) / upstream-bug-draft-dashboard-tls (draft, dated) /
model-a-fallback-plan (D-123 Model B adopted; fallback preserved in
archive) / stage3-adversarial-review-20260716 (R3-F register,
dispositioned in 2.10) / dc-dc-replication-DR-seed (absorbed per
workflow) / dc-dc-ipv6-charm-research + dc-dc-netem-and-ula-gua-proposal
(stage 4+ research, refs updated). RETAINED 16 top-level, justified in
the session changelog. Live-surface refs to all moved files rewritten to
archive paths (18 files). G3 cell + ledger + changelog updated same
commit (the L10 fire on a Status-line path rewrite is satisfied by the
CURRENT-STATE touch -- the check worked as designed).
Revert: git revert this commit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZbUeRE8weySLSGY1odrCi
|

GA-F10/H1 + GA-R1/R6: token migration, State-line demotions, E1 type tags (2.5+2.6)
...
Mapping record: docs/audit/h1-token-map-20260719.md -- all distinct
tokens dispositioned, none unmapped. Live-surface migration: workflow
doc (26 flags -> 0; header drops the tracker model, 8 State lines demote
to identity + CURRENT-STATE pointers), runbooks (18 -> 0; close-out
instructions RETARGETED to record status in CURRENT-STATE, not the
workflow tracker), readiness doc (5 -> 0), CURRENT-STATE itself (6 -> 0:
G9 STOPPED -> BLOCKED with named blocker; stale "GA-R1 NOT yet ratified"
header + pre-D-130 divergence rows corrected per C2). Gate rows gain
GA-R6/E1 type tags ([V]/[R]) with legend. CLAUDE.md expectation line
demoted per S5b. History classes (ledger, changelogs, design-decisions)
deliberately untouched -- their disposition is Batch 4/GA-R3 structural.
Extractor re-run: zero flagged occurrences on live non-history surfaces.
Batch 2 items 2.5 + 2.6.
Revert: git revert this commit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZbUeRE8weySLSGY1odrCi
|
| 2026-07-18 |

D-129 partial-rule: adopt VR1 edge plugin profile + pin the rest at deploy steps
...
Operator directive 2026-07-18 ("install the recommendations + pin the rest").
Doc/runbook-only; the LIVE install is operator-gated (auto-mode classifier
blocked the agent POST) and pending verification -- no cloud mutation here.
- D-129 PARTIALLY RULED (status line kept OPEN so ledger-scan still tracks the
4 sub-decisions: COS-edge scope, os-frr, os-tailscale, edge-NTP). VR1 profile
{os-qemu-guest-agent, os-iperf} adopted; pinned-at-steps mapping added.
- dc-dc-phase2 (DC-edge section): pin the VR1 profile at edge bring-up + build
the reusable opnsense-api profile-installer there.
- dc-dc-phase6 Step 10: pin os-node_exporter gated on the COS-edge scope call.
- vr1-office1-as-built: FreeBSD base 14.3->15.1 recorded; directed plugins noted.
- session-ledger + machine block synced.
Revert: git revert this commit; nothing was installed/applied on the cloud.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUBUyinU4sBAT4HV1b9vSz
|
| 2026-07-14 |

D-119: region-qualify the VR1 DC namespace -- C3 / gap #19 CLOSED (Stage 3 unblocked)
...
THE BUG: the token `dc0` meant TWO DIFFERENT CLOUDS depending on the file --
VR0's LIVE testcloud in scripts/lib-net.sh, VR1's FIRST DC in the NetBox
importer. One string, two clouds, one of them in production.
THE RULING (operator): the repo adopts the apex's names verbatim.
vr0-dc0 VR0's DC0 the LIVE testcloud (a DIFFERENT region)
vr1-dc0 VR1's FIRST DC GUA 2602:f3e2:f02::/48
vr1-dc1 VR1's SECOND DC GUA 2602:f3e2:f03::/48
Bare dc0/dc1/dc2 are now REJECTED LOUDLY everywhere.
D-119 COMPLETES D-117, it does not reverse it: it executes D-117's own amendment
across the three surfaces D-117 never touched. ZERO NetBox writes -- the apex was
already correct and self-consistent (MEASURED: f02::/48 -> vr1-dc0, f03::/48 ->
vr1-dc1); the REPO was the only surface out of step. Renaming the apex to match
the repo was considered and REJECTED (production IPAM write; VR1 would become the
only 1-indexed region; and vr1-dc1 would mean VR1's FIRST DC while vr0-dc1 means
VR0's SECOND).
THE PRIZE: the importer's DC->site map is now an IDENTITY -- there is no offset
table left to get wrong, and an assert enforces it. The original defect was
precisely a WRONG LOOKUP TABLE. The bug class is deleted, not defended.
TWO REAL BUGS the naming fix ALONE would NOT have closed (found by review sweep):
- BREAK-1: descriptions were built with f"VR1 {dc.upper()} ..." -- under D-119 that
renders "VR1 VR1-DC0 provider-public" on all 36 prefixes. Same class as the
original bug (deriving a label by munging a token), hidden in the description
field where slug-focused review missed it. Now looked up from SITES[name].
- BREAK-2 (the important one): DC_GUA_PREFIX was NEVER cross-checked against --dc.
`--dc vr1-dc0 DC_GUA_PREFIX=<f03>` was ACCEPTED: it writes the SECOND DC's GUA,
carved with the FIRST DC's ULA nibble, scoped to the FIRST DC's site -- a
silently mis-bound datacenter assembled from two disagreeing sources. Identity-
mapping the slug leaves the ADDRESSING free-floating. Now guarded by EXPECTED_GUA.
ALSO: vdc1/vdc2 -> vvr1-dc0/vvr1-dc1 (D-114 amendment). D-114's own DR primitive is
`virsh destroy vdc1`, which read as "destroy VR1 DC1" while MEANING "destroy VR1
DC0". A mislabelled destroy command in a DR drill is not cosmetic. Neither VM is
built, so it is free. voffice1/Office1 KEEP their number (operator ruling).
Env var: DC1_/DC2_V4_SUPERNET -> VR1_DC1_V4_SUPERNET (both old names rejected).
rbd-mirror's --site-name aligned: `--dc vr1-dc0 --site-name dc1` was a re-created
two-namespace collision on one command line.
TESTS: dc-selector 21->30, prefixes-import 40->82 (identity invariant; EXPECTED_GUA
in BOTH mismatch directions; mismatched run writes NOTHING; matching pair still
succeeds; no munged description). GAUNTLET ALL GREEN (57). repo-lint 0 fail.
The old harnesses PINNED THE WRONG MAPPING -- they would have gone green while
enforcing the bug.
THE tofu apply IS NOT DONE -- IT IS GATED. Plan: 11 to add, 0 to change, 11 to
destroy (libvirt object names are ForceNew; moved{} makes the plan reviewable but
cannot suppress a replace). MEASURED SAFE: all 11 are EMPTY -- no guests, no
volumes, Stage 3 hasn't run. Office1's live objects are not in the plan.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
| 2026-07-10 |

DOCFIX-167: bundle.yaml -- Designate reactivation + D-108 DR mechanism (gaps #6+14)
...
Adds designate/designate-bind/designate-mysql-router/designate-hacluster
(D-106, supersedes D-019) and cinder-backup/ceph-rbd-mirror (D-108) to
bundle.yaml -- the same file this repo's jumphost uses against the live
VR0/DC0 rehearsal cloud, edited with corresponding care. Every new charm's
relation/binding shape was checked against its real metadata.yaml, not
guessed: caught and fixed three mistakes this way during self-review
(designate's real endpoint is dnsaas, not public; cinder-backup is a
subordinate with no amqp relation; ceph-rbd-mirror needs ceph-local/
ceph-remote, not a single invented binding key). Corrected ceph-mon's
rbd-mirror binding from storage to replication. Documents, rather than
invents, that ceph-remote (the peer DC's ceph-mon) needs a cross-model
relation or the manual CLI flow -- D-104's per-DC-independent-controller
design means it can't be a same-bundle relation line. Deliberately does
NOT reactivate os-public-hostname in this shared bundle (pushed to a
proposed per-DC overlay instead). Bundle parses clean (56 apps, 108
relations); provider-bundle-check.py PASS, all invariants unaffected.
Not applied to any live model.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QrcJx8TUar7pYAvpGJw57A
|

DOCFIX-157/158/159: Stage 4/6/7 runbooks -- MAAS deploy, DR drill, Designate/COS/Magnum
...
Completes all seven Stage 1-7 DC-DC runbooks (tooling gap register item #9
CLOSED):
- Stage 4 (MAAS enlist/commission/deploy, per DC): adapts phase-00's
validated single-rack sequence per DC. Mandates the $DC selector
convention (DOCFIX-151) and honestly documents that lib_hosts_select_dc
will keep failing until this stage's own enrollment populates real host
data. Names 7 real multi-rack gaps rather than working around them.
- Stage 6 (DR wiring and failover drill): implements Section 8's
failover/failback skeleton, one-way-then-two-way per D-108. Found three
real bundle.yaml gaps (missing cinder-backup/ceph-rbd-mirror charms,
wrong-plane rbd-mirror binding) and makes fixing them the runbook's own
first gated step. Includes a negative-control drill before the real one.
- Stage 7 (Designate, COS, Magnum/CAPI): quotes the bundle's actual
current "NO designate" text before describing the D-106 reversal;
identifies the reversal also affects the bundle's separate
os-public-hostname posture; leaves COS's mechanism as an operator
decision rather than inventing one.
Four new tooling-gap-register items (#12-15) added for cross-cutting
findings this runbook-authoring pass surfaced. None of the seven runbooks
have been executed against real infrastructure yet -- prep-only session.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QrcJx8TUar7pYAvpGJw57A
|