--- type: changelog title: Bundle Change Log description: Chronological update history for the OKF knowledge bundle. tags: - okf - maintenance - changelog timestamp: 2026-10-19 --- # Bundle Change Log Entry law (since 2026-10-19): one dated entry = what changed + the durable lesson, a few lines. Full incident narratives are recoverable from git (`git log --follow omp-docs/log.md`); knowledge that outlives an entry lives on its concept page, linked here. Never re-expand an entry in place. ## 2026-10-19 — dankvoice cut over to the `dank/dankvoice` package (Refs #34) Drop-in `agent/extensions/dankvoice.ts` and its 26-test suite retired; the package carries the behaviour (41/41 black-box suite) and is installed with `pi install git:`. Law: install and prove `/say status` speaks on a box *before* pulling the cutover commit — the shared settings file keeps menu state across both transports, so the swap is stateless once installed. ## 2026-10-19 — dankvoice: silence and timeouts, root-caused (Refs #32) The humanizer's raw `fetch` to frank-zealot omitted `chat_template_kwargs. enable_thinking: false`, so the Qwen35 hybrid *thought* instead of answering: 6.9 s of `reasoning_content`, `content: ""` — timing out the rewrite twice (12 s dead air) and, when it did answer inside the window, speaking silence. Root-caused by replaying the exact wire body against the live endpoint. Fix: pin the kwarg in the request body; treat empty-content-with-reasoning as failure (mechanical voice), not "nothing worth saying"; the menu's test phrase fires without blocking its handler. Lesson: the harness injects thinking-off for managed roles, but raw HTTP callers must set it themselves — 26/26 green with three red-captured regressions. ## 2026-10-19 — dankvoice: humanized narration and thinking aloud (Refs #27) Spoken units are rewritten by the `@tiny` role (frank-zealot) under the bundle's speech budgets before synthesis, with mechanical cleanup as fallback; auto-speak narrates the last message's thinking blocks first; all toggles persist. 7 new scenarios, 22 green; live smoke through real zealot + frank-tts. ## 2026-10-19 — dankvoice: segmented sequential speech `agent_end` awaiting one whole-answer synthesis hit the harness's 30 s extension-handler timeout — lesson: extensions must never await work that can exceed 30 s. Ported the built-in vocalizer's utterance-splitting state machine (boundary = `[.!?…]+` + whitespace, abbreviation/code guards, per-answer segment budget); segments synthesize strictly sequentially. `DANKVOICE_MAX` is now a segment budget. 17/17 in `tests/dankvoice.bats`. ## 2026-10-18 — dankvoice: `/say` options menu with output-device routing (Refs #23) `/say menu` (pi-peon-style): auto-speak, voice, PipeWire output device (`wpctl` → `pw-play --target`), player, char cap, test phrase. Precedence env > `~/.omp/cache/dankvoice.json` > defaults — born from the incident where PipeWire's remembered Bluetooth route played answers into nowhere. ## 2026-10-18 — dankvoice: the cloned voices finally speak in the TUI (Refs #21) The harness gates `--voice` against the bundled Kokoro enum, so frank-tts's cloned voices were unreachable in-TUI. Added `agent/extensions/dankvoice.ts` (`/say …`) synthesizing over the OpenAI speech route, endpoint read from the `api: openai-speech` row of `agent/models.yml` (no host or secret in code). ## 2026-10-18 — Noctalia bar layout clobbered by trunk-sync stash, recovered GUI-built bar customizations existed only in the working tree; a trunk-sync stash-then-drop destroyed them. Recovery: `git fsck --lost-found` surfaced the dropped stash as a dangling commit; validated in a sandboxed `XDG_*_HOME` before restore. Lesson: GUI-written config is only durable once committed — the motivation for the live-sync heartbeat below. ## 2026-10-18 — Fleet law: issue/PR attribution footers Every agent-opened issue/PR body ends with `cwd:` + `session:` footer, in both `dank/command-center` and `dank/serverAppConfigs` AGENTS.md: machine-made artifacts must trace to the box and session that produced them. ## 2026-10-18 — live-sync heartbeat for machine-written paths (Refs #11) A month of silent divergence in the live checkout proved the checkout-is- deployment model needs a committer: `scripts/live-sync.sh` + systemd user timer auto-commits allowlisted tiers (memories, managed-skills, live config, dotfiles) with hooks armed, merges `origin/main`, pushes, reaps stale `wt/*`. Non-allowlist dirt never staged; conflicts abort-and-alert. See [tools/live-sync.md](tools/live-sync.md); tier law in AGENTS.md. ## 2026-10-18 — Fleet law: filed PRs open in Frank's browser immediately `xdg-open ` the moment a PR opens — codified in both repos' git rules. ## 2026-10-18 — Trunk law: extension route closed unmerged; direct repo alignment Operator closed PR #9 (cwd-scoped `before_agent_start` extension) in favor of editing each repo's AGENTS.md. Durable findings: every context-file provider (AGENTS.md walk-up, `.omp/` dirs, CLAUDE.md) resolves at or below the repo root — ancestor-scope files can never load; user-level `APPEND_SYSTEM.md` broadcasts to all sessions; serverAppConfigs never had git-flow. ## 2026-10-18 — SDLC switched to trunk-based development `develop` retired (single-dev repo). Law in AGENTS.md § Trunk-based SDLC: branch off freshest `origin/main`, PRs target `main`, `--no-ff` merges, tags `vX.Y.Z` on main. Managed skill `gitflow-back-merge-plumbing` is historical. ## 2026-10-18 — Sibling-vault overlap census; system docs realigned to live ground truth Census of `omp-docs/` vs `serverAppConfigs-docs` (subagents + live-ssh probes) found four contradicting pairs; ours fixed, theirs flagged for their PR flow. Recorded then: RTX 3090 moved Dankserver→Dankclaw 2026-09; dankserver = 2× Radeon AI PRO R9700 (the "board swap" story was false); served models per live units. Current state always: [/system/index.md](/system/index.md) (27B-era zealot figures here are historical; live census 2026-10-19 below). ## 2026-10-18 — Status line rebuilt on custom segments; full-source audit New page [core/statusline.md](core/statusline.md) with an audit log — four first-pass claims were false and corrected against the minified bundle + a live screenshot matrix (context meter is `box`/`band` only; `composer.shape` routes segment arrays; `mode` states = Plan/Prewalk/Goal/Vibe/Loop). Bar rebuilt on `band` + custom segments; frank-archon display name slimmed in models.yml. ## 2026-10-09 — Blankpad DE redesign: desk profiles, keybinds, Handy wiring Per-desk niri profiles keyed by EDID long name (connector names reshuffle between docks; identity travels) + `scripts/desk.sh`; niri 26.04 has **no hotplug event** (`OutputConfigChanged` is only an ACK per niri-ipc) — the autoswitch daemon diffs output sets on `WorkspacesChanged`. Keybind cheat sheet now generated (`scripts/gen-keybinds.sh`); noctalia docs corrected to the v5 `noctalia msg` API. Handy: niri owns autostart; open breaker — frank-secondary answers in `reasoning_content` with empty `content`, and Handy cannot send `chat_template_kwargs.enable_thinking=false`. 27/27 green. ## 2026-10-09 — Incident: agent sudo-loop tripped pam_faillock, locked out the operator A subagent retried `sudo yay` (no TTY) for ~15 min; `pam_faillock` deny=3 locked user `blank` — correct-password sudo failed, mimicking a password change. Recovery: `faillock --user blank --reset`. Law: agents never run `sudo`/`yay`/`pacman`/`pkexec`; root steps go to the operator as exact commands. Skill `faillock-sudo-lockout-recovery`. ## 2026-10-09 — Full secret audit of the command-center repo: clean Five layers (live-value scan across 77 revs/765 blobs, whole object store incl. dangling, shape triage, entropy ≥4.3, LFS payloads) — no secret in any reachable or dangling object; quarantine list holds. Fixed `hf_token_write` 0644→0600. Open gap: the pre-commit gate lacks `hf_`/`npm_`/`pypi-`/`AIza`/ Stripe/Telegram shapes and basic-auth URLs — widening it is an open decision. ## 2026-10-09 — Gitea token moved out of every remote URL Remotes bare; credential in `~/.config/secrets/gitea` (0600) behind a global `credential.helper store`. Trap (git 2.56.0, measured): `git credential-store` rejects the `protocol=`/`host=` block shape the man page shows — the store file must be one URL per line, port included. Verified with `GIT_TERMINAL_PROMPT=0`. Details: [tools/gitea/client-access.md](tools/gitea/client-access.md). ## 2026-10-09 — Working tree reconciled: callsign renames, compaction move, gitignore quarantine 200-entry dirty tree committed as seven atomic units. Harness model ids renamed `frank-{medium,large,small}` → `frank-{archon,dragoon,zealot}` — **services keep old names on the wire**; the engines accept any request model id, so renames are harness-side only. Server-side compaction moved to zealot's 3090 (threshold 70→85 %). `.gitignore` quarantine for worktree-keyed memory buckets and runtime dirs. Skill renames are not losses: git renders directory renames as mass delete+add; pre-cutover content intact at `12c5e88`. ## 2026-09-28 — Retired workstation purged from the knowledge base Sold box: hostname, both LAN addresses, Wi-Fi SSID gone bundle-wide; the knowledge distilled into [system/network.md](system/network.md) (multi-link resolver law: a static resolver must be pinned on each *connection*) and [tools/niri/displays.md](tools/niri/displays.md) (portrait transforms, the three ways a multi-monitor rig breaks). Hostname stays only where it is a lookup key (install.sh `--host`, `packages/.pkgs`). ## 2026-09-01 — Retry backoff and thinking default (pi era) Pi `settings.json`: 10 s base retry backoff (10/20/40 s), `defaultThinkingLevel: medium` (no per-model thinking field exists in `models.json`). ## 2026-08-28 — KB rebuilt to OKF v0.1; live-verified fleet facts `omp-docs/` copied from legacy `~/.pi/agent/docs`, rebuilt as git-tracked OKF v0.1 (checkout *is* the deployment); unverifiable claims tagged `unverified`. Conformance pass promoted concept-in-disguise indexes, stripped index frontmatter, resolved all links; `scripts/kb-lint.sh` exits 0. Hardware facts were corrected *then* (3090-on-dankserver since moved — see 2026-10-18). Inventory census recorded under `inventory/` for the pruning session. ## 2026-08-23 — Homepage deployed to production; Caddy KB doc Homepage live on Dankclaw via `scripts/deploy.sh` (status checker timer, deployed.js, rendered basicauth hashes, health check). Hard-won Caddy lesson: top-level directives are *sorted*, so `rewrite` runs before `basicauth` and auth matchers saw rewritten paths — serve each page from its own `handle` block to preserve order; a `handle` inline matcher is a single token; a leading `@name ` parses as a matcher definition. Now documented on [caddy/caddyfile.md](caddy/caddyfile.md). A compose mount change needs a container *recreate*, not a reload. 116 tests green. ## 2026-08-23 — Homepage design settled (grilling complete) All 38 open questions answered; full record lives in serverAppConfigs (`docs/Infrastructure/Homepage Design Grilling.md`). Key deltas: per-service tcp/http probes, 5 s timeout, TUI-style panel grid, no client auto-refresh, git-driven deploy, full TDD. Correction recorded: the Dankserver media stack runs as bare processes, not containers — never probe it as a compose stack. ## 2026-08-22 — vllmScripts merged into serverAppConfigs Full-history two-parent import; one repo, one checkout per host, one `deploy.sh`. The plaintext sudo password from old docs was NOT carried over (a bats leak-check guards it); it remains in both repos' history on the LAN Gitea — rotation recommended. ## 2026-08-21 — Fleet ops: passwordless sudo, Hermes SSH keys `/etc/sudoers.d/dank-nopasswd` on both servers (per-command drop-ins remain); dedicated ed25519 key for the Hermes container, verified into all three machines. ## 2026-08-19 — pi-web-access: SearXNG endpoint re-pointed to dankclaw (pi era) `searxngBaseUrl` moved off dead `.235:8081` to `.143:8081`; pi caches `web-search.json` per process — new endpoint needs a new session. `yt-dlp` installed (2026.07.04). ## 2026-08-19 — SearXNG + Gluetun bring-up on dankclaw Durable field notes (now on concept pages — see [agentic-web-research/vpn-routing.md](agentic-web-research/vpn-routing.md), [searxng-tuning.md](agentic-web-research/searxng-tuning.md), [engineering/infra/containers.md](engineering/infra/containers.md)): manual-WireGuard Proton needs `VPN_SERVICE_PROVIDER=custom` + the single-peer `WIREGUARD_*` env names (not `protonvpn`, not `WIREGUARD_PEERS_*`); gluetun ships no curl and `:8000` is the control server, not health; the limiter's JSON cap (`API_MAX=4`/hour) is hardcoded Python — `pass_ip` is the only bypass; rootless podman strips client IPs on published ports, so SearXNG must sit behind Caddy for XFF; quadlet generator rejects `CapAdd=`/`Device=` and generated units enable via `[Install] WantedBy=default.target`. ComfyUI on gfx1151: build on AMD's ROCm base and filter the torch family out of ComfyUI's requirements or you clobber the gfx1151 kernels. ## 2026-08-17 — Fleet redo + vLLM tool calling (pi era) Fleet moved off the pipeline-parallel + NPU topology; Quark W8A8 quant chosen over the Avesed INT8 for clean Qwen3 XML tool calls. ## 2026-08-16 — Gitea boot-persistence fix (dankclaw) `unattended-upgrades` reboot exposed that the compose-era Gitea had no systemd units (~1 h down). Stack rewritten as quadlet (names, `systemd-gitea` network, linger + `WantedBy=default.target`, app.ini env-override gotcha, UID 100999 ownership) across `tools/gitea/*`; `podman generate systemd` marked deprecated in [engineering/infra/containers.md](engineering/infra/containers.md). ## 2026-08-13 — Pi subagent limits recorded (pi era) Effective caps: globalConcurrencyLimit 2, parallel.maxTasks 8 / concurrency 4, maxSubagentDepth 2, turnBudget 30; no per-model limit. See [pi/packages/pi-subagents.md](pi/packages/pi-subagents.md). ## 2026-08-11 — Engineering research area; skills leaderboard verified Created `engineering/` (SDLC, agent instruction files, stacks, infra, plugins, skills ecosystem, Signal remote) via parallel research fleet. Skills leaderboard replaced with the ranked list from the skills.sh API (zero-based pagination, 200-skill pages). ## 2026-08-11 — Agentic web research section; exhaustive bundle audit Created `agentic-web-research/` (8 pages) and rewrote them on 2025/2026 evidence (SearXNG valkey deployment, real engine defaults, limiter budgets, Gluetun pattern, open-model claim triage, MCP transports). Audit: 154+ wikilinks resolved, dead external links fixed, `MemorySleepMode=deep` verified valid (systemd 256+), ASD-STE100 style pass. `AGENTS.md` created as the system behavior contract. ## 2026-08-06 — Link fixes; ComfyUI docs; major documentation overhaul Fixed 15 broken wikilinks (missing frontmatter) + title mismatches → zero broken. Added ComfyUI pages, per-host system docs, pi config tree, tools entries; orphaned root duplicates moved to `.AGENTTRASH/`. ## 2026-07-18 — Maintenance tooling Expanded `references/okf-maintenance.md` (cross-links, health metrics, troubleshooting); created `core/log.md` and `.okf/config.yaml`. ## 2026-01-15 — OKF conversion Docs bundle converted to OKF v0.1; files migrated into `core/`, `tools/`, `packages/`, `references/` with frontmatter on all files. ## 2025-08-05 — Gitea documentation Added [tools/gitea/index.md](tools/gitea/index.md) (topology, management, data persistence) to the tools index.