KRouter

Changelog

Release pace. 1.1.x was held to fixes from 2026-10-15; 1.2.0 shipped on 2026-10-19, ahead of the planned 2026-11-12, at the maintainer’s call; 1.3.0 on 2026-11-09. The early weeks shipped many versions a day; that pace was development, not a support promise.

Minor releases (new features) at most once a week; patch releases (fixes, docs, benchmark updates) when ready. 1.0.0 to 1.0.2 went out on one day: 1.0.0 at the maintainer’s call, 1.0.1 and 1.0.2 as fixes from outside reviews. From 1.0.0 the version follows semantic versioning; what counts as the stable surface is listed in docs/DETAILS.md. Each entry starts with what you will notice, then the details.

Unreleased

Nothing yet.

1.3.0 — 2026-11-09

What you will notice

Details

1.2.1 — 2026-10-20

What you will notice

Details

1.2.0 — 2026-10-19

What you will notice

Details

1.1.1 — 2026-10-15

What you will notice

Details

1.1.0 — 2026-10-14

What you will notice

Details

1.0.4 — 2026-10-14

What you will notice

Details

1.0.3 — 2026-10-12

What you will notice

Details

1.0.2 — 2026-10-12

What you will notice

Details

1.0.1 — 2026-10-12

Fixes from an outside review of 1.0.0.

What you will notice

1.0.0 — 2026-10-12

1.0 means the surface agents and vaults depend on is now stable: the vault layout, the alias table, the receipt fields, the routes, the MCP tools, the KROUTER_* variables and the importers’ page markers change only in a major release, with a migration. Scoring may still be retuned in minor releases, always with before / after numbers on the public benches. Nothing breaks from 0.13.0: same vault, same table, same receipts; re-run the install line to upgrade.

What you will notice

Details

0.13.0 — 2026-10-12

What you will notice

Details

0.12.1 — 2026-10-11

0.12.0 — 2026-10-11

Renamed: DSH-KRouter → KRouter. It was never specific to DeepSeek Harness. Old links, the old clone URL, the old one-line install and old release downloads all redirect (checked after the rename). The npm / DSH plugin package keeps its name (dsh-krouter), and so do the skill directory, KROUTER_* variables and the timer labels, so existing installs are untouched.

The nightly writer is confined (seventh outside review). The review said the claude and grok writers, run with permission prompts skipped and no sandbox, could read and write the whole account — keys file, ~/.ssh — not just the vault, and that the docs claimed otherwise. Tested: under the old flags grok read a file outside the vault through both its file tool and its shell. Now:

Also from the review

0.11.3 — 2026-10-11

0.11.2 — 2026-10-11

What a stranger’s agent checks before recommending it, plus the sixth outside review.

Consent and integrity of the one-line install (sixth review)

Windows, now in CI

For a stranger’s agent

0.11.1 — 2026-10-11

0.11.0 — 2026-10-11

For anyone, with nothing to know and nothing to maintain. Plus the fifth outside review’s two secret findings.

One line to install

Chinese recall on a fresh (small) vault

Secrets (fifth review)

When the night’s work did not happen

Docs: README leads with the one-line install; an alias table is no longer a prerequisite for recommending it; what leaves the machine now names secret pages and says why keys never live in the vault.

The DSH bridge tests (extras/dsh/test-*.mjs) no longer write the host’s query log either — the last test entry point that did.

Not changed: answer cards stay on by default until the scheduled real-traffic test on 2026-10-16 (the author’s decision). Tests 172/172 on both router paths.

0.10.2 — 2026-10-11

Fourth outside review. Both new findings reproduced, both fixed with regression tests that fail on 0.10.1.

0.10.1 — 2026-10-11

0.10.0 — 2026-10-11

Third outside review (two parts: a re-review of 0.9.3, and “would a stranger’s agent recommend this”). Every finding was reproduced first; one proposed fix was measured and replaced (below).

Behaviour that did not match the docs

Answer cards

Recall

The host’s data

Visibility and disclosure

Evidence and process

Tests 133/133 on both router paths.

0.9.3 — 2026-10-11

Fixes from a second outside review, of 0.9.2. Each finding was reproduced before it was fixed.

Same-run checks (author vault, installed alias table): synthetic top-1 85%, held-out gold page found 88% / first 75%, wrong locks 0 — identical to 0.9.2. On the 92 real router queries the top hit and the answer line are identical to 0.9.2 for every query (40 carry an answer), so the front-page judge number stands. Tests 119/119 on both router paths.

0.9.2 — 2026-10-11

Fixes from an outside review of 0.9.0. Each finding was reproduced before it was fixed.

Synthetic sets after the fix: top-1 85%, held-out gold page found 88% (one question fewer than 0.9.0), wrong locks 0, off-topic unchanged. Tests 117/117 on both router paths.

0.9.1 — 2026-10-11

Docs only. The README had grown one appended section per release, each with its own numbers from a different run. Now: the front page states what the product does today (lock, then ranked recall with precomputed answers, refusing instead of guessing; topics and answer cards built overnight) and quotes one same-run number — 92 real router queries, blind-judged, ≤ 0.5.1 vs 0.9.0: mean usefulness 0.62 → 1.47 of 2, direct answers 14 → 55, useless 49 → 12. The four after-the-lock features are one section. Evidence is four layers: docs/VERIFY.md adds layer 4 (real traffic) with the method, every per-release run, the held-out synthetic set, the judge’s noise (±0.05), and what still fails. PROTOCOL.md and docs/ARCHITECTURE.md now describe the miss path the code runs, and drop “a rejected page still locks”, which stopped being true in 0.7.0.

0.9.0 — 2026-10-11

Answer cards (sleep-time compute). The router used to stop at “here is the right page”: the one-line how was just the page’s first sentence (你的层(全局结构)), so an agent still had to open the page. Real traffic is predictable — half the calls repeat an earlier question — so answer_cards.py precomputes, for every rule and topic page, 3–5 question → one-line answer cards taken only from that page (447 cards on 104 pages in the author vault). Cards live in 90 系统文件/自动化/下意识问答.jsonl (no source page is edited), carry the page’s content hash, and are rewritten only when the page changes; a card whose page changed is ignored until then. Card questions also act as recall triggers, and the best-matching card on each hit prints as answer:.

One-concept queries (DSH, 发版, grok-fixed; not bare numbers) skip the two-content-word gate, and a query that is a page’s name (title, file name, or topic_terms) doubles that page; a named dossier now outranks same-named scattered rule pages. Speed: the per-query freshness walk no longer builds a pathlib object per file — recall 112 → 30 ms in-process, router p50 ~105–111 ms.

Field self-report, author vault (not in clone): 92 real router queries, blind-judged 0.8.0 vs 0.9.0: mean 1.34 → 1.43 of 2, direct hits 46 → 52, useless 15 → 12; 40 of 92 now carry an answer: line. Synthetic: top-1 82% → 85%, held-out right page 88% → 92%, wrong locks 0, off-topic unchanged.

0.8.0 — 2026-10-10

Topic dossiers: the missing middle layer. Retrieval was near its ceiling (synthetic: right page top-1 83%, top-10 95%); what still failed on real traffic was knowledge that lived only in daily logs (SyGJ in 44 logs, zero pages). consolidate_topics.py merges each listed topic (90 系统文件/自动化/主题档案清单.psv) into 02 经验与方法/主题档案/主题|…md: one-line summary, current state as of the latest evidence, facts with a [[source]] each, user corrections, timeline, open conflicts, authority pages first. Evidence is the vault only (authority pages, other pages, logs newest first, capped); frontmatter is written by the script, not the model; every wikilink must resolve or is demoted to text; a page is regenerated only when its evidence hash changes. Status stays provisional.

Recall treats dossiers as their own tier and only boosts one when the question names its topic (title or topic_terms), so a 20 KB page cannot win on stray words. Refusal got stricter where dossiers made it looser: bigrams with function characters (的了我你他她吗呢吧啊么什) and words that only appear in model-written triggers no longer count as content; a latin term the vault has never seen (Kubernetes) refuses unless more than two real words match. Single CJK characters are dropped from the query.

Field self-report, author vault (not in clone): 92 real router queries, blind-judged old vs new: mean 0.66 → 1.41 of 2, direct hits 14 → 52, useless 45 → 14; 16 topic questions written before the dossiers existed: 0.62 → 1.31. Synthetic held-out unchanged (88% / top-1 75% / wrong locks 0 / 0 of 6 off-topic answered). p50 ~115 ms.

0.7.0 — 2026-10-10

Memory maintenance, measured on the router’s own real traffic. 92 de-duplicated queries the author’s agents actually sent in 30 days, blind-judged (old vs new shuffled, Opus scores 0/1/2): mean 0.74 → 1.26, direct hits 20 → 42, useless 44 → 18. Synthetic held-out set: right page 88% → 92%, top-1 75%, wrong locks 0, 0/6 off-topic answered; p50 ~113 ms.

0.6.0 — 2026-10-10

A lock miss is now answered by L1 recall instead of a whole-sentence literal grep. skill/krouter-obsidian/scripts/recall_index.py keeps a rebuildable SQLite FTS5 cache under ~/.cache/krouter/ (stdlib only, no service, no vectors): CJK bigrams + latin words, title and triggers weighted, rule pages first, superseded pages sink, cross-word junk bigrams filtered. Each hit prints its how line and the best matching line; weak overlap prints recall: none and must not guess. Triggers come from the alias table plus any 90 系统文件/**/下意识触发词.psv (rel|phrase;phrase) and never lock.

The lock got stricter: a short alias inside a longer question (日更 in 日更能不能交给云端跑) only ranks suggestions. route_knowledge.sh now execs the Python twin (one process instead of four); KROUTER_SH_ONLY=1 keeps the shell path. Ships the L0 compiler compile_subconscious.py and the status seal lines (daily_seal*) from the health page.

Field self-report, author vault (not in clone): 30 held-out questions written before tuning, right page 21% → 88%, top-1 0% → 75%, wrong locks 0, 0/6 off-topic answered, p50 118 ms. Clone tests: tests/test_recall_index.py.

0.5.1 — 2026-09-05

Windows can run the same lock through skill/krouter-obsidian/scripts/route_knowledge.py; DSH on win32 prefers that file. Same-score miss across two pages prints host_prompt and must not guess. sha256 falls back to Python when shasum is missing. One protocol, two launchers. Does not ship L0 / 下意识.md.

0.5.0 — 2026-08-31

Ask-as-product matcher in skill/krouter-obsidian/scripts/ask_product.py. At most one provisional page per utterance. record never writes active; promote does, after adopt + this task accepted. Triggers live on the page (triggers:) or 90 系统文件/自动化/ask-triggers.json. install.sh copies extras/cursor/ask-product.mdc. This clone does not ship an author’s trigger table. Codex / Claude still paste the snippet.

0.4.3 — 2026-08-28

Lock-vs-neighbor Claim C: multilingual MiniLM; CJK inversion gone; H15 发版 already ranks the seal page before any floor (precision, not a threshold miss). Claim D: BGE-M3 middleweight dense; hit 16/16; at 0.40 the leftover is neighbor B03 (生产事故 → timer), not one of the 12 OOD negatives. Do not merge C and D into “neither matched the lock.” On this contract (refuse + no neighbor cite), featherweight beats that middleweight stack — the “better than mainstream embedding RAG” line. Heavyweight hybrid + rerank is out of scope. Pytest replays frozen JSON (no extra pip in CI). Hub snapshots are not in the clone. Ship scripts/verify_clean.sh so the upload gate named in CONTRIBUTING exists in the clone.

0.4.2 — 2026-08-27

Ship in_force / live_rows / parse_frontmatter on canonical_lookup.py. verify_canonical_map.py and the lock-vs-neighbor runner imported them since 0.4.1; the lookup module on GitHub did not. Clone python3 scripts/verify_canonical_map.py raised ImportError. Not L0.

0.4.1 — 2026-08-27

Docs and checkers. No new product lane.

Already on main since 0.4.0, first tagged here: public lock-vs-neighbor fixture (N=36), clone_25 analogue, host-facing listing, both rungs of the ladder, receipt SVGs, latin-fragment alias rule, API-key-first / CLI subscription writer.

0.4.0 — 2026-08-21

0.3.1 — 2026-08-21

0.3.0 — 2026-08-21

0.2.0 — 2026-08-21

0.1.0 — 2026-08-21