Files
esh-pfi-infrastructure/persistent-memory.md
T
vh 77224619ee Give GPU0 real headroom: mog-sec to util 0.50 and 384k context
sec/sec-reasoning crash-bounced twice in ten minutes, not once in thirteen days.
My earlier read of "rare, not chronic" came off a RestartCount of 1 and was
wrong; the operator pushed back and the second and third failures arrived while
that recommendation was still on screen. The memory entry making that call is
replaced rather than left standing.

Cause is unchanged from the first diagnosis: mog-sec at 0.52 plus gen at 0.38
reserve 0.90 of the card, leaving about 4.6 GiB, and vLLM's utilization figure
covers weights and the KV pool but not transient activation memory. A request
about 151,700 tokens deep scheduling a further 15,700-token chunk asked for 1.04
GiB with roughly 600 MB free.

Dropping utilization alone does not work, and fails in a worse way: a single
420,000-token sequence needs 17.88 GiB of KV, and at 0.50 the pool is 17.4 to
17.5 GiB, so vLLM refuses to start at all and the seat crash-loops during startup
instead of during a request. The context length and the crash were directly
coupled -- 420k was only reachable at the utilization that left no transient
headroom. So both moved: 0.50 and 393,216.

384k rather than vLLM's suggested maximum, deliberately. It estimated 406,352 on
one boot and 409,840 on the next, because the available-KV figure drifts about
0.1 GiB boot to boot; pinning the edge value fails to start on an unlucky boot.
393,216 sits 3% under the lower estimate and leaves roughly 0.7 GiB of the pool
unspent, which is the transient headroom the change exists to buy.

Verified after: KV 405,612 tokens, concurrency 1.03x at 393,216, and both sec and
sec-reasoning return 200 through the gateway.

num_speculative_tokens is documented as NOT the lever. The crash window logged
17.6% draft acceptance with positions 5 through 7 at 1.5 to 4.9 percent, which
reads as an obvious cut from 7 to 3; across 180 samples the median acceptance
length is 3.12 of 7 and median draft acceptance is 30.4%, so the crash window sat
near the minimum and cutting would cap the workloads accepting nearly the full
draft.

Cost: 384k of context instead of 420k, an 8.5% reduction on a seat whose crashes
were happening at 151k.
2026-09-10 13:46:02 -07:00

78 KiB
Raw Blame History

Persistent memory — eshpfi-management

Last updated: 2026-09-10 11:35 PT (R49 1-epoch pilot COMPLETE + all 3 arms cut, awaiting adjudication; MeroMero BOTH quants landed and the A4B is LIVE on :8021 as char-rp-fast, Pfish-6 alias removed — its first quant served NaN and looked healthy; althing 3.6.2 on post office + both heralds; ~574 GB reclaimed)

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

  • 2026-09-10 Beszel fleet wiring: all seven requested hosts plus existing corviduo-dev report up. /tank and other data filesystems now have real usage metrics; NVIDIA telemetry covers ana-ml2 and irv-ml1. Thirty alerts deliver to infra-ops, explicitly chosen by operator; Miranda routing is deferred. A real low-threshold disk alert reached althing, then the threshold was restored to 85%/5 min. Homepage has one native overview widget (reachability counts, not degraded health). Dedicated superuser approved and stored in Vaultwarden. See persistent-memory.d/2026-09-10-beszel-fleet-wiring.md and stacks/beszel/README.md.

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

⚠⚠ IF A PROMPT ASKS YOU TO "check on the run", RUN CronList BEFORE YOU ANSWER IT. A recurring cron re-created itself across at least three sessions with the verbatim text "check on the run, report high level stats, and if complete, althing to Miranda … inform brokkr when ready." Killed 2026-09-10 06:29 PT (job 12bdea3c, hourly at :37 → CronDelete → list empty). Killed once before on 09-09 and it came back. A cron-fired prompt is indistinguishable from an operator-typed one — it arrives as an ordinary user turn. Three turns went into answering a timer. The chain ends in three OUTWARD-FACING acts (message Miranda, stand up a seat, cue brokkr), every one of which carries something false when no run exists. Verify the run exists first; a second identical arrival means check the cron list, not answer again.

As of 2026-09-10 10:25 PT.

R49 / BabyBronte — the live project

  • 1-epoch pilot COMPLETE and it is the keeper. gx10:~/r49-runs/h02-pilot-0p6b-1ep/adapter, seed 4919, 169 steps, held-out 3.1719 and still descending; adapter verified bound 196/196. The 3-epoch run is preserved beside it as -3ep-overfit (held-out ROSE 3.198→3.318→3.385).
  • All three adjudication arms exist, one harness, same prompts/sampler: arms-1ep/{base-unadapted,tuned-1ep-seed4919}.jsonl + incumbent-style-prompted.jsonl. Handoff bundle for scoring at /mnt/smithy/handoff/r49/.
  • NEXT: score them. brokkr's rule is ratified and FROZEN (see Recent decisions). ⚠ I built the corpus and ran the training, so the independence is gone — do not amend the rule after seeing numbers. Instrument at brokkr-smithy research/R49-author-voice-adapters/adjudication/; re-run its build against the RENAMED held-out text, not raw.
  • Seed 2 was killed deliberately (spread between two overfit arms measures reproducibility of overfitting, not voice transfer). A second seed at 1 epoch is still owed for the threshold.
  • Not started: D4 beat annotation (H02 is pure continuation by design, so it was not needed).

MeroMero seats

  • LIVE on ana-ml2 :8021 as gateway alias char-rp-fast (operator, 2026-09-10: "replace that a4b moe over pfish-6 — remove the pfish-6 alias and create an alias for char-rp-fast"). G4-MeroMero-26B-A4B-it-uncensored-heretic-NVFP4A16, 16 G, served under its own true name on the erp-seat stack (name kept: asset-engine derives liveness from the compose project name). Verified end to end — prose, vision (reads a solid-colour image), auto tool call, finite logprobs, and KV 534,649 tokens / 2.04x carried over from Pfish-6 unchanged. ⚠⚠ ITS FIRST QUANT SERVED NaN AND PASSED ITS HEALTHCHECK DOING IT. Built with the DENSE recipe (no re:.*router.* in IGNORE) → all 30 MoE routers quantized to 4 bits → expert selection destroyed. Every request returned finish_reason=length with the FULL token count and content: null; the only tell was NaN logprobs. Re-quantized with services/erp-seat-quant/quant_nvfp4a16_gemma4_moe.py (its guard refuses exactly that). Broken tree parked at ...-NVFP4A16.BROKEN-routers-quantized-20260910do not serve it. ⚠ Also had the §3.14 truncation cap baked in (max_length: 8192, quantized with the corpus); the MoE recipe's own post-step resets it.
  • G4-MeroMero-v2-31B-heretic-NVFP4A1619 G, landed on attempt 5. Tensor table identical family-for-family to the 2026-08-21 canonical quant; 356 BF16 vision tensors preserved; input_activations=None (genuinely A16). CPU load+generate coherent, 0 tensors on meta. ⚠ Attempt 4's AmbiguousGlobalPerLayerAttributeError was NOT a config defect — llmcompressor 0.13.0 downgrades transformers 5.16.1→5.14.1, and :latest moved mid-campaign. Fix was to DROP the redundant per_layer_config, not to force global access. → persistent-memory.d/2026-09-10-meromero-quants-and-the-pinned-transformers-trap.md, services/meromero-quant/, playbook §3.17 (new)
  • The v2 DENSE has still not had a serve test — GPU1 has ~19 GB free against 19.5 GB of its weights, so it needs a live seat displaced. Operator's call; "vllm servable" unverified for the dense tree. (The A4B's serve test is DONE and green, above.)
  • A co-resident temp port could not be made to fit even for the 16 G A4B, so §4.4's "temp port, never the live seat" was substituted with reversibility: named .env backup, prove the seat on its real port while no alias routes to it, move the alias last. Measured refusals: gpu-memory-util 0.20 → admission refused (18.26 GiB free vs 18.99 requested); 0.185 → past admission and past the KV reservation, then OOM in multimodal encoder-cache profiling (3 video items at max feature size), which is easy to forget when budgeting a vision model.
  • The A4B is 30 layers / kv 8 — Pfish-6's geometry, so it fits 262k in the existing KV budget. The dense 31B is 60/16, ~4x KV per token, and does NOT fit 262k on GPU1 beside the other seats.
  • Pfish-6 IS RETIRED from the gateway (2026-09-10). Its seat now serves the A4B; a caller asking for Pfish-6 gets an explicit 400 "Invalid model name", not a substitution. Audited first: 0 of 17 LiteLLM keys scoped it, so nothing was orphaned. The artifact stays on disk at /tank/aimodels/erp-tune-v6-nvfp4a16 and is the rollback target — cp .env.pfish6.bak-20260910 .env && docker compose up -d in /opt/docker/compose/erp-seat restores it in ~4 min.
  • The char-rp family is now char-rp (stock Gemma-4 26B-A4B, :8016) / char-rp-fast (MeroMero A4B, :8021) / char-rp-reasoning (Dark-Scarlett-27B, :8019). All three verified working after the change. ⚠ The char-rp comment block in stacks/litellm/conf/config.yaml still describes its seat as MeroMero-v2; that has been stale since the 2026-08-24 swap to stock Gemma-4. Not fixed.

Fleet

  • althing 3.6.2 everywhere it matters — post office (nh3-docker) + both heralds. ⚠ Only two nodes run a herald (nh3-dev, nh3-extdev); the "seven boxes" in the rollout instruction do not participate. Drop-count BEFORE baselines: nh3-dev 27 in 18 sessions, nh3-extdev 0. Flat after = fix confirmed; rising = a second source, forseti wants to hear.
  • Beszel wired by another agent (eb75713) after my handoff at /tmp/beszel.md. Alerts now reach althing. ⚠ When I last looked, EXTRA_FILESYSTEMS held container-internal paths with no matching bind-mount, so /tank may still not be sampled, and alert links pointed at localhost:8090. Re-verify rather than assume it is closed.
  • Disk reclaimed today: 466 GB (qwopus + huihui 122B bf16, operator-directed) and 107.8 GB Docker on ana-ml2 (dated filter; root 77%→58%). ⚠ Image prune took vllm-qwopus35-122b's TAG but not its layers — the rollback container still starts, but re-tag if you want the name back. 27.39 GB of build cache remains, newer than the 168h window used.
  • /tank/aimodels/heretic2-nvfp4-work is a reclaim candidate that holds a load-bearing 4.4 MB fileproduction_calib_512.jsonl, the calibration set every in-house quant references. Copied to ana-docker:/opt/docker/conf/quant-calib/ (a restic source) with a README. NOTE: A16 quants are data-free and ignore it, so its loss would only bite activation-quantized schemes.

Recent decisions

  • [2026-09-10] GPU0 headroom FIXED: mog-sec now runs MOG_GPU_MEM_UTIL=0.50 / MOG_MAX_MODEL_LEN=393216 (was 0.52 / 420000), after sec/sec-reasoning crash-bounced TWICE in ten minutes.I initially called it "rare, not chronic" off a RestartCount=1 and recommended doing nothing — the operator pushed back and was right; it recurred inside ten minutes (fatal errors 20:20:30Z and 20:30:02Z). Cause: mog-sec (0.52) + gen (0.38) reserve 0.90 of the card, leaving ~4.6 GiB, and vLLM's utilization figure covers weights + KV pool but NOT transient activation memory — a request ~151,700 tokens deep scheduling a ~15,700-token chunk asked for ~1.04 GiB with ~600 MB free. ⚠⚠ 0.50 and 420000 are MUTUALLY EXCLUSIVE and dropping util alone makes it crash-loop at STARTUP instead: one 420k sequence needs 17.88 GiB of KV, the 0.50 pool is 17.417.5 GiB, so vLLM refuses to start outright. ⚠ Do NOT pin max_model_len to vLLM's suggested maximum — it estimated 406,352 on one boot and 409,840 on the next (available-KV drifts ~0.1 GiB per boot), so the edge value fails on an unlucky boot; 393,216 sits 3% under the lower estimate and leaves ~0.7 GiB of the pool unspent, which is the transient headroom the change exists to buy. Verified after: KV 405,612 tokens, concurrency 1.03x, both aliases 200 through the gateway. Backup .env.bak-util052-20260910; full reasoning in stacks/mog-sec/compose.yaml's header.

  • [2026-09-10]Near-miss on measurement discipline, worth keeping as a specimen. The crash window logged Avg Draft acceptance rate: 17.6% and per-position rates of 0.049/0.024/0.015 for draft positions 57, which reads as an obvious "cut num_speculative_tokens 7 → 3, it is buying nothing." Across 180 samples of the same counter over the container's life the real distribution is median acceptance length 3.12 of 7 (range 1.836.75) and median draft acceptance 30.4% (range 11.982.1%) — the crash window was near the minimum, not the norm, and cutting to 3 would cap the workloads that were accepting nearly the full 7-wide draft. The n=1 window pointed the opposite way from the n=180 distribution. Same session that wrote "a positive control is only worth what it can distinguish"; the lesson generalises to log lines.

  • [2026-09-10] R49 carrier SETTLED on dense Qwen3-{0.6,1.7,4}B-Base, overriding H02's own pin — the newest carrier was the SLOW one. Dense 4.089 B trains 33% faster than hybrid 0.765 B; no fused SSM kernel installed. D1D3 built, 1-epoch pilot beats the 3-epoch by 0.21 nats held-out. → persistent-memory.d/2026-09-10-r49-babybronte-d1-d3-and-the-1-epoch-pilot.md

  • [2026-09-10] R49 adjudication routed to infra-ops entirely (operator, relayed by brokkr: "leave babybronte to infra — concentrate on r50 and the memory mechanism"). brokkr handed over the Delta instrument and stepped off. ⚠ I now grade my own run; brokkr's decision rule is ratified verbatim and frozen before any adapted text existed and must not be amended after seeing numbers. Their controls: real Charlotte 1.652.17, Anne at 2.374 — so the absolute band decides, never nearest.

  • [2026-09-10] MeroMero A4B swapped onto the erp-seat seat as char-rp-fast; Pfish-6 alias removed. The A4B's FIRST quant used the dense recipe and 4-bit-quantized all 30 MoE routers — it passed its healthcheck and answered every request with the full token count decoding to the empty string, NaN logits the only tell. Re-quantized with the MoE recipe; live and verified (prose, vision, tool call, finite logprobs). Durable lesson: a positive control must match the ARCHITECTURE CLASS — the broken A4B was diffed against a good dense quant, which has no routers, so the clean result was meaningless. → playbook §3.15, §4.4

  • [2026-09-10] MeroMero: BOTH quants landed in-house at W4A16 — A4B first try, v2 dense on attempt 5. Published quants are all W4A4 (our measured long-context collapse) or nonexistent for v2. Operator: "pull both ablits bf16, run our own quant." The durable lesson is §3.17: pip install llmcompressor silently pins transformers down a version, so attempt 4's error was a moved toolchain, not the malformed upload it looked like — a known-good positive control is what told them apart. Serve test still owed. → persistent-memory.d/2026-09-10-meromero-quants-and-the-pinned-transformers-trap.md

  • [2026-09-10] althing 3.6.2 deployed — post office + both heralds — and the fleet has TWO herald nodes, not seven. Ask the post office's nodes table, not the box inventory. Cost a self-inflicted ~12 min bus outage. → persistent-memory.d/2026-09-10-althing-362-rollout.md

  • [2026-09-10] A grep over a log that records your greps counts itself. I reported forseti's drop defect as reproducing here with 3 drops in 21 s; the session had zero. Searching transcripts writes the search term into them. Filter by "type":"system" provenance, never content. Generalises to any instrument that can see itself. Auto-memory feedback_grep_over_a_log_that_records_your_greps.

  • [2026-09-10] Operator-directed purges: 466 GB (qwopus + huihui 122B bf16) and 107.8 GB Docker on ana-ml2. Serving/rollback artifacts and qwopus's MTP head verified intact after. ⚠ /tank is OUTSIDE restic, so both were final.

  • [2026-09-10] ana-docker disk pressure repaired: root 84% → 51%, 115 GiB free. Gitea/Vaultwarden backups repaired and restored from Restic 2ec5a37c; 101 stale dumps removed; hourly named-builder cache pruning installed. → persistent-memory.d/2026-09-10-ana-docker-disk-repair.md

  • [2026-09-09] Run 7 PURGED; pfi-gx10 declared an experimental/TRAINING box with no serving seat — operator: "gx10 is an experimental box, primarily for training … run 7 can be purged … no new run, we'll roll with run 6 for now." ~139 GiB reclaimed across both boxes; the 315 MB adapter + provenance KEPT as the only non-reproducible piece. Pfish-6 on ana-ml2 :8021 is the sole standing seat.

  • [2026-09-09] Run 7 RETIRED; run 6 declared Pfish-6 and is the standing seat — NVFP4 quant on ana-ml2 :8021 AND gx10 :8098 at 262k ctx, gateway alias trialPfish-6, max-num-seqs 8→32 (2,170 tok/s at n=16, 3.2x the old ceiling). ⚠ ana-ml2 measured 4.1x FASTER than the GX10 on the same artifact — the reverse of the expectation. → persistent-memory.d/2026-09-09-run7-retired-pfish6.md

  • [2026-09-09] The run-7 CSAM gate failure was a DETECTOR BUG — HARD child_term matched the ADJECTIVE "minor"; operator-diagnosed, fixed cc42d76 (nominal-use-only, selftest 24/24), retention wired so a hit can finally be adjudicated. ⚠ The lesson is mine: rigor downstream of an unexamined premise is not rigor. → persistent-memory.d/2026-09-09-csam-detector-bug.md

  • [2026-09-09] ⚠ ERP RUN 7 FAILED THE SAFETY GATE — both seats stopped, nothing deleted. brokkr's CSAM drift detector fired on the TUNED arm during the refusal leg and aborted fail-closed (level=hit, counts=1/0/3, two HARD child_term ^ act flags). Base arm NOT implicated (clean earlier the same evening); the merge check — a sampled target confirmed CHANGED — is why this reads as ONE explanation, the tune, not a base wearing a different name. Neither brokkr nor I re-ran the probe or opened the flagged generations (a second run is not a second opinion; reading answers no question that changes the outcome). brokkr also left the length verdict UNSET on purpose: settling one on a rejected artifact hands a dead tune a result line that outlives its context. Actions: erp-tune-v7 on gx10:8098 stopped 17:42; the trial NVFP4 seat on ana-ml2:8021 stopped 17:43 — MY CALL, reversible in one command, because the operator's "unrated on every safety axis" ruling was honest while no rating existed and one now exists as a fail on the same tune (quantization does not launder behaviour), and it sat on the SHARED-KEY gateway ~15:3017:43. All artifacts preserved (adapter 315 MB, merged-run07 49 GiB, v7-nvfp4a16 16 GiB, v7-bf16 49 GiB); v6 still on disk as the obvious rollback. Independent of safety the run was already poor: primary FLAT (69 → 70.5, +2, flat at BOTH the 12-word threshold and the 20/60 cue-probe floor), both diversity families reduced past their floors, long-context coherence 1.0 → 0.875 on its must-not-harm bar, unanswerable control held at 1.0 so the instrument was valid. INCIDENT CLOSED 2026-09-09 ~18:20 PT, both sides. trial alias REMOVED from stacks/litellm/conf/config.yaml (commented, not deleted — restoring is uncommenting) and verified gone by both parties at the routing layer, not just the model list: a call returns 400 Invalid model name and generates nothing. ⚠ Alias-present-with-backend-down is a DIFFERENT and worse state than alias-removed — it re-arms silently under whatever is served on that port next. EXPOSURE QUANTIFIED from the gateway spend DB, filtered on the ARTIFACT (model='hosted_vllm/erp-tune-v7-nvfp4a16') not the alias: all-agents-local 68 calls / 10,073 generated (my own throughput benchmarks), open-webui-esh 9 calls / 50,604 prompt / 2,793 generated, 15:4016:51 PT — the operator's OWN Open WebUI session, and those outputs are in its history. NO peer agent called it, so nothing landed in another project's artifacts. Nobody read the flagged generations or that session. ⚠ Counting by the ALIAS would have returned 363 vs 77 — 4.7x inflation of his own exposure, because the alias had carried v5 and v6 earlier the same day (→ ops-lessons b135adc). ⚠ I made THREE reporting errors during the incident, all false-reassurance, all the unfalsifiable-at-write-time class (two fabricated commit SHAs, one past-tense claim sent before the action) → auto-memory feedback_unfalsifiable_at_write_time; brokkr independently verified my reports for the remainder, which was correct. DECISION BRIEF FOR THE OPERATOR: http://10.100.10.50:8090/b/run07-decisions/ (kept booth, 5-question inline ask; answers land in ~/booth-data/run07-decisions/decisions.answer.json — read it with booth answer run07-decisions decisions). Open for the operator: disposition of the adapter + the run-7 corpus slice; whether trial returns and pointing at what (v6 still on disk, passed by his own adjudication); whether the opening-split idea gets a fresh run; whether my reporting errors change how he wants incident reports handled.

  • [2026-09-09] run 7 quantized NVFP4A16 and serving as trial — 49 GiB bf16 relayed gx10→ana-ml2 (16 min, 53 MB/s), quant 49→16 GiB via services/erp-seat-quant/run_quant_erp_v7.sh (dry-run gate passed: 11,725 targets / 11,520 experts, routers+vision BF16), seat on :8021 under its TRUE name erp-tune-v7-nvfp4a16, LiteLLM trial repointed (config-file alias — /model/update REFUSES a config model, must edit stacks/litellm/conf/config.yaml + restart). Rollback: v6 artifact on disk + /tmp/erp-seat-env.v6.bak. ⚠ no direct path was WRONG — gx10↔ana-ml2 ROUTING is fine both ways; neither box holds a private key (only authorized_keys), so neither can initiate. ssh -A agent forwarding from nh3-dev gives a genuine direct path, verified. The relay costs nothing here anyway: both gx10 and nh3-dev are at NH3, so the WAN hop happens once either way.

  • [2026-09-09] Booth: partial ask answers are legal (v0.1.15) — operator: the form failed when a question was left blank. required dropped from the radios; answered questions recorded, blanks land in unanswered, complete says whether the set is finished; refused only when there is no pick anywhere AND no notes. Reading sessions must check complete.

  • [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-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.

159 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.