# Raw Memories ## 01a11a28-0cdb-70df-9edd-7d10adfcd213 updated_at: 1791447271 ## Halogen 400 max_tokens-does-not-fit Fix (frank-large, dankclaw) ### Root Cause - HALOGEN_CTX (per-slot ceiling) was 200192. Harness budgeted max_tokens=57344 as a fixed allocation. When prompt_tokens (server-counted) + max_tokens > HALOGEN_CTX, engine returns 400 invalid_request_error. - Harness estimates tokens at ~chars/4 (under-counts by ~3% vs server tokenizer), so harness "65% of 200k" ≈ 157k server tokens, exceeding the effective usable window of 200192 - 57344 = 142848. ### Fix Applied - HALOGEN_CTX raised from 200192 → 262144 (native Qwen3.8-Flash-Next context window). - HALOGEN_KV_POOL_POSITIONS raised to 524288 (2 slots × 262144). - Harness models.yml contextWindow set to 217088 = 262144 - 45056 (maxTokens margin). - Harness maxTokens set to 45056. - Compaction threshold set to 85% of contextWindow → triggers at ~184524 estimated tokens. ### The Fit Law (formula) ``` engine_ceiling = 262144 harness_contextWindow = engine_ceiling - maxTokens = 217088 effective_max_tokens = min(maxTokens, contextWindow - est_tokens - reserve) reserve = 4096 (safety margin) ``` With ~3% under-count robustness: a 10% under-count on est_tokens (2300–4450 tokens) still fits with ~43k margin. ### VRAM / Memory Budget (121.2 GiB unified, RTX 3090) - Weights: ~62 GiB (Qwen3.8-Flash-Next) - KV pool: 524288 positions × 28 KiB ≈ 13.3 GiB (measured 14.4 GiB) - Arena: ~5.5 GiB - Vision: ~2 GiB - Total: ~83 GiB used, ~39 GiB remaining, 20 GiB reserve → 9.4 GiB measured margin - Boot ledger NOTE fires (advisory, n-gram table served from disk page cache) - Pin-gate floor on restart: MemAvailable ≥ ~78 GiB required ### Deploy Command `dankclaw --service frank-large` (e2e gate 33/33, frank-large 20/20 including new fit-law seam test) ### Live Probe Verification 226,663-token prompt (26k past old ceiling) → HTTP 200, correct answer, ~137s at ~1600 t/s prefill. Decode 19.7–21.9 t/s, prompt-cache 99%+. ### Pitfalls - HALOGEN_CTX is per-slot ceiling, not total KV budget. KV pool must be sized ≥ sum of all slot contexts. - If KV pool is undersized, halogen clamps context silently at boot (check boot ledger for clamp message). - The harness contextWindow must always be < HALOGEN_CTX by at least maxTokens to prevent 400s. - frank-primary MAX_SEQS test (#180) is a pre-existing failure, unrelated. ### Files Modified - `/home/blank/.omp/agent/models.yml` — contextWindow: 217088, maxTokens: 45056 - Dankclaw frank-large env (HALOGEN_CTX=262144, HALOGEN_KV_POOL_POSITIONS=524288) - Commit `76aaa25`: env + bats + AGENTS.md + runbook ## 01a10fc3-5009-7470-980a-fb58b594886f updated_at: 1791422424 ## Authentik Human-User Template (ridley shape) Every human user in the fleet gets: username ``, email `@franksdank.cloud`, display name `Name`, active, path `users`, groups: Non-Admin Users + jellyfin_users + openwebui_users. This is the canonical template recorded in `serverAppConfigs-docs/Infrastructure/Authentik.md`. ## Audit-Before-Destroy Rule Before deleting an Authentik user, check across: MFA device tables, `authentik_core_token`, `providers_proxy_proxysession`. Fleet column names differ from ORM names — `events.user` is denormalized JSON (not FK), `certificatekeypair` has no `user_id`. Events survive user deletion because of the denormalized user field, so audit trail integrity is preserved after delete. ## Jellyfin LDAP Outpost DN Stability The DN format is `cn=,ou=users,…`. Recreating a user with the same username preserves the Jellyfin user record (DN unchanged), so Jellyfin picks it up on the outpost's refresh cycle without user re-provisioning. ## Password Handling Never touch argv, logs, or repo with passwords. Login verification uses `authenticate()` (PasswordStage code path): returns user for correct password, `None` for wrong one. ## Fleet Authentik Roster (as of 2026-10) Superuser: akadmin. Humans: admin, alex (pk 15, recreated from pk 7 on 2026-10-08), ridley, kassie (pk 14). Plus QA and service accounts. The `admin` account is flagged as an open question (deactivate?). ## Commit Pattern for Docs-Only Changes `bats tests/docs_completeness.bats` gate → `git add` → commit with detailed message → `git push -q origin main`. No deploy.sh needed for docs-only commits. ## 01a11414-45b0-744e-894d-0751abafe264 updated_at: 1791390151 ## frank-large 400 max_tokens overflow — diagnosis and fix ### Error pattern ``` 400 max_tokens 50013 does not fit: prompt is 150306 tokens and the context is 200192, leaving room for 49886. ``` Server rejects because promptTokens + maxTokens > contextWindow. ### Root cause The harness computes `max_tokens = min(maxTokens, contextWindow − estimatedPromptTokens − 4096)` using a chars/4 token heuristic. On code-heavy prompts this estimate **under-runs** the server's actual BPE token count by ~2.8%. When the prompt is already near the compaction threshold, the 2.8% error (~127 tokens at 150k prompt size) is enough to push max_tokens over the remaining room by a small margin. ### Design constraints (from AGENTS.md / models.yml) - contextWindow: 200192 (per-slot hard ceiling, HALOGEN_CTX=200192) - Compaction triggers at 70% = 140,134 tokens - Compaction budget: 57,344 tokens - The clamp: `max_tokens = min(maxTokens, contextWindow − estimate − 4096)` - reserveTokens in compaction logic: 16,384 (so compaction threshold = 200,192 − 16,384 = 183,808 for the internal compaction model call) - maxTokens in models.yml: 45056 (44 × 1024) - HALOGEN_MAX_TOKENS_CAP in frank-large.env must stay >= maxTokens value - Worst-case estimate error at compaction threshold (183,808): ~5,147 tokens, leaving effective maxTokens <= 16,384 ### Fix - Lower maxTokens in models.yml OR add a larger safety buffer (the −4096 in the clamp is insufficient when estimate error is ~2.8%) - Alternatively, lower the compaction threshold so the prompt never reaches sizes where estimate error matters - The raw failed request is logged at `/home/blank/.omp/logs/http-400-requests/` for post-mortem ### frank-large config summary (as of this rollout) - Engine: halogen-flash-server 0.16.2 - Model: Quat3rnion/halogen-swift1.5-qwen3.8-flash-next-v2-abliterated (66.7 GB .hgn, r2 compacted) - MTP: ALWAYS ON (HALOGEN_SPEC_ADAPT=0 — adaptive policy disabled because it halves decode) - Vision: ON (image_url content parts, >=256px) - Reasoning field: `reasoning_content` - reasoning_effortMap: minimal/low→low, medium→medium, high/max→xhigh (any other value rejected, not clamped) - Performance: 53-57 t/s greedy, ~1,640 t/s prefill at 34k, ~72% fewer thinking tokens than censored 27B - TWO slots at HALOGEN_CTX=200192 each ## 01a10f30-003b-74c6-a60f-ae34c9eac5fa updated_at: 1791316694 ## Radiance Runtime (StillDeadcode) — frank-primary deployment **Runtime**: radiance (StillDeadcode v1.0.7), image `stilldeadcode/radiance` digest-pinned (~287 MiB). This is NOT vLLM — completely different rules, flags, and architecture. Key distinction: native-precision checkpoints need no container or quantization step. **Model**: `Qwen/Qwen3.8-Flash-Next-FP8` (official Qwen checkpoint, 172.8 GB, 131 shards). Served at native modelopt block-FP8 — zero requantization, zero calibration. Converted no-recipe to `qwen4exp-fp8-native.rad` (177,109 MiB = 173.0 GiB). Experts byte-stacked, PLE re-encoded at checkpoint's own bf16 scale. **Chat template**: `huggingface.co/froggeric/Qwen-Fixed-Chat-Templates` **Key radiance-specific concepts/flags**: - `.rad` payload format (radiance's native model format) - `libr4d` kernels (gfx1201 for RDNA4/R9700) - `--tp-wire wht6` for tensor parallelism - `--placement expert_tiered` for expert placement strategy - `--expert-vs-cache-ratio 0.82` (ratio of pinned host pool to VRAM cache for experts) - `--ngram-placement ram` (PLE pinned to host RAM) - MTP (Multi-Token Prediction) spec decode, depth 3 - `--max-num-seqs`, `--max-model-len`, `--mnbt` (minimum batch tokens) **Topology (dankserver 192.168.0.235:7770)**: - Both R9700 GPUs, TP=2 - fp8 KV cache, 7.32 KiB/token - max-model-len 200000, MNBT 2048, max-num-seqs 2 - 40 GiB/rank pinned host pool for experts - PLE 47.7 GiB pinned to RAM **Critical constraint**: A checkpoint served at its own precision needs no container/quantization. Quote from docs: "A checkpoint served at its own precision needs no container: radiance --model ~/models/Qwen/Qwen3.8-Flash-Next-FP8" **Fleet history note**: Prior deployments used "radiance-vLLM" (tcclaviger fork) and "vllm-radiance" — these are different from the new StillDeadcode radiance standalone runtime. The new runtime is a completely different codebase with different CLI, flags, and model format. **Cutover date**: 2026-10-06 00:55. Stable config commit: c80c250 (spec=3, seqs=2). ## 01a11006-6c8c-7288-9049-6d53c24be957 updated_at: 1791283043 ## frank-large halogen-flash-server v2 (Swift1.5 Abliterated) — Cutover 2025-01 ### Deployment State (post-cutover) - Host: Dankclaw (192.168.0.143), Strix Halo iGPU gfx1151 (Radeon 8060S, ~114 GiB GTT) - Container image: halogen-flash-server v2 (NOT the old halogen 0.1.4 from ghcr.io/peonist-ai/halogen) - Model: Swift1.5 Abliterated, 62.11 GiB weights (incl. 0.84 GiB vision tower) - KV pool: 400,384 positions ≈ 11.0 GiB, 2 slots over ONE pool, each request up to 200,192 ctx - Prompt cache: ON, 12 entries, inplace - Sampler: temp 1.0 / top_p 0.95 / top_k 20 (server-side, embedded in engine) - Speculative decoding: draft_n=12, draft_n_accepted=9 (observed on test prompt) - Watchdog: on, 180s - Host RAM left after load: 15.6 GiB (tight but stable; engine pin gates all passed) - Vision: works (512×512 red PNG probe returned "The image is red.") - N-gram table: NOT pinned (mmap read-through confirmed in boot ledger) ### Performance (post-cutover measured) - Prefill: 210 t/s - Decode: 30.6 t/s - Previous (halogen 0.1.4 qwen3.8-27b-p1w4d-d2): ~31.7 t/s mean across eight workloads (publisher claim) ### Rollback Revert commit `31b1ec3` and redeploy. The 27B payload at `/home/dank/models/halogen-qwen3.8-27b/`, its fetch script, and halogen 0.1.4 image digest all remain on disk. ### Repo & Deploy Infrastructure - Repo: `/home/blank/Projects/serverAppConfig` (singular "Config" in path) - Gitea remote: `http://192.168.0.143:3000/dank/serverAppConfigs.git` (plural "Configs" in repo name) - Cutover commits: `31b1ec3` (config), `2d89bf9` (docs) - Deploy gate: 362 unit tests + 33 Playwright e2e tests must pass - Docs updated: models.yml, runbook, index, AGENTS.md (317 insertions, 114 deletions across 3 files) ### Fleet Co-tenancy (Dankclaw) - frank-large: halogen-flash-server v2, 62 GiB weights + 11 GiB KV (iGPU) - frank-small: llama.cpp on RTX 3090 - Full AI/search/observability stack ### Operational Pitfalls - `systemctl mask` FAILS on relinked units (unit file in /etc/systemd/system/ is a symlink into checkout). Stop is sufficient for bench windows; re-deploy restores the unit instead of unmasking. - Engine stdout logs: `/home/dank/logs/frank_large.log` — boot ledger (KV pool, drafter state, clamps) lives there. - Env tunables: `scripts/frank-large.env`; serve script: `scripts/serve-frank-large.sh`; systemd unit: `scripts/frank-large.service`. ### Benchmarking Policy (Dank fleet) - STOP production service BEFORE benchmarking: `sudo systemctl stop frank-large` - Use runtime's own harness for benchmarks; rolling your own bench requires asking first. - After benching: unmask/restart (or re-deploy for symlinked units), verify health. - `live-llm-benchmark-hygiene`, `live-endpoint-server-timing-ab`, `spec-decode-ab-single-gpu-host` skills govern methodology. ## 01a10fad-1e4d-71ba-95a6-376974fd706a updated_at: 1791280376 ## frank-small IQ3_S swap attempt (cancelled/rolled back) ### What was attempted Replace frank-small (llama.cpp CUDA, RTX 3090) serving MiMo-V2.6-Distill-Qwen-9B Q6_K with `ukisai/Swift-1.5-Qwen3.8-27B-GSQ-RCO-GGUF` in IQ3_S quant, MTP, cap context 128k/slot, KV FP8 (q8_0), vision on, max parallel slots. ### Why it was rolled back User issued explicit rollback order mid-swap. The Bonsai2-CRACK swap was also superseded. Both tasks were cancelled, not completed. ### Final live state (verified) - **frank-small**: Swift RCO-IQ3_XXS + draft-mtp, 2×131072 context slots, health OK - **Repo**: clean at commit `bb3532d`, pushed - **Bonsai**: parked on disk (`models/Bonsai2-CRACK/` + `GitPackages/llama-prism/`), nothing committed ### Technical knowledge extracted from the sizing analysis **IQ3_S 27B on RTX 3090 VRAM budget:** - IQ3_S ≈ 3.44 bpw → ~11.6 GB weights for 27B - MTP head (nextn layer) if included: small addition - mmproj (vision tower): ~1.5 GiB runtime if separate file - KV q8_0 for qwen35 hybrid (12 full-attn layers × 8 kv_heads × 128 dim × 2B × 2): ~24 KiB/token → ~3.0 GiB per 131072-token slot - At 24 GB card: 11.6 (weights) + 1.5 (mmproj) + N×3.0 (KV) + buffers → fits ~2-3 slots at 128k with q8_0 KV - Previous runbook: `serverAppConfigs-docs/LLM/frank-small-qwen38-gsq-rco.md` (ISTA-DASLab GSQ-RCO IQ3_S ran 2026-09-16→09-17) **MTP on qwen35 27B architecture:** - MTP = property of the FILE (needs `qwen35.nextn_predict_layers` in GGUF metadata) - MTP head tensors: `blk..nextn.*` (e.g. blk.48 for 48-layer 27B) - Activate with `--spec-type draft-mtp` (sets `load_mtp`) - Flash-Next MTP heads do NOT load on current loaders (need full per-layer `blk..hc_attn_norm.weight`, Flash-Next ships only blk.48). This is Flash-Next specific, not qwen35. - qwen35 MTP worked historically: eemin W4A4 ROCm, ROCmFPX Q6_AGENT+MTP eras **KV FP8 in llama.cpp:** - "FP8" in llama.cpp = `q8_0` (8-bit quantized storage) - Flags: `--cache-type-k q8_0 --cache-type-v q8_0` - Requires `GGML_CUDA_FA_ALL_QUANTS=ON` in CUDA build (build-cuda rebuilt with this ON 2026-09-17) - q8_0 KV halves f16 KV storage **Vision on frank-small:** - Requires `--mmproj` pointing at mmproj GGUF file - Qwen3.8-27B checkpoint DOES carry a vision encoder (halogen engine ignores it, llama.cpp can use it) - Must verify HF repo ships `mmproj-*.gguf` **qwen35 27B architecture (for KV math):** - 16 × (3 Gated DeltaNet + 1 Gated Attention) = 48 layers total, 12 full-attention layers - Full-attn KV: 12 layers × 8 kv_heads × 128 head_dim ### Operational patterns - **Mid-swap rollback**: User can cancel a swap order mid-flight. Handle by reverting to prior endpoint, verifying, and dropping stale todo items (use `drop` op, not `done`). - **Bonsai2-CRACK**: parked on disk at `models/Bonsai2-CRACK/` + `GitPackages/llama-prism/` if revisited. - **llama-prism**: the package name associated with Bonsai (likely a vision adapter for llama.cpp). ## 01a10f44-6c75-7548-86b1-a7a3603ca8af updated_at: 1791270185 ## Hardware / Stack Constraints - Strix Halo iGPU with ~114 GiB GTT aperture is the compute target for ComfyUI. - The discrete 3090 is permanently occupied by frank-small; ComfyUI MUST run on iGPU only. - BF16 Qwen-Image checkpoint (~20 GB) is too heavy to occupy the iGPU while the box stays responsive. Use FP8 or Q6 quantized checkpoints instead. ## ComfyUI Goal Template (Qwen-Image Workflow) Success criteria confirmed by user: 1. One Qwen-Image workflow JSON saved into repo's ComfyUI area (comfyui/workflows/). 2. One PNG actually generated through live ComfyUI API on Dankclaw's iGPU. 3. Short recommendations page (≤5 models/LoRAs with names, sizes, download sources). 4. Must use FP8 or Q6 quantization (user explicit constraint). ## Image Display in Terminal (Ghostty) - Ghostty natively supports kitty graphics protocol; default `--image-storage-limit` is 320 MB per screen (0 disables images). - Hand-rolled `\e_G` escape sequences emitting base64 PNG data are in-spec and work without any helper binaries. - No image preview helpers installed by default (chafa, icat, viu, catimg all absent). `pacman -S chafa` would add `chafa file.png` with auto protocol detection. - Two ~1-2 MB PNGs (~3 MB total b64) are well within ghostty's 320 MB limit. ## Harness Read Tool Image Behavior - Plain `read ` (no selector): image-capable models receive text note + inline image block; max input 20 MiB (MAX_IMAGE_INPUT_BYTES). - Text-only model role: receives metadata + `?q=` hint (no inline block) — this is documented behavior, not a failure. - `read ?q=`: routes to vision model, returns text answer. - If current model role is text-only, PNGs will NOT display inline in chat; use `?q=` for vision analysis or kitty protocol for terminal display. ## 01a10e21-a0a6-7161-92a2-18c1cf17d7ed updated_at: 1791260816 ## Context Bloat Diagnosis - nonMessageTokens (system prompt overhead) consistently ~37904-38171 tokens regardless of conversation length — this is the fixed floor before any user/assistant messages. - Components measured: AGENTS.md (repo file), memory_summary.md (~413 chars, small), managed-skills descriptions (MAJOR bloat), user skills, tool definitions. - Method to measure: `wc -c AGENTS.md`; count skills with `ls ~/.omp/agent/managed-skills | wc -l`; parse SKILL.md frontmatter descriptions with python for total desc bytes. - Skills with descriptions are injected into context even when only names/descriptions are needed (not bodies). 175 skills × descriptions was the dominant bloat source. ## Skill Library Distillation Workflow - Managed skills live at `~/.omp/agent/managed-skills//SKILL.md` (175 dirs, 1.7MB total). - User skills at `~/.omp/agent/skills/` (9 items). Repo skills at `.omp/skills/`. - Distillation: convert SKILL.md directories → vault reference pages (markdown in git repo, commit to Gitea). Removes them from context-injection path entirely. - After distillation, move original dirs to `~/.AGENTTRASH/-