docs: three dangling links, and a gate so they cannot accumulate

The vault is the project's source of truth, so a link to a page that does not
exist is a promise the repo cannot keep. Three were dangling:

- Dankclaw/Gitea.md pointed twice at dankclaw/compose.yaml — **which this
  session retired**. The clean cutover obligation from my own change: the page
  now describes the unit that publishes 3000 and the canonical Caddy unit, and
  records why the compose file is gone.
- Dankclaw/Hermes-Dashboard.md linked [[LAN DNS]]; the page is [[LAN-DNS]].
- LLM/frank-medium-radiance-mxfp4.md linked [[Observability on Dankclaw]]; the
  page is [[Observability]].

scripts/check-vault-links.py + a seam keep it that way. The checker models
Obsidian's rules, which took three corrections to get right — and each was a
false positive that would have sent me editing healthy docs:

  1. Wikilinks are case-insensitive. A case-sensitive matcher reported 45
     breaks; 39 were `[[qBittorrent]]` vs qbittorrent.md.
  2. `[[folder/Note]]` resolves by path suffix, not by stem.
  3. `%20` in a markdown link is URL-encoding, not a filename.

Validating the linter against the resolver it models is the prerequisite for
trusting any of its output — the same discipline that caught a bad assertion of
my own earlier tonight.
This commit is contained in:
Frank
2026-09-16 07:43:33 -07:00
parent 80a070d71b
commit 2e33ec36c1
5 changed files with 91 additions and 5 deletions
+2 -2
View File
@@ -103,9 +103,9 @@ Back up `/home/dank/Containers/gitea/` (tar) or `pg_dump` the database. See the
containers. Edit files as the owning user with
`podman exec --user 1000 gitea-server ...`.
- **The host auto-reboots.** `unattended-upgrades` reboots Dankclaw when a package needs it. The quadlet units make Gitea survive that. See the 2026-08-16 incident below.
- **Port 3000 vs 3001.** The live host port is 3000. The full-stack [`dankclaw/compose.yaml`](../../dankclaw/compose.yaml) maps 3001. Align the two before deploying the full stack.
- **Port 3000, and one owner.** The live host port is 3000, published by the `gitea` Quadlet unit. The `dankclaw/compose.yaml` that mapped 3001 was **retired on 2026-09-16** (staged in `.AGENTTRASH/`) once an ownership audit showed every container on this host reports a `PODMAN_SYSTEMD_UNIT` label — a second composition path could only spawn a duplicate fighting a unit for a name. Do not reintroduce a compose service for Gitea or the proxy.
- **Legacy compose retired.** `/opt/gitea/podman-compose.yml` is retired to `/opt/gitea/.deprecated/`. Do not run it. Its containers collide with the Quadlet units on ports 3000 and 2222.
- **Canonical proxy.** `gitea.franksdank.cloud` is served by the Caddy service in `dankclaw/compose.yaml`, which proxies to `192.168.0.143:3000`. Do not recreate a Gitea-specific Caddy unit or publish another proxy on ports 80/443. During migration, the deployer stages any installed legacy unit under `~/.AGENTTRASH/YYYYMMDD-gitea-caddy/` before starting canonical Caddy.
- **Canonical proxy.** `gitea.franksdank.cloud` is served by the canonical Caddy **unit** (`dankclaw/caddy/quadlet/caddy.container`, repo `dankclaw/Caddyfile`), which proxies to `192.168.0.143:3000`. Do not recreate a Gitea-specific Caddy unit or publish another proxy on ports 80/443. If a legacy unit is ever installed again, the deployer stages it under `~/.AGENTTRASH/YYYYMMDD-gitea-caddy/` before starting canonical Caddy.
## Incident: 2026-08-16 — down after unattended reboot
@@ -54,7 +54,7 @@ login — there is no unauthenticated bind:
reverse-proxies `192.168.0.143:9119` directly, with **no** Anubis/Outpost guard
chain in front of it (exempt-by-construction: the app carries its own complete
auth). The name deliberately has no public DNS record, so the vhost resolves on
the LAN only; WAN clients get NXDOMAIN. See [[LAN DNS]].
the LAN only; WAN clients get NXDOMAIN. See [[LAN-DNS]].
2. **`http://192.168.0.143:9119`** — the raw published port. Still reachable from
any LAN host (the container binds `0.0.0.0` inside its namespace and publishes
`9119:9119`), so treat the LAN as a trusted boundary here, not as a gate.
@@ -426,8 +426,8 @@ scraped — Prometheus has `frank-medium` and `frank-large` jobs
`vllm:kv_cache_usage_perc` (per-card pool fill), `vllm:num_requests_waiting`
(queue depth), `rate(vllm:prefix_cache_hits_total[5m]) /
rate(vllm:prefix_cache_queries_total[5m])` (whether pinned conversations are
served warm), and the request-latency histograms. See
[[Observability on Dankclaw]], and one Grafana dashboard reads them
served warm), and the request-latency histograms. See [[Observability]], and one
Grafana dashboard reads them
(**LLM fleet — capacity and reuse**).
Five rules watch this service (`shared/prometheus/rules/llm-fleet.yml`): pool