All ~173 managed skills read in full and merged, one polished reference page per skill-cluster: - LLM cross-cutting (17 pages): GGUF Compatibility, Llama Cpp Serving Sizing, Llama Cpp Multi-Device Splits, PCIe Link and Atomics, RDNA4 Container Serving, RDNA4 MoE Expert Offload VRAM Budget, vLLM Boot Forensics, vLLM Porting and Compile Triage, LLM Bench Windows, LLM Performance Diagnosis, Model Swap and Rollback, Tcclaviger Fork Ops, Heterogeneous Split Triage, FreeToken Builds + deltas folded into the retired runbooks (GLM DFlash2 port laws, Lucebox dual-R9700, R9V qualification pipeline, FLM pack registration, ik hybrid envelope, frank-medium split rebalance, llama.cpp GGUF preflight, batch-ubatch split section, bench-window D-state/stale-read notes, second-endpoint bring-up). - Architecture (3): Stale Signal Audit, Quadlet Lifecycle, Deploy State Triage. - Operations (6 + index): Remote Job Runner, Payload and Disk Reclaim, Container Host Reachability, Fleet Ops Playbook, Fleet Audit and Posture, SSH and Remote Access. - Infrastructure: Observability Provisioning + Homepage Status Probes; updates to Authentik, Anubis, LAN-DNS (per-client DoH bypass, Porkbun zone ops), Swap Configuration, OpenWebUI, Hermes (pre-existing page preserved and extended). - FrankBook-Pro: ARR-Stack filled (API split, schema-first probing, auth-posture, auth-config trap); qBittorrent E2E verification. - Desktop/Agent/Research: Noctalia and Niri, OMP Harness, Agent Docs and Edits, Command Center Dotfiles, PICO-8 Asset Standards. - Indexes: LLM Cross-Cutting References section, Operations/ and Agent/ index pages, root-index Skill Distillation section, AGENTS.md pointer. - log.md carries the wave plan. check-vault-links.py 0 unresolved (185 pages); ./tests/run.sh 366/366.
12 KiB
type, title, description, tags, timestamp
| type | title | description | tags | timestamp | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| reference | OMP Harness | The omp agent harness as configured on this fleet — compaction chain arithmetic, per-model sampler routing via compat.extraBody, and the static-preamble/skill-library audits that keep session context lean. |
|
2026-10-05T00:00:00-07:00 |
OMP Harness
The harness reaches the fleet through ~/.omp/agent/models.yml (model
registry; single source of truth — there is no copy on the servers) and
~/.omp/agent/config.yml (roles, compaction, global samplers). Nothing in
this file is repo-managed; edits are harness-side only.
Compaction chain arithmetic (verify before ANY window change)
When a fleet endpoint's context grows past its harness-declared window, OMP
compacts by sending the conversation to a designated target model. Before
changing any contextWindow/maxTokens, verify the chain arithmetically —
a target whose window is smaller than the source's trigger point silently
breaks compaction.
Where the contract lives:
~/.omp/agent/config.yml→compaction.remoteEndpoint(target URL),methodOrder,thresholdPercent(70), idle settings~/.omp/agent/models.yml→ per-modelcontextWindow,maxTokens,compactionModelreferences- Implementation: omp plugin
dist/core/compaction/compaction.js
The arithmetic (the coupled contract every endpoint's maxTokens comment encodes):
- Source trigger =
thresholdPercent × source contextWindow(0.70 × 200,704 = 140,492 for frank-primary on the current shape) - Output budget = capped at the target model's
maxTokens(32,768 for frank-small; 36,864 frank-primary; 57,344 frank-large — the largest, because halogen'sHALOGEN_MAX_TOKENS_CAPmust stay ≥ it) - REQUIREMENT: prompt (≤ trigger) + budget ≤ the target's per-slot window. Worked pairs from the live registry: 140,492 + 36,864 = 177,356 ≤ 200,704 (frank-primary); 140,490 + 57,344 = 197,834 ≤ 200,700 (frank-large); 140,492 + 32,768 = 173,260 ≤ 200,704 (frank-small).
Procedure (recompute from the LIVE files every time — windows rotate with every swap; the numbers above are the 2026-10-05 state):
- Read the
config.ymlcompaction block +models.ymlentries for source and target. Every endpoint'scontextWindowcomment carries its own arithmetic — read them. - Read the target checkpoint's
max_position_embeddings(native window) — the served window may be a concurrency contract, not the native limit (--parallel NDIVIDES the pool; the per-slot number is the contract). - If native ≥ trigger + budget, reslice the pinned pool:
MAX_RUNNING × CONTEXT_LENGTH ≤ MAX_TOTAL_TOKENS(the pin exists because the runtime's autofit leaves too little for deferred loads + prefill workspace; checknvidia-smiheadroom — expect ~0.8 GB workspace margin). - Changes: host env (CONTEXT_LENGTH-style env tunables) via git →
./tests/run.sh→ deploy; harnessmodels.ymldirectly (no repo copy). - Verify:
/health200, boot log's pool line, then a long-prompt probe at ≥ trigger height (the compaction-fit guarantee), then concurrent requests.
Known reconciliation trap: comments in models.yml have described compaction
as running "on the dankserver endpoint" while remoteEndpoint pointed at
dankclaw — the comment/config disagreed. The comments now name the real
target (compaction.remoteEndpoint = dankclaw :7771). The config is
truth; fix comments in the same change. maxTokens never changes for a
reslice — it caps output; contextWindow caps input. Boot-shape OOM
laddering is a different problem (Llama Cpp Serving Sizing).
Per-model sampler config (compat.extraBody)
models.yml has no per-model sampler keys. Sampling is global
(config.yml: temperature, topP, topK, minP, presencePenalty,
repetitionPenalty; default -1 = not sent). The per-model hook is
compat.extraBody:
Why it works: applyOpenAIExtraBody runs last in the
openai-completions builder — after applyChatCompletionsCompatPolicy — via
Object.assign(params, extraBody). So extraBody overrides global settings
and compat-policy output.
compat:
reasoningEffortMap:
max: xhigh
extraBody:
temperature: 1.0
top_p: 0.95
top_k: 20
min_p: 0.0
presence_penalty: 0.0
repetition_penalty: 1.0
preserve_thinking: true
Use wire names, not OMP camelCase. Two traps:
preserve_thinkingis not user-settable as a compat key.qwenPreserveThinkingis auto-derived inbuildOpenAICompatfrom the auto-detectedthinkingFormat+ local baseUrl, beforeapplyCompatOverrides. Settingcompat.thinkingFormat: qwenin models.yml does not enable it. Custom-named models (frank-large) match no Qwen id pattern → useextraBody: {preserve_thinking: true}.- Never put
chat_template_kwargsinextraBodywhere a compat policy also sets it —Object.assignis shallow and replaces the whole object, silently dropping thereasoning_effortkwarg the compat policy set. Top-levelpreserve_thinkingis honoured by halogen. (frank-primary's FreeToken entry currently carries achat_template_kwargsextraBody with a comment asking to verify-and-prune — the exact trap to check at that endpoint's next swap.)
Gotcha: silent greedy decode. halogen has no server-side sampler
defaults — temperature absent or 0 = greedy. If OMP sends nothing, the
endpoint decodes greedy while looking configured. This is why frank-large's
entry carries the recipe on the wire and a comment saying "do not drop it".
Reasoning-effort folding. Qwen3.8's template accepts only
{xhigh (default), medium, low} for reasoning_effort and 400s on anything
else ("Unexpected reasoning effort high"). Every endpoint's
reasoningEffortMap folds all harness levels onto that set; a role whose
level is unmapped fails on its FIRST request, and the failure names Jinja,
not the model.
Verify the exact wire body (echo-capture)
Don't trust the YAML — capture what OMP actually emits:
- Echo server on
127.0.0.1:18099that dumps the JSON body to a file and returns a cannedchat.completion(includereasoning_contentso thinking paths exercise). - Copy the real models.yml into a throwaway profile with only the
baseUrl swapped:
sed 's|http://<host>:7770/v1|http://127.0.0.1:18099/v1|' \ ~/.omp/agent/models.yml > ~/.omp/profiles/wiretest/agent/models.yml - Run and inspect:
Confirm every intended field is present with the right value.
omp --profile wiretest --model "<provider>/<model>" -p "hi" \ --no-tools --no-session --no-extensions --no-skills --no-rules jq 'del(.messages, .tools)' last-body.json
Verify a field is honoured, not just accepted — unknown fields often
return 200 anyway. Prove behavior with a prompt-token delta: replay an
assistant turn carrying a long reasoning_content, then compare
usage.prompt_tokens with the flag true vs false. A large delta means the
field changed template rendering; zero delta means it was ignored.
Cleanup: trash the probe profile and echo server (profiles/.AGENTTRASH),
never rm.
Static-preamble audit ("the context feels bloated")
What loads statically every session (measure each, don't guess):
- Repo rules file —
wc -c AGENTS.md(baseline 2026-10-05: 72,179 B, ~18k tokens — historically the largest block). - Skill index — only names+descriptions load; bodies are on-demand. Sum
description bytes across all SKILL.md frontmatter:
Baseline 2026-10-05: 171 managed skills / ~38 KB descriptions + 9 user skills.
python3 - <<'EOF' import glob, re, os for root in [os.path.expanduser("~/.omp/agent/managed-skills"), os.path.expanduser("~/.omp/agent/skills"), ".omp/skills"]: n=tot=0 for sk in glob.glob(root+"/*/SKILL.md"): fm=re.search(r'^---.*?---', open(sk, encoding="utf-8", errors="replace").read(), re.S) d=re.search(r'description:\s*(.*(?:\n(?:\s{2,}.*)*)?)', fm.group(0) if fm else "") n+=1; tot+=len(d.group(1)) if d else 0 print(root, n, tot) EOF - Memory lessons —
find ~/.omp/agent/memories -name 'MEMORY.md' -o -name 'memory_summary.md' | xargs wc -c. The injected block ≈ the largest MEMORY.md. - Harness/system prompt + tool schemas + CLI persona: fixed cost, ~20 KB; not prunable.
Known rot patterns:
- Near-duplicate auto-captures of the same lesson (three "authentik ORM"
entries, the freetoken-build pair, the three job-runner skills) — dedupe
via
manage_skill delete/update. - Corrupted captures containing stray CJK characters (
一团ly,等方法) mid-sentence — a known defect of the auto-capture path; delete the corrupt copy, keep the clean one. - Stale host/service names in consolidated memory (pre-rename
frank-default-large) — the repo's AGENTS.md topology table is ground truth.
Fix strategy: AGENTS.md prose (measured runbook narratives) → move to
serverAppConfigs-docs/LLM/ runbooks, keep laws + tables in AGENTS.md (the
repo's own docs-tree rule mandates this). Managed skills live in
~/.omp/agent/managed-skills (safe to edit); user-authored skills in
~/.omp/agent/skills are NEVER touched by tooling. Memory store edits:
stage removed captures to trash first (~/.AGENTTRASH/YYYYMMDD-topic).
Baseline to beat (2026-10-05): ~35–40k tokens of preamble — AGENTS.md ~18k, skill index ~10k, lessons ~3.5k, harness ~6k. Proposed reductions: −12k (AGENTS.md slimming), −3k (skill dedupe).
Managed-skill library hygiene
Use when auditing, pruning, or consolidating ~/.omp/agent/managed-skills
(the auto-captured skill store; the full index is injected into EVERY
session's context, so dead or duplicate entries are a permanent tax).
The static-context budget (measured 2026-10-05):
| Block | Size | Notes |
|---|---|---|
AGENTS.md (repo) |
72,179 B ≈ 18k tok | biggest single item |
| Skill index (~173 skills) | ~40 KB ≈ 10k tok | names+descriptions only |
| Learned-lessons block | ~14 KB | can contain corrupted/duplicate captures |
| Harness system prompt + tool schemas | ~23 KB | fixed |
Audit procedure:
- Build an inventory: per skill, name, mtime, body word count, description, first 12 headings (one pass, out to a file; read in pages).
- Group into: retired-runtime (host/service gone; its runbook already lives
in
serverAppConfigs-docs/LLM/), verbatim-duplicate pairs/triples (same lesson captured twice — often the SAME DAY), same-lesson families (N skills = one procedure), keep. - Read full bodies of every merge candidate before proposing a merge; description alone proves overlap only for exact dupes.
- Present A/B/C/D verdicts for user approval. NEVER execute before the discussion concludes — the user gates execution explicitly.
- On approval: stage everything to trash first
(
~/.AGENTTRASH/YYYYMMDD-<topic>/), never rm. After merging: recreate the surviving skill viamanage_skillupdate with body = superset, delete absorbed ones.
Known rot classes (this library, 2026-10-05):
- Same-day duplicate captures (freetoken-build-dankclaw vs freetoken-dankclaw-build; the three job-runner skills).
- CUDA-skill vs its self-declared HIP twin (pcie-link-capability-probe vs pcie-link-probe-hip-rdna4) → merge.
- Era ghosts: skills naming retired runtimes (freetoken, lucebox, r9v/ radiance, old halogen-flash-server image, ik_llama, GLM-5.3 experiment).
- Skills contradicting user standing orders (live-bench-dashboard vs the 2026-09-29 delete-dashboards order) — flag for user, don't assume.
- Memory store: corrupted captures with CJK noise from broken ssh commands; stale host/service renames.
Sizing verdicts that worked: bench family → 2 skills (harness vs discipline), not one mega-skill; keep profiler/kernel-time attribution standalone; fold go/no-go arithmetic skills into their probe skill (heterogeneous-accelerator-split-triage → PCIe probe).
Related
- Agent Docs and Edits — editing vault docs and hashline targets safely
- Command Center Dotfiles — the
~/.omprepo deploy this config rides - Llama Cpp Serving Sizing — the engine-side sizing the chain must fit
- LLM Bench Windows and Measurement — measuring the endpoints this config routes