docs: distill the managed skill library into the vault (waves 1-7)
All ~173 managed skills read in full and merged, one polished reference page per skill-cluster: - LLM cross-cutting (17 pages): GGUF Compatibility, Llama Cpp Serving Sizing, Llama Cpp Multi-Device Splits, PCIe Link and Atomics, RDNA4 Container Serving, RDNA4 MoE Expert Offload VRAM Budget, vLLM Boot Forensics, vLLM Porting and Compile Triage, LLM Bench Windows, LLM Performance Diagnosis, Model Swap and Rollback, Tcclaviger Fork Ops, Heterogeneous Split Triage, FreeToken Builds + deltas folded into the retired runbooks (GLM DFlash2 port laws, Lucebox dual-R9700, R9V qualification pipeline, FLM pack registration, ik hybrid envelope, frank-medium split rebalance, llama.cpp GGUF preflight, batch-ubatch split section, bench-window D-state/stale-read notes, second-endpoint bring-up). - Architecture (3): Stale Signal Audit, Quadlet Lifecycle, Deploy State Triage. - Operations (6 + index): Remote Job Runner, Payload and Disk Reclaim, Container Host Reachability, Fleet Ops Playbook, Fleet Audit and Posture, SSH and Remote Access. - Infrastructure: Observability Provisioning + Homepage Status Probes; updates to Authentik, Anubis, LAN-DNS (per-client DoH bypass, Porkbun zone ops), Swap Configuration, OpenWebUI, Hermes (pre-existing page preserved and extended). - FrankBook-Pro: ARR-Stack filled (API split, schema-first probing, auth-posture, auth-config trap); qBittorrent E2E verification. - Desktop/Agent/Research: Noctalia and Niri, OMP Harness, Agent Docs and Edits, Command Center Dotfiles, PICO-8 Asset Standards. - Indexes: LLM Cross-Cutting References section, Operations/ and Agent/ index pages, root-index Skill Distillation section, AGENTS.md pointer. - log.md carries the wave plan. check-vault-links.py 0 unresolved (185 pages); ./tests/run.sh 366/366.
This commit is contained in:
@@ -5,3 +5,115 @@ description: "The *arr automation stack (Prowlarr, Sonarr, Radarr, Lidarr, Reada
|
||||
tags: [arr-stack, prowlarr, sonarr, radarr, lidarr, readarr, qbittorrent, frankbook-pro, dankserver]
|
||||
timestamp: 2026-09-04T00:00:00Z
|
||||
---
|
||||
|
||||
# *arr Stack
|
||||
|
||||
The *arr automation stack runs on **FrankBook-Pro** (the Mac mini) as quadlets
|
||||
inside its podman machine; all egress rides the gluetun WireGuard netns. The
|
||||
per-service pages ([[Prowlarr]], [[Sonarr]], [[Radarr]], [[Lidarr]],
|
||||
[[Readarr]], [[qBittorrent]]) carry deployment facts; this page holds the
|
||||
cross-cutting API and auth-posture procedures.
|
||||
|
||||
## API version split (memorize before any *arr HTTP call)
|
||||
|
||||
- Sonarr/Radarr: `/api/v3/…`; Lidarr/Readarr/Prowlarr: `/api/v1/…`.
|
||||
- Prowlarr is port **9696** — 8090 is Jackett.
|
||||
- **Empty body = endpoint absent**, not a failure: probe endpoints by status
|
||||
code first; v1 has no `/api/v1/profile` endpoint at all.
|
||||
- `PUT /downloadclient` and `PUT /indexer/{id}` take a SINGLE resource object
|
||||
(GET it, patch `settings`, PUT the whole object back). An array body fails
|
||||
with `Path: $ | BytePositionInLine: 1`.
|
||||
- API keys live in each container's config:
|
||||
`podman exec <svc> grep -o "<ApiKey>[^<]*" /config/config.xml | cut -d">" -f2`.
|
||||
They are local-only secrets — they stop being secret the moment a vhost
|
||||
serves the API unauthenticated.
|
||||
|
||||
## Schema-first probing (validators are free documentation)
|
||||
|
||||
Send the FULL schema template object with fields filled; v1 validators reject
|
||||
partials, and each error names the next required field — peel validators one
|
||||
live call at a time instead of guessing payload shapes:
|
||||
|
||||
- `'Fields' must not be empty` → send a full schema copy, not `fields:[]`.
|
||||
- `'Base Url' must not be empty` when keys were camelCase → **PascalCase is
|
||||
required** (`BaseUrl`, `ApiKey`) — schema keys, not the JSON wire keys.
|
||||
- `DefaultMetadataProfileId must be > 0` → fetch real ids from
|
||||
`GET /api/v1/metadataprofile` (rows like `(1,'Standard')`);
|
||||
`GET /api/v1/qualitydefinition` returns the quality CATALOG — ids ≠
|
||||
profiles.
|
||||
- `targetType null` → configContract not registered in that build (this
|
||||
Prowlarr build has no Prowlarr-plugin indexer; integration is
|
||||
Torznab-family only).
|
||||
- `testingPackageId` in a PUT body downgrades validation failures to
|
||||
warnings.
|
||||
- `syncLevel` is enum `ApplicationSyncLevel` — omit it or use the int; a
|
||||
string is rejected.
|
||||
|
||||
**Verification rules:** `POST /downloadclient` returns the COLLECTION, not
|
||||
the created object — verify via GET. Test endpoints return verdicts in the
|
||||
BODY at HTTP 200 (`{}` = pass, a list = fail) — judge from bodies, not
|
||||
status codes. Command POSTs (`MoviesSearch`, `ApplicationSync`) run
|
||||
server-side and respond only when the work finishes: curl `-m` timeouts
|
||||
(HTTP 000) during a search are NOT failures — poll queue/history afterward
|
||||
instead of re-firing; warm small commands (`RefreshMonitoredDownloads`)
|
||||
answer in ~20 ms, so a hang means live work in progress, not a dead API.
|
||||
|
||||
**DB as arbiter:** when endpoint shapes are opaque, stop the container and
|
||||
edit `/opt/prowlarr/config/prowlarr.db` with `sudo python3` sqlite directly,
|
||||
then start. The indexers table columns are
|
||||
Id/Name/Implementation/Settings/ConfigContract/Enable/Priority/Added — the
|
||||
enable flag column is `Enable` (not `EnableRss`). Prowlarr's real application
|
||||
settings values live in `prowlarr.db` → `Applications.Settings` JSON (the
|
||||
`/api/v1/applications` GET responses carry `fields: []`).
|
||||
|
||||
## Auth posture probe (ground truth is behavior, not config flags)
|
||||
|
||||
`AuthenticationMethod=None` + `AuthenticationRequired=Enabled` in
|
||||
`config.xml` is ambiguous on paper; on the wire it means a login screen with
|
||||
**zero users** — first-account-wins.
|
||||
|
||||
1. **Confirm which host runs the service before probing** (`podman ps` on
|
||||
the target, not the box you ssh'd into first — the arrs live on
|
||||
FrankBook-Pro).
|
||||
2. Probe an API endpoint that bypasses the SPA shell, locally and through
|
||||
any vhost: `curl -s -o /dev/null -w "%{http_code}"
|
||||
http://<host>:<port>/api/v3/system/status`. **SPA roots (`/`) always
|
||||
serve a 200 shell — never conclude "open" or "gated" from `/`.**
|
||||
401 = gated; 200 + JSON = API fully open (anyone on the net can drive it
|
||||
with curl).
|
||||
3. For config truth, dump the whole file
|
||||
(`podman exec <svc> cat /config/config.xml`), not a piped
|
||||
`grep | sed -n 2p`: **`sed -n Np` exits 0 on zero matches**, so the
|
||||
pipeline hides a miss and you conclude "empty field" when the grep itself
|
||||
failed.
|
||||
4. Decision framing: when posture = gated-with-zero-users, present it as a
|
||||
decision menu (None behind the front-door wall vs External/authentikarr),
|
||||
not a silent change — first-account-wins means whoever logs in first owns
|
||||
the instance.
|
||||
|
||||
## The `None` + `Enabled` auth-config trap (v1 .NET apps)
|
||||
|
||||
`<AuthenticationMethod>None</AuthenticationMethod>` +
|
||||
`<AuthenticationRequired>Enabled</AuthenticationRequired>` is
|
||||
self-contradictory: the UI Save is permanently disabled, and any save throws
|
||||
`DryIoc.ScopedItemException` in `AuthorizationMiddleware` → 500 on every
|
||||
page after restart. The valid no-auth representation is **absence of the
|
||||
`<AuthenticationRequired>` key**, not the literal string `Disabled`. Fix =
|
||||
delete the key from `/config/config.xml`
|
||||
(`sed -i "/<AuthenticationRequired>/d"`), restart the container. Tell-tale:
|
||||
one v1 app boots clean while siblings 500-sprawl → diff their config.xml
|
||||
auth blocks; the healthy one shows the correct shape. (Prowlarr runs
|
||||
`Forms` + `Enabled` healthily — the crash combo is `None`+`Enabled` only.)
|
||||
|
||||
General rules that saved the session these came from: container
|
||||
`State=running` ≠ app serving — read `podman logs --tail 12 <c>` before
|
||||
theorizing; when a UI gate blocks saving, go under it (these apps keep
|
||||
plaintext XML config on disk — read/edit via `podman exec`).
|
||||
|
||||
## See Also
|
||||
|
||||
- [[Prowlarr]] — indexer feeds and the v2 sync model
|
||||
- [[Sonarr]] · [[Radarr]] · [[Lidarr]] · [[Readarr]] — the managers
|
||||
- [[qBittorrent]] — download client, 4.6.7 pin, E2E verification
|
||||
- [[FrankBook-Pro]] — the host and its podman machine
|
||||
- [[Homepage Status Probes]] — how the e2e gate treats this sleeping host
|
||||
|
||||
Reference in New Issue
Block a user