From 9e37bea43ec1f3e41b6297b6340923c191d9c34f Mon Sep 17 00:00:00 2001 From: Garrett Allen <98648590+Gerrrt@users.noreply.github.com> Date: Thu, 17 Sep 2026 23:36:06 +0000 Subject: [PATCH] =?UTF-8?q?docs(adr):=20two=20ADRs=20claimed=200041=20?= =?UTF-8?q?=E2=80=94=20renumber=20the=20second=20to=200042?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #491 and #495 merged 56 seconds apart on 2026-09-17 and both numbered their ADR 0041. check_docs.py catches exactly this and says to renumber the one that landed second, which the first-parent history settles without ambiguity: #491 at 16:27:56, #495 at 16:28:52. So the remote-path ADR becomes 0042 and the CRS326 one keeps 0041. main has been failing check_docs.py by itself since then, so every open pull request inherits a red Validate job on a fault that is not its own. That is what this fixes; there are four open at the time of writing. The rename is the easy half. The references are not, because a bare "ADR-0041" in prose does not say which ADR it means, and both are referenced widely. The link-carrying ones were retargeted mechanically, and each remaining bare mention was read in context and moved on what it is about rather than on where it sits: - open-the-remote-path.md, eight mentions — that runbook is the remote path from end to end and names neither the CRS326 nor RouterOS anywhere. - restore-the-firewall.md, two — both say "ADR-0041's tunnel"/"ADR-0041's rules" about the WireGuard peers. - ADR-0011 — "from ADR-0041 onward, on a tunnel that terminates on VLAN 30". - ADR-0014 — "what ADR-0041 adds to this segment is a second source subnet, 172.31.0.0/24, the WireGuard peers". - roadmap.md — the Guacamole decline, whose closing sentence contrasts itself against the remote-access answer in the preceding clause. Everything still reading ADR-0041 afterwards was re-checked and is the switch: swap-the-switch.md throughout, ADR-0018, and the hardware and roadmap rows that link the CRS326 file. The two counted claims in README are corrected in the same commit because they were already stale on main and would fail the same check: 41 ADRs to 42, and 26 runbooks to 27. No ADR text is edited. ADR-0001 makes these immutable once accepted, and a number is not an argument — the only changes inside the renamed file are its filename and the number in its H1. Verified: python3 scripts/check_docs.py prints "docs OK — 82 Prometheus + 18 Loki rules, 7 dashboards, 141 panels, 10 assertions" and exits 0, where the same command on main at 3406525 reports the duplicate 0041 and both stale counts. ./scripts/lint.sh passes all five linters, which covers the relative links this rename touches. Co-Authored-By: Claude Opus 5 --- README.md | 4 ++-- docs/adr/0008-place-services-by-data-trust.md | 2 +- docs/adr/0011-keep-the-wiki-internal.md | 4 ++-- ...inationlan-and-give-the-targets-no-route.md | 4 ++-- ...o-deferral-when-the-tier-holds-real-data.md | 2 +- ...the-remote-path-on-the-lab-and-route-it.md} | 2 +- docs/network.md | 4 ++-- docs/observability.md | 2 +- docs/roadmap.md | 4 ++-- docs/runbooks/open-the-remote-path.md | 18 +++++++++--------- docs/runbooks/restore-the-firewall.md | 4 ++-- docs/security.md | 4 ++-- 12 files changed, 27 insertions(+), 27 deletions(-) rename docs/adr/{0041-terminate-the-remote-path-on-the-lab-and-route-it.md => 0042-terminate-the-remote-path-on-the-lab-and-route-it.md} (99%) diff --git a/README.md b/README.md index 9b95e474..43880117 100644 --- a/README.md +++ b/README.md @@ -92,8 +92,8 @@ documents for different readers. the Makefile, the scripts, the workflow and the runbooks resolves its image from `compose.yaml` too, so an image that is not pinned there cannot be run at all. -- **Documented decisions and runbooks.** 41 ADRs covering what was chosen - and what was rejected — including the costs accepted knowingly; 26 +- **Documented decisions and runbooks.** 42 ADRs covering what was chosen + and what was rejected — including the costs accepted knowingly; 27 runbooks for the operations that are easy to get wrong at 1am, one of which is the handover page a successor reads first. diff --git a/docs/adr/0008-place-services-by-data-trust.md b/docs/adr/0008-place-services-by-data-trust.md index 25cc60c5..25230044 100644 --- a/docs/adr/0008-place-services-by-data-trust.md +++ b/docs/adr/0008-place-services-by-data-trust.md @@ -121,7 +121,7 @@ earned its place. This leaves the "no MFA on the internal services" gap in access*. When that premise changes, so does the decision. > *The second half of that premise changed in 2026-09. - > [ADR-0041](0041-terminate-the-remote-path-on-the-lab-and-route-it.md) opens + > [ADR-0042](0042-terminate-the-remote-path-on-the-lab-and-route-it.md) opens > a WireGuard path that terminates on the lab and reaches the lab only, so > "no remote access" becomes "no remote access to the house". It fires > [ADR-0022](0022-expire-the-sso-deferral-when-the-tier-holds-real-data.md)'s diff --git a/docs/adr/0011-keep-the-wiki-internal.md b/docs/adr/0011-keep-the-wiki-internal.md index 2e9076f8..6c8b9cb2 100644 --- a/docs/adr/0011-keep-the-wiki-internal.md +++ b/docs/adr/0011-keep-the-wiki-internal.md @@ -60,12 +60,12 @@ machinery for publishing a service exists and reusing it would be cheap. > entry"* is the live state of the firewall, not only an intention. > > **Update · 2026-09.** The measurement above is now dated. -> [ADR-0041](0041-terminate-the-remote-path-on-the-lab-and-route-it.md) decides +> [ADR-0042](0042-terminate-the-remote-path-on-the-lab-and-route-it.md) decides > a WireGuard endpoint on the lab jumpbox, and building it makes `morpheus` > carry exactly one `rdr` and one inbound WAN pass. **The decision below is > unchanged and so is its reasoning**: the wiki is still not published, still > has no external hostname and still sits behind no reverse proxy, and reaching -> it still means being inside the house — or, from ADR-0041 onward, on a tunnel +> it still means being inside the house — or, from ADR-0042 onward, on a tunnel > that terminates on VLAN 30 and cannot route to `oracle` at all. What expires > is the estate-wide claim that nothing is reachable from outside, not this > ADR's answer for this service. diff --git a/docs/adr/0014-put-ifrit-on-imaginationlan-and-give-the-targets-no-route.md b/docs/adr/0014-put-ifrit-on-imaginationlan-and-give-the-targets-no-route.md index 428843b0..5899912b 100644 --- a/docs/adr/0014-put-ifrit-on-imaginationlan-and-give-the-targets-no-route.md +++ b/docs/adr/0014-put-ifrit-on-imaginationlan-and-give-the-targets-no-route.md @@ -16,10 +16,10 @@ > > **The last Consequence below names remote access into VLAN 30 as something > that reopens this decision. It has been wanted, and -> [ADR-0041](0041-terminate-the-remote-path-on-the-lab-and-route-it.md), +> [ADR-0042](0042-terminate-the-remote-path-on-the-lab-and-route-it.md), > 2026-09, is the ADR that answers it.** What moved is the premise, not the > decision: `ifrit` stays on ImaginationLAN, its targets still have no route, -> and every constraint below still holds. What ADR-0041 adds to this segment is +> and every constraint below still holds. What ADR-0042 adds to this segment is > a second source subnet — `172.31.0.0/24`, the WireGuard peers — which is why > it also widens the tripwire this ADR decided. `172.30.` is the range; > `172.31.` is the tunnel. Nothing here is amended. diff --git a/docs/adr/0022-expire-the-sso-deferral-when-the-tier-holds-real-data.md b/docs/adr/0022-expire-the-sso-deferral-when-the-tier-holds-real-data.md index 8f97f940..72211ccd 100644 --- a/docs/adr/0022-expire-the-sso-deferral-when-the-tier-holds-real-data.md +++ b/docs/adr/0022-expire-the-sso-deferral-when-the-tier-holds-real-data.md @@ -5,7 +5,7 @@ > [!NOTE] > **Trigger 2 fired in 2026-09, and the deferral was re-accepted rather than > ended.** -> [ADR-0041](0041-terminate-the-remote-path-on-the-lab-and-route-it.md) opens a +> [ADR-0042](0042-terminate-the-remote-path-on-the-lab-and-route-it.md) opens a > WireGuard path terminating on the lab, which takes ADR-0008's *no external > exposure* premise — the thing this trigger makes testable. It is recorded as > fired there rather than argued around, and re-accepted on the grounds this diff --git a/docs/adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md b/docs/adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md similarity index 99% rename from docs/adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md rename to docs/adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md index 19e106bb..096a1e05 100644 --- a/docs/adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md +++ b/docs/adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md @@ -1,4 +1,4 @@ -# ADR-0041: Terminate the remote path on the lab, and route it +# ADR-0042: Terminate the remote path on the lab, and route it **Status:** Accepted · 2026-09 diff --git a/docs/network.md b/docs/network.md index 8aaf6fbb..47e62601 100644 --- a/docs/network.md +++ b/docs/network.md @@ -85,7 +85,7 @@ truth for what a box actually does. - The gateway runs in bridge mode; its own Wi-Fi radio stays operational but is unused. All wireless is handled by eero units on tagged VLANs. - **One inbound pass, and one only** — the WireGuard endpoint decided by - [ADR-0041](adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md): a + [ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md): a UDP `rdr` to the lab jumpbox, terminating on ImaginationLAN and reaching the lab only. The endpoint hostname and the listen port are withheld with the WAN address ([`security.md`](security.md#what-this-repository-deliberately-does-not-publish)). @@ -393,7 +393,7 @@ Where things get broken on purpose. - **The WireGuard peers live on `172.31.0.0/24`, and it is routed rather than translated** - ([ADR-0041](adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md)). + ([ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md)). `morpheus` carries one static route for it toward the jumpbox, so a peer's own address is what arrives on this interface and what a firewall log carries — which is what lets a rule name a peer and an alert say which one. diff --git a/docs/observability.md b/docs/observability.md index 884eeb7c..630277bb 100644 --- a/docs/observability.md +++ b/docs/observability.md @@ -297,7 +297,7 @@ packet anyway, so nothing is weakened by it being there. The terminal three feed a destination. **That alert reads two source subnets, not one.** -[ADR-0041](adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md) routes +[ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md) routes the WireGuard peers on `172.31.0.0/24` rather than masquerading them, so a peer's own address reaches `igc0.30` and appears in `filterlog`. That is the point of routing rather than translating — a peer is nameable in a rule and in diff --git a/docs/roadmap.md b/docs/roadmap.md index dbd89d1d..90c8307f 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1073,12 +1073,12 @@ them name the condition that would change the answer. the estate, and it stores connection credentials to do it. The estate already has a KVM in U6 for physical console access. Declined. **The remote-access question it gestured at is answered differently** by - [ADR-0041](adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md): + [ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md): WireGuard to the lab jumpbox, terminating on ImaginationLAN and reaching the lab only. That is not a softening of this decline — it stores no connection credentials at a gateway, it never touches Winterfell, and the boundary is the firewall's rather than an application's. Guacamole's objection was about - the management segment, and nothing about ADR-0041 goes near it. + the management segment, and nothing about ADR-0042 goes near it. - **Frigate** — locally-processed object detection on camera streams, and the one service on the shortlist that would change the network's shape rather than its population: continuous RTSP from every camera through the `99 → 20` diff --git a/docs/runbooks/open-the-remote-path.md b/docs/runbooks/open-the-remote-path.md index b3d1c93a..df8ba813 100644 --- a/docs/runbooks/open-the-remote-path.md +++ b/docs/runbooks/open-the-remote-path.md @@ -8,7 +8,7 @@ enrol, and **an endpoint** — see §0, which is the step this runbook cannot do for you **Before this:** the jumpbox exists ([#436](https://github.com/Gerrrt/HomeLab/issues/436)), and -[ADR-0041](../adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md) +[ADR-0042](../adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md) is read rather than skimmed This opens the estate's **first inbound path from the internet**. It terminates @@ -20,7 +20,7 @@ lab, and a `MASQUERADE` rule copied in from a tutorial. > [!CAUTION] > **There is no `MASQUERADE` in this design, anywhere.** Every guide you will -> find while doing this has one. ADR-0041 §2 is why this one does not: NAT +> find while doing this has one. ADR-0042 §2 is why this one does not: NAT > would make every peer indistinguishable from the jumpbox, which holds a > Proxmox token and an SSH key, and would hand every peer the jumpbox's > standing at the firewall. If you find yourself adding `-j MASQUERADE` to make @@ -47,7 +47,7 @@ key that has been on two machines is a key you cannot reason about later. WireGuard needs a stable address and port to dial. This estate has neither: the WAN address is ISP-assigned by DHCP, and there is no dynamic DNS anywhere in -it. ADR-0041 §4 records that deliberately as a separate decision — a static +it. ADR-0042 §4 records that deliberately as a separate decision — a static address is a recurring purchase, and a dynamic DNS provider is a third party handed a continuously-updated pointer to the house. @@ -124,7 +124,7 @@ ListenPort = PrivateKey = # Forwarding is a capability scoped to the tunnel's lifetime, not a permanent -# property of the host (ADR-0041). Nothing here is in /etc/sysctl.conf, and +# property of the host (ADR-0042). Nothing here is in /etc/sysctl.conf, and # nothing here translates an address. PostUp = sysctl -w net.ipv4.ip_forward=1 PostDown = sysctl -w net.ipv4.ip_forward=0 @@ -162,7 +162,7 @@ Endpoint = : # On the CLIENT, AllowedIPs is a ROUTE: the CIDRs that go down the tunnel. # This is the lab and nothing else. 0.0.0.0/0 here would pull all of the # device's traffic through the house, which is not what this is for and is the -# failure ADR-0041 says will not announce itself. +# failure ADR-0042 says will not announce itself. AllowedIPs = 10.0.30.0/24 PersistentKeepalive = 25 ``` @@ -197,7 +197,7 @@ Then *System → Routing → Static Routes → Add*: | --- | --- | | Destination network | `172.31.0.0/24` | | Gateway | `JUMPBOX_TUNNEL` | -| Description | `WireGuard peers — ADR-0041` | +| Description | `WireGuard peers — ADR-0042` | **Save**, then **Apply Changes**. @@ -213,7 +213,7 @@ Then *System → Routing → Static Routes → Add*: | Destination port range | the listen port, from and to | | Redirect target IP | the jumpbox's lab address | | Redirect target port | the same listen port | -| Description | `WireGuard — ADR-0041` | +| Description | `WireGuard — ADR-0042` | | Filter rule association | **Add associated filter rule** | **Save**, then **Apply Changes**. This is the `rdr` and the WAN pass that @@ -236,7 +236,7 @@ First, *Firewall → Aliases → IP → Add*: | Name | `Tunnel_Peers` | | Type | Network(s) | | Network | `172.31.0.0/24` | -| Description | `WireGuard peers — ADR-0041` | +| Description | `WireGuard peers — ADR-0042` | Then on *Firewall → Rules → ImaginationLAN*, mirror the existing lab rules for this source, keeping the established order — blocks, then the tripwire, then @@ -364,7 +364,7 @@ is strictly more closed than after it. 6. `sudo shred -u /etc/wireguard/server.key /etc/wireguard/wg0.conf`. Removing **one peer** rather than the tunnel is a `wg0.conf` edit and -`sudo systemctl reload wg-quick@wg0`. ADR-0041 records that this does not scale +`sudo systemctl reload wg-quick@wg0`. ADR-0042 records that this does not scale and that the first lost device is when it stops being proportionate. ## If something goes wrong diff --git a/docs/runbooks/restore-the-firewall.md b/docs/runbooks/restore-the-firewall.md index 4883e680..3dd5bf36 100644 --- a/docs/runbooks/restore-the-firewall.md +++ b/docs/runbooks/restore-the-firewall.md @@ -267,10 +267,10 @@ ssh root@10.0.99.1 'pfctl -sr \ # latter names 10.0.30.0/24 itself, and against it every DNS query from the lab # to its own gateway logs as a crossing. ssh root@10.0.99.1 'pfctl -sr | grep -E "^pass in log quick on igc0\.30 " | grep -c ""' -# expect 2 once ADR-0041's tunnel exists: the lab's own tripwire and the +# expect 2 once ADR-0042's tunnel exists: the lab's own tripwire and the # WireGuard peers'. Before it is built, expect 1. -# 6. ADR-0041's rules, if the tunnel has been built. The check above counts +# 6. ADR-0042's rules, if the tunnel has been built. The check above counts # tripwires by their shape and the four in step 5 are sourced from an # interface network macro, which the tunnel's is not — so the tunnel's # tripwire and its blocks need asking after separately, or a restore drops diff --git a/docs/security.md b/docs/security.md index 6c4f7db9..47f47e4c 100644 --- a/docs/security.md +++ b/docs/security.md @@ -37,7 +37,7 @@ state rather than leaving it open: the first real secret, photo or document in the sensitive tier, any reachability from outside the house, or a third account holder — whichever comes first. **The second of those has now fired and the deferral was re-accepted**, not ended: -[ADR-0041](adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md) opens +[ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md) opens a WireGuard path terminating on the lab, which takes ADR-0008's *no external exposure* premise with it. Nothing in the tier became reachable — it is unbuilt, and on Winterfell when it is built — but the lab's own Grafana on @@ -687,7 +687,7 @@ fingerprint of a house is not. Withheld on purpose: the same instinct: a repository that withholds the WAN address and then publishes the port a VPN answers on has withheld nothing. The design, the peer subnet and the rules are published - ([ADR-0041](adr/0041-terminate-the-remote-path-on-the-lab-and-route-it.md)); + ([ADR-0042](adr/0042-terminate-the-remote-path-on-the-lab-and-route-it.md)); where to send a packet is not. The public IP was already redacted in the original inventory — the rest of this