Commit Graph

55 Commits

Author SHA1 Message Date
jeremy beb727528a docs: UniFi controller consolidation, STP fix, NFS recovery
- Remove duplicate unifi-os-server container from .100; sole UniFi
  controller is now the .150 Podman instance (UI :11443, inform :8080).
  Data preserved; compose dir kept.
- Document STP root-cause/fix for wifi client drops: version mismatch
  (stp vs rstp) + default priorities -> root flapping; fixed by RSTP
  everywhere + .159 pinned root @4096.
- Known Issue #20: correct the stale .100:11443 blackbox probe note -
  the probe DID exist in the live config and was removed 2026-10-06
  (backup saved) + Prometheus reloaded; UnifiDeviceDown rule is inert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-06 19:06:05 -05:00
jeremy 9a81138cc9 docs: QR sign-in confirmed working end-to-end
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 16:36:27 -05:00
jeremy 84021278f9 docs: MAS deployment - CLAUDE.md service lists and known issues 24,27,28,29
- Synapse DB history rewritten (SQLite -> local -> PostgreSQL, and why)
- #27: Synapse no longer serves /login; Traefik compat routing is load-bearing
- #28: MAS tags are not v-prefixed; distroless; /health only on :8021
- #29: MAS signing keys need a vault home (vault currently locked out)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 15:21:21 -05:00
jeremy a0bbf801f1 feat: enable MSC4108/MSC4388 - QR sign-in now advertised
org.matrix.msc4108 = True (was False); rendezvous endpoint live (400 not 404).
msc4388_mode: authenticated so unauthenticated internet parties cannot open
rendezvous sessions. All bots syncing, 0 errors.
New containers total ~263MB (mas 39MB, mas-db 40MB, synapse-db 184MB).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 15:18:10 -05:00
jeremy 8825cc3d4a feat: publish MAS at auth.hobbs.farm; route login/logout/refresh to MAS
Under MAS, Synapse returns M_UNRECOGNIZED for the login endpoints, so the
mess-auth-compat router (priority 1000) sends /_matrix/client/*/login,
/logout and /refresh to MAS while everything else stays on Synapse.

Cloudflare A record for auth.hobbs.farm already existed (98.160.103.126,
DNS-only). Blackbox probes added for MAS internal health (:8021) and the
public discovery endpoint; all four matrix-related probes UP.

Snapshot of the node's traefik dynamic config committed for reference.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 15:15:57 -05:00
jeremy 9dff3c2d95 feat: synapse auth delegated to MAS; 20 users/53 tokens/53 devices migrated
Verified: auth_metadata 200, migrated password authenticates via MAS compat
layer, migrated access tokens still valid against Synapse, all bots syncing.
Downtime 55s (20:09:17Z-20:10:12Z).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 15:12:27 -05:00
jeremy f9a024ce10 docs: syn2mas dry-run results and count reconciliation
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 15:09:07 -05:00
jeremy af2b560686 feat: deploy matrix authentication service 1.23.0 on :8020
Config at /mnt/docker-data/configs/mas/config.yaml (node-only, holds signing keys).
Health on :8021 (distroless image - no container healthcheck possible).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 15:07:23 -05:00
jeremy 89eddfc134 chore: synapse ported sqlite -> postgres (20 users/93888 events/65 devices verified)
Node-side config change; homeserver.yaml is not tracked in the repo.
Downtime 2m35s. SQLite file retained inert at /var/lib/synapse/homeserver.db.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 15:04:32 -05:00
jeremy d7ca70db32 feat: add mas-db postgres for matrix authentication service
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 15:01:45 -05:00
jeremy a220e7903b feat: add postgres 16 for synapse (local disk, C collation) ahead of MAS
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 14:59:35 -05:00
jeremy 986f219135 docs: matrix auth inventory and MAS QR sign-in plan
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 14:57:55 -05:00
jeremy bfb9b03a26 fix: move jellyfin config to local /var/lib/jellyfin (NFS SQLite lock stalls); decommission OpenVAS
Jellyfin lockups root-caused to jellyfin.db (WAL mode) on NFS: SQLite
"database is locked" errors escalated 22->33->125/day, with DB commands
blocking 60-102s, causing healthcheck flaps and playback stalls. Config
rsynced from /mnt/docker-data/configs/jellyfin to local /var/lib/jellyfin
on bart; healthy after redeploy. jellyfin:2026060106 v12 image pin
unchanged. Old NFS copy left in place as backup.

OpenVAS fully removed from bart per user (~39GB reclaimed: containers,
volumes incl. PG DB, image). Prometheus probe and Farm Manager link
removed. Compose dir kept for reference; Known Issue #21 marked moot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 18:21:20 -05:00
jeremy 8a051939ed docs: OpenVAS pg_upgrade mountpoint loop (Known Issue #21) — DB wiped fresh 2026-07-15
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 20:03:31 -05:00
jeremy 66c65d1b4e fix: repin jellyfin to v12 tag 2026060106 (DB is v12 schema)
The 2026-07-13 media redeploy overwrote a node-side pin with the repo's
:latest (10.11.x), downgrading jellyfin under its v12-migrated DB and
breaking Resume/home queries ('no such column: b.ExtraIds'). Repinned;
do not unpin until official stable >= 12.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 21:24:21 -05:00
jeremy 45573cf9fc fix: nzbhydra2 stale NFS H2 lock -> local /var/lib/nzbhydra; add Farm Manager links page to post-change checklist
nzbhydra2 was the 4th victim of the 2026-07-12 power-event stale NFS locks
(H2 'file is locked' retry loop; the earlier mem bump was a red herring).
Farm Manager links updated (AdGuard/Actual Budget/Portainer removed, UniFi
-> :11443) and image rebuilt; links maintenance is now checklist item 5.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 20:39:14 -05:00
jeremy d35af1ddad chore: decommission clip-service (.192) and Actual Budget (.100)
clip-service: container+volumes+compose removed, ~2GB RAM freed; frigate-notify
config never referenced it. Actual Budget: container+compose removed, data kept
at /mnt/docker-data/configs/actual-budget. Prometheus probes for both removed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 20:24:29 -05:00
jeremy ed5f330d2c chore: decommission AdGuard Home (dead since 2026-05-17, LAN uses router DNS)
Container, data, compose dir, and Prometheus probe removed from .192.
Ports 53 and 3000 freed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 20:20:37 -05:00
jeremy 5d7c8ea030 fix: recover from 2026-07-12 power-event fallout + efficiency cleanup
- gitea: LevelDB queues -> local /var/lib/gitea-queues (stale NFS lock, 7,972-restart loop)
- semaphore-db: data -> local /var/lib/semaphore-db (stale ibdata1 NFS lock, 975 restarts)
- sonarr: config -> local /var/lib/sonarr (SQLite-on-NFS migration crash)
- nzbhydra2: mem_limit 768M -> 1G (was pinned at limit, unhealthy)
- jellyfin: deploy pending VAAPI device passthrough (i965/renderD128)
- openvas: disable Watchtower (latest major pull forced pg_upgrade crash-loop)
- onyx: fully decommissioned (down since ~June 8 unnoticed)
- remove duplicate monitoring/traefik/guacamole stacks from .100, failover guacamole from bart
- synapse: raise rc_message (alertmanager receiver was 429-limited; alerts silently dropped for weeks)
- prometheus: UniFi probe 8443 -> 11443, solo.hobbs.farm via 401-tolerant module, drop onyx target
- frigate restart cron: unwritable /var/log path meant it never ran; now 4x daily to ~glyptic
- CLAUDE.md: document all of the above + AdGuard broken/unconfigured since 2026-05-17

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 19:20:10 -05:00
jeremy 81a7464dd8 docs: record CouchDB/Obsidian LiveSync in CLAUDE.md
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 12:04:02 -05:00
jeremy 0e4b2f7d1a feat: deploy CouchDB on hf-pdocker-02 for Obsidian LiveSync (:5984)
Backs the Obsidian 'Second Brain' vault (private repo: git.hobbs.farm/jeremy/
second-brain) with self-hosted multi-device sync. LAN-only for now; no public
Traefik route yet.

- couchdb:3.4 pinned, Watchtower disabled, mem_limit 1g.
- Data on LOCAL disk (/var/lib/couchdb) -- CouchDB file locking breaks over
  NFSv3, same class as guacamole-db and semaphore-db.
- local.ini mounted READ-WRITE, deliberately: CouchDB 3.x writes runtime config
  back into the last-loaded ini, and with :ro it exits 1 and logs NOTHING --
  a silent crash-loop that is very hard to diagnose.
- CORS allows app://obsidian.md and capacitor://localhost (LiveSync desktop +
  mobile origins); a wildcard origin is not allowed alongside credentials.
- require_valid_user everywhere EXCEPT /_up, so the blackbox probe can health
  check it without credentials. Anonymous callers get 401 on all data.
- Admin credentials in Vaultwarden ('CouchDB - Obsidian LiveSync'); .env is
  gitignored, .env.example carries a placeholder.

Prometheus probe added (probe_success=1). Vault database: 'secondbrain'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 12:03:15 -05:00
jeremy f0e2918bd1 revert: remove LifeOS deployment
Evaluated and torn down at the user's request. Container, image, source
(/opt/lifeos), SQLite data (/var/lib/lifeos) and compose dir removed from
hf-pdocker-02; Prometheus probe removed and both instances reloaded; port
8095 released.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:43:14 -05:00
jeremy f48c7a40cd fix: make LifeOS actually render in local mode
The container served a blank page. Four upstream assumptions broke a
root-served, Supabase-less deployment; all are patched at build time with
grep assertions so a silent upstream rename fails the build instead of
shipping a blank page again.

- React Router was pinned to basename '/app' (upstream is hosted under an
  /app path). At '/' it matched no route and rendered nothing -- silently,
  with only a console warning. This was the blank page.
- supabase.ts calls createClient() at module scope, which throws
  'supabaseUrl is required' on an empty string and killed the bundle before
  React mounted. Dummy values fix it; nothing reads Supabase in local mode.
- initAuth() only booted the local user for Tauri/Electron, so a browser
  build fell through to a Supabase login screen the backend cannot serve
  (it has no /api/auth/login or /api/auth/signup -- it is single-user).
- The local API adapter has no realtime layer, so supabase.channel() was
  undefined and every subscribing component tripped the ErrorBoundary
  ('Something went wrong'). Added no-op stubs; realtime is meaningless on a
  single-user instance.

Verified in a browser: dashboard and routed pages render, 0 fatal errors.

Known gap: the Flask backend implements only a subset of the cloud schema,
so quests, messages, partnerships, grocery_lists, recurring_transactions,
junction_traditions and habit_suggestions 404. Non-fatal; those features
degrade. Core (tasks/habits/goals/health/finance/journal/XP/AI chat) works.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:32:14 -05:00
jeremy 27f6d95bf6 chore: sync accumulated infra changes and docs
Removals: openwebui and netclaw compose + Traefik routes (both decommissioned).
Updates: litellm, n8n, vaultwarden, ai-agents, media, traefik routes, CLAUDE.md
(nodes/ports/known-issues), agent definitions.
Additions: Rongorongo tree, LinkedStorm plan, rename-bart spec, vllm brief,
tls-options and security-headers Traefik config.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:19:21 -05:00
jeremy 47ac49a039 fix: anchor friday-voice gitignore to repo root
The unanchored pattern also swallowed compose/hf-pdocker-01/friday-voice/.
Only the top-level nested repo should be ignored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:19:12 -05:00
jeremy 971fe8dda8 feat: standalone node-exporter + telegraf compose per node
Post-Swarm: node-exporter must run standalone with pid:host, since Swarm mode
blocked it and cross-node /proc namespaces contaminated swap metrics. Marks the
stacks/ definition superseded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:19:04 -05:00
jeremy 266ea11447 feat: FRIDAY Voice stack on the GPU machine; VoiceCoach history
FRIDAY Voice (speaches GPU STT/TTS + hermes agent + push-to-talk console) on
.150 Docker Desktop, fronted by coach.hobbs.farm. Also captures the VoiceCoach
compose/agent trees and deploy notes it replaced, which had never been committed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:19:04 -05:00
jeremy dddc6734d0 feat: frigate-notify v2 (modular app, CLIP recognition) + clip-service
Splits the single main.py into config/database/models/routes/vision/recognition/
ollama_client/cleanup modules, adds a web UI, and introduces clip-service for
CLIP (ViT-L-14) embeddings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:19:03 -05:00
jeremy 835a8d6644 feat: deploy LifeOS on hf-pdocker-02 (:8095)
Self-hosted LifeOS (github.com/lifeos-app/lifeos, pinned 3009bf6) in local
mode: no Supabase. Multi-stage build - Node builds the Vite bundle, gunicorn
serves it plus the bundled Flask/SQLite API from one process.

LAN-only on purpose: the backend is single-user with no auth, so anyone who
reaches the port has full read/write. Needs Traefik basicAuth before it can
ever be exposed publicly.

Two upstream bugs patched via sed (build fails loudly if they are renamed):
the chat model was hardcoded to the author's private 'sentient-teddy' bridge,
and a hardcoded 30s timeout failed every first message because Ollama needs
~46s to cold-load the model (0.7s warm). Both are env vars now.

SQLite stays on local disk - NFSv3 breaks WAL locking.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:18:46 -05:00
jeremy 41ee6452fc chore: ignore tool scratch dirs and the nested friday-voice repo
.playwright-mcp/ and .superpowers/ hold browser console dumps and brainstorm
session state. friday-voice/ is a separate Gitea repo and would otherwise be
committed here as a dangling gitlink.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:18:46 -05:00
jeremy a5df6d4d3c feat: add PostgreSQL to LiteLLM for UI auth support
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 22:13:23 -05:00
jeremy 0c3ce454bd feat: deploy LiteLLM proxy on hf-pdocker-01
Routes claude-opus-4-8, gpt-5.5, qwen2.5:14b, llama3.1:8b through a
single OpenAI-compatible endpoint on :4000 (LAN-only, no auth).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 22:07:36 -05:00
jeremy 7218a11f20 docs: LiteLLM proxy design spec
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 22:04:39 -05:00
jeremy 98cae1e08f feat: linkedstorm docker-compose and Traefik route
Add compose/hf-pdocker-01/linkedstorm/ with 3-container compose (pipeline :8300, api :8310, cron) and stacks/traefik/dynamic/linkedstorm.yml routing linkedstorm.hobbs.farm -> :8310.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 10:54:53 -05:00
jeremy cd3f3161da docs: add LinkedStorm home audio assistant design spec
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 21:59:32 -05:00
jeremy 904d1ef397 fix: onyx nginx - use rewrite to strip /api/ prefix with variable proxy_pass
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 13:58:30 -05:00
jeremy a7dfbdeb79 fix: onyx nginx - use Docker DNS resolver to prevent stale upstream IPs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 13:30:42 -05:00
jeremy 6233cf9e1d fix: disable Onyx telemetry (stops data posting to telemetry.onyx.app) 2026-05-22 09:00:46 -05:00
jeremy 0d5b781aef fix: onyx nginx - strip /api prefix when proxying to api_server
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 08:30:37 -05:00
jeremy 6f485ff6e5 docs: update CLAUDE.md — Coral USB TPU, Onyx redeploy, infra fixes 2026-05-20
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 08:06:05 -05:00
jeremy 752b8230ed infra: clean redeploy of Onyx on bart with latest images
Full wipe and fresh start: removed gitea_patch/unstructured_patch
hacks from startup commands, upgraded all onyxdotapp images from
nightly-latest-20260331 pin to :latest, removed UNSTRUCTURED_SERVER_URL
(service decommissioned 2026-04-14), added Watchtower disable labels
to ALL services (was missing on web_server, model_servers, db, cache,
opensearch, vespa, nginx), added nginx.conf for reverse proxy.

Alembic ran 349 migrations cleanly on fresh DB. All 10 containers up,
0 restarts, HTTP 200 at :3005.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 07:12:03 -05:00
jeremy 03b7a46a96 fix: pin guacamole/guacd to 1.6.0 and disable Watchtower to prevent schema breakage
Watchtower pulled a newer guacamole:latest image whose JDBC extension expected
tables not present in the existing DB (guacamole_user_attribute etc.). Fixed by
reinitializing the DB with the official 1.6.0 schema (001-create-schema.sql +
002-create-admin-user.sql) and pinning both guacamole and guacd to 1.6.0 with
com.centurylinklabs.watchtower.enable=false to prevent recurrence.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 06:44:40 -05:00
jeremy 78b824bb39 fix: pin gitea to 1.26.1 and disable Watchtower to prevent broken image pulls
Watchtower pulled gitea/gitea:latest three times (Mar 12, Apr 19, Apr 25)
and at least one pull resulted in a broken image with git binary failures.
Pin to stable gitea/gitea:1.26.1 and add watchtower.enable=false label
so the image is only updated by deliberate human action.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:17:15 -05:00
jeremy a908973264 infra: rongorongo state-sync backend + Traefik basicAuth
Add a Flask backend service for cross-device state persistence, storing
JSON state on an NFS volume at /mnt/docker-data/configs/rongorongo/data.
Frontend Dockerfile/nginx.conf reorganised into frontend/ subdirectory;
frontend API calls now route to /api/* handled by the backend container
over a dedicated bridge network. Traefik basicAuth middleware added to
the public URL with the bcrypt hash deliberately kept out of git
(REPLACE_AT_DEPLOY placeholder in rongorongo.yml). Prometheus probe moved
from https-external to internal http://192.168.86.192:8181/health to
bypass the new auth wall.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 18:51:47 -05:00
jeremy 795908e1ef infra: deploy Rongorongo decipherment engine to hf-pdocker-01
Standalone Compose service running a locally-built nginx image that
serves a static Anthropic-API frontend. Traefik dynamic route added
for public HTTPS access. Blackbox probe added to prometheus.yml for
uptime monitoring. CLAUDE.md updated with service entry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 13:10:47 -05:00
jeremy 04a18efc6a infra: pin onyx-backend to nightly-latest-20260331, disable Watchtower
DB alembic HEAD is 1d78c0ca7853 (remove_voice_provider_deleted_column).
20260331 is the exact build where that revision is HEAD — alembic runs
clean with no migrations applied. Later builds (20260412/latest) introduce
migrations d8cdfee5df80–503883791c39 that break api_server startup.

Watchtower disabled on api_server and background to prevent future
auto-upgrades from breaking alembic compatibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 15:00:42 -05:00
jeremy eb739c365c fix: sentence aggregator minimum 40-char threshold, no single-word flushes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:46:43 -05:00
jeremy 9943fd4410 infra: repurpose Spirit as autonomous infrastructure ops agent
Spirit now monitors #notifications Matrix room for Prometheus alerts,
auto-investigates issues, takes corrective action (container restarts,
disk cleanup, etc.), and documents incidents in Wiki.js.

Changes:
- Custom spirit-ops Docker image (Docker CLI + SSH + diagnostic tools)
- Docker socket mount for local container management
- SSH keys for remote access to hf-pdocker-02 and bart
- Wiki.js API integration for incident documentation
- Prometheus probe for Spirit gateway health
- Safety guardrails: protected services, rate limiting, escalation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 10:36:20 -05:00
jeremy 59f529e3a7 infra: deploy Open WebUI on hf-pdocker-01 with Ollama + Claude backends
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 14:13:16 -05:00
jeremy cd37bb9858 infra: hf-pdocker-01 Phase 2 migration — all services returned from failover
Node hf-pdocker-01 hardware fully repaired and rebuilt (2026-03-08). This
commit captures the completed Phase 2 migration where all failover services
are returned from hf-pdocker-02/bart back to hf-pdocker-01 as their permanent
home.

New compose stacks for hf-pdocker-01:
- adguard: AdGuard Home DNS/ad-blocking (:3000, :53)
- traefik: Reverse proxy with TLS (:80/:443/:8090), .env.example included
- monitoring: Grafana, Prometheus, Alertmanager, InfluxDB, Blackbox, matrix-receiver
- smarthome: Home Assistant (:8123), ESPHome (:6052), Mosquitto (:1883/:8883)
- matrix: Synapse homeserver (:8008) + synapse-db + well-known (:8010)
- guacamole: Guacamole (:8199) + guacd + guacamole-db (local MySQL)
- farm-manager: Farm Manager API (:8888)

Updated compose stacks for hf-pdocker-01:
- frigate-notify: MQTT/Matrix hosts reverted from bart (.167) to hf-pdocker-01 (.192)

Documentation:
- docs/plans/2026-03-08-hf-pdocker-01-phase2-migration.md (new)
- CLAUDE.md: Full service distribution update — failover labels removed,
  hf-pdocker-02/bart cleaned up to reflect only permanent services,
  NetClaw/Aaron added to hf-pdocker-02, DNSStubListener fix noted

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 19:58:03 -05:00