Trigger: operator asked for a full health/status sweep after the vcloud host patch+reboot, which surfaced a recurring Office1-access break; the fix + operating-model ruling are recorded here. Branch dc-dc-stage3-phase2-dc-substrate. Live-host UNIT INSTALL is still PENDING (operator sudo) -- see below.
The vcloud HOST completed its bookend patch+reboot: running 6.8.0-136, apt upgradable = 0, no reboot-required. Libvirt recovered clean (12 nets + 4 pools active/autostart; voffice1 + office1-opnsense autostart=enable, both RUNNING). Autostart chain proven end-to-end -- all guests + the edge reported ~3h37m uptime matching host boot, i.e. virsh autostart -> LXD boot.autostart self-recovered the whole Office1 stack with zero manual start. In-guest (after access restore): opnsense pf Enabled/80 rules, kea-dhcp4 on 10.10.0.1:67, vtnet0/vtnet1 active, LAN+egress OK; office1-netbox HTTP 302; office1-tailscale online 100.64.0.53 advertising 10.10.0.0/22; both LXD service VMs RUNNING. No repo change; sweep result only.
ssh voffice1 / office1-* timed out post-reboot. Root cause (measured): office1-local is an ISOLATED libvirt net (no <ip>/<forward>), so the host's own leg -- 10.10.0.10/24 on the bridge (as-built :41)
10.10.1.0/24 via 10.10.0.20 (:88) -- lives nowhere in the libvirt XML and is dropped on every reboot. ip route get 10.10.0.20 fell through to the default lab gw; ping .20 100% loss. D-126 made the layers ABOVE this durable but assumed base reachability existed.Access restored LIVE (operator sudo, gated) to verify the exact recipe before encoding it: sudo ip addr add 10.10.0.10/24 dev virbr2 + sudo ip route replace 10.10.1.0/24 via 10.10.0.20 dev virbr2 -> voffice1 0% loss, all aliases live. This is AD-HOC (non-persistent) until the unit is installed. Revert: sudo ip addr del 10.10.0.10/24 dev virbr2 (and the route is dropped on next reboot anyway).
scripts/site-baseleg.sh + tests/site-baseleg/ (D-126 amendment)Root Type=oneshot systemd unit that re-adds the base leg + compose route at boot, After=libvirtd.service so it runs AFTER libvirt creates the autostart bridge -- which is why it does NOT hit the netplan-vs-libvirt race that made D-126 reject "persist the L3 route" (narrow reopening, base leg ONLY; root because L3 has no rootless equivalent -- the D-126 forward DEPENDS on this leg). Subcommands render|apply|check|install| remove|list. The bridge is DISCOVERED from the stable net NAME (virsh net-info office1-local), never a baked virbrN (lib-net.sh PATTERN-1); apply is idempotent (guarded add + ip route replace) and root-guarded; check is the read-only session-verify. Harness tests/site-baseleg/run-tests.sh 24/24 (offline: unit shape, no-baked-bridge, discovery present, idempotency, root-guard, no baked secret, no inferred DC IP). Gauntlet ALL GREEN (67 harnesses); repo-lint 0-fail. Revert: git rm scripts/site-baseleg.sh tests/site-baseleg/; on any host where installed, sudo bash scripts/site-baseleg.sh remove office1.
Ordering MEASURED (not inferred): this host runs monolithic libvirtd.service (active; virtnetworkd/ virtqemud inactive), so After=libvirtd.service is correct; the unit also orders after virtnetworkd.service for modular-libvirt hosts (harmless no-op here). Type=oneshot has no Restart=, so the 60s bridge poll is the only backstop (documented limitation). ExecStart is the script's ABSOLUTE path -> a repo rename (D-110) breaks the boot unit.
INSTALLED 2026-07-17 (operator sudo); boot-race UNPROVEN. install wrote + enabled /etc/systemd/system/site-baseleg-office1.service; its apply ran at install -> status=0/SUCCESS, check office1 -> ok. That run was POST-boot (bridge already up), so it exercised the apply logic but NOT the After=libvirtd+poll race. Boot durability stays UNPROVEN until an ACTUAL reboot shows ssh voffice1 self-heals -- the next natural reboot is the proof; no separate test reboot forced.
docs/design-decisions.md: D-126 amendment (base-leg durability + the tool) and NEW D-128 (VR1 operating model -- Claude on the vcloud jumphost; two-plane origin split with Plane 1 on vcloud / Plane 2 executing on voffice1; workstation tailnet is the human path; D-107 left untouched). ASCII-clean (non-ASCII count unchanged at 239). Revert: delete the amendment + the D-128 block..claude/skills/openstack-cloud-ops/SKILL.md: added a routing row (site unreachable post-reboot -> site-baseleg.sh check office1) and the D-128 operating-model INVARIANT in the bootstrap loop. Revert: git checkout the file.docs/dc-dc-deployment-workflow.md: added the operating-model bullet to Cross-cutting discipline. Revert: git checkout the file.Advisor-conferred on the sweep scope + the base-leg mechanism gap. The operating-model ruling followed a grounded discussion: the tooling FIXES execution hosts by design (outer qemu:///system on vcloud; inner qemu+ssh-from-Office1, R-5), so Claude's host only picks transport -- relocating the session to the workstation would trade away the ONE-session/Remote-Control portability, relocate the gating/secrets contract, and put the riskiest Plane-1 ops over a droppable transport, for a reachability win the base-leg oneshot already delivers.