| 2026-07-14 |

D-115 office carve IMPORTED into the Office1 NetBox; DC import blocked on ORG_ULA_48
...
netbox/d115-office-carve.py (+ tests/d115-office-carve/ 20/20 PASS)
Applied to the Office1 sandbox: site vr1-off1, roles office + edge (edge is NEW),
and 8 prefixes. Idempotent (re-run: 0 created / 11 present).
10.10.0.0/16 office container the Office v4 block, /22 per office
10.10.0.0/22 office container VR1 Off1's /22
10.10.0.0/24 office active office1-local LAN (Kea on the edge)
10.10.1.0/24 office active lxdbr0 compose net (MAAS DHCP)
172.30.0.0/16 edge container NEW Edge role; mirrors v6 2602:f3e2:fe::/48
172.30.1.0/24 edge active office1-wan, the simulated ISP uplink
2602:f3e2:f01 :/56 office container mirrors VR0 Off0's e01 :/56
2602:f3e2:f01 :/64 office active office subnet (NOT deployed; v6 has no egress)
Every address was already RUNNING. D-115 blesses what is deployed -- zero
renumber. What it fixes is that three of them were SQUAT: on the wire with no
allocation behind them.
Writing upstream is GATED IN CODE: the tool refuses a non-sandbox target unless
given --yes-write-upstream. Feeding the production apex is an operator decision,
never a side effect of running an import.
BLOCKED, deliberately: dc-dc-prefixes-import.py --dc dc0 CANNOT run. It needs
ORG_ULA_48, which is still UNASSIGNED (gap G3; the scope doc recommends
fd50:840e:74e2::/48 but no ADOPTED decision assigns it -- grep ORG_ULA
design-decisions.md returns nothing). Using it anyway would be an inferred value
(hard rule 2). This is a DECISION gate, not a tooling gap: the tooling is fixed,
tested and ready. Recorded in the ledger with the exact commands to unblock.
Also: docs/vr1-office1-as-built.md gains the IPAM table, and records that the
Tailscale 10.10.0.0/22 route is now ENABLED (edge GUI reachable from the
workstation with no tunnel), superseding the tunnel instructions.
repo-lint 0 fail. run-tests-all: ALL GREEN (55 harnesses).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013ZBxzAbmqwLW7jEmMG23Xw
|
| 2026-07-13 |

D-116 ADOPTED: no Office1-local GitBucket -- keep using git.baldurkeep.com
...
Operator ruling: "we've decided not to build a separate one on the test cloud. We will continue to
use the current setup and create new repos for deployment tasks as needed."
SUPERSEDES the GitBucket half of D-103 (which gave Office1 three service VMs) and removes GitBucket
from Stage 2's build list entirely. Office1's MAAS-composed service machines are now exactly TWO --
office1-netbox and office1-tailscale -- and both are LIVE.
WHAT THIS ACTUALLY CLOSES, and why it is a simplification rather than a deferral: the Stage 2 runbook
carried an OPEN QUESTION about the Office1-local GitBucket -- "what it mirrors, and under what repo
path, is not decided" -- because a SECOND GitBucket alongside the pre-existing git.baldurkeep.com
raised a real authority/mirroring question nobody had answered. That question is now MOOT. There is
one git service, it is the existing one, and it is authoritative.
Recorded explicitly in D-116 so nobody misreads the scope: D-107's per-DC ARTIFACT mirror (OS/package
artifacts for node provisioning) is a SEPARATE concern and is NOT affected. And if Roosevelt later
wants a site-local git service, that is a fresh decision against real requirements -- not something
this ruling forecloses.
Applied everywhere it was an instruction, not just recorded:
- runbooks/dc-dc-phase1-office1-standup.md: Step 11 replaced with a TOMBSTONE (kept rather than
deleted -- step numbering is referenced elsewhere, and someone WILL come looking after reading
D-103); removed from the sequence, the compose steps, and the open-questions list.
- docs/dc-dc-deployment-workflow.md: dropped from Stage 2's Build and, importantly, from its GATE --
"GitBucket serving" is no longer a gate condition.
- docs/design-decisions.md: D-103 annotated in place with the supersession, so grepping for GitBucket
lands on the amendment rather than the stale instruction.
- docs/vr1-office1-as-built.md + session ledger updated.
repo-lint 0 fail.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|

Tailscale: office1-tailscale joined the SELF-HOSTED tailnet as the Office1 subnet router
...
Operator's control plane is self-hosted (https://tailscale.baldurkeep.com:443), NOT Tailscale's
public one -- so the public login-URL flow from the previous commit was void. Node reset off
controlplane.tailscale.com and re-enrolled against the operator's server with their auth key.
REACHABILITY PROVEN FIRST, not assumed: DNS + TCP 443 + HTTPS to tailscale.baldurkeep.com confirmed
from the node BEFORE running `tailscale up`, so a failure would have been a network fact rather than
a confusing registration error.
AS BROUGHT UP: --login-server=https://tailscale.baldurkeep.com:443 --authkey=<from 0600 file>
--advertise-routes=10.10.0.0/22 --accept-routes --accept-dns=false --hostname=office1-tailscale
Online as 100.64.0.53 (fd7a:115c:a1e0::35), no health warnings, advertising 10.10.0.0/22 -- exactly
the D-115 Office1 carve, so D-107's "Office1 ONLY" front door is enforced by the CARVE itself rather
than by policy alone.
ONE DELIBERATE DEVIATION from the operator's usual command: --accept-dns=false. This is a
MAAS-managed machine and MAAS's bind9 serves its internal names; letting the tailnet take over DNS
would break that resolution. Flagged rather than silently applied -- trivial to flip if MagicDNS is
wanted here.
OPERATOR ACTION STILL REQUIRED: the 10.10.0.0/22 route is ADVERTISED but must be ENABLED on the
control server (Headscale: `headscale routes enable`) before other tailnet nodes route to Office1.
Once enabled, the whole Office1 carve -- edge GUI, MAAS UI, NetBox -- is reachable from the tailnet
with NO SSH tunnels, superseding most of the tunnel commands in the as-built doc.
SECRET HANDLING: the auth key was written by the operator to a 0600 file OUTSIDE this session,
consumed BY PATH, never printed into context, and the copy shipped to the node was SHREDDED after
enrolment (tailscaled holds its own node key now). Tracked as SEC-008 -- a rotation obligation, not
a delete-me, since the key remains on vcloud for re-enrolment.
docs/vr1-office1-as-built.md updated with the tailnet addresses, the exact bring-up command, the
DNS deviation, and the pending route-enable step.
repo-lint 0 fail.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|

Office1: edge route to the compose net + Tailscale subnet router + an as-built connection reference
...
THE ROUTE -- and an OUTAGE I CAUSED AND REVERTED. Adding a LAN gateway on OPNsense for voffice1
SILENTLY STOLE THE DEFAULT ROUTE: the edge's default flipped from 172.30.1.1 (ISP) to 10.10.0.20,
and the site lost egress. Root cause: OPNsense's `defaultgw` field in the API output is DERIVED
FROM `priority` (lower = more preferred), NOT from the value you send -- I sent defaultgw="0", it
came back True, and I had ALREADY run `reconfigure` before reading anything back. Detected within
~2 minutes by checking egress, reverted by deleting the gateway; default route and egress restored.
Redone SAFELY: add the gateway, READ THE CONFIG BACK, verify WAN_GW is still the default, and only
THEN apply. WAN_GW is now priority 1 (explicitly preferred); OFFICE1_LXD_GW is 255. Verified after
apply: default still 172.30.1.1, egress OK, and the edge now routes 10.10.1.0/24 -> 10.10.0.20 and
reaches NetBox. The lesson is in the as-built doc's trap list.
Also re-learned the hard way: root's shell on the edge is tcsh, so `2>&1` in my verification command
died with "Ambiguous output redirect" -- the exact trap already written down in this repo's standing
lessons. Feed remote commands to `sh -s`.
TAILSCALE: office1-tailscale composed by MAAS (2 cores / 2 GiB / 25 GB -- VR0's sizing), deployed
Ubuntu 24.04, Tailscale 1.98.8 installed, IP forwarding on, brought up as a SUBNET ROUTER advertising
10.10.0.0/22 -- exactly the D-115 Office1 carve, so "Office1 only" (D-107) is enforced by the carve
itself. Authenticated via the login-URL flow, NOT an auth key: no tailnet secret passes through the
session. PENDING OPERATOR: authorize the node, and approve the 10.10.0.0/22 route in the admin
console. The tailnet ACL/tag policy remains operator design (runbook open question 5).
NEW: docs/vr1-office1-as-built.md -- the operator-requested connection reference. Every value
MEASURED, not planned: networks + who owns DHCP on each, hosts/services/levels, how to reach each
thing from vcloud AND from a workstation, where every credential lives, and the site's standing
traps. Explicitly NOT an address authority -- NetBox is the IPAM apex; this is operational.
Also noted: MAAS's bind9 intermittently SERVFAILs a first-time external lookup and succeeds on
retry (seen twice -- docker registry, tailscale.com). Retry before diagnosing.
repo-lint 0 fail.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|