# 2026-07-17 -- vcloud post-restart sweep + D-126 base-leg oneshot + D-128 operating model

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.

## vcloud post-restart health sweep (read-only)

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.

## Finding: the base L3 leg is the un-persisted foundation D-126 never owned

`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`)
+ compose route `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).

## NEW: `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.

## Records: D-126 amendment + D-128 operating model + skill/doctrine

- `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.

## Why (evidence trail)

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.
