Files
esh-pfi-infrastructure/persistent-memory.md
T

65 KiB
Raw Blame History

Persistent memory — eshpfi-management

Last updated: 2026-09-09 15:10 PT (fleet-ops: ERP run 7 COMPLETE — erp-seat-base-ara serving for brokkr's base window, erp-tune-v7 staged awaiting his swap cue; Booth ASKS primitive shipped and then made INLINE per operator ruling; ana-ml2 pool actions landed; sox on nh3-dev; docs refreshed across booth/ana-ml2/nh3-dev/run-07 runbook)

Always check for /tmp/infra-ops-handoff.md — if it exists and its Written: stamp is under an hour old, read it (it carries the in-flight handoff from the previous session), then delete it. Older than an hour: stale — delete it unread.

Repo purpose

Reference workspace for PFI infrastructure: server inventory, canonical Docker Compose stacks, ops playbooks, and conventions. Authoritative copies of compose files live on the servers under /opt/docker/compose/<stack>/; this repo mirrors them for version control, editing, planning, and CI-driven deploys. It was originally spun up to handle the fleet backups — keep that lens when triaging backup/storage issues.

Tools and conventions

Sister repos (separate gitea repos, deployed by playbooks here):

Repo Role CI status
vh/task-board MCP + web dashboard for assistant task state (port 7878) push-to-main → CI deploys (2026-04-29)
vh/vor Inquisitor UI sidecar (port 7879) push-to-main → CI deploys (2026-04-29)
vh/nevermore Twice-daily LLM-curated briefing (port 8181, replaces news-digest) push-to-main → CI deploys (2026-04-30)
vh/asset-engine Internal control plane over inference services (port 8200, LAN-direct) push-to-main → CI deploys (2026-05-12)
vh/althing Lean trusted inter-agent message bus — v3.0.0 "the post office" as of 2026-08-28 (U9b flag day, one-way, no rollback): ONE container on nh3-dev at http://10.100.50.40:8390 is the only stateful component; althing-po-herald one per box; althing-listen one per session; postbox is the client. Every v2 command was DELETED, not deprecatedalthing-clipostbox, althing-wake-listeneralthing-listen, althing-light-monitor/althing-receiver gone. Sessions need BOTH ALTHING_POST_OFFICE and ALTHING_HANDLE; there is no default address. ⚠ An unreachable post office is an OUTAGE, never an empty inbox. → persistent-memory.d/2026-08-28-althing-v3-cutover.md per-box install (NOT CI-deploy); nh3-dev = container host + repo; nh3-extdev = system WHEEL at /opt/uv-tools, needs its own wheel install (playbooks/nh3-extdev-althing-v3.yaml)
vh/mead-hall Bifrost tool-provider sidecar (port 5173 on dev VM 10.100.10.50) push-to-main → CI deploys (2026-05-16)
vh/skaldsong Wizard + reader surface (port 8300, ana-docker, registry-pull pattern) push-to-main → CI deploys (2026-05-19)
vh/Worldtree Conversation API (corviduo-dev demo :8080 / personal :8081 / pinned :8082) — Heimdall auth, Bifrost integration. gitea-runner builds on ana-docker; claude-bot ADMIN collaborator (2026-06-20). Now v1.0.0b19. push-to-main → CI build-and-deploy (runner on ana-docker)
vh/yt-voice-clipper YouTube → diarized voice-clip dataset builder + audition console (irv-ml1 :8000) push-to-main → gitea-webhook auto-deploy to irv-ml1 (2026-06-03) — see docs/runbooks/ytvc-autodeploy.md
vh/arbo Catalog-driven ComfyUI engine (irv-ml1 :8201, comfy-dev owns engine/catalog/image) push-to-main → gitea Actions CI (deploy-engine.sh, build-local, health-gated) now LIVE; catalog via :9009 webhook
vh/zonos-gateway OpenAI-compatible TTS gateway over stock ZONOS2 (:8890 irv-ml1); emotion dials-first + voice mapping; reached via LiteLLM ext-tts alias. v0.2.1 (2026-07-18): voice-resolved emotion presets (resolve_preset(name,voice); angry/happy/startled_happy per-voice). 8 voices incl. 4 clones pushed to gitea (main 8f1885b/v0.2.1); deployed irv-ml1 tree still NON-git (hand-updated build context — CI-wire = open follow-up). Spec docs/EMOTION-DIALS-SPEC.md; host-managed voices bind-mount (./voices:/app/voices, drop wav + restart, no rebuild)
vh/soong-lab Noonien Soong character-design studio (SPA + /api + WT /bifrost/tool-call); containerized 2026-07-18, LIVE on corviduo-dev :8443 (image vh/soong-lab:latest). soong-dev owns Dockerfile/compose/workflow; infra-ops owns the host CI = Gitea Actions build+push+DEPLOY on tag/dispatch (fleet recipe: docker:cli + raw buildx, pushes AS vh; auto-redeploy LIVE 2026-07-18 — runner SSHes corviduo-dev as deploy, compose pull && up -d from /opt/soong-lab, health-gated on /api/version). Manual redeploy sudo -u deploy bash -c 'cd /opt/soong-lab && docker compose pull && docker compose up -d'. → archival-memory.md (archived 2026-08-16)
model-training-forge (mtf-dev) Fine-tuning recipe forge; T1 = E-RP writing LoRA, retargeted qwopus-122B→AEON-27B (2026-07-06) (SFT→DPO, LitBench-RM reward) training runs, not a deployed sidecar

(vh/volva + Heid were re-architected from systemd daemons to Claude Code session orchestrators 2026-06-08; their nh3-dev .service units were removed — no longer deployed sidecars here. See Recent decisions.)

  • Two-layer backups — Backrest orchestrates restic for file+DB (5 fleet repos, daily 01:00 PDT); PBS-ANA primary + PBS-NH3 DR mirror for VM images. ana-nas is the SPOF for postgres + PBS-ANA datastore + cross-site restic targets — see docs/runbooks/disaster-recovery.md for the blast-radius matrix. ⚠️ The restic file+DB layer routes through TWO rest-servers (rest-server-ana @ ana-docker:8000 → ana-docker/ana-ml2/esh-docker-vm/vm-esh-nas; rest-server-nh3 @ nh3-nas:8000 → irv-ml1/nh3-docker). Both depend on their NAS's NFS export of /mnt/backup. (rest-server-ana recovered 2026-06-20.)

  • pull-hf-repo.yaml is the canonical "get a HuggingFace model/dataset onto ana-ml2's shared cache at /tank/aimodels/huggingface/" playbook. Supports --var repo_type=model|dataset|space. Replaces ad-hoc huggingface_hub.snapshot_download patterns.

  • Worldtree admin auth — per-instance. Each Worldtree deployment (demo :8080, personal :8081, pinned :8082) has its own Heimdall registry and its own bootstrap admin key. Infra-ops's stored long-lived admin key (key_id 61419c92) at ana-docker:/opt/docker/conf/.secrets/worldtree-infra-ops-admin auths against demo only. Personal-instance admin (the ~/.config/worldtree/personal-admin-token, mode 600) POSTs /admin/keys (mints per-project keys; takes user_id+label, no scope param — scopes are tier-derived). On-instance mint recipe (cleaner than DB-manip): docker exec worldtree-worldtree-api-1 POST /admin/keys with the in-container WORLDTREE_BOOTSTRAP_ADMIN_KEY; cleartext once in .key=wt_live_+16hex. auto-memory reference_worldtree_demo_key_mint.

  • Per-project user keys against personal Worldtree (issued 2026-05-19): skaldsong:79744637, skaldsong:7c1dbbbe, althing:50d85460, mead-hall:a360822d. Mint via /admin/keys, drop value to /tmp/wt-personal-<name>.key mode 600, dev collects + shreds (DO NOT cat to chat transcript).

  • Skaldsong CD pattern (registry-pull). vh/skaldsong's CI builds and pushes gitea.phasefinal.com/vh/skaldsong:<sha> + :latest; playbooks/deploy-skaldsong.yaml on ana-docker pulls + recreates. SHA-pin only. Prereq: host needs docker login gitea.phasefinal.com once.

  • gitea internal route for fleet hosts. gitea is a container on ana-docker — git-SSH 10.250.50.70:222, HTTP :3000. Fleet/colo hosts must use this internal route, NOT public gitea.phasefinal.com (38.120.12.44) — the public path fail2bans the host egress IP. Full gotcha in docs/orientation.md → Git/gitea.

  • docker-as-root pattern (for ops with no admin API, or to edit deploy-owned/root-owned files without sudo): docker run --rm -v <target-dir>:/wt docker:cli sh -c "...". docker-group membership is effectively root via bind-mount. Foot-gun: relative paths in compose.yaml resolve against the sandbox CWD but the daemon interprets them against the HOST fs — always pass -e VAR=/abs/path for any relative-default config dir.

  • scripts/elway sudo handling — elway prompts for the sudo password ONCE via getpass before the first sudo: true step → can't run unattended from a non-TTY tool if any step needs sudo. Sudo-free playbooks run fully non-interactive over key SSH.

  • Per-host SSH identity matters for sudo. infra-ops has NOPASSWD sudo on most PFI Linux boxes (corviduo-dev included since 2026-06-15). On ana-docker: default ssh ana-docker = lkraven (docker-group, NO passwordless sudo); ssh infra-ops@ana-docker HAS NOPASSWD root. → For any sudo op on ana-docker, use ssh infra-ops@ana-docker. ssh infra-ops@10.100.10.50 (nh3-dev) ALSO NOPASSWD sudo; on nh3-extdev infra-ops is sudo-LESS by design (ssh lkraven@10.100.50.42 is the NOPASSWD path). irv-ml1: ssh irv-ml1 = lkraven, docker-group (plain docker) but sudo needs a PASSWORD (no NOPASSWD) — stage model pulls to /home, not root-owned /worktank.

Current state / in-flight

As of 2026-09-09 00:35 PT (end of the 09-08 fleet-ops session — operator: "snapshot and we'll do all 3 on clean context"). Older in-flight blocks (09-08 morning, 09-05/06) are preserved verbatim in archival-memory.md § Superseded in-flight snapshots.

  • 🔥 ERP RUN 7 TRAINING on pfi-gx10 — launched 2026-09-08 23:06 PT, pid in ~/erp-tune/run-07.pid, 542 steps at ~80 s/it, adapter ~noon 09-09. Watch: ssh infra-ops@10.100.50.60 "tr '\r' '\n' < ~/erp-tune/run-07.log | tail". DONE 2026-09-09 13:23 PT — 542/542 steps, 14h17m, train_loss 3.205 (low 2.799 @ step 420), 410-tensor adapter, flex_attention requested AND resolved, harness 0a6bd2e0 clean. Merged to serve/merged-run07 (48.1 GiB, template ae53464b, processor_config byte-identical to stock 32bdf45d). erp-seat-base-ara SERVING on 10.100.50.60:8098 (run-5/6 flags; health 200, round trip verified); erp-tune-v7 staged, NOT serving — awaiting brokkr's swap cue on thread 01M20AHY9DY92RJK84YD24VSY9. Miranda notified for the operator. ⚠ Sampler padding 17.1% (run 6: 0.0%) — the short opening-split rows pair badly; throughput only, not correctness.
  • ana-ml2 pool actions DONE 2026-09-09 02:02 PT (playbooks/ana-ml2-pool-health.yaml): tank scrub clean + cleared, nvme-cli in, zroot 73%. ⚠ Open follow-ups, operator's call: (a) ZFS pool-health ALERTING — tank sat DEGRADED 04-23→09-05 with nvme7 physically absent and nobody knew (ZED mails root, no MTA); (b) nvme7 / slot 0-5 keep-vs-replace — media_errors 2084 lifetime, 0 growth over a full scrub, watch it each visit; (c) boot-time import race (vdevs UNAVAIL→ONLINE + no_replicas every boot). → persistent-memory.d/2026-09-09-ana-ml2-pool-actions-done.md.
  • trial (LiteLLM) → erp-tune-v6-nvfp4a16 on ana-ml2 :8021 (stack stacks/erp-seat, vLLM nightly 311b3513, no gate by operator ruling). Forced tool_choice is prompt-driven (6/9); response_format: json_schema is deterministic. ⚠ stacks/gemma4-charrp lacks --exclude-tools-when-tool-choice-none (same empty-turn trap); applying it bounces the char-rp seat — operator's call, not taken.
  • 📮 althing reachability on a bg seat = the cc-channel route: althing-route declare --handle infra-ops --pid <pid from $CLAUDE_CODE_MESSAGING_SOCKET> per session (--discover-pid refuses on a forked child). The harness kills detached background tasks under memory pressure — use bounded foreground polls (≤590 s), not background watchers, for long waits.
  • Open items carried from 09-06 (unchanged): NASPool evac copy ospool/naspool-evac (1.65 T) + @evac snaps can be destroyed once ONE Backrest run is confirmed (scrub clean, PBS landing); pfi-pve PSU1 dead + backplane bays 9/10 dead (cold spares, next colo visit); FortiGate WAN SSH still temporarily open (trusthost2/3 = NH3 + ESH static) — close when the edge is retired; irv-ml1 on-site decisions (reverse tunnel / UDM fwd 47822 / wg0 config deletion) pending Irvine access; ~10 running irv-ml1 service cards still carry dead 10.100.79.3 hrefs (recreate each to apply labels); deployed .env for asset-engine / open-webui / skaldsong may hold the dead default.
  • MEMORY.md (auto-memory index) is near its 24.4 KB read cap — compaction pass still owed.
  • persistent-memory.md was 830 lines; this snapshot moved the superseded in-flight blocks and 09-08-or-older settled entries to archival-memory.md. The remaining bulk is Tools-and-conventions rows CLAUDE.md already covers — a deliberate redundancy trim is still the real fix (not done).

Recent decisions

  • [2026-09-09] ERP run 7 COMPLETE and the base arm is serving. 542/542 steps in 14h17m on pfi-gx10, adapter 13:23 PT, train_loss 3.205 / low 2.799, merge verified a sampled target actually changed (the silent-no-op check). erp-seat-base-ara up on 10.100.50.60:8098 for brokkr's floors, erp-tune-v7 merged and staged pending his cue; Miranda notified for the operator. Runbook docs/runbooks/gx10-run-07.md.

  • [2026-09-09] Booth asks render INLINE in a custom report, placed by the author (v0.1.14) — operator ruling: "the asks should be inline with the artifacts, not on a separate page." Placeholders data-booth-ask="<stem>" / "<stem>:<key>" / data-booth-ask-submit, plus <!-- booth:ask … -->; per-question fragments bind to ONE form via the HTML5 form= attribute so a four-voice audition submits every pick in a single POST. ⚠ The placeholder must sit OUTSIDE any grid/flex parent or it becomes a cell (measured on redo-anchors: a 224 px sixth grid cell). Unplaced questions + a missing submit block are appended, so a partially marked-up page can never yield an unsubmittable 400 — a test caught that as a real drop. redo-anchors/index.html was hand-marked-up on the LIVE copy; tts-dev told to move it into the generator or a regeneration loses it.

  • [2026-09-09] The Booth gained an ASKS primitive (v0.1.12): a session drops <stem>.ask.json in a booth, the operator answers a radio form + notes in the browser, the pick lands as <stem>.answer.json the session reads (booth ask|asks|answer --wait). Multi-question form via a questions list. ⚠ Two defects found and fixed the same day: a booth serving its OWN index.html never rendered the panel (verbatim path returns early) → amber chip + standalone /b/<name>/asks page; and single-ask title was silently dropped. The booth CLI was ALSO not on PATH anywhere despite the global link-board convention telling every session to run it → symlinked to ~/.local/bin. Global CLAUDE.md now teaches the primitive.

  • [2026-09-09] ana-ml2 pool actions LANDED (scrub 0 errors in 1h33 → zpool clear; nvme-cli + full-drive SMART table; zroot 91→73% via dangling-image + builder prune, tagged rollback seats kept) — and the missed-scrub mystery SOLVED: nvme7 (slot 0-5, S47VNY0K600221) was absent from every boot 04-23→09-05, tank was raidz2-DEGRADED for 4½ months, Debian's scrub/trim cron only touches ONLINE pools, and ZED's alert went to a root mailbox with no MTA. nvme7's 2084 media errors did not move across the scrub → historical, keep + watch. Playbook playbooks/ana-ml2-pool-health.yaml; inventory in servers/ana-ml2/README.md. → persistent-memory.d/2026-09-09-ana-ml2-pool-actions-done.md

  • [2026-09-09] ana-ml2 tank: 2 CKSUM errors on nvme7n1 after a boot-time resilver, NO scrub since 04-12, zroot 91% — three actions DEFERRED to a clean-context session (scrub → nvme-cli SMART → docker prune), operator ruling "we'll do all 3 on clean context"; tracked at commit 3e18a04 + the post-clear handoff. ESH 10G links measured clean (fiber run live on UDM SFP+2 ↔ USW-Pro-XG Media). → persistent-memory.d/2026-09-09-ana-ml2-pool-actions-deferred.md

  • [2026-09-08] ana-ml2 mesh return routes PERSISTED as /etc/network/if-up.d/mesh-routes (Debian 13 ifupdown, no netplan) via playbooks/ana-ml2-mesh-routes.yaml (elway, verified) — operator: "persist the routes". Hook not yet exercised by a real reboot. f923d6a.

  • [2026-09-08] ERP run 7 LAUNCHED on pfi-gx10 23:06 PT under operator-2026-09-08-rnd-run7 — opening-split slot + mask union; free check passed with two explained deltas; first launch died on a missing recipe (zsh quoting). → persistent-memory.d/2026-09-08-erp-run7-launched.md

  • [2026-09-08] erp-tune-v6-nvfp4a16 quantized (data-free W4A16, ~90 s) and serving on ana-ml2 :8021; trial aliased to it ("no gate"); tool calling fixed where it can betool_choice:none flag; forced tool_choice is prompt-driven on Gemma-4 by vLLM design, nightly 311b3513 raises it 1/9→6/9; json_schema is the deterministic path. → persistent-memory.d/2026-09-08-erp-seat-nvfp4-trial-and-toolcalling.md

  • [2026-09-08] Run-6 gate: CSAM level=review soft trip HALTED it; operator adjudicated GO ("baby is a pet name"); TRANSFERRED finalized without the tuned refusal leg; k=25 legs cut — the flagged text exists nowhere by design. → persistent-memory.d/2026-09-08-run6-gate-csam-adjudication.md

  • [2026-09-08] ESH static-WAN follow-ups landed (FortiGate trusthost3, esh-ana IPsec rebind, UDP 41641 → mesh direct); YTVC chased back up (nh3-scale SOCKS, stale yt-dlp layer, punkt_tab) and v0.3.6 CrisperWhisper deployed; gitea webhook repointed off the dead wg0 IP with the HMAC secret re-applied.persistent-memory.d/2026-09-08-esh-static-wan-followups-and-ytvc.md

  • [2026-09-08] ERP run 5 = RESCUED (landmark R49.5) — first capability-gate pass in the ERP-seat line; the 3.46%-loss dependency-forcing slot (GovReport+QMSum) broke the coupling runs 3c/4 couldn't. Seat erp-tune-v5 served on gx10:8098, trial alias repointed 3c→v5. → persistent-memory.d/2026-09-08-run5-rescued.md

  • [2026-09-08] R47 base settled from bytes = STOCK google/gemma-4-26B-A4B-it — three-way sha match (local == HF etag == stock LFS oid; commit 4d7ae498 == stock HEAD); the -heretic label is a naming error, all runs trained from stock. Accept-vs-swap now evidenced. → persistent-memory.d/2026-09-08-base-provenance-stock.md

  • [2026-09-08] yt-voice-clipper back UP — dead since the 09-06 danted retirement (every job failed at yt-dlp, bot-gated on the Irvine datacenter IP). Fix: danted on nh3-scale (CT107) at socks5h://100.64.0.1:1080, fleet-ACL'd, residential egress 70.230.226.88 measured; YTVC_PROXY repointed, worker recreated, end-to-end job DONE with positive (proxied) + negative (direct = bot-gate) controls. Homepage card href/siteMonitor → irv-ml1.nh3.internal:8000 (was dead wg0 IP). Then a SECOND fault: full downloads 403'd through the proxy (cookies irrelevant) = stale yt-dlp 2026.07.04 from a cached Dockerfile layer → compose build --no-cache api (2026.08.19), which dragged in a whisperx/nltk that needs punkt_tab → staged on the data volume + NLTK_DATA in the override. Operator's video x7kWJojf1MI → done, 8 clips. yt-voice-clipper-dev shipped both Dockerfile fixes + CrisperWhisper 2.0 (v0.3.6, b62849d) — deployed and verified (12 clips, [UM]/[UH] tags). ⚠ The gitea push webhook had been targeting the dead wg0 IP since 09-06 (never fired) → repointed to 10.6.110.50:9008 with the HMAC secret re-applied; deploy script passes YTDLP_REFRESH. Script scripts/setup-nh3-scale-socks-egress.sh. → auto-memory reference_nh3_egress_proxy, reference_ytvc_autodeploy.

  • [2026-09-08] ESH WAN static 128.177.138.182/30 (gw .181) is LIVE — the Cityside /30 that was 'not provisioned' on 09-04 now carries traffic; egress verified from esh-docker-vm. CGNAT at ESH is over. Added to the crowdsec esh allowlist. All three follow-ups LANDED same day: FortiGate trusthost3 → the static (login from ESH verified), dormant esh-ana IPsec rebound to wan1/static, UDP 41641 forward → esh-scale now peers DIRECT (was DERP).

  • [2026-09-08] ERP run 6 COMPLETE — 524/524, train_loss 3.259 (run 5: 3.235). Merged; base seat erp-seat-base-ara serving on gx10:8098 for floors, awaiting brokkr's swap cue → erp-tune-v6. ⚠ abliterated repo lacks processor_config.json — stock's carried in (32bdf45d). Miranda informed.

  • [2026-09-08] ERP run 6 LAUNCHED on pfi-gx10 on the jenerallee78 ARA-abliterated base (index 33c59654…, 32/32 shards byte-verified vs brokkr pins, stock tokenizer set installed over the repo's 256-token-truncating one, run-5 recipe byte-held, free check exact). Operator's direct grant operator-2026-09-08-rnd-run6; run-5 seat unloaded (trial dark). Gate names: erp-seat-base-ara / erp-tune-v6. → docs/runbooks/gx10-run-06.md, commit 3fec668.

  • [2026-09-08] Miranda = operator's chief of staff, may relay his directives — added to user-level ~/.claude/CLAUDE.md (dotfiles 7134a22) as the named exception to the no-relayed-auth rule (unidentified peer relays still excluded); material-consequence calls she relays stay the operator's own.

  • [2026-09-08] Fleet fixes shipped — WhereTF Homepage card + DNS (4506ef6); ext-tts LiteLLM alias → irv-ml1.nh3.internal (DB /model/update + extra_hosts, 957c8f1); the 09-06 irv-ml1 stale-IP trail repointed across 25 composes + services.yaml + ssh-target → DNS name (e0d1c44); Homepage /api/services outage fixed — ana-ml2 discovery via a socat proxy on ana-docker (stacks/ana-ml2-proxy, 913d2d2, reversible).

  • [2026-09-07] Fleet internal TLS pattern shipped — caddy (cloudflare-plugin build, ~/.local/bin/caddy-cf, fleet-tls-caddy.service) on nh3-dev is the wildcard cert authority: publicly-trusted LE *.nh3.phasefinal.com via Cloudflare DNS-01, resolved internally by an AdGuard split-horizon rewrite (all 3 resolvers). talk self-terminates on :8092 with the trusted cert (operator's in-container-TLS ruling), renewal auto-synced by fleet-tls-cert-check.timer. Interstitial gone; secure-context+AudioWorklet verified via headless Chromium. Pattern + foot-guns (restart-disrupts-inflight → clients need retry; wildcard = name-only, never IP) → auto-memory reference_fleet_internal_tls_pattern.

  • [2026-09-07] cc-channel registered for this infra-ops session's wakealthing-route cc route → the CC session's $XDG_RUNTIME_DIR/cc-socks/<pid>.sock; herald pokes the socket directly at a turn boundary. Replaces the FIFO/poll waiter that Claude Code 2.1.257 kept killing while the seat sat in shell. Session-local — re-declare per session.

  • [2026-09-07] irv-ml1 /mnt/smithy remount fixed post-cutover — export allowed 10.0.0.0/8 (old wg0) but not the mesh 100.64.0.0/10 irv-ml1 now sources from → all-uid "permission denied"; added the mesh range to the nh3-nas smithy export + remounted (clientaddr now 100.64.0.6). nh3-nas admin = infra-ops PASSWORD auth (vault nh3-nas/infra-ops-password), sudo ALL, SFTP subsystem OFF. → auto-memory reference_irv_ml1_gpu_r14 (corrected).

  • [2026-09-07] irv-ml1.nh3.internal DNS repointed to the live Irvine LAN IP 10.6.110.50 (was the dead wg0 10.100.79.3); CLAUDE.md fleet-row + placement-rule updated to mesh reality. commit 0336e03.

  • [2026-09-07] Subnet routers excluded from vzdump fleet-wide (ana-scale 114/pfi-pve, nh3-scale 107/nh3-pve, esh-scale 108/esh-pve) so a hung backup can't blackhole a site; nh3-headscale (106, control plane) KEPT; ESH backup moved 02:15→03:30. Root cause of this morning's ESH outage: an overnight vzdump left CT108 (esh-scale) locked → whole site dark. → auto-memory feedback_esh_backup_window_0330.

  • [2026-09-07] Booth link board: pin/favorite + multi-select delete + newest-first (booth-v0.1.8, commit 76fdf45, tag booth-v0.1.8) — pins in a .pins sidecar (content-ids), one <form> + formaction buttons so ×/★/bulk-delete all degrade with JS off.

  • [2026-09-06] Headscale cutover COMPLETE — all three site-pairs on the mesh; Site Magic + both IPsec tunnels DORMANT. Operator disabled Site Magic (UI); NH3↔ESH re-homed to a direct 8ms path. Exit nodes advertised at all three sites (multi-location egress proxy) with source preservation kept via a selective-masquerade rule (NoSNAT + mesh-exit-masq.service per router). Throughput 761/464 Mb/s vs old 250 IPsec. ⚠ FortiGate WAN-SSH left open (temp, scoped NH3+ESH). Method: disable tunnel FIRST then add mesh route. → persistent-memory.d/2026-09-06-headscale-cutover.md

  • [2026-09-06] Headscale overlay mesh: control plane live at headscale.phasefinal.com (CT 106 nh3-pve) + subnet routers nh3-scale/esh-scale/ana-scale serving their /16s; nh3-dev enrolled. NOT cut over — Site Magic + IPsec still carry site-to-site. ⚠ accept-routes-before-return-path black-holed nh3-dev's LAN for a minute. infra-ops user added on all four PVE hosts. → persistent-memory.d/2026-09-06-headscale-mesh-phase1.md

  • [2026-09-06] pfi-pve NASPool REBUILT as six-wide raidz2 after a backplane fault killed bays 9/10 (Route C hybrid, operator-directed): parked 1.65T on ospool, destroyed, recreated, restored, backup tier back 04:03Z; guests never stopped (ALL boot disks are on ospool — the prior brief had this wrong). Legacy vzdump pruned to newest-per-guest by omission. OPEN: destroy ospool/naspool-evac after scrub + one backup cycle; backplane swap next visit; PSU1 still dead. → persistent-memory.d/2026-09-06-pfi-pve-naspool-raidz2-rebuild.md

  • [2026-09-05] A peer's "2.7x serving-stack effect" was a coin flip — the operator rejected it on instinct and the arithmetic backed him. Each floor was |b0-b1| from n=2; the ratio is half-Cauchy, P=0.452. ⚠ The disconfirming evidence sat in brokkr's own sentence, and he named why: the claim was his and flattering. → persistent-memory.d/2026-09-05-floor-claim-n2-retraction.md

  • [2026-09-05] vLLM RUNS on sm_121 — the blocker was ninja off PATH, not the silicon — and run 4 launched after two peer artifacts were rejected by reading the harness rather than accepting a "confirm this". ⚠ I declined to fill in missing root_sha256 values I knew, because supplying both sides of a check makes it inert. → persistent-memory.d/2026-09-05-vllm-on-sm121-and-run4.md

  • [2026-09-04] ERP run 3c trained and GATED — the 20x LR cut erased the diversity gain and did NOT remove the 40pp selfharm regression. LR-robust, so it comes from corpus content. CSAM clean on all three arms. ⚠ A pooled preserve-list test cannot see a single-axis collapse. → persistent-memory.d/2026-09-04-run3c-trained-and-gated.md

  • [2026-09-04] gen moved to ana-ml2 GPU0 to stop vllm-embed OOM-crashing (7 restarts) — and I sized it against vLLM's declared budget, not its runtime footprint. Cost: gen KV down to 1.02x concurrency at 262K. → persistent-memory.d/2026-09-04-ana-ml2-gpu-rebalance.md

  • [2026-09-04] SMB account dsp created + vaulted for the Windows AudioGridder box — and esh-nas turns out to be wide open. Twelve NFS exports rw to 10.0.0.0/8, guest-writable SMB. → persistent-memory.d/2026-09-04-esh-nas-smb-and-exposure.md

  • [2026-09-04] SLZB-MR1U Zigbee coordinator moved to esh-iot (VLAN 90) at 10.0.90.10, DHCP-reserved, DNS'd, handed to ha-dev. ⚠ Home Assistant cannot resolve .internal at all (Docker's 127.0.0.11 upstream excludes the fleet AdGuard) — pre-existing; ha-dev declined the fix. Runbook docs/runbooks/slzb-mr1u-zigbee-coordinator.md, commits fed29be/0bbdaf9.

  • [2026-09-03] Run 3c is STAGED on pfi-gx10 and deliberately NOT launched — the launch is a 13.3 h commitment and the operator stood this port down once already. Base shards AND the encoded corpus sha256-verified identical to ana-ml2's, so the transformers 5.15.1→5.16.1 / x86-64→aarch64 delta is measured inert. ⚠ The encode-cache FILENAME differs by design (base_model_path is in the key) — input hash, not output. ⚠ Tripped the pkill -f ssh self-match again; the launcher guards on a pidfile because of it. → persistent-memory.d/2026-09-03-gx10-run3c-staged.md

  • [2026-09-03] SearXNG returned ZERO results for every query while reporting healthy for 7 days — 4.5 months stale. Moved to nh3-docker (residential egress beats the colo's CAPTCHA-gated 38.120.12.42), updated, and exposed to every CC session as the user-scope web_search MCP tool. ⚠ /healthz cannot tell you whether search works. → persistent-memory.d/2026-09-03-searxng-nh3-move.md

  • [2026-09-03] pfi-gx10 racked: VLAN 50 via a DHCP RESERVATION on the UDM, not a host static — operator ruling, so the box stays portable. ⚠ The racked port arrived on the NATIVE VLAN; ⚠ port_overrides is a whole-array PUT; ⚠ prove inter-VLAN routing with ping -I <wired> BEFORE downing the Wi-Fi escape hatch. Now single-path. → persistent-memory.d/2026-09-03-gx10-rack-network.md

  • [2026-09-03] Three Macs onboarded (mini / Air / Studio) with infra-ops, NOPASSWD sudo, rotated+vaulted passwords and dsh on device-scoped keys — and the fourth is scripts/provision-mac-dsh.sh, not a fourth hand-run.sudo -u keeps the CALLER's $HOME and nearly wiped a working install; ⚠ a wrong USERNAME is indistinguishable from a wrong password. → persistent-memory.d/2026-09-03-mac-fleet-dsh.md

  • [2026-09-03] nh3-dev wedged for ~40 min and it was the BACKUP, not the disk — a stalled cross-site vzdump holding every guest write via copy-before-write. Symptoms screamed dying disk: 45 writes in flight completing zero, jbd2 + flush kworkers in D state 33 min, io pressure full 96%, load 26, virtio_ring in the stack. ⚠ The discriminator was the ABSENCE of errors — no SCSI/ATA/IO errors, rpool ONLINE 21%, guest fs 79%, memory fine, and Dirty only 3.8 MB (so nothing backed up in page cache; it was stuck BELOW the block layer). ⚠ The hypervisor was IDLE — load 0.63, io pressure 0.00, zpool ~0 writes: nothing was reaching the disk because the filter held it. Cause: vzdump of VM 102 → pbs-ana did 1% at 64 MiB/s then collapsed to 1.4 MiB/s for 35 min; Proxmox backups interpose a copy-before-write filter, so every guest write queues behind the backup's copy-out. FIX = cancel the task (pvesh delete /nodes/localhost/tasks/<UPID>); filter detached, inflight 45→0, D-states gone, 191 MB/s dsync restored. ⚠ fleecing 0 on the job is why a slow TARGET can stall a GUEST — fleecing routes copy-before-write to a fast local image instead. Job = backup-5d8f1221-8f71, daily 21:00, all 1, storage pbs-ana → recurs nightly until changed. A prior run of this VM managed 941 MiB/s read, so 1.4 MiB/s is degradation, not normal. → docs/runbooks/nh3-dev-io-stall.md

  • [2026-09-02] althing deploy is SIX surfaces, and #6 is outside the althing repo: ~/.claude/settings.json crossSessionInbound: "accept". Without it Claude Code HOLDS every cc poke — it auto-delivers only when the sender's permission-mode class matches, and the herald is a daemon that asserts none, so the notice goes to a human watching the pane instead of to the session. ⚠ The seat reports declared, reachable and green throughout — same failure shape as the SessionStart hook that was never deployed. Set on nh3-dev by forseti 09:28 with operator authorization (diff verified: one key, backup at /tmp/settings.json.bak-20260902T092829). Operator's reasoning: the herald reaches only local seats and a pane poke already types+Enters into a session, so the socket channel is strictly NARROWER than what it replaces — stating the existing trust boundary, not widening it. Cost without it is first-contact-only (in-memory correspondent record), not per-message. ⚠ No attestation exists for the herald to send — CC identifies a sender by verified pid against the session registry and reads that session's LIVE runtime mode; a daemon is not in it, and from_mode on a type:"user" frame is never consulted. deploy-althing.sh reports surface 6 and deliberately never SETS it — a deploy script that edits its own trust settings grants itself trust. → docs/runbooks/althing-deploy.md

  • [2026-09-02] vastblue gitea org created (id 8, private, owner vh) with empty repo vastblue/platform — third entity namespace alongside corviduo and pfi; most repos still live under vh/. Home of VastBlueDocumentAI + the anchor healthcare-billing SPA (signed 3-yr client contract). Org scope was the decision: org-level runner registration and secrets are inherited free by the DocumentAI repo when it splits out, and that is the only binding expensive to retrofit. Deliberately NOT set: org runner (instance-wide ana-docker-runner already serves it; org scope is for the DEDICATED runner, deferred to U10) and org secrets (none exist yet; a guessed secret looks bound). ⚠ Dedicated runner is gated on the first client-premises release cut, not on the first green pipeline — the risk is another repo's CI sharing a root-level daemon with a build that ships to a healthcare client, see the runner entry above. Push needs no credential: vastblue-dev is on nh3-dev and git-SSH there auths as vh. → stacks/gitea-runner/README.md

  • [2026-09-02] althing 3.3.0 deployed — the cc channel, and a plugin-cache false green. CC seats are now poked over their own message socket ($XDG_RUNTIME_DIR/cc-socks/<pid>.sock) instead of by typing into the pane: no process to reap, nothing near the input line. infra-ops moved to channel=cc; the dwarves stay on pane and their guard-4 exposure is UNCHANGED (declare prefers cc, falls back). ⚠ An undocumented Claude Code interface, taken deliberately (operator: the FIFO poker was also an unsanctioned hack — a better instance of a class we already had). Break mode = seat goes pull-only with a logged reason, mail still held. ⚠ claude plugin update matches on the plugin VERSION and declines a content-only change — 3.3.0 edited plugin content at an unchanged 0.1.1, so the CC cache stayed stale while every version check reported success (delta was docs-only, harmless this time). deploy-althing.sh now diffs marketplace vs live cache. ⚠ Ordering: herald restart BEFORE anything declares cc, or the seat goes silently pull-only. ⚠ This box was at 3.2.4, not 3.2.5 — rollback target here is 3.2.4. Follow-on 3.3.1: the statusline bell measured a MECHANISM, not the property — it read wake-listener-<handle>.lock, so a cc seat renders 🔕 while push/reachable. Both copies now ask the post office (reachable from the status payload) and add 📵 for an outage. ⚠ TWO COPIES of that script now existscripts/claude-statusline-command.sh here (the operator's wired one) and althing's plugin/scripts/statusline.sh — independently fixed to the same shape; a drift surface with a countdown, convergence not yet raised with the operator. → docs/runbooks/althing-deploy.md

  • [2026-09-02] Every CI job on the shared pfi-fleet runner is root on ana-docker — and container.valid_volumes: [] does NOT prevent it. Measured: a job container is uid 0, /var/run/docker.sock is mounted by act_runner independently of that list, docker ps returns all 49 host containers (gitea itself, synapse, phasefinal-web, adguardhome), docker compose v2.33.0 on PATH. ⚠ LOAD-BEARINGvh/Worldtree, vh/soong-lab, vh/skaldsong, vh/wt-matrix-bridge all drive buildx through that socket, so it cannot simply be closed; isolate sensitive builds onto a dedicated runner instead. Also measured the same night: services: containers work (Postgres 16), and full-URL uses: https://gitea.phasefinal.com/actions/checkout@v4 resolves from the local mirrors — the un-parked half of the github-independence work, needing neither DEFAULT_ACTIONS_URL=self nor the act_runner auth path that blocked it on 2026-08-05. Prompted by vastblue-dev's CI-posture question for a client-funded healthcare repo. → stacks/gitea-runner/README.md

  • [2026-09-02] pfi-gx10 BASELINED: 79.36 s/it median on the run-3c shape, and the training stack works on aarch64/sm_121. Median across 10 timed steps, 0.19% spread, peak 75.1 / 121.6 GiB — 46 GiB spare, attn_resolved: flex_attention. 6× slower than ana-ml2 where compute predicts 2.7× → likely memory-bandwidth-bound; capacity box, not throughput box. Ruled bare metal, not Proxmox (no aarch64 PVE; the GPU is on-package and cache-coherent, so passthrough would partition the unified memory that is the whole point). ⚠ sm_121 is NOT in torch's arch list — everything JITs from sm_120 PTX, so warm up before timing anything (an unwarmed bench read 27 TFLOP/s against a true 93). → persistent-memory.d/2026-09-01-pfi-gx10-onboarding.md

  • [2026-09-02] I priced a failure in the units I happened to be measuring — operator overruled me, correctly. Recommended run 3c to ana-ml2 by costing a breaker trip as "≤50 steps ≈ 11 min of recompute". It is a 40-minute drive each way with 13 Anaheim hosts dark, three of them SureFire CLIENT machines. save_steps caps the recompute, never the outage. ⚠ General form: a metric in hand will volunteer itself as the unit of risk.persistent-memory.d/2026-09-01-pfi-gx10-onboarding.md

  • [2026-09-02] althing 3.2.0→3.2.4 deployed, and ALTHING DEPLOY IS FOUR SURFACES not three. The fourth (plugin) had no runbook step and was frozen at Aug 28 — missing the SessionStart/SessionEnd hooks and pane-route.sh entirely, so "CC seats re-declare automatically" was never true here. Now one command (scripts/deploy-althing.sh). ⚠ uv tool install . without --force is a silent no-op. ⚠ A missing deploy surface presents as "the migration needs manual work", not as an error.persistent-memory.d/2026-09-01-althing-320-deploy.md

  • [2026-09-01] irv-ml1 GPU resident map, and dots-tts holds 14,430 MiB against a ~6 GB baseline — tts-dev's prompt-feature cache, capped at 32 entries after two incidents; the cap still permits a long way of growth. 3090 at 76% behind a warn-only watchdog. ⚠ Restates the GPU-ordering foot-gun: device_ids: ["1"] is the A6000 in a container, but a bare native CUDA_VISIBLE_DEVICES=1 gets the 3090. → persistent-memory.d/2026-09-01-irv-ml1-gpu-residents.md

  • [2026-09-01] The Ada inference server is a used Dell R750xa (JPJ1ZP3) and the reseller stripped four things Dell shipped — half the RAM, the 2400 W PSUs, and the GPU risers/cables/fans are absent from the invoice. Card is RTX 6000 Ada, not L40S. GPU power chain resolved via NVIDIA 930-00030-1546-000. NVMe in the drive bays is CLOSED (SAS/SATA backplane). → persistent-memory.d/2026-09-01-ada-inference-server-r750xa.md

  • [2026-09-01] pfi-gx10 onboarded headless — and it is the intended new home for run 3c, which died on a tripped breaker. GB10/sm_121/aarch64, 121 GB unified. NOT racked yet. Bare of any CUDA stack; probe throughput before porting. → persistent-memory.d/2026-09-01-pfi-gx10-onboarding.md

  • [2026-09-01] Ada migration is zfs send (branch a) — and the DESTINATION IS SMALLER THAN THE SOURCE. 99 MB/s measured; ~3.9 h. ⚠ Measured 2026-09-01: storetank = 1.81 TiB pool, 1.45 TiB used, 80% CAP already, compression off / compressratio 1.00x (safetensors are incompressible — no win at recv). Settled payload ~1.47 TiB; the R750xa's as-bought 2× 1.92 TB mirrored is ~1.75 TiB → arrival at ~84%. Fix = 2× 2 TB SATA SSD on the buy list (6 bays free) → ~3.57 TiB at ~41% with redundancy; pair the two NEW drives together (a mirror vdev caps at its smallest member). ⚠ Pruning is NOT a substitute — comfy-dev found ~215 GiB unreferenced, and deleting every byte still lands the as-bought mirror at 72%: the constraint is vdev layout, not payload, so the prune audit and the drive purchase are independent and neither gates the cutover. ⚠ "Onboarded" is not "landed" — infra-ops read ALLOC mid-pull and re-added the whole batch on top, inflating 84% to a quoted 90%. Also: branch (b)'s original reason was WRONG — comfy-dev enumerated all 12 containers, only comfyui mounts /storetank, so (b) was unavailable during the transition, not structurally (right conclusion, wrong reason — infra-ops reasoned about the BOX when the question was the MOUNT). Plus the retain-vs-reclaim call and the two-boxes confusion (the Ada box and the GX10 are DIFFERENT machines). → persistent-memory.d/2026-09-01-ada-migration-branch-a.md

  • [2026-09-01] Matrix: Synapse 1.120→1.159, appservice namespace opened, /_synapse/admin closed to the internet, alias convention ratified. Schema migrations are one-way; push is event_id_only and assembled on-device. → persistent-memory.d/2026-09-01-matrix-upgrade-and-hardening.md

  • [2026-09-01] A named failure class: a correct check aimed at the wrong object. Six instances in one day across three sessions; re-running the same check cannot catch it. Recommended for docs/pfi/training-throughput-playbook.md §4 — NOT YET WRITTEN, awaiting operator.persistent-memory.d/2026-09-01-wrong-object-measurement.md

  • [2026-09-01] Ops boundary ruled by the operator: worldtree-dev writes the bridge code; infra-ops OPERATES the Worldtree/Matrix instances and may change them. Corrects a mis-route where infra-ops asked worldtree-dev to provision an account on a box it does not run. Tracked at 931bac8 + althing 01M1F4PK796EDGDCBKZ9W3JC0S.

  • [2026-09-01] Idle VRAM on this fleet is a RESERVED scratch pool, not waste. Operator declined raising vllm-mog-sec from gpu-memory-utilization 0.52: single-user dev fleet, KV headroom nobody will consume is worth less than room for ephemeral models and small training runs. vLLM's "fully utilize gpu memory" startup hint does NOT apply here. Tracked in auto-memory feedback_idle_vram_is_reserved_not_waste.

  • [2026-08-28] althing v3 flag day (U9b) executed, then six releases to 3.1.1 in one afternoon — and the post office MOVED to nh3-docker. Every v2 command deleted; 73 handles seeded and verified by set difference; 5,043 orphaned wake FIFOs deleted (v2 named them per-session+PID, v3 per-handle). Image now registry-pulled, digest-pinned, under the claude-bot namespace. → persistent-memory.d/2026-08-28-althing-v3-cutover.md

  • [2026-08-28] A stale ALTHING_HANDLE silently reads another agent's inbox and reports it empty — a SECOND route into the failure v3 exists to prevent. Outbound mis-signing sometimes gets caught; inbound never does. Shipped as a 3.1.1 warning. ⚠ My session_handles.json grounding was wrong (v2 artifact, v3 never opens it) and the same stale source had survived inside my statusline rewrite. → persistent-memory.d/2026-08-28-handle-resolution-wrong-inbox.md

  • [2026-08-28] nh3-dev's three OOM events attribute to CLAUDE CODE, and the "no kernel evidence" was a permissions artifact. journald was persistent all along; journalctl silently shows only your own messages outside adm. Single CC sessions measured 5.4-18.4 GB, so 27 GB is 3-4 long-lived sessions. sysstat + atop now instrument the ramp. → persistent-memory.d/2026-08-28-nh3-dev-oom-attribution.md

  • [2026-08-28] sec moved to ana-ml2 GPU0 and is serving (operator-directed) — GPU1 had ~28 GB free against the ~51 GB it reserves, so it could not start there. Re-arms the two-GPU load condition on a circuit that tripped 36h earlier; accepted with the constraint stated. → persistent-memory.d/2026-08-28-sec-seat-gpu0.md

  • [2026-08-28] BELAYED by the operator, both explicitly: (a) a cgroup memory cap on CC sessions, (b) putting ana-gw + ana-wg + one BMC on separate power. Both were my recommendations; neither is open work. Do not re-raise as new — the atop ramps that would inform (a) are now being collected, so revisit only with a week of data. Tracking surface: this entry.

  • [2026-08-28] The deployed CC plugin copies are a release step nobody owns. sync_skill.sh covers the SKILL, not the plugin; both copies must be rsync'd from the repo's plugin/ on every althing release or they carry the previous release's bugs into the live surface. Raised with forseti for their release notes. Tracking surface: althing thread 01M14QHZNDKDK8KH9DN92VF6VE.

  • [2026-08-28] althing v3.0.0 flag day (U9b) executed — the post office replaced the P2P bus on both boxes, one-way. 73 handles seeded and verified by set difference; 5,043 orphaned v2 wake FIFOs deleted (v2 named them per-session+PID and never reaped; v3 names them per-handle, so the leak is bounded by construction); v2 db left inert. → persistent-memory.d/2026-08-28-althing-v3-cutover.md

  • [2026-08-28] nh3-dev's three OOM events attribute to CLAUDE CODE — and the "no kernel evidence" was a permissions artifact. journald was persistent all along; journalctl silently shows only your own messages outside adm. Single CC sessions measured at 5.4-18.4 GB, so 27 GB is 3-4 mature sessions, not the ~66 a 408 MB estimate implies. sysstat + atop now instrument the ramp. → persistent-memory.d/2026-08-28-nh3-dev-oom-attribution.md

  • [2026-08-27] Run 3 gated: the preregistered rule PASSED and a k=25 follow-up found a 44pp self-harm guardrail collapse — DO NOT SERVE. A pooled preserve-list test structurally cannot see a single-axis collapse. → persistent-memory.d/2026-08-27-run3-gate-safety-regression.md

  • [2026-08-27] The corpus mix was specified in a unit the optimiser never sees — 45.8% dialogue by CONTEXT, 24.2% by LOSS. Harness now leads with loss share and calls context a memory budget (dd5a12e). → persistent-memory.d/2026-08-27-mix-specified-in-the-wrong-unit.md

  • [2026-08-27] Dose-response: benefit and damage are ONE direction in weight space — every axis monotone in scale, no knee. The merge-back cannot separate them; vLLM cannot LoRA-serve this MoE at all. → persistent-memory.d/2026-08-27-dose-response-entanglement.md

  • [2026-08-27] Anaheim tripped a power breaker; four guests including the NAS had onboot unset and never came back. Fixed with dependency ordering — ana-nas order=1,up=45 ahead of the databases. ⚠ ONE CIRCUIT FEEDS THE WHOLE RACK including the firewall serving the public IP (operator) — so ana-gw, ana-wg and every BMC go down with the load, and there is NO remote management path to Anaheim during a power event. → persistent-memory.d/2026-08-27-anaheim-breaker-and-onboot-gap.md

  • [2026-08-27] A transport failure that enters a measurement as a VALUE looks like whatever you hoped to find. heid's lost panel arms found a live defect in brokkr's t4_dissect an hour later. → persistent-memory.d/2026-08-27-empty-response-as-a-datum.md

  • [2026-08-27] Run 3c authorised (lr 20x cut, single variable) and then HELD by the operator after the breaker trip. Config built and validated at /tank/erp-tune/run-03c.json; save_steps made configurable in the harness (0a6bd2e) because the first launch lost 80 steps with no checkpoint. Tracking surface: commit 0a6bd2e + that config path. Relaunch is one command once power is triaged.

  • [2026-08-27] An event report with no timestamp is a claim about "now" — and it manufactured a launch that never happened. brokkr reconstructed a phantom third 3c launch because my 23:03 report narrated a 21:07 kill in the present tense. Every fact in it was true; it was unreadable in sequence. → persistent-memory.d/2026-08-27-run3c-launch-count-reconstruction.md

  • [2026-08-27] save_steps was hardcoded at 100 in the harness — a claimed provenance entry the run could not have honoured. Made configurable, default unchanged (0a6bd2e, 242 tests green). Caught by checking the config carried the change rather than trusting that it had been made.

  • [2026-08-27] Six defects in run 3's staged build, none of which would have errored — a dialogue-only survivor list that would have silently dropped 96% of the corpus, an impersonation mask not subsumed by the low-quality mask, kvasir unbounded at 67.8% of context, a save_pretrained config-key drop that made the merged model unservable, and the mix-unit error. Every one produced a plausible completed run. Full record /tank/erp-tune/recipe-r3/RUN-03-BUILD-NOTE.md.

  • [2026-08-27] The 18 unpushed eitri-smithy commits are pushed — run 3's harness_commit 9d27b4fe now resolves off-box, verified by fetching into a fresh empty repo rather than trusting the push output. ⚠ HTTPS push 403s for every gitea token including site-admin; SSH works. Untracked __pycache__ (894fbe8) because a tracked .pyc dirtied the tree and would have stamped harness_dirty_at_launch: true.

  • [2026-08-26] Run 3's corpus is built and HELD — creative-writing-multiturn is a MEGAMIX containing bluemoon, PIPPA, LimaRP and stheno, and the remix promoted two roots that overlap at median jaccard 0.873. Dedup direction reversed to keep the primary source. F1 does not do what the recipe says; F2 does. → persistent-memory.d/2026-08-26-run3-corpus-and-the-megamix-containment.md

  • [2026-08-26] No conversation admission threshold for run 3 (brokkr delegated, then endorsed). Masked context costs the transformer body but NOT the LM head — the harness drops IGNORE_INDEX before the 262k-vocab head — so a 20% trim buys ~35 min against a 3-hour run, and it would be a fifth filter confounding a run whose purpose is testing the filters alone. Tracked in the run-3 detail file.

  • [2026-08-26] Run 2's gate FAILED and is recorded as a FAIL — T3 constraint 12.0 against a ~1 pt floor. But gate 1 is the result: T6 spatial +15.0 where run 1 failed the same axis at 3.5, base swap the only intended variable. Neither run ships; the pair prices what the abliteration cost. Plus the long-form-only stability regression a short-answer gate would have passed, and PIPPA's 123-word clip in the length signal. → persistent-memory.d/2026-08-26-erp-run2-complete-and-served.md

  • [2026-08-26] Run 2 complete, merged, coherence-gated and serving as erp-tune-v2 — stock-instruct base, and the mask proven by a 221,712 loss-token delta against byte-identical context. Also the p50 claim I asserted and had to withdraw. → persistent-memory.d/2026-08-26-erp-run2-complete-and-served.md

  • [2026-08-26] Playbook §4 written: "when the artifact lies about itself" — seven landmines plus a pre-launch checklist, from a night in which three separate fixes each shipped a check that could not fail. The unifying line is brokkr's: when you change what an artifact means, every derived artifact keyed on the old meaning is now a liar. Commits dae6eded54f256; the doc is docs/pfi/training-throughput-playbook.md (filename kept for inbound links; scope is now wider than the name).

  • [2026-08-26] Served under a NEW name on a NEW port (erp-tune-v2 / :8098), never re-pointing erp-tune-v1. Run 1's artifact still exists and is still what that name refers to; re-pointing would be the silent substitution the standing no-false-aliases rule forbids. brokkr independently asked for the same and additionally wants the concrete backing model + date in provenance, not just the alias — an alias has silently changed meaning under recorded results before.

  • [2026-08-26] DPO stage gated on an axis-list decision that is not mine to makedocs/pfi/erp-dpo-stage-prep.md. No preference data for refusal axes exists; trl is not installed; the Gutenberg sets on disk are prose-quality only. ⚠ Do not install trl (or anything) into the training venv while a run is saving — a resolution that upgrades transformers under a live process can break its save path.

  • [2026-08-25] Run 2's base is an OPEN OPERATOR DECISION, deliberately not staged — four options with materially different safety postures, detailed in Current state. Tracked at althing thread 01M0WQ8W5574KMEVCHCEKEXNS5. ⚠ Do not let it get filed as a config knob; it is a reversal of the trainee-selection decision.

  • [2026-08-25] Fused MoE kernel path — DEFERRED, tracked at park fused-moe-kernel-path-for-gemma-4-moe-training (id 47). Operator: "note the fused MoE kernel for round two… if we nail it soon, the math has us wanting to restart the run anyway." Training MFU is 8.6% (27.1 of a benchmarked 313.8 TFLOPS) because transformers runs the Gemma-4 experts in a Python loop — 128 experts × 30 layers, ~11,500 iterations per step under gradient checkpointing. ⚠ The same fused 3-D expert layout that made bitsandbytes skip 88.5% of the model is exactly what a grouped GEMM wants — the format is good for storage and for fused kernels, and hostile only to naive iteration. Two fixes: group_by_length (29.9% compute, free, but breaks the seeded order manifest and re-opens a batch-composition call brokkr already made) and a grouped-GEMM/compiled MoE forward (the remaining ~10×). Not applied to the live run — restarting mid-flight to change batch ordering was judged a bad trade at step ~50 of 1,312.

  • [2026-08-24] Serving the tuned ERP model: LoRA-on-NVFP4 PREFERRED, merged weights the expected fallback — and the recorded objection may be STALE. Operator: "if you CAN load it as a lora, all the better, the issue is that we will want to run nvfp4 weights, which we had some serious trouble with loading loras on top of nvfp4." ⚠ The archived root-cause says it was NOT NVFP4-specific: [2026-07-07] vLLM 0.24.0 qwen3_5 LoRA application was a silent no-op (#47639, regression from #37912) — adapter loads HTTP 200, zero deltas at inference, proven quant-agnostic (NVFP4 AND FP8 both inert) and adapter-format-agnostic by a 3-peer dwarf panel. Fix PR #47640 was OPEN then. ana-ml2 is FAR past 0.24.0 and the box runs a SPREAD, not one version (measured 2026-08-24): gen on nightly-311b3513 = 0.27.2rc1.dev150, mog-sec on nightly-e9d1398d = 0.26.1rc1.dev1102, the small seats still on 0.24.0, and char-rp/trainee-bench pinned to v0.26.0. ⚠ vllm/vllm-openai:v0.27.1 is already ON DISK, unused — a TAGGED release, which is the right retest target: no nightly variance, no pull, ~4 months past the diagnosis. So: RETEST hot-swap LoRA on v0.27.1 before designing around merge — it is cheap, and if it works the post-tune gate can be two aliases on one engine. If it still no-ops, merged weights it is, which means the harness must EMIT merged weights and Eitri needs that in the contract while he is early. Tracked at this snapshot commit; settle it in the QLoRA sizing conversation.

  • [2026-08-24] speaches on irv-ml1 stopped, stack retained — Eyra was abandoned pre-implementation (Scriberr covers the need), leaving it no consumer. Disposition confirmed to eyra-dev; one command to restart. Tracked at althing thread 01M0RRJX8GPZEBDHF1E3W18RZF.

  • [2026-08-24] nconnect=8 on /mnt/smithy — approved but DEFERRED at operator instruction. brokkr-smithy-dev pre-approved it for "once the FortiGate work settles" and does not need re-asking; the operator declined it in this session's scope. Tracked at althing thread 01M0R46SFYF83099N16WD67KGD.

  • [2026-08-19] AI-tab Dormant regrouping BELAYED by the operator — six seats (char-rp Magidonia, char-rp-reasoning Heretic2, Granite summarizer, Qwen-Image-Bench, Skaldsong, Chatterbox Fast) show amber EXITED inside live groups rather than AI - Dormant. Fix is a label change + recreate per stack; needs the operator's read on which are retired vs temporarily down. untracked by operator choice (his words: "belay the ai dormant regrouping for now").

  • [2026-08-16] esh-vm-docker hardened: the wedge is hard NFS at RUNTIME, which the boot-ordering fix never addressed. All four mounts were hard, so a NAS stall at 10.0.50.50 blocks I/O forever (D-state). The existing x-systemd.before=docker.service fstab fix solved the boot race — a different bug. Exposure was far below what the park item assumed: only 2 of 12 containers touched NFS, and container state was already local (/var/lib/docker). Removed: /mnt/compose (2.1G, fully vestigial — zero containers referenced it, dockge reads local /opt/docker, its one mention was a comment in beszel-agent-esh/.env about a different host) and /mnt/documents (2.0K, paperless's empty spool dirs → /opt/docker/data/paperless at the same 0777). fstab backup /etc/fstab.bak-nfs-harden-20260816. 4 mounts → 2, 2 wedge-capable containers → 1. traefik needed no change (already restart: unless-stopped — why it self-recovered). Watchdog services/esh-vm-docker-watchdog/ live on esh-pve (not the guest): probes traefik over HTTP, deliberately not ping/SSH — the wedge signature is "guest OS alive, services dead" (/ is local disk so sshd answers straight through a total outage and a TCP check reports HEALTHY). 5 failures × 2 min → qm reset 100, 30-min cooldown, running-only guard, /etc/esh-vm-docker-watchdog.disabled. All paths tested without power-cycling. DEFERRED (operator): /mnt/books stays hard — calibre's SQLite metadata.db would risk corruption under soft/softerr. That is the one remaining wedge vector. Commit 55705ba; park item 28 promoted. ⚠ qm over non-interactive ssh throws a bogus JSON::Backend::XS error — use ssh host 'bash -s' <<'EOF', not ssh host "qm …".

  • [2026-08-16] DS v1.0's one real refusal is self-contradicting boilerplate, not a content constraint. On a direct "drop character and state your content policy" probe she returned "I don't generate explicit sexual content, graphic violence, or material that glorifies harm, non-consensual acts, or illegal activity"in the same run where she generated all three at 0% refusal. Reads as a learned recital triggered by meta-questions about policy. If production refusals share that shape the failure is prompt-shaped, not model-shaped, and a consumer-side system-prompt fix may beat a model swap entirely — worth settling before spending the GPU window. Separately, 7/85 bare-framing samples were persona breaks (in-character AI acknowledgement): not refusals, but DS will admit to being an AI unless the card explicitly forbids it.

  • [2026-08-15] RP-seat direction: KEEP MeroMero on char-rp; Artemis-31B rejected; next move is Dark-Scarlett on a Qwen3.8 base when it lands (operator). Evaluated TheDrummer/Artemis-31B-v1.1 — mechanically a drop-in (same google/gemma-4-31B-it base, identical 1188-tensor/356-vision census, same missing-preprocessor_config.json trick), so it's purely a quality call, and our own survey already ranked MeroMero #1 vs Artemis #6; Artemis is also unlicensed and its author deprioritizes correctness + warns of token-banning-for-stability, which fights char-rp's tool-calling requirement. MTP verified impossible on both (Gemma-4 has no MTP head at all — base/MeroMero/Artemis are all MTP=0; no finetune can add one). But speculative decoding IS reachable on a Gemma-4 seat via a DETACHED drafter — vLLM 0.24 supports eagle3 + gemma4_mtp, and real drafters exist: google/gemma-4-31B-it-assistant (0.94 GB, 4-layer, 761K dl), RedHatAI/gemma-4-31B-it-speculator.eagle3 (4.47 GB), AEON-7/…eagle3-NVFP4 (3.53 GB). ⚠ all list their verifier as stock gemma-4-31B-it, not an RP finetune, so acceptance against MeroMero is unmeasured and likely well below the gen seat's ~48%. UNTESTED — parked, ~45 min to measure, needs GPU0 headroom (card is at 94.4/97.9 GB). Why the Dark-Scarlett 3.8 plan is the strong one: DS is Qwen3.6-based today, so a 3.8 respin lands on the gen seat's architecture → native MTP returns and the whole mixed NVFP4+FP8 recipe + graft ports directly. Watch two things on arrival: from_pretrained silently drops MTP heads during finetuning (verify 15 mtp.* tensors in the index; graft from stock if absent), and DS v1.0 required the Qwen3_5ForConditionalGeneration wrapper class to save a config vLLM/SGLang accept. Both in docs/pfi/model-quantization-playbook.md.

  • [2026-08-09→10] dots.tts (rednote-hilab) TTS burn-in on irv-ml1 + canonical voice corpus built (voices/). Operator-directed eval to potentially replace chatterbox-fast. dots.tts VERIFIED real (canonical HF ns dots-studio/, rednote-hilab/dots.tts-* redirects there; Apache-2.0; PyPI dots.tts 0.2.1; 2B continuous-AR = semantic enc + Qwen2.5-1.5B LLM + flow-matching acoustic head over 48kHz AudioVAE; zero-shot clone from wav+transcript). Runs on Ampere 3090 (sm_86, bf16, no fp8 dep); optimized RTF 0.22 at num_steps=10 (from_pretrained(..., optimize=True) CUDA graphs — raw unoptimized was 1.21), ~6GB VRAM, 48kHz, streams (generate_stream). Venv+cache at irv-ml1:/home/lkraven/dots-tts (~10GB). Operator design calls: SGLang Omni serving (OpenAI /v1/audio/speech), transcribe-refs-first, soar variant. ⚠ Omni serves soar but its continuous-batching + streaming opts are mf-only (soar = single-request) — non-issue for ratatoskr's single-consumer RP surface. KEY FINDING — dots is highly sensitive to an accurate AND sentence-bounded reference transcript: mismatched transcript → 0.16s collapse; over-long/messy transcript → reference-audio BLEEDS as an output prefix; mid-clause trim → dangling-word leak (glados "we'll", emmie "And,"). RECIPE (baked into voices/derive.py): trim ref to a clean ~610s clip ending on a sentence boundary + accurate transcript of exactly that clip. CANONICAL VOICE CORPUS stood up in eshpfi voices/ (operator idea): engine-agnostic canonical/<v>.wav + transcripts/<v>.txt → per-engine ref sets DERIVED by derive.py reading engines.yaml profiles (dots/chatterbox/zonos); canonical wavs git-tracked (small/curated), derived/ gitignored. 4 voices optimized + verified CLEAN for dots: donut, glados, emmie, miranda (glados canonical is low-SR 16kHz — flagged upgrade candidate). ⚠ GPU GOTCHA: irv-ml1 native CUDA orders A6000=device0 (ComfyUI-full) — pin the 3090 with CUDA_DEVICE_ORDER=PCI_BUS_ID CUDA_VISIBLE_DEVICES=0; and PYTORCH_CUDA_ALLOC_CONF=expandable_segments CONFLICTS with optimize=True CUDA graphs (curr_block error). Booths: dots-vs-chatterbox, dots-voices-optimized. SHIPPED 2026-08-10: operator A/B verdict "dots is very good" → containerized as a thin FastAPI wrapper over DotsTtsRuntime (chosen over SGLang Omni — Omni's batching is mf-only, unneeded for ratatoskr's single consumer; wrapper is SERIALIZED one-gen-at-a-time via a threading.Lock, Omni+mf = parked API-compatible escalation if multi-consumer ever lands). LIVE on irv-ml1:8198 (local/dots-tts:v1, OpenAI /v1/audio/speech + /health + /v1/voices, container healthy, both stream + non-stream verified CLEAN, 4 voices donut/glados/emmie/miranda) alongside chatterbox :8197 (nothing repointed). Stack = stacks/dots-tts/ (Dockerfile/app.py/compose/.env.example/README). ⚠ CONTAINER GOTCHA: optimize=True (torch.compile/inductor/triton) needs a C compiler at RUNTIME — slim image must apt install build-essential or model-load dies "Failed to find C compiler" (host venv had gcc ambient, masking it); persist TORCHINDUCTOR_CACHE_DIR to a mounted dir or every restart re-JITs ~5min. Corpus home = eshpfi voices/ (operator ruled keep-here). REMAINING: ratatoskr client cutover to :8198 /v1/audio/speech (Phase-2 tail, peer-coupled — draft the ask). reference_chatterbox_fast_repo reference_zonos_tts_stack reference_verify_hf_repo_ids_before_pull

275 older entries archived to archival-memory.md.

Tried and abandoned

  • [2026-09-04] Forcing 10G on the ESH-Media DAC — it linked, then degraded over hours, and I reported a plateau at two minutes. ⚠ A clean zero-error link at 1G does NOT rule out a marginal cable; autoneg's fallback was protecting something real. → persistent-memory.d/2026-09-04-dac-forced-10g-failed.md

  • [2026-08-03] ComfyUI --enable-triton-backend on the irv-ml1 A6000 crashes EVERY render — Ampere has no hardware e4m3. adhoc-agent's operator-approved probe: comfy_kitchen's triton backend has a FUSED int8 matmul that would beat the eager backend's ~1.9x-slower unfused int8 path (21.3s vs 11.2s fp8 on the Moody Krea2 int8 checkpoints). Flipped it (added to COMFY_CMDLINE_EXTRA, recreated) → triton.compiler.errors.CompilationError: ValueError("type fp8e4nv not supported in this architecture. supported: fp8e4b15, fp8e5") in comfy_kitchen/backends/triton/quantization.py:145 dequantize_per_tensor_fp8, failing at node 5 CLIPTextEncode. Triton's fp8 dequant kernel targets fp8e4nv (Hopper/Ada e4m3); sm_86 Ampere (A6000) lacks hardware e4m3 → the JIT compile dies. With triton on it grabs the global --fp8_e4m3fn-text-enc dequant, so every render (fp8 AND int8) dies upstream at the text-encode step — the int8 UNet path never ran, so the convrot-coverage caveat wasn't even the limiter. Reverted cleanly (~15s to healthy, image unchanged sha256:94afb8ca, sage intact, prod restored). The parked cu130 rebuild won't fix it (e4m3 = hardware format, not CUDA version). DEFERRED to the Ada refresh (operator: "ada is coming, we'll optimize then" — Ada sm_89 has native e4m3, so triton's fp8 path should compile there). Mechanics: --enable-triton-backend is a compose environment: var, so toggling it needs docker compose up -d (recreate), NOT docker restart (reuses the baked env, no-ops silently). Full: auto-memory parked_triton_backend_ampere_fp8.

152 older entries archived to archival-memory.md.