docs: move narrative wiki under knowledge/wiki/ (phase 3)

Problem: node and cross-cutting narratives lived at the repo root
(containers/, vms/, infrastructure/, host .md files), interleaved with the
machine-readable substrate.

Change:
- Move containers/ -> knowledge/wiki/containers/, vms/ -> knowledge/wiki/vms/,
  infrastructure/ -> knowledge/wiki/infrastructure/, hosts/{hubris,strong}.md ->
  knowledge/wiki/hosts/, infrastructure/references/ -> knowledge/sources/references/,
  GLOSSARY.md -> knowledge/GLOSSARY.md.
- Add knowledge/{index.md,log.md,sources/index.md} scaffolding.
- Rewrite all relative links repo-wide via a path-resolving mapper (inbound +
  outbound + between-moved-files), including .hermes/, runbooks, operations,
  investigations, plans, README, AGENTS.
- Repoint inventory.yaml doc_page fields and regenerate hosts/*.yaml (which
  embed doc_page); update oikos/gen-topology.py output path, candidate doc
  paths, and footer links; update code-comment doc paths.

Substrate untouched in place: inventory.yaml, hosts/*.yaml (regenerated,
idempotent), oikos/ code, mcp/, secrets/, bin/.

Verification:
- Logical broken-link set identical to pre-move baseline (net 128 -> 127; the
  topology regen fixed one, introduced none). Remaining are pre-existing refs
  to destroyed/archived nodes, out of scope for this move.
- gen-topology.py --check exit 0 (in sync); cards carry knowledge/wiki/ doc paths.
- build_host_files.py idempotent; all inventory doc_page targets resolve.
- MCP contract verified: get_page/search_docs/get_changelog resolve moved pages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-06 14:35:23 +02:00
parent bb5c0717a1
commit 8a6422bd7d
129 changed files with 249 additions and 264 deletions

View File

@@ -5,7 +5,7 @@ Repo-side half of the Week-3 approval flow. This module owns the request/
grant lifecycle and the HMAC signing; it does NOT talk to Matrix directly.
There is no dedicated Matrix bot in this homelab — alerts already go out
as the operator's own Hermes agent posting to @dtoro:avispero (see
infrastructure/monitoring.md's homelab-health-watchdog). The integration
knowledge/wiki/infrastructure/monitoring.md's homelab-health-watchdog). The integration
contract is:
1. An agent or the Week-3 scheduler calls `request()` (or the CLI

View File

@@ -6,7 +6,7 @@
- role: docker-apps
- address: 192.168.8.205 (mesh: tailscale:apps)
- mounts: /mnt/library
- doc: containers/105-apps.md
- doc: knowledge/wiki/containers/105-apps.md
- secrets: enrolled (age key present)
## Blast radius
@@ -18,4 +18,4 @@
- see the services this host runs for action-level risk classes
## Recent changes
- (none yet)
- 2026-07-06T11:57:21+00:00 deploy-oikos-console (config_mutation) — ok

View File

@@ -6,7 +6,7 @@
- role: arr-stack
- address: 192.168.8.245 (mesh: tailscale:arr)
- mounts: /mnt/media_local
- doc: containers/122-arriman.md
- doc: knowledge/wiki/containers/122-arriman.md
## Blast radius
- impacts: service:arr_stack

View File

@@ -5,7 +5,7 @@
- runs-on: host:hubris
- role: authentik-gateway
- address: 192.168.8.6
- doc: containers/106-auth-outpost.md
- doc: knowledge/wiki/containers/106-auth-outpost.md
## Blast radius
- impacts: (none)

View File

@@ -5,7 +5,7 @@
- runs-on: host:hubris
- role: reverse-proxy
- address: 192.168.8.175
- doc: containers/121-caddy.md
- doc: knowledge/wiki/containers/121-caddy.md
## Blast radius
- impacts: service:caddy

View File

@@ -5,7 +5,7 @@
- runs-on: host:hubris
- role: dns-server
- address: 192.168.8.2
- doc: containers/107-dns.md
- doc: knowledge/wiki/containers/107-dns.md
## Blast radius
- impacts: service:dns
@@ -16,4 +16,4 @@
- see the services this host runs for action-level risk classes
## Recent changes
- (none yet)
- 2026-07-06T11:40:28+00:00 add-record (config_mutation) — ok

View File

@@ -5,7 +5,7 @@
- runs-on: host:strong
- role: matrix-server
- address: 192.168.8.242
- doc: containers/118-elementsynapse.md
- doc: knowledge/wiki/containers/118-elementsynapse.md
## Blast radius
- impacts: service:matrix

View File

@@ -6,7 +6,7 @@
- role: git-server
- address: 192.168.8.121 (mesh: tailscale:gitea)
- mounts: /mnt/library
- doc: containers/104-gitea.md
- doc: knowledge/wiki/containers/104-gitea.md
## Blast radius
- impacts: service:gitea

View File

@@ -6,7 +6,7 @@
- role: book-library
- address: 192.168.8.247
- mounts: /mnt/media_local
- doc: containers/130-grimmory.md
- doc: knowledge/wiki/containers/130-grimmory.md
- secrets: enrolled (age key present)
## Blast radius

View File

@@ -5,7 +5,7 @@
- runs-on: host:hubris
- role: home-automation
- address: 192.168.8.101 (mesh: tailscale:homeassistant)
- doc: vms/108-haos.md
- doc: knowledge/wiki/vms/108-haos.md
## Blast radius
- impacts: service:haos

View File

@@ -5,7 +5,7 @@
- runs-on: host:strong
- role: family-planner
- address: 192.168.8.244
- doc: containers/129-house.md
- doc: knowledge/wiki/containers/129-house.md
- secrets: enrolled (age key present)
## Blast radius

View File

@@ -5,7 +5,7 @@
- role: hypervisor
- address: 192.168.8.77 (mesh: netbird:proxmox-server.netbird.selfhosted)
- mounts: /mnt/library
- doc: hosts/hubris.md
- doc: knowledge/wiki/hosts/hubris.md
- secrets: enrolled (age key present)
## Blast radius

View File

@@ -6,7 +6,7 @@
- role: media-server
- address: 192.168.8.246 (mesh: tailscale:jellyfin)
- mounts: /mnt/media_local
- doc: containers/101-jellyfin.md
- doc: knowledge/wiki/containers/101-jellyfin.md
## Blast radius
- impacts: service:jellyfin

View File

@@ -6,7 +6,7 @@
- role: photo-management
- address: 192.168.8.136 (mesh: tailscale:muleimage)
- mounts: /mnt/library
- doc: containers/120-mule-images.md
- doc: knowledge/wiki/containers/120-mule-images.md
## Blast radius
- impacts: service:photos

View File

@@ -6,7 +6,7 @@
- role: file-sync
- address: 192.168.8.224 (mesh: tailscale:nextcloud)
- mounts: /mnt/library
- doc: containers/114-nextcloud.md
- doc: knowledge/wiki/containers/114-nextcloud.md
## Blast radius
- impacts: service:nextcloud

View File

@@ -5,7 +5,7 @@
- runs-on: host:hubris
- role: storage-export
- address: 192.168.8.200
- doc: containers/102-nfs-export.md
- doc: knowledge/wiki/containers/102-nfs-export.md
## Blast radius
- impacts: (none)

View File

@@ -6,7 +6,7 @@
- role: document-archive
- address: 192.168.8.130 (mesh: tailscale:paperless)
- mounts: /mnt/library
- doc: containers/103-paperless.md
- doc: knowledge/wiki/containers/103-paperless.md
## Blast radius
- impacts: service:paperless

View File

@@ -6,7 +6,7 @@
- role: rom-manager
- address: 192.168.8.249
- mounts: /mnt/media_local
- doc: containers/134-romm.md
- doc: knowledge/wiki/containers/134-romm.md
## Blast radius
- impacts: (none)

View File

@@ -6,7 +6,7 @@
- role: anime-media-server
- address: 192.168.8.248
- mounts: /mnt/media_local/anime
- doc: containers/133-seanime.md
- doc: knowledge/wiki/containers/133-seanime.md
## Blast radius
- impacts: (none)

View File

@@ -6,7 +6,7 @@
- role: workshop
- address: 192.168.8.109 (mesh: tailscale:sophia)
- mounts: /mnt/library
- doc: containers/119-sophia.md
- doc: knowledge/wiki/containers/119-sophia.md
## Blast radius
- impacts: (none)

View File

@@ -4,7 +4,7 @@
- state: active
- role: hypervisor
- address: 192.168.178.181
- doc: hosts/strong.md
- doc: knowledge/wiki/hosts/strong.md
- secrets: enrolled (age key present)
## Blast radius

View File

@@ -6,7 +6,7 @@
- role: teddycloud
- address: 192.168.8.150
- mounts: /mnt/library
- doc: containers/131-teddycloud.md
- doc: knowledge/wiki/containers/131-teddycloud.md
## Blast radius
- impacts: service:teddycloud
@@ -17,4 +17,4 @@
- see the services this host runs for action-level risk classes
## Recent changes
- (none yet)
- 2026-07-06T11:05:35+00:00 activate (config_mutation) — ok

View File

@@ -5,7 +5,7 @@
- runs-on: host:hubris
- role: trmnl-middleware
- address: 192.168.8.211
- doc: containers/128-trmnl.md
- doc: knowledge/wiki/containers/128-trmnl.md
## Blast radius
- impacts: service:trmnl

View File

@@ -5,7 +5,7 @@
- runs-on: host:hubris
- role: nas-frontend-eval
- address: 192.168.8.195
- doc: vms/100-zimaos.md
- doc: knowledge/wiki/vms/100-zimaos.md
## Blast radius
- impacts: service:zimaos

View File

@@ -1,7 +1,7 @@
# arr_stack (service:arr_stack)
- backend: host:arriman
- doc: containers/122-arriman.md
- doc: knowledge/wiki/containers/122-arriman.md
## Blast radius
- impacts: (none)

View File

@@ -2,7 +2,7 @@
- backend: host:apps
- url: https://artifacto.hubris.network
- doc: containers/105-apps.md
- doc: knowledge/wiki/containers/105-apps.md
- config repo: dtoro/Artifacto
## Blast radius

View File

@@ -2,7 +2,7 @@
- backend: host:netbird-vps
- url: https://auth.hubris.network
- doc: containers/106-auth-outpost.md
- doc: knowledge/wiki/containers/106-auth-outpost.md
- risk notes: SSO provider — outage locks login to OIDC/forward-auth services
## Blast radius

View File

@@ -1,7 +1,7 @@
# caddy (service:caddy)
- backend: host:caddy
- doc: containers/121-caddy.md
- doc: knowledge/wiki/containers/121-caddy.md
- config repo: dtoro/caddy-conf
- risk notes: wide blast radius — every *.hubris.network route rides on it (see oikos/policy.yaml service_overrides)
@@ -17,4 +17,4 @@
- edit-config-and-deploy — config_mutation (approval: operator)
## Recent changes
- (none yet)
- 2026-07-06T11:29:56+00:00 add-site-block (config_mutation) — ok

View File

@@ -1,7 +1,7 @@
# dns (service:dns)
- backend: host:dns
- doc: containers/107-dns.md
- doc: knowledge/wiki/containers/107-dns.md
- risk notes: LAN-wide resolver — misconfig breaks name resolution for every client
## Blast radius

View File

@@ -2,7 +2,7 @@
- backend: host:gitea
- url: https://git.hubris.network
- doc: containers/104-gitea.md
- doc: knowledge/wiki/containers/104-gitea.md
- config repo: dtoro/gitea-customizations
- risk notes: hosts all config repos + deploy webhooks; outage blocks auto-deploy and sync

View File

@@ -1,7 +1,7 @@
# haos (service:haos)
- backend: host:haos
- doc: vms/108-haos.md
- doc: knowledge/wiki/vms/108-haos.md
## Blast radius
- impacts: (none)

View File

@@ -2,7 +2,7 @@
- backend: host:apps
- url: https://mcp.hubris.network/mcp
- doc: infrastructure/homelab-context.md
- doc: knowledge/wiki/infrastructure/homelab-context.md
- config repo: dtoro/Homelab-Docs
- risk notes: agents' primary read surface — outage degrades every agent to grepping the clone

View File

@@ -2,7 +2,7 @@
- backend: host:jellyfin
- url: https://media.hubris.network
- doc: containers/101-jellyfin.md
- doc: knowledge/wiki/containers/101-jellyfin.md
- risk notes: native Authentik OIDC via SSO-Auth plugin, no Caddy forward-auth gate; VAAPI transcode depends on GPU passthrough on strong
## Blast radius

View File

@@ -2,7 +2,7 @@
- backend: host:elementsynapse
- url: https://matrix.hubris.network
- doc: containers/118-elementsynapse.md
- doc: knowledge/wiki/containers/118-elementsynapse.md
- risk notes: alert/approval channel for Oikos — outage silences agent escalation
## Blast radius

View File

@@ -2,7 +2,7 @@
- backend: host:nextcloud
- url: https://cloud.hubris.network
- doc: containers/114-nextcloud.md
- doc: knowledge/wiki/containers/114-nextcloud.md
## Blast radius
- impacts: (none)

View File

@@ -2,7 +2,7 @@
- backend: host:paperless
- url: https://paperless.hubris.network
- doc: containers/103-paperless.md
- doc: knowledge/wiki/containers/103-paperless.md
- risk notes: document archive — treat data as irreplaceable; DB operations are destructive-class
## Blast radius

View File

@@ -2,7 +2,7 @@
- backend: host:mule-images
- url: https://photos.hubris.network
- doc: containers/120-mule-images.md
- doc: knowledge/wiki/containers/120-mule-images.md
- config repo: dtoro/mule-image
## Blast radius

View File

@@ -2,7 +2,7 @@
- backend: host:hubris
- url: https://proxmox.hubris.network
- doc: hosts/hubris.md
- doc: knowledge/wiki/hosts/hubris.md
- risk notes: hypervisor UI — changes here affect every guest on the node
## Blast radius

View File

@@ -2,7 +2,7 @@
- backend: host:teddycloud
- url: https://teddy.hubris.network
- doc: containers/131-teddycloud.md
- doc: knowledge/wiki/containers/131-teddycloud.md
- risk notes: no Caddy forward-auth gate (unlike sab.hubris.network on the same Caddyfile) — reachable to anyone on the LAN/mesh who can resolve teddy.hubris.network; undocumented in inventory.yaml until 2026-07-06 (drift-caught)
## Blast radius

View File

@@ -2,7 +2,7 @@
- backend: host:trmnl
- url: https://trmnl.hubris.network
- doc: containers/128-trmnl.md
- doc: knowledge/wiki/containers/128-trmnl.md
- config repo: dtoro/terminalito
## Blast radius

View File

@@ -2,7 +2,7 @@
- backend: host:zimaos
- url: https://zimaos.hubris.network
- doc: vms/100-zimaos.md
- doc: knowledge/wiki/vms/100-zimaos.md
## Blast radius
- impacts: (none)

View File

@@ -3,7 +3,7 @@
Deploys the same way `homelab-mcp` and `secrets-issuance` already do:
Shape B webhook (own checkout, own systemd units, own deploy secret) on
LXC 105 (apps), reading `HOMELAB_CONTEXT_DIR=/opt/homelab-context` for
all data. See [infrastructure/auto-deploy.md](../../../infrastructure/auto-deploy.md)
all data. See [infrastructure/auto-deploy.md](../../../knowledge/wiki/infrastructure/auto-deploy.md)
for the general pattern; webhook ids 10 (homelab-mcp, :9811) and 11
(secrets-issuance, :9821) are the direct precedent — this is a third
webhook on `dtoro/Homelab-Docs`, port :9831.

View File

@@ -215,7 +215,7 @@ def check_pct_list(inv: dict | None = None) -> list[dict]:
def check_caddy_backends(inv: dict | None = None) -> list[dict]:
"""Caddy's /etc/caddy (a git checkout of dtoro/caddy-conf, per
containers/121-caddy.md) vs inventory service backend IPs. Best-effort
knowledge/wiki/containers/121-caddy.md) vs inventory service backend IPs. Best-effort
grep for reverse_proxy targets; skips services whose Caddyfile snippet
doesn't use a bare IP (e.g. references a Caddy snippet/import)."""
inv = inv or _load_inventory()

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python3
"""
Generate infrastructure/topology.md (Mermaid views) and per-entity context
Generate knowledge/wiki/infrastructure/topology.md (Mermaid views) and per-entity context
cards from inventory.yaml.
Views:
@@ -42,7 +42,7 @@ from oikos import policy as oikos_policy # noqa: E402
from oikos import relations as oikos_relations # noqa: E402
INVENTORY = REPO / "inventory.yaml"
OUTPUT = REPO / "infrastructure" / "topology.md"
OUTPUT = REPO / "knowledge" / "wiki" / "infrastructure" / "topology.md"
CARDS_DIR = REPO / "oikos" / "cards"
BANNER = (
@@ -82,15 +82,15 @@ def _host_card(name: str, entry: dict, inv: dict) -> str:
lines.append(f"- mounts: {', '.join(entry['mounts'])}")
doc = None
if entry.get("kind") == "lxc" and pve:
cand = REPO / "containers" / f"{pve}-{name}.md"
cand = REPO / "knowledge" / "wiki" / "containers" / f"{pve}-{name}.md"
if cand.exists():
doc = str(cand.relative_to(REPO))
elif entry.get("kind") == "vm" and pve:
cand = REPO / "vms" / f"{pve}-{name}.md"
cand = REPO / "knowledge" / "wiki" / "vms" / f"{pve}-{name}.md"
if cand.exists():
doc = str(cand.relative_to(REPO))
elif entry.get("kind") == "proxmox-host":
cand = REPO / "hosts" / f"{name}.md"
cand = REPO / "knowledge" / "wiki" / "hosts" / f"{name}.md"
if cand.exists():
doc = str(cand.relative_to(REPO))
if doc:
@@ -192,9 +192,9 @@ def render(inv: dict) -> str:
parts = [
BANNER,
"# Topology (generated)\n",
f"Source: [inventory.yaml](../inventory.yaml) — {counts}.",
"Edge semantics: [oikos/ontology.yaml](../oikos/ontology.yaml). "
"Operating model: [OIKOS.md](../OIKOS.md).\n",
f"Source: [inventory.yaml](../../../inventory.yaml) — {counts}.",
"Edge semantics: [oikos/ontology.yaml](../../../oikos/ontology.yaml). "
"Operating model: [OIKOS.md](../../../.agents/OIKOS.md).\n",
"## Compute & ingress\n",
"\n".join(compute_view(inv)) + "\n",
"## Storage (mounts)\n",

View File

@@ -2,7 +2,7 @@
Split out of oikos/gen-topology.py so it's importable (a hyphenated
filename can't be `import`ed as a module). oikos/gen-topology.py is the
CLI entrypoint that writes infrastructure/topology.md + oikos/cards/;
CLI entrypoint that writes knowledge/wiki/infrastructure/topology.md + oikos/cards/;
oikos/console/app.py imports this module directly to render the live
/graph page without shelling out.
"""

View File

@@ -4,7 +4,7 @@
Both are generated text, not sent directly to Matrix — same integration
contract as oikos/approve.py: there's no dedicated Matrix bot in this
homelab, so Hermes (already posting alerts as @dtoro:avispero, see
infrastructure/monitoring.md) is the one that actually delivers this text.
knowledge/wiki/infrastructure/monitoring.md) is the one that actually delivers this text.
The daily brief is meant to run once a day (e.g. chained after an early
oikos-scheduler.service run, or its own systemd timer); the weekly report
is a deeper markdown review.

View File

@@ -75,7 +75,7 @@ _HEALTH_OVERRIDES = {
"url_transform": lambda url: url.rstrip("/").rsplit("/", 1)[0] + "/health",
},
# Token-gated at the app level (401 without a token is correct, not
# down) — see containers/128-trmnl.md, which documents a dedicated
# down) — see knowledge/wiki/containers/128-trmnl.md, which documents a dedicated
# /health endpoint returning 200 unauthenticated.
"trmnl": {"url_transform": lambda url: url.rstrip("/") + "/health"},
}