Files
Frank 327e78b950 docs(vault): destroy the dead weight — 53 pages and the change diary
The vault was 155 pages / 31,210 lines, most of it measurement ledgers for
payloads that no longer run. A throughput figure for a runtime nobody operates is
not a record: AI moves faster than the vault, so the number is wrong before
anyone reads it, and a wrong number in a runbook gets believed. Per the new
purpose test in `AGENTS.md` → *Documentation Policy*, it is destroyed.

Gone (`.AGENTTRASH/20261019-destruction/`, KILL-LIST.txt is the manifest):
- the `frank-medium` endpoint and its five era pages, `frank-npu`, FastFlowLM,
  the ikllama/kingjones/dealign/frank-redo eras, the ling/swift15/freetoken/ubatch
  campaign pages, qwen3.8 spec-matrix and strix-optimizations, the two
  "Running Qwen3.6 …" pages;
- the whole `Pipeline Parallelism/` folder (no live script passes a pipeline flag)
  and the multi-device/x4-pair/hybrid/offload experiment pages;
- every vLLM page — no vLLM endpoint exists on this fleet;
- `LLM/deployment.md` (`Architecture/Deployment Flow.md` is the test-referenced
  owner) and the external surveys (SGLang, Lemonade, llama.cpp forks/diff,
  self-hosted app census, the TTS survey) that were obsolete by construction;
- `log.md`, 2,380 lines. Git holds the chronology; a causal law belongs to the
  page that owns the thing it governs, never to a diary.

Survivors: 101 pages, 17,542 lines, 0 OKF violations, 0 unresolved links. Eras
tables keep the window, payload, runtime, reason and rollback pointer; the rate
columns are blanked. The live shapes stay verbatim — those numbers are what the
deployer and `models.yml` consume.
2026-10-19 10:56:37 -07:00

7.0 KiB

type, description, tags, timestamp
type description tags timestamp
reference FrankBook-Pro — the Mac mini running the *arr stack + qBittorrent inside a podman machine VM, gluetun-gated
frankbook-pro
mac
arr
qbittorrent
gluetun
wireguard
podman-machine
2026-09-01

FrankBook-Pro

FrankBook-Pro (192.168.0.112, macOS x86_64, Intel) runs the *arr automation stack and qBittorrent inside a podman machine VM (Fedora CoreOS-style core user). Seven quadlet units live in frankbook-pro/<svc>/quadlet/: gluetun, qbittorrent, prowlarr, sonarr, radarr, lidarr, readarr.

Why a VM, and why inside it

  • macOS podman runs containers inside a VM; quadlet units are installed in the VM (/home/core/.config/containers/systemd/) via podman machine ssh.
  • /Volumes/COMPLETE (review disk) and /Volumes/INCOMPLETE (in-progress disk) are virtiofs-mounted into the VM, so qBittorrent writes straight to the same disks the human review workflow uses.
  • Grab-only stack: the arrs never auto-import; nothing writes to the entropy volume. Completed files land in /Volumes/COMPLETE/Finished Torrents.

WireGuard gate (gluetun) — ACTIVE

qBittorrent downloads through gluetun (netns share); the arrs run without it. Provisioned 2026-09-01 with a second Proton WireGuard config (server PA-12; the downloaded .conf lives in ~/Downloads/FrankBook-Pro-PA-12.conf on Dankware). One config = one keypair — reusing Dankclaw's would bounce the server-side endpoint and kill SearXNG. The Seattle server the plan originally assumed is equally valid; only endpoint + server pubkey must match the chosen config. Egress verified from inside the VM: curl ifconfig.me shows the Proton PA exit (never the residential IP), ~19 MB/s sustained on a live torrent.

/home/core/Containers/gluetun/env (0600, inside the VM):

VPN_SERVICE_PROVIDER=custom
VPN_TYPE=wireguard
WIREGUARD_PRIVATE_KEY=<from the Proton .conf>
WIREGUARD_ADDRESSES=<from the Proton .conf>
WIREGUARD_PUBLIC_KEY=<that server's pubkey>
WIREGUARD_ENDPOINT_IP=51.179.177.2
WIREGUARD_ENDPOINT_PORT=51820
WIREGUARD_ALLOWED_IPS=0.0.0.0/0,::/0
WIREGUARD_PERSISTENT_KEEPALIVE_INTERVAL=25s

The private key is hashed into the VM env file and never enters the repo. NAT-PMP inbound forwarding is available on Proton (gluetun supports it FIREWALL_INPUT_PORTS + NATPMP=true) — deliberately deferred: the e2e gate passes outbound-only, and swarm peers needing an inbound port is a seeding-era concern, not a grab-only one.

Deploy flow

Same deployer as every host: ./scripts/deploy.sh frankbook-pro --service <svc> from Dankware. The Mac-side handler (deploy_frankbook_stack in scripts/deploy-remote.sh) pipes unit files + a seed script through podman machine ssh bash -s, seeds qBittorrent's first-boot config once (marker file qbit-seeded), restarts the selected unit inside the VM, and health-checks its published port on Mac loopback.

LAN reachability

gvproxy forwards published ports to Mac loopback only. LaunchAgents (local.fwd.* in ~/Library/LaunchAgents) run socat forwarders binding the LAN IP (192.168.0.112) for arr UIs (9696/8989/7878/8686/8787) and the qB WebUI (8080). The two 6881 tcp+udp agents were retired: gvproxy binds a wildcard *:6881/udp listener (dual-stack; Go sets SO_REUSEADDR on TCP but not UDP), so the socat-specific bind collides at every boot — delete the agents; swarm inbound (if ever needed) is the Proton NAT-PMP path, not the LAN one. Note macOS's application firewall still filters gvproxy inbound from non-local sources (stealth mode drops unsolicited packets), so cross-host reachability of 8080 from other LAN boxes may need socketfilterfw allowlisting of gvproxy — Mac-local use and swarm egress are unaffected.

qBittorrent runtime + wiring (2026-09-01)

  • WebUI\Password_PBKDF2 is a PBKDF2 @ByteArray(salt:hash) (PBKDF2-HMAC-SHA512, 100k iterations, 64 bytes) — qB ≥ 4.2 ignores plaintext. The plaintext lives in /home/core/Containers/qbittorrent/env (mode 600, VM-local) for the arr wiring. The first seed wrote the hash under the legacy WebUI\Password key (silently ignored → every client got Unauthenticated); the live conf was patched and scripts/deploy-remote.sh fixed to write the _PBKDF2 key. Gotcha (live, 2026-09-01): after qB 5.x ran, its conf rewrite left a hash line 4.6.7 rejects (invalid credentials for every login, including the arrs) rewriting the same @ByteArray line fresh (same password, 100k iterations) restored login. Any future version flip: regenerate the line.
  • HostHeaderValidation=false + ServerDomains=*: the socat forwarder preserves the LAN Host header, which would otherwise be rejected.
  • Save-path convention: Session\DefaultSavePath=/Volumes/COMPLETE/ Finished Torrents, Session\TempPath=/Volumes/INCOMPLETE/incomplete (two-disk layout: partials on INCOMPLETE, qB moves on completion). qB 5.2 API adds with a category do not inherit the category save path (no auto-TMM), so the default itself points at Finished Torrents: every grab lands there regardless of client behavior; human review moves files onward; nothing writes to the entropy volume.
  • Categories seeded: Finished Torrents, lidarr, radarr, readarr tv-sonarr (all → Finished Torrents).
  • Download clients (gateway 10.88.0.1:8080, user admin): all five test green against live qB — sonarr (tv-sonarr), radarr, lidarr, readarr (rows pre-created in the prior session; passwords re-pushed via API), and prowlarr (created from the /downloadclient/schema template — a hand-minimal body 400s in Prowlarr's create-time test). Readarr's EOL validator (last release 2023) rejects qB ≥ 5's 204 empty login success as "Authentication failure" — that kills runtime auth too, not just API creates; the fix was pinning qB itself (below), after which readarr tests 200 like the rest.
  • qB pinned to 4.6.7 (Image=lscr.io/linuxserver/qbittorrent:4.6.7 not latest): latest resolved to 5.x, whose 204 login breaks Readarr's frozen client; 4.6.7 answers the legacy 200 + "Ok." that every client accepts. Pinned in frankbook-pro/qbittorrent/quadlet/qbittorrent.container.
  • Prowlarr Applications push to sonarr/radarr/lidarr (fullSync gateway ports). Readarr deliberately omitted: prowlarr's indexer-push test to readarr's /api/v1/indexer/test 500s (EOL schema drift). Legacy Prowlarr-* indexer rows carried in the migrated dankserver DBs pointed at the unresolvable hostname prowlarr:9696 and were deleted; the current *(Prowlarr) entries test OK.
  • E2E proven (2026-09-01, on 4.6.7): added a legal test torrent via the API with category Finished Torrents — downloaded through the tunnel (~17 MB/s), qB moved it INCOMPLETE → COMPLETE into /Volumes/COMPLETE/Finished Torrents, then deleted with data.

Citations

  • Plan: local://podman-standardization-arr-migration-plan.md (session 2026-09-01)
  • Units: frankbook-pro/*/quadlet/*.container, seam tests/frankbook_quadlet.bats
  • Handler: deploy_frankbook_stack, scripts/deploy-remote.sh