# Changelog (/docs/changelog) # Changelog [#changelog] All notable changes to kimetsu land here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow [SemVer](https://semver.org/spec/v2.0.0.html). From v1.0.0 onward the project follows SemVer normally: patch releases are bug-fix-only, minor releases are backward-compatible additions, and breaking changes require a major bump. ## v2.8.0: Durable memory and scoped answerability [#v280-durable-memory-and-scoped-answerability] [Released September 9, 2026](https://github.com/RodCor/kimetsu/releases/tag/v2.8.0). The [metric summary](/docs/memory-benchmark/answerability) preserves the measured pre-release build fingerprints and limitations. ### Memory evidence and hardening [#memory-evidence-and-hardening] * Opt-in scoped fact evidence, partial answers and persistent conflict warnings; a rebuildable schema-15 projection binds facts to sources and claim revisions. * Durable corrections, bounded delivery, conservative lifecycle decisions and atomic replay/sync. Remote context honors the server's disabled reranker. * The [paired answerability study](/docs/memory-benchmark/answerability) retained 24/27 hits and reduced unwanted injections 15/18 → 3/18 on its new synthetic fixture. Exact metadata matched 36/45 in both repeats; p95 was 376.6 → 386.6 ms. Mean MCP response bytes increased 613.5 → 651.2 (+6.2%); p95 increased 2.7%. These measure evidence delivery, not final-answer accuracy. Compound retrieval and unsupported-subject fallback remain incomplete, and the guard remains disabled by default. ### Security [#security] * Updated transitive `h2` from 0.4.14 to 0.4.16, fixing `RUSTSEC-2026-0258` (unbounded empty HTTP/2 DATA frames). * Reject redirected repository roots and Windows path aliases; validate existing brain state paths before initialization shortcuts. * Enforce HTTPS and disable redirects for signed Bedrock requests; validate region labels and encode model IDs as path segments. * Replace yanked `der` 0.8.0 with 0.8.2. ### Release validation [#release-validation] * 1,500 workspace tests passed with six intentionally ignored; 132 benchmark Rust tests passed after the dependency refresh. * Release notes now support titled changelog headings and reject empty output. ## v2.7.0: Retrieval that knows when to stay silent [#v270-retrieval-that-knows-when-to-stay-silent] This release hardens the semantic broker around the cases that ordinary retrieval benchmarks miss: unrelated memories that should not be injected, near-miss traps, cited incumbents that have been superseded, and ranking policy that used to disappear whenever a cross-encoder reranker ran. The final release candidate raises comprehensive BrainBench from **91.3% to 92.4%** over 264 scenarios. Its importance dimension moves **92.1% → 97.4%** and retrieval **56.6% → 97.0%**, with calibration and dedup unchanged. On the new workflow fixtures it scores **79.0%** over a stratified 150-scenario slice; the 100-scenario update stream reaches **89.3%** overall and resolves the newer fact over its cited incumbent in **33/33** applicable cases. ### Added [#added] * **Absolute-evidence abstention for new brains.** The old whole-bundle gate read a normalized composite whose best candidate was strong by construction, so it could not distinguish a useful hit from the best item in an unrelated corpus. New project configs use a per-embedder auto floor on raw cosine. Existing configs keep the gate off unless they opt in, and lean/cross-model retrieval is exempt because lexical relevance is not on the calibrated cosine scale. * **Cross-encoder arbitration for borderline bundles.** The evidence band is now resolved by the reranker, and the same implementation is used by the CLI, MCP server, and warm embed daemon. A rejected bundle becomes a true skipped, zero-token result instead of leaking low-confidence capsules downstream. * **Supersession-aware ranking.** Newer near-restatements beat older cited incumbents, with correction-language and lexical-identity support for larger rewrites. Same-batch co-writes are protected, and ambiguous low-similarity pairs consult query relevance so historical questions still retrieve the fact that was true at the requested time. * **Post-rerank usefulness policy.** Learned citation/regret tiers and supersession hints ride on each capsule and are reapplied after cross-encoder scoring. This prevents relevance-only rerankers from silently erasing broker policy while retaining their ordering within each policy tier. ### Fixed [#fixed] * The CLI now has reranker parity with the MCP and daemon paths; semantic benchmark runs no longer measure a different ranking pipeline from shipped commands. * Reranker initialization failures are reported before Kimetsu fails open to bi-encoder ordering, instead of silently making an intended cross-encoder run look successful. * User-defined Hugging Face rerankers honor `HF_HOME`, allowing benchmark and sandbox workspaces to share one cache instead of repeatedly downloading the same model into each current working directory. * Reranker retention and band admission are evaluated on raw cross-encoder evidence before supersession penalties, usefulness ordering, or output caps, so policy cannot accidentally change whether a bundle is admitted. ## v2.6.1: Dependency security sweep [#v261-dependency-security-sweep] A security-only patch release. Clears every open advisory against the repository's dependency tree — all 15 of which were npm packages in `website-fumadocs`, the documentation site. **No changes to the shipped CLI, brain, or remote server.** The Rust crate sources are byte-identical to v2.6.0; the workspace version moves only so the release carries a single coherent number. Nothing in `kimetsu-ai`, `kimetsu-remote`, or the published crates was reachable from any of these advisories — neither npm package has third-party runtime dependencies (both declare only `optionalDependencies` on their own platform binaries), and `cargo audit` reports zero vulnerabilities against the Rust tree before and after. ### Security [#security-1] Docs-site dependencies moved to patched versions (`website-fumadocs`): * `next` 16.2.9 → 16.2.11 — clears nine advisories (GHSA-6gpp-xcg3-4w24, GHSA-p9j2-gv94-2wf4, GHSA-89xv-2m56-2m9x, GHSA-m99w-x7hq-7vfj, GHSA-4c39-4ccg-62r3, GHSA-68g3-v927-f742, GHSA-4633-3j49-mh5q, GHSA-q8wf-6r8g-63ch, GHSA-955p-x3mx-jcvp). * `postcss` 8.5.16 → 8.5.25 (GHSA-r28c-9q8g-f849). * `sharp` 0.34.5 → 0.35.3 (GHSA-f88m-g3jw-g9cj), transitive via `next`. * `js-yaml` 5.2.0 → 5.2.3 (GHSA-pm4m-ph32-ghv5, GHSA-724g-mxrg-4qvm), transitive via `fumadocs-core` / `fumadocs-mdx`. * `fast-uri` 3.1.3 → 3.1.5 (GHSA-v2hh-gcrm-f6hx), transitive via `serve` → `ajv`. * `brace-expansion` 1.1.15 → 1.1.18 (GHSA-3jxr-9vmj-r5cp), transitive via `serve` → `serve-handler` → `minimatch`. The four transitive bumps are pinned through `overrides` in `website-fumadocs/package.json`, since no direct dependency had yet released a manifest pointing at the patched versions. Drop each override once its parent ships a release that resolves above the floor on its own. Note that `brace-expansion` is pinned to `^1.1.16`, a 1.x-only range: today the tree holds exactly one instance (under `minimatch@3`), but a future dependency wanting 2.x or 4.x would collide with this pin. `sharp` crossing a major (0.34 → 0.35) is the one bump with real breakage risk, as `next` uses it for build-time image optimization. Verified by a full `npm run build`: 72 static pages including the `/og/docs/**/image.png` Open Graph routes, which are the paths that actually exercise `sharp`. ## v2.6.0: Speak first on every host [#v260-speak-first-on-every-host] The README says Kimetsu "speaks first." An audit found that true on Claude Code, thin on Codex, and absent on Cursor, Pi and OpenClaw. This closes that gap and files the v2.6 plan behind it. ### Fixed — the semantic build, and what it was silently dropping [#fixed--the-semantic-build-and-what-it-was-silently-dropping] * **`--features embeddings` did not compile, and the reason on record was wrong.** The RFC listed four open items as blocked on an unreachable ONNX Runtime prebuilt. `ort` fetches fine and every model was already cached; the build failed on `E0063` in Kimetsu's own code. `daemon_capsules_to_bundle` sits inside `#[cfg(feature = "embeddings")]` and never supplied the three `ContextBundle` fields that the ordering and coverage work added, so no lean build could see it. CI does run `cargo test --features embeddings` — the branch had simply never been pushed. * **Ordering and evidence-coverage never reached anyone on a semantic build.** This is the part that mattered. On a build with a live embed daemon, `try_daemon_retrieve` answers first and the in-process retrieval — which measures coverage and renders capsules in date order — runs only on a miss. So the daemon path, the *default* proactive path on the semantic flavor, was serving bundles with neither. Two features the RFC listed as landed and tested reached nobody on the flavor where retrieval is good enough to trust them. Now: ordering queries decline the daemon outright, because the wire protocol carries no date to order by and the in-process path does; and coverage is measured on the daemon path too, degrading to "no claim" rather than to a false "memory does not cover X" when the brain will not open. * **The Deep tier could not talk to any current frontier Claude model.** The Anthropic provider sent `"temperature"` on every request, hardcoded to 0.1–0.3 across the pipeline. Sampling parameters were removed from the Claude line at Opus 4.7: `temperature`, `top_p` and `top_k` now return a **400** on Opus 4.7, Opus 4.8, Opus 5 and Fable 5, and Sonnet 5 rejects any non-default value. So configuring any of those as the distiller, `ask`, or reflection model failed outright — not degraded output, no output. Anything at or below the Opus 4.6 / Sonnet 4.6 generation was unaffected, which is why it went unnoticed. The parameter is now omitted for models that reject it. The gate is an *allowlist* of models known to accept it, so a model this build has never heard of omits it: guessing wrong by omitting costs a little determinism on one distillation, and guessing wrong by sending costs the entire request. Sampling removal has only ever moved one way across the Claude line. Matching starts at the first `claude-`, so bare, Bedrock (`anthropic.claude-…`) and cross-region inference-profile (`us.anthropic.claude-…`) ids all resolve the same way. * **A test wrote into the developer's own brain.** `remote_write_is_attributed_to_the_token_user` let project discovery walk out of its tempdir and into `~/.kimetsu`. On this machine it failed loudly on a schema mismatch, which was the lucky outcome — on a machine where the schemas agree it passes, having written a test memory into a real brain. ### Added [#added-1] * **A TypeScript SDK** at `npm/kimetsu-sdk`, published as `@kimetsu-ai/sdk`. The ecosystem Kimetsu integrates with — Pi extensions, OpenClaw plugins, Cursor, VS Code, MCP clients — is TypeScript, and every one of those integrations was shelling out to the binary and parsing its text output. That is how the Pi extension and its published npm copy drifted apart without anyone noticing: there was no shared typed surface for them to share. It mirrors the Python SDK method-for-method (`memory`, `config`, `models`, `benchmark`, plus `context` / `record` / `status` / `insights` / `cite`), reads the same `KIMETSU_REMOTE_*` variables, and keeps the same four error classes so a caller can tell "retry this" from "re-authenticate" from "the answer is no". Zero runtime dependencies — Node 18's `fetch` — because an embedded client's dependencies become its host's. One client rather than a sync/async pair, since in JavaScript every call is already a promise. `client.call()` reaches tools newer than the SDK, so a version mismatch never sends anyone back to parsing text. * **`kimetsu brain drift`** reports which recent sessions wandered off the task they opened with — cosine of each turn against the session's first prompt, which is what it set out to do. Nautilus Compass gets ROC AUC 0.83 on this shape of signal against real Claude Code traces with no model in the loop, and Kimetsu already keeps a warm embedder, so the marginal cost is one embedding per turn. What it sees is narrower than the paper's setting and the docs say so: Compass reads agent traces, a memory sidecar reads user prompts, so this is a claim about the session's topic and not about the agent's behaviour. Divergence must be sustained across three consecutive turns — one tangential question is a question — and the anchor is the opening turn rather than a rolling window, since a rolling anchor lets a session walk anywhere one step at a time without registering. Report-only: retrieval is not silently re-anchored on a signal with no measured operating point. On a build with no embedder the command says there is nothing to compute rather than substituting a lexical stand-in on a different scale. * **Injected memory is framed as a prior conclusion, not as knowledge.** MemSyco-Bench reports most memory systems scoring *worse* on sycophancy than using no memory at all: a retrieved memory arrives looking like ground truth, so the model defers to it over evidence directly in front of it. Kimetsu's header read "Kimetsu brain relevant knowledge for this task" — and *knowledge* is the wrong word for what was recorded at some past moment by someone who believed it then. The injection now states which questions memory settles (what was decided, learned, or preferred — the repository does not record why) and which it does not (what the code currently is), and resolves the conflict case explicitly: prefer what you can check now over what was recorded then. The memory itself is never hedged — an agent told "this might be wrong" ignores memory, which is the whole product — only outranked. The proactive hook gets a short suffix rather than a preamble, since it interrupts work already underway on a one-capsule budget. MCP clients get the same rule through `usage.how_to_use`. * **`brain import` quarantines packs from the network.** Provenance-weighted trust discounts a poisoned pack; it does not stop one. Memory poisoning is worth stopping rather than ranking down precisely because, unlike prompt injection, it persists across every future session. So an imported pack is now held in the review queue `brain memory proposals` already drives, and nothing in it can reach a session until you accept it. On by default for `http(s)://` sources — content authored elsewhere and fetched over the network is the widest attack surface here — and off for a local file or stdin, which you chose and can open; `--quarantine` / `--no-quarantine` override either way. `--mode replace` alongside quarantine is refused, since superseding memories you have in favour of content you have not read is the worst of both. Entries matching a memory you already hold are deduped rather than proposed, because a review queue nobody can face is not a safety mechanism. Nothing reaches backward: packs imported before this stay live and stay discounted by origin. ### Fixed [#fixed-1] * **`retry` now matches a corpus that says `retries`.** The light query stemmer stripped `-ing/-ed/-es/-s` but had no y→ies rule, so `retries` reduced to `retri`, `retry` matched no suffix at all, and neither prefixed the other. Since matching downstream is substring and FTS-prefix, a query about `retry` treated a corpus that plainly said `retries` as never mentioning it — losing the term's IDF weight in the lexical floor and, since v2.6, reporting it to the user as a gap in coverage. It affects every `-y` word: `query`, `policy`, `memory`, `binary`, `registry` — a large share of the vocabulary this corpus is made of. A trailing `y`/`i` after a consonant is now stripped so both forms land on the shared prefix. Vowel-`y` (`delay`, `gateway`, `journeys`) is left alone, as are short words. Found by BrainBench's new sycophancy track, which flagged a gap on a question the fixture memories answered outright. * **The skills loop tells you it is waiting.** A memory cited across three distinct runs earns skill status, and detection has run on the maintenance schedule since the daemon landed — into a log file nobody opens. So a memory could cross the threshold and sit there indefinitely, because closing the loop needed a person who was never told there was anything to close. `find_synthesis_candidates` having exactly one caller was the same fact stated as a call graph. The warm start now carries one line naming what is waiting and the command that acts on it: candidates with no draft yet, and drafts awaiting a decision. A candidate that already has a proposal is not counted as a candidate — the loop has moved on. Silent when there is nothing to act on. * **Proactive injections are scored per hook surface.** `broker.proactive_prefetch` has been default-off since it shipped, its doc comment saying graduation waits on evidence that file-path-augmented queries do not add noise — while nothing recorded which surface an injection came from, so that evidence could never accumulate and the flag could never graduate on any timescale. Injections now carry their surface, and `kimetsu brain policy` reports acceptance (injected vs. subsequently cited) for each: `posttool`, which reacts to a command that observably failed; `pretool_command`; and `pretool_prefetch`, which predicts from a file path alone. Scored apart, so a strong surface cannot launder a weak one's noise. Events from before this change carry no surface and are dropped rather than bucketed into a default, which would credit one surface with another's history. The default stays off until the comparison is made on a real brain — what changed is that it can be. * **Ordering questions get dated, ordered memories.** Memories carry `created_at` and capsules did not, so a bundle rendered in score order with no dates gave a reader asked "did we switch to `thiserror` before or after the migration?" nothing to order the answer by — the reason event ordering was the weakest measured ability (32.5% on BEAM 100K). Retrieval was never at fault: the memories were found and selected, and the ordering was thrown away at render time. When a query carries an ordering marker (`before`, `after`, `first`, `when`, `timeline`, …) the bundle is now re-rendered oldest-first with each memory's date in front of its text, under a line telling the reader that is what they are looking at. It runs after the budget loop, so it is presentation and not selection — it cannot admit a capsule the broker rejected or drop one it chose — and `used_tokens` is recomputed because the dates cost tokens. Repo files, which have no position in the memory timeline, keep their relative order after the dated ones rather than being dropped or dated. The marker gate is narrow on purpose: dating every capsule on every query would spend tokens on the majority of questions that are not about time. Exposed as `chronological` / `chronological_note` on `kimetsu_brain_context`. * **Pi and OpenClaw now inject anything at all.** Both generated extensions spawned `kimetsu` with `stdio: "ignore"`, so the context hook read an empty stdin (bailing on its minimum-prompt guard) and its output went to `/dev/null`. Kimetsu was write-only on those hosts. The extensions now pipe stdio, feed the hook payload in, and return the parsed context through the host's own contract — Pi's `before_agent_start` message, OpenClaw's `agent_turn_prepare` `prependContext`. Every failure mode stays a silent no-op: missing binary, hung binary, crash, unparseable output. * **One source of truth for integration assets.** The Pi and OpenClaw templates moved out of string literals in `bridge.rs` into `crates/kimetsu-chat/assets/`, pulled in with `include_str!`. The published `kimetsu-pi` npm copy is vendored from the same file by `scripts/sync-pi-package.sh`, and a new CI job diffs the two. The drift this prevents was real: the npm copy had timeout hardening the installed copy never got, so a hung binary could stall a Pi lifecycle hook indefinitely. * **`digest::is_stale()` is wired up.** It was implemented and documented as driving a detached rebuild, with no production caller — so a moved corpus put a synchronous digest rebuild in front of the agent's first turn. The cached digest is now served immediately and the rebuild spawns detached. ### Added [#added-2] * **Warm start on every host.** `kimetsu brain context-hook --warm-on-first-prompt` prepends the repo digest and episodic resume to the first turn of a session, exactly once — covering Codex (which has no `SessionStart` event), Pi, OpenClaw, and any future host with only a per-turn hook. Claude Code does not pass the flag and keeps its `SessionStart` route, so nobody receives the block twice. A short prompt still gets the warm start: the length guard exists to skip meaningless retrieval, not to withhold orientation. * **Cursor warm start over MCP.** Cursor has no hook surface at all, so the first `kimetsu_brain_context` call of a session now returns a `warm_start` field alongside the capsules, and the installed Cursor rule tells the agent to make that call at task start. Scoped to the stdio path only — one `kimetsu-remote` process fans out across many sessions. ### Measured — an agentic re-run that does not reproduce the 13x claim [#measured--an-agentic-re-run-that-does-not-reproduce-the-13x-claim] `kbench` was run end-to-end for this release: 12 Terminal-Bench tasks stratified across all nine families of `prog-families-v1`, `claude+km` against `claude`, 24 trials on Claude Opus 5, no grading or quota errors. | | wins | cost | cost/win | input tokens | | ----------- | ---- | ------ | -------- | ------------ | | `claude+km` | 8/12 | $82.19 | $10.27 | 13.9M | | `claude` | 9/12 | $67.32 | $7.48 | 11.4M | The win-rate difference is a single task and is **not** a result — discordant pairs are 1 vs 2, one flip reverses the ranking, and a repeat of the same task inside this session scored differently between runs. What n=12 supports is *no detectable difference in win rate*, not that the brain hurts. The cost difference is firmer, because token counts are measured rather than sampled: 22% more tokens overall, 37% more per win. That is the opposite direction from the \~13x cost-per-win advantage recorded in `docs/ROI-METHODOLOGY.md`, which is now caveated in place rather than quietly left standing. That figure was measured on Sonnet 3.5 against a different, unenumerated slice, so this is not a like-for-like refutation — but it is enough that 13x should not be quoted without the caveat. Worth stating because it is the fairest reading and still not an excuse: Terminal-Bench gives every task a fresh container and unrelated neighbours, so there is almost no prior-session knowledge for a cross-session memory system to retrieve. It is the weakest setting for Kimetsu's thesis. It is also the instrument the 13x number came from, so it cannot be used to dismiss this result while retaining that one. ### Measured — BrainBench re-run, and two safety tracks that now exist [#measured--brainbench-re-run-and-two-safety-tracks-that-now-exist] Full 264-scenario BrainBench re-run on the semantic build, plus the sycophancy and poisoning tracks this release had to withdraw a claim about. **dedup 77.0% (published 77%) and forgetting 87.8% (published 88%) reproduce almost exactly.** Two independent measurements landing on the same number is the useful result — it says the harness and the brain are both stable. Importance gained \~16 points, outside its confidence interval and apparently real. **Calibration reads 99.7% at n=122, and that is a problem rather than a win.** BrainBench's own published standard is that a benchmark returning \~100% measures nothing; a ±0.3% interval means the track has stopped discriminating. Those scenarios are synthesized from a retrieval pool rather than authored, and they have become too easy to be informative. **The Overall Brain Quality Index is not comparable across the two runs**, and the docs now say so rather than banking the delta. It is an unweighted mean over whatever ran; the mix changed from 142 scenarios to 264, with calibration alone now 46% of the run at 99.7%. A mean dominated by a saturated dimension rises whether or not anything improved. The published 80.0% stands as the figure it was, over the set it was measured on. The new tracks are `poisoning` and `render-contract`, in `kimetsu-bench`. They confirm three shipped defences work: 4b import quarantine, 4a trust-weighted ranking, and `brain audit` write-burst detection. Both score 100%, which is again a weakness and is documented as one — five scenarios covering the straightforward case, with no adversarial case that breaks. `render-contract` is deliberately not named "sycophancy": MemSyco measures a *reader* over-deferring to memory, BrainBench has no reader, and a number labelled sycophancy sitting next to `dedup 77%` is exactly the claim this release already had to withdraw once. Neither safety dimension is folded into any Overall Brain Quality Index. ### Changed — the installed instructions, restructured (and a claim withdrawn) [#changed--the-installed-instructions-restructured-and-a-claim-withdrawn] Kimetsu's own guidance — the MCP server instructions, the CLAUDE.md block, and the Cursor / Pi / OpenClaw skill files — was written in 2025-era style: numbered steps plus a conservative filter on the write path (*"Do NOT call for trivial or well-known knowledge"*, *"before non-trivial tasks"*, *"things that required real effort"*). It now states when to reach for each tool rather than fencing off when not to, drops the step-numbering, and tells the retrieval path plainly that an empty result cost nothing. **The behavioural claim behind this change did not survive being measured, and the honest version is the useful one.** The prediction was that stacked conservative qualifiers suppress `brain_record` on models that follow instructions literally, so removing them would raise the write rate. An A/B on `claude-opus-5` — three instruction variants × 10 scenarios × 5 repetitions, each a fresh headless session — says otherwise: | variant | clear-record | ambiguous middle | clear-skip | | -------------------------- | ------------ | ---------------- | ---------- | | old text | 100% | 23% | 0% | | new text | 100% | **17%** | 0% | | new text, minus one clause | 100% | 23% | 0% | Two findings, neither of them the one expected. The write rate did not rise; the only measurable movement was **downward**, and it came from a clause this release itself introduced — *"well-known facts and things the repository already states are already available next session"*. Removing that clause returns behaviour exactly to the old text, which isolates it as the sole active ingredient: every other change was inert on this measurement. The clause is therefore gone. The second finding is the more interesting one. The rewrite replaced a prohibition with a reason on the theory that a literal reader applies a reason narrowly and a prohibition broadly. The model's own stated rationales show the opposite: under the old text it cited *"no real effort"*, and under the new one it cited the new clause almost verbatim — *"repo already states it"*. A reason that is **easier to evaluate** ("is this in the repository?") anchors harder than a vague bar ("did this require real effort?"). Reason-versus-prohibition was the wrong axis; specificity was the axis that mattered. Scope of the evidence, stated plainly: this measured the *record* decision only, via an explicit policy judgement rather than observed tool use inside a real agent loop, at n=5 with 8 of 10 scenarios unanimous across all three variants. The middle-band difference is 2 decisions out of 30 — small enough that "no detectable loosening" is the safe reading rather than "a proven regression". The retrieval-side change was not measured at all. What the release claims is therefore only that the text is structurally cleaner, not that it performs better. The `_REQUIRED` bridge and delegate variants are deliberately untouched: forcing the tool is what that mode is for, and the benchmark harness depends on it. A regression test asserts the instructions name each tool and carry no prohibition. * **`[broker] normalization`** selects how a candidate's raw relevance becomes the `relevance` term: `per_kind` (the rule through v2.5) or `global`. Per-kind normalizes within each capsule kind, so the best memory and the best repo\_file each reach `relevance = 1.0` however good either actually is — which is why the lexical and semantic floors have to exist, pruning weak candidates before normalization can flatter them. Global uses one max, so relevance means the same thing across kinds. Ships with a per-request override so both rules can be compared in one process against one corpus. The default stays `per_kind`, and the reason is unusual enough to state: the eval fixture is 18 memories of a single kind, and on a single-kind corpus the two rules are *arithmetically identical*. `brain bench` cannot tell them apart. Settling this needs a mixed-kind corpus that does not exist yet, and building it inside the release that flips the default would be authoring the instrument and the measurement together. * **CI builds and tests the TypeScript SDK**, and the release workflow publishes it. `@kimetsu-ai/sdk` shipped in this release series with neither: no job compiled it, and no step pushed it to npm. The whole argument for an SDK is that integrations call a typed client instead of parsing text, which only holds if the types compile. It publishes at its own package.json version rather than the git tag — its API moves independently of the binary's, and its PyPI sibling is versioned the same way. Two corrections that belong in the record even though the planning document carrying them is not published: * The reason given for the `embeddings` flavor not building was an unreachable ONNX Runtime prebuilt. It was not; see **Fixed** above. Anyone who reads that diagnosis somewhere else should ignore it. * Sycophancy and poisoning tracks were described as landed in `kimetsu-bench`. They are not there. The *feature* is real and asserted end-to-end in `cli_smoke.rs` — that test is what caught the y→ies stemmer bug — but the benchmark tracks were never built and remain open. ### Docs [#docs] * `interfaces.md` listed `kimetsu_skill`, `cite_memory` and `expand_capsule` as MCP tools. The first does not exist; the other two belong to the autonomous agent pipeline, and are now documented there instead. * `the-broker.md` documents that capsules fill against **half** of the requested `budget_tokens` — every published budget number read as double the real one. * `[storage] backend` no longer carries stale TODOs for `graph-lite` and `graph`; both are implemented, and the doc now says what they do and notes that `graph-lite` needs `kimetsu brain graph build` before it differs from `flat` at all. ## v2.5.3: Close the benchmark learning loop [#v253-close-the-benchmark-learning-loop] A focused follow-up to v2.5.2. Adds the host-side path that lets a graded task feed its outcome back into the brain, so the consolidation machinery (usefulness, query-routes, staples) receives a real signal on every solve. ### Added [#added-3] * `kimetsu brain benchmark-credit --task --passed`: on a pass, groups a citation for the memories most relevant to the task and routes it through the same grouped, query-linked path consolidation consumes. Driven by a benchmark harness after grading, so the learning signal never depends on the agent inside the sandbox calling a tool. This is what makes an iterated-benchmark learning loop actually reach the brain; before it, the benchmark memory path recorded outcomes but never exercised consolidation. ## v2.5.2: The brain that learns from its own outcomes [#v252-the-brain-that-learns-from-its-own-outcomes] Consolidation v1: the first release where citation outcomes reshape the brain itself, with every mechanism model-free and every constant documented on one page. Backward-compatible (schema v9 → v10, automatic on open). ### Consolidation v1 (new) [#consolidation-v1-new] * `kimetsu brain reinforce`: offline consolidation pass. `--staple` merges memories that were repeatedly cited together into single fact memories (precomputed multi-hop joins; originals kept; provenance carries part ids). `--routes` builds a query-routing index from citation history: memories that answered similar questions before get a bounded retrieval boost. * `kimetsu brain cite` accepts repeated `--memory-id` (citing a GROUP — the co-citation signal stapling consumes) and `--query` (linking citations to the question they answered, feeding the routing index). * Retrieval-time routing boost with a fixed per-retrieval budget, per-candidate cap, minimum support, and power-law decay. ### Learning-loop guardrails [#learning-loop-guardrails] * The usefulness boost's relevance gain is capped: a heavily-cited memory can win ties but can never outrank a genuinely more relevant one (fixes a measured retrieval-flooding failure mode under sustained citation feedback). * Cited-in-failure penalty now scales with citation history (`-1.0 / (1 + prior citations / 3)`): a proven memory absorbs occasional flaky-run hits; an unproven one takes the full penalty. * All scoring constants (deltas, caps, envelopes, decay) now live in one documented module, `scoring.rs`. ### Quality of life [#quality-of-life] * Schema-mismatch errors name the offending `project.toml` and hint at the fix (project discovery climbs to the enclosing git root, so the file is often far from where you ran the command). * npm packages ship with provenance attestations (Sigstore): every published package is publicly verifiable as built by CI from this repo. * Internal: `project.rs` and the CLI `main.rs` split into focused modules. ### Benchmarks [#benchmarks] * LoCoMo: 89.4% on the standard 1,540-question set (LLM-judged accuracy). * Learning-curve harness validated: citation feedback never degrades retrieval across repeated iterations, with a train/holdout split proving generalization. ## v2.5.0: Ship the brain to your team [#v250-ship-the-brain-to-your-team] Flagships: retrieval level presets (`basic`/`flexible`/`deep`/`advanced`), temporal validity and date-aware ingestion, fleet write-safety (concurrent writers, per-event origin), convergent team sync (HLC replay + conflict surfacing), Kimetsu Remote GA with per-user attribution, and shareable brain packs (gzip + security-scrubbed export, merge/replace import from file or URL). Docs site moved to kimetsu.dev. ## v2.0.0: Never explore twice [#v200-never-explore-twice] The biggest token sink is RE-EXPLORATION: the agent re-deriving what the brain (or the repo) already knows. v2.0 attacks it from three flagship directions and adds a pluggable storage tier. Backward-compatible: existing `project.toml` and `brain.db` files upgrade in place (schema v3 → v6, automatic on open). ### Flagship: Session warm-start (never re-establish your work) [#flagship-session-warm-start-never-re-establish-your-work] ADDED * **Episodic work-resume.** A new `work_episode` record (event-sourced, schema v5) captures your working state at SessionEnd: the task, what you did, what FAILED and why (dead-ends), open threads, and the working hypothesis, scoped per-repo (one live episode per repo). `kimetsu resume` prints it; `kimetsu checkpoint [note]` saves one manually. Distilled via the cheap model when configured, else a rule-based summary (never blocks). Episodes are LOCAL-ONLY and never sync/export. * **Project digest.** `kimetsu brain digest [--refresh]` assembles a compact (\~400-token) digest: repo manifest + top-usefulness memories + current focus, cached at `.kimetsu/digest.md` by content hash, refreshed on git/ corpus drift. (The digest is currently rule-based; a cheap-model distillation hook-point is present but not yet wired.) * **SessionStart injection.** A new `kimetsu brain session-start-hook` emits the digest + resume as `additionalContext`, gated by `[broker] warm_start` (default on). Wired for Claude Code; other hosts' SessionStart context surface is not yet verified and is intentionally left unwired. ### Flagship: The active brain (never wait on the brain) [#flagship-the-active-brain-never-wait-on-the-brain] ADDED * **`kimetsu brain ask ""`.** Terminal Q\&A answered entirely from the brain: full retrieval + a grounded answer composed by a LOCAL/cheap model, with memory-id citations. Zero frontier tokens; works offline. Falls back to distiller credentials, then to verbatim top-capsules when no model is configured. Grounded-only: refuses rather than hallucinating when memory has no answer. `--json`; an answer marked helpful counts like a citation. * **`kimetsu_brain_answer` MCP tool.** A read-only synthesis tool the host agent can call mid-task ("what do we know about X?") for a grounded, cited brief instead of re-discovering. * **Command recall fast-path.** "How do I…" queries surface matching `command`-kind memories runnable-line-first. * **Answer-grade injection.** Very-high-confidence capsules (score ≥ `[broker] answer_grade_min_score`, default 0.92) are prefixed "Verified answer from project memory:" so the model can act in one turn. Render-time only (ranking is untouched) and suppressed when the memory was recently a floor-drop regret. * **Proactive pre-fetch.** Opt-in `[broker] proactive_prefetch` (default off) warms trajectory-relevant memories at PreToolUse. ### Flagship: Memory → skill synthesis (never re-derive a solution) [#flagship-memory--skill-synthesis-never-re-derive-a-solution] ADDED * **Skill synthesis.** A memory cited ≥3 times (or a tight cluster) becomes a synthesis candidate; `kimetsu brain skills [--review]` drafts an executable skill from it (grounded strictly in the cited memories) and, on explicit accept, installs it into the host-native skill dir with provenance back to the source memory ids. Propose-only (never auto-installed); flagged stale when a source memory is superseded. Schema v6 (`skill_proposals`). ### Local-model independence [#local-model-independence] ADDED * **Ollama as a first-class provider** (`provider = "ollama"`, OpenAI-compat, `localhost:11434/v1` default, no key) and a single optional `[cheap_model]` config that all cheap-model consumers resolve (distiller, consolidation, digest, resume, skill draft, `ask`). Back-compatible with `[learning.distiller]`; OPTIONAL everywhere: every consumer degrades gracefully when no model is configured. `kimetsu doctor` probes the local endpoint. New guide: `docs/LOCAL-MODELS.md` (fully-local = zero external calls). ### Pluggable storage backends [#pluggable-storage-backends] ADDED * **`RetrievalBackend` trait** with `[storage] backend = "flat" | "graph-lite" | "graph"` (default `flat`). The broker stays backend-agnostic; switching backends re-projects from the event log. * **Graph-lite (Tier 1)**: a typed-edge projection (`memory_edges`, schema v4) with 1-2 hop expansion blended as graph-provenance candidates (a strict superset of flat, no recall loss; the broker still filters). `supersedes` edges populate now; episode-sourced edge types are reserved. * **Petgraph (Tier 2, remote-only)** behind the `graph` feature (off in local lean/embeddings builds, petgraph is never compiled there). In-memory graph with centrality / shortest-path / community-detection helpers, plus a cross-backend benchmark harness. Spike verdict: an embedded graph DB (Kùzu/Cozo) is not justified through \~100k memories. ### Continuous self-tuning + ROI v2 [#continuous-self-tuning--roi-v2] ADDED * **Re-tune triggers** (≥50 new memories since last tune, or elevated regret rate) surfaced via `kimetsu brain tune --status` + a Stop-hook one-liner, proposed, never auto-applied. **Model re-selection advisor** (`tune --models`) with reindex/download cost stated. **Regret-driven objective**: the tune objective now penalizes floor configs that produced regrets. **ROI v2**: per-memory ROI (`roi --top`), output-token accounting, and warm-start (`digest_served`/`resume_served`) savings attribution. ### Personal brain sync [#personal-brain-sync] ADDED * **Event-log replication** (not file copying). `kimetsu brain sync export --since <cursor>` / `import` move durable memory-lifecycle events as portable JSONL with per-event idempotency; telemetry, raw queries, and local-only episodes are excluded by an allowlist; redaction is respected. `[sync] dir` drives a server-less directory protocol (Dropbox/Syncthing/NAS) with per-machine batches and per-source cursors; `--dry-run` and `--status` throughout. Object-storage backends (e.g. S3) are deferred. ### Hardening & release [#hardening--release] FIXED * Analytics/doctor active counts, reindex, peek/undo, and `memory list` now consistently exclude superseded rows; `config set`/`tune --apply` preserve toml comments + unknown keys (`toml_edit`); dropped-capsule + proactive-state sidecars write atomically. Cursor/Gemini MCP schemas verified against live docs. * **Release pipeline**: a `version-guard` job fails in seconds on a tag/workspace-version mismatch (and the built binary must self-report the tag): closing the gap that produced the v1.5.0 botch; core GitHub Actions bumped to Node-24-ready versions; `scripts/bump-version.sh` codifies the one-step version bump. KNOWN LIMITATIONS * SessionStart warm-start is wired for Claude Code only; the digest is rule-based pending the cheap-model distillation wiring; full retrieval- quality and first-turn-token benchmarks require the embeddings + Docker environment and were not run in CI; remote-bench process isolation (#23) remains open. ## v1.5.1: version-stamp re-release [#v151-version-stamp-re-release] Identical feature set to v1.5.0. The v1.5.0 artifacts were built before the workspace version bump, so their binaries self-report `1.0.0` (which also broke the crates.io publish: `kimetsu-core@1.0.0` already existed). npm forbids reusing a published version, so the corrected release ships as v1.5.1. If you installed v1.5.0 from npm or the GitHub release, update. FIXED * Workspace and inter-crate versions stamped correctly (`kimetsu --version` now reports the release version; crates.io publish unblocked). ## v1.5.0: pays for itself [#v150-pays-for-itself] ADDED * **Telemetry capture.** Raw query text is now stored in `context.served` telemetry events when `[learning] store_queries = true` (default; set `false` to revert to the pre-v1.5 query-hash-only behavior). A `session_id` field is also written when the host provides one (Claude Code hooks; absent for hosts that do not emit it). Dropped-capsule sidecar (`~/.kimetsu/cache//dropped-recent.json`) records capsules that were floor-filtered out so that a later citation of one is detected as a `retrieval.regret` event, feeding the self-tuning loop. All telemetry stays on-machine; nothing is exported. * **ROI ledger (`kimetsu brain roi`).** Conservative per-kind token-savings estimates (failure\_pattern=1500, command=400, convention=300, fact=500, preference=200 tokens per citation) minus brain-injection overhead give a net-positive / net-negative verdict. Dollar estimates are shown when the active model is recognized from a built-in price table (Claude 3/4, GPT-4/5 families, Bedrock routing prefixes) or when `[model] price_per_mtok` is set in `project.toml`. `--window 7d|30d|all` and `--json` for scripting. The Stop hook appends a per-session savings sentence when ≥1 citation occurred; zero-citation sessions are silent. Calibration methodology and honest limitations: `docs/ROI-METHODOLOGY.md`. * **Token budget: render-time capsule compression and session dedupe.** Two `[broker]` toggles, both default `true`: * `compress_capsules`: capsule summaries are compressed at render time (strips `[tags: ...]` / `(context: ...)` annotations, caps at 3 sentences). Ranking is never affected: this runs only after retrieval and reranking. Set `false` to inject full memory text. * `session_dedupe`: the `UserPromptSubmit` hook skips capsules whose handle was already injected earlier in the same session (tracked via the proactive-state sidecar). Soft policy: falls back to injecting all capsules when dedupe would produce an empty set. This addresses the pre-v1.5 behavior where the main hook re-injected the same top capsule on every prompt of a long session. * **Self-Tuning Brain: `kimetsu_brain_cite` MCP tool + `kimetsu brain tune`.** `kimetsu_brain_cite` is a new write-gated MCP tool that records a `memory.cited` event from inside an MCP session, closing the ground-truth gap when the model leans on a memory but doesn't explicitly call `cite_memory`. Personal eval set: `tuneset` builds positive eval cases from `context.served` + citation joins (exact session\_id or ±30-minute window fallback). `kimetsu brain tune --status` reports case count and kind coverage. `kimetsu brain tune` (dry-run by default) sweeps `broker.min_lexical_coverage` ∈ \{0.3, 0.4, 0.5, 0.6} × `broker.min_semantic_score` ∈ \{-1.0(AUTO), 0.0, 0.25, 0.35, 0.45} against the production embedder; `--apply` writes only the floor parameters (not the reranker; that change is recommended separately); `--revert` restores the previous tune-history entry. A holdout guardrail (deterministic 20% split) prevents writing a config that regresses the holdout objective. * **Consolidation: `kimetsu brain consolidate` + `kimetsu brain triage`.** Schema migrated to **v3** (`superseded_by` column + index on `memories`). `brain consolidate` (Story 3.1, default): brute-force cosine scan within the same embedding model; clusters at ≥ 0.92 cosine (configurable with `--threshold`) are merged: survivor keeps its id and text, members get `superseded_by` set and a `memory.superseded` event written (rebuild-safe); citations are reassigned to the survivor. `--distill` (Story 3.2): looser clusters (0.75-0.85 cosine band, ≥3 memories, ≥1 shared tag) are fed to the configured distiller; result lands as a memory proposal for human review; prints clusters and exits 0 when no distiller is configured. `brain triage` (Story 3.3): interactive per-item keep / prune / skip of memories below a usefulness and age threshold (`--score-floor 0.2`, `--age-days 30`); `--prune-all --yes` for batch non-interactive pruning. * **Reach: export redact, Cursor + Gemini CLI installers, CI embeddings job.** `kimetsu brain export --redact` strips the `(context: …)` segment from exported memory text; `--redact-tags` (requires `--redact`) additionally strips the `[tags: …]` prefix. Both flags are useful for sharing brains without leaking workspace-specific file paths or tag metadata. `kimetsu plugin install cursor` and `kimetsu plugin install gemini-cli` write MCP config (`.cursor/mcp.json` / `.gemini/settings.json`) and an always-on guidance file (`.cursor/rules/kimetsu-brain/rule.md` for workspace installs; `GEMINI.md` merged into the project root or `~/.gemini/GEMINI.md` for global installs). Neither host has a `UserPromptSubmit`-style hook system, so MCP + the guidance file are the complete integration surface. The Cursor and Gemini CLI config schemas match each host's current official MCP documentation (Cursor: `mcpServers` with `type: "stdio"`; Gemini CLI: `mcpServers` with transport inferred). CI: a new `test-embeddings` job (ubuntu-only, `--features embeddings`, HuggingFace + fastembed cache) runs alongside the existing lean test matrix. CHANGED * `kimetsu.mcp_write_tools` gate now covers `kimetsu_brain_cite` alongside the existing write tools (same env / config / default-true logic for the local stdio server; remote server remains env-only, default-deny). * Stop hook output includes a per-session token-savings line when the brain was cited at least once that session. * `brain.db` schema advanced from **v2 → v3** (automatic on first read-write open; sidecar backup taken per the existing migration policy). * `brain export` gains `--redact` / `--redact-tags` flags (no behavior change for existing callers). FIXED * Tune sweep now runs against the production embedder (not the Noop embedder used in tests), so floor calibration is on real vectors. ## v1.0.0: durable migrations, analytics, semantic retrieval, proactive recall [#v100-durable-migrations-analytics-semantic-retrieval-proactive-recall] ADDED * **Remote cross-encoder rerank stage.** `kimetsu-remote serve` now applies a cross-encoder reranker to every `kimetsu_brain_context` call (`--reranker`, default `jina-reranker-v1-tiny-en`, operator-level; `"off"` disables; any curated or HuggingFace ONNX id accepted). The default was chosen by the 100-memory benchmark: jina-tiny MRR 0.931 vs 0.914 for TinyBERT on the local bench; the remote path has no hook-latency budget so the fastest effective reranker wins. Benchmark lift with reranker: jina-v2-base-code MRR 0.904 → 0.906, bge-small MRR 0.901 → 0.909 (production floors active). * **Model-aware AUTO semantic floor + kimetsu-remote benchmark.** `kimetsu brain bench --remote` boots a real kimetsu-remote server per embedder, drives the 100-case dataset over HTTP MCP (sequential + concurrent), and reports quality/latency/throughput/server-RSS. Its first run caught a real bug: the 0.35 cosine floor (calibrated on bge) was KILLING relevant jina-v2 results on every production path (remote MRR 0.90 -> 0.77). `broker.min_semantic_score` now defaults to -1.0 = AUTO: 0.35 on bge-family models, disabled elsewhere (jina-v2 own precision keeps noise low); explicit values still win. Confirmed: jina-v2 remote recovered to MRR 0.906 / recall\@4 0.939 on the 100-memory corpus (with the server reranker: \~416ms/request, \~5 rps at concurrency 4, \~1.2GB peak RSS). * **Benchmark-chosen retrieval defaults: jina-v2-base-code + TinyBERT.** `kimetsu brain bench` (100 real-memory cases) drove the defaults: embedder `jina-v2-base-code` (recovers oblique queries bge-small never pools; \~4x less off-topic noise) + reranker `ms-marco-tinybert-l-2-v2` (\~43ms, within noise of the best MRR). Existing brains need `kimetsu brain reindex` after upgrading (vector dims 384 -> 768); set `embedder.model`/`embedder.reranker` back to taste and re-judge with `kimetsu brain bench`. Lean-RAM alternative: bge-small + tinybert. * **Local MCP write tools enabled by default (`kimetsu.mcp_write_tools`).** The brain's own workflow tells the agent to record lessons (`kimetsu_brain_record`, the Stop-hook harvest cue), but the privileged- write gate default-denied unless `KIMETSU_MCP_ENABLE_WRITE_TOOLS=1` was in the MCP server's env, so every session ended with the agent goaded into a blocked call. The gate is now config-driven for the LOCAL stdio server: `kimetsu.mcp_write_tools` (default true), personalizable via `kimetsu config set kimetsu.mcp_write_tools false`. Precedence: the env var when set always wins (both directions) > config > default. The REMOTE server is unchanged (env-only, default-deny) because a cloned repo's project.toml is untrusted input and must never enable writes. * **Cross-encoder reranking (opt-in) + retrieval eval harness + 300ms hook budget.** The warm daemon can apply a final cross-encoder rerank stage: over-fetch a 12-capsule pool, score each (query, memory) pair jointly with a fastembed reranker (`[embedder] reranker` = a curated id; local default ms-marco-tinybert-l-2-v2; "off" disables), drop below a 0.30 relevance floor, truncate to the cap. Every knob was chosen by measurement: `jina-reranker-v1-tiny-en` (default) beat the larger turbo model on both quality and speed in the head-to-head benchmark, a pool of 6 matches pool-12 quality exactly at half the latency, and summaries must stay FULL (snippet truncation cratered recall\@4 from 0.83 to 0.66, worse than FTS). With those settings a warm rerank answers inside the 300ms hook budget on a real brain (\~265ms measured); slower machines degrade gracefully to floored-FTS for that turn, or set `reranker = "off"`. Backing the default path, the cosine floor: `broker.min_semantic_score` is now ON by default (0.35) *and actually wired* (it previously defaulted to 0.0 and was never populated from config in any production path). The hook's daemon budget tightens 750ms → 300ms; a warm semantic answer fits with \~70ms to spare, and misses fall back to floored FTS. Daemon spawn hygiene for the lazy path: the entrypoint now binds the socket BEFORE loading models (a redundant spawn exits in ms, not seconds), and on Windows the hook clears HANDLE\_FLAG\_INHERIT on its std handles before spawning so the long-lived daemon can never hold the harness's stdout pipe open (previously the first prompt of a session could stall until the host's hook timeout). New `kimetsu brain eval [--fixture ...]` measures recall\@2/4 + MRR across fts / semantic / semantic+rerank modes against a committed fixture (`fixtures/eval-retrieval.json`), so ranking changes are measurable: baseline shows semantic recall\@4 0.90 / MRR 0.91 vs FTS 0.72 / 0.81. `--rerankers ` benchmarks cross-encoders head-to-head (quality + per-query latency) and `--pool` sweeps pool sizes; non-curated models load as user-defined ONNX from any HuggingFace repo via hf-hub. Benchmark results: jina-tiny recall\@4 0.896 / MRR 0.938 at \~44ms per query (pool 6) vs turbo 0.833 / 0.875 at \~137ms (pool 12); ms-marco TinyBERT-L-2 is \~5× faster still (8.5ms) but its quality (0.715) merely matches FTS. * **Warm embedder daemon: semantic recall at hook time.** The `UserPromptSubmit` context-hook can now match memories by *meaning*, not just lexically. A single per-user daemon (`kimetsu brain embed-daemon`, keyed by embedder model) loads the ONNX model once and serves full embedding/ANN retrieval to the hook over a local socket / named pipe (`interprocess`); the hook is a thin client with a ≤300ms budget and a hard fall-back to floored-FTS, so the prompt is never blocked. `kimetsu brain warm` (wired to each harness's startup hook) pre-warms it so a running session never pays a cold model load. One model in RAM regardless of how many projects/agents are active. Config: `[embedder] daemon` and `warm_on_start` toggle it; `[embedder] model` (and `kimetsu brain model set`) pick the model. `KIMETSU_EMBED_DAEMON=0` is a runtime kill switch. Embeddings builds only; lean builds keep the floored-FTS hook. New `kimetsu brain daemon status|stop` to inspect/control it. * **Durable schema migrations.** brain.db now migrates forward automatically on open via a versioned, forward-only runner (each migration applied in one transaction). The DB is backed up to a `brain.db.bak-*` sidecar before any version-advancing migration (skipped for empty brains; the three newest backups are kept). Read-only opens of an un-migrated brain degrade gracefully; an event-upcast seam keeps old traces replayable. The project.toml config version is decoupled from the DB schema version so the schema can evolve without breaking existing projects. * **Proof-of-value analytics.** New `kimetsu brain insights` command and `kimetsu_brain_insights` MCP tool: retrieval hit-rate & skip-rate, citation rate, proposal acceptance rate, usefulness trend, harvest yield, corpus health, and token economy, computed over a configurable recent-runs window. A new `context.served` event records every retrieval (hit or miss); `context.injected` now carries injected-token counts. * **Semantic retrieval (usearch HNSW ANN).** On the embeddings build, an approximate-nearest-neighbour index (usearch HNSW) finds memories whose *meaning* matches the query even with no shared words: **O(log N) per query**, so retrieval stays fast as the corpus grows. The index is candidate generation only; final ranking is an exact cosine rerank over the stored f32 vectors, so the index can be quantized (**f16 by default**, `i8`/`f32` via `KIMETSU_ANN_QUANTIZATION`) for a large RAM saving with negligible quality loss. Retrieval is sharpened with embedding-MMR (collapses true paraphrase duplicates) and an absolute semantic-relevance floor (genuinely off-topic queries return nothing). Capsule caps are config-driven (default 8) and injected tokens drop while the relevant capsule is preserved. The lean (FTS-only) build is unchanged. * **Scales to \~1M memories.** A million-memory corpus runs on modest hardware: **\~1.8 s p99 semantic retrieval and \~3 GB RAM at 1M** (f16 default; \~2.8 GB with `KIMETSU_ANN_QUANTIZATION=i8`). Both retrieval *and* conflict-detection-on-write are O(log N) via the HNSW index, no brute-force vector scan. Bulk ingest batches embedding; the index builds in parallel across cores, maintains itself incrementally, persists a sidecar so a restarted server loads instead of rebuilding, and Kimetsu Remote pre-warms each repo's index on startup. * **Proactive & cost-shrinking recall (the agent brain).** Before the first implementation attempt, a tight retrieval surfaces a "Known pitfalls" block (failure patterns / conventions), proactive, not just post-failure. Tasks are classified (Debug / Feature / Refactor / Docs / Investigation) to route recall by kind. A per-run recall ledger deduplicates capsules across stages (rendered once, back-referenced after), and the long tail is injected as one-line headlines the agent expands on demand via a new `expand_capsule` tool, so brain overhead shrinks in relative terms as tasks grow (an adaptive sublinear, per-run-capped budget). * **`kimetsu config edit` and `kimetsu run abort`** are now fully implemented: `config edit` opens `$EDITOR` on project.toml and re-validates on save; `run abort` cleanly finalizes a dangling run. No stub subcommands ship. * **`kimetsu doctor --selftest`** proves the brain pipeline works end-to-end (ingest → retrieve → record) without needing a live model or network. * **Process & maintenance commands.** `kimetsu ps` / `stop` / `restart` list and stop running MCP servers (the host respawns one on the next tool call); `doctor` now flags a stale running MCP server after an update. `kimetsu brain export` / `import` move memories between brains as portable JSON; `kimetsu brain memory edit` / `undo` fix a bad recording in place; `kimetsu runs prune` and `kimetsu brain compact` (VACUUM, optional event-trim) keep the install lean. * **Kimetsu Remote (beta): the brain over HTTP MCP.** Under active testing; the `kimetsu-remote` **server is a separate package** and is NOT installed by `cargo install kimetsu-cli` / `npm i -g kimetsu-ai`: install it on the server with `npm install -g kimetsu-remote` or `cargo install kimetsu-remote --features embeddings` (or its standalone GitHub-Release archive). A new standalone `kimetsu-remote` server hosts one brain per repository under a data dir and exposes the memory/retrieval/curation tools over remote MCP (`POST /mcp/{repo}`), so a team (or you across machines) can share one brain with no local checkout. Bearer-token auth (global or per-repo); repo-keyed (the client supplies the id, derivable from the git remote); the agent-facing pure-DB tool subset only (workdir/host-local tools are excluded). Each repo brain is standalone (user-brain merge off). Plain HTTP: terminate TLS at a reverse proxy. `kimetsu-remote serve --addr 0.0.0.0:8787 --data <dir> --token <t>` (build with `--features embeddings` for semantic retrieval). Wire a host with `kimetsu plugin install <claude-code|openclaw> --remote <url> [--repo <id>] [--token <t>]`: it writes a `url`+`Authorization` MCP entry (no local hooks), deriving the repo id from your git remote and referencing `${KIMETSU_REMOTE_TOKEN}` by default so the secret isn't written to disk. The server ships as a separate package (`npm i -g kimetsu-remote` / `cargo install kimetsu-remote --features embeddings`) with its own standalone release archive. Hardening: per-token rate limiting (`--rate-limit ` → 429 when exceeded), a structured per-request log * an unauthenticated `GET /metrics` (Prometheus text, aggregate counts by outcome, no repo labels), and optional in-process HTTPS (build `--features tls`, pass `--tls-cert`/`--tls-key`; rustls/ring, off by default a reverse proxy is still the recommended terminator). Optional shared **org brain** (`--org-brain `, outside `--data`): `global_user`-scoped memories are stored there and merged into every repo's retrieval (cross-project team memory), while `project`-scoped memories stay per-repo. Off by default: each repo brain is standalone. Optional **server-side ingest** (`--repos-file` + `--checkout-dir`): the operator pre-registers repo-id → git URL, the server clones/refreshes a managed checkout, and `kimetsu_brain_ingest_repo` indexes its files into the repo's brain so `context` retrieval includes file capsules remotely (clients can't trigger arbitrary clones; private repos use the server's own git auth). * **AWS Bedrock provider.** The agent *and* the auto-harvester can run on Anthropic models served through Amazon Bedrock (InvokeModel, SigV4-signed from `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` (+ optional `AWS_SESSION_TOKEN`) and `AWS_REGION`, no AWS SDK). Set `[model] provider = "bedrock"` and/or `[learning.distiller]`; the two are configured independently, so you can run the agent on Bedrock and harvest on Bedrock or direct Claude/OpenAI. * **Two more host integrations: Pi and OpenClaw.** `kimetsu plugin install pi` wires a TypeScript extension (Pi has no MCP) plus a `kimetsu-brain` skill; `kimetsu plugin install openclaw` registers the MCP server, a hooks plugin, and a `kimetsu-context` skill. Both join Claude Code and Codex across `plugin status`, `plugin uninstall`, and `setup`. *Which* hosts you wire is a runtime choice you change anytime, no reinstall. **Every official prebuilt + npm binary (lean and embeddings) includes all four host integrations;** they're opt-in Cargo features only for a minimal source build, added with `--features pi,openclaw`. Every embedded hook degrades to a silent no-op if the `kimetsu` binary isn't on PATH, so a host is never left broken. * **Full plugin lifecycle.** `kimetsu plugin status` shows what's wired where (host × scope: installed / partial / absent + which pieces); `kimetsu plugin uninstall ` removes only the wiring (keeping the binary + brain); `kimetsu setup` runs init + plugin install + a selftest in one command. `kimetsu brain backup` writes a consistent full-DB snapshot via the SQLite online-backup API. * A 5-minute quickstart was added to the README. CHANGED * **Lean `.kimetsu/`.** The `brain.db` events table is now the durable log: memory writes no longer create per-write `runs//` directories, so a brain-only `.kimetsu/` holds just `brain.db` + `project.toml`. Transient proactive / chat / bench output moved to `~/.kimetsu/cache/`. * **Bidirectional config: every optional feature is turn-off-able.** `[embedder] enabled`, `[broker] ambient`, `[kimetsu] use_user_brain` (plus the existing `[learning] auto_harvest` / distiller and `[shell] redact_secrets`) are honored at runtime with the precedence env override > config > default. New `kimetsu config set` / `get` read and flip them from the CLI. * **Tiered, non-orphaning uninstall.** `kimetsu uninstall` now removes the host plugin wiring (Claude Code & Codex hooks / MCP / skills / agents, workspace + global) via a 3-tier prompt (binary only / * plugins (default) / + brains (typed confirm)) so it no longer leaves hosts pointing at a missing binary. A binary locked by a running kimetsu process is handled (offer to stop it / deferred delete) instead of a misleading "needs admin". * **Install/upgrade hardening.** Golden tests lock the non-destructive config-merge for Claude/Codex hooks, MCP config, and CLAUDE.md (user content always preserved; re-installs are byte-idempotent). Windows now runs the full test suite in PR CI. * **Clippy is a hard CI gate** (`-D warnings`) on both the lean and embeddings builds. * **Retrieval ordering is fully deterministic:** a stable tiebreak eliminates non-reproducible ranking across runs. * **Terser `--help` menu + flavored `--version`.** Top-level commands show short imperative labels (full detail stays in `kimetsu --help`), and `kimetsu --version` reports the build flavor (`1.0.0 (embeddings)` vs `(lean)`) so semantic-search availability is obvious at a glance. * **Run dirs self-prune.** New agent runs opportunistically GC run dirs older than 30 days (keeping the newest 20; `KIMETSU_RUNS_GC=0` to disable), only at run creation, never on the hot brain-open path. * **One-command npm semantic build.** `kimetsu npm-flavor embeddings` fetches the semantic build once and persists the choice (in `/kimetsu/npm/flavor`), so npm users no longer keep `KIMETSU_NPM_FLAVOR` exported across runs; `lean`/`status` round it out (the env var stays a per-run override). FIXED * **Lexical retrieval no longer injects off-topic memories that merely share the project name.** A broad conceptual prompt ("tell me about kimetsu, what's the idea of the repo") surfaced narrow debugging war-stories whose only overlap with the query was the corpus-ubiquitous token "kimetsu". Root cause: on the FTS-only `UserPromptSubmit` hook path there was no relevance floor (the cosine-based `min_semantic_score` is inert without an embedding), and `normalize_and_score` divides relevance by the *per-kind* max, so the best memory of each kind became `relevance = 1.0` no matter how weak the actual match, easily clearing the `min_score` gate on freshness + confidence alone. New `broker.min_lexical_coverage` floor (default 0.5): query tokens are stripped of stopwords and IDF-weighted over the memory corpus (so the project name, present in nearly every memory, contributes \~0; a word in *no* memory also contributes 0 since it can't discriminate), and a memory is dropped before scoring when the IDF-weighted share of the query it covers is below the floor and it has no semantic support. Repo-file and manifest capsules pass through untouched. Memories whose only match is the project name are now reliably dropped; the brain stays silent rather than injecting noise. (Keyword-overlap-but-off-topic hits that match a real, non-ubiquitous word still need the semantic path; this is a lexical floor.) * **`Stop` hook no longer trips "invalid stop hook JSON output".** `kimetsu brain stop-hook` printed a bare-text banner on stdout, but Claude Code validates a Stop hook's stdout as the advanced JSON control object, so the banner was rejected. The hook now emits a well-formed JSON object: informational banners via `systemMessage`, and the end-of-session harvest cue via `decision: "block"` so the cue text actually re-enters the model (plain stdout never reached it in a Stop hook, so the cue was previously inert). The one-cue-per- session guards keep blocking from looping. * **MSRV portability.** A 1.87-only API that violated the declared `rust-version = "1.85"` MSRV was replaced with the compatible 1.85 equivalent. * **GlobalUser memory writes work from any directory again:** a regression where recording a global-user memory required a loadable project is fixed. * **`UserPromptSubmit` context-hook no longer risks the host's 30s timeout.** The per-prompt hook runs in a throwaway process that can't reuse the long-lived MCP server's warm model cache, so in the embeddings build it was paying a cold fastembed/ONNX model load on every prompt, fast on a warm OS file cache but able to exceed 30s on a cold first prompt (worst under disk contention / AV scanning), which fails the hook. The hook is now FTS-only (lexical retrieval, no embedding model loaded); semantic ANN recall stays with the warm MCP `kimetsu_brain_context` tool the agent calls. Steady-state hook latency drops to \~300 ms regardless of build flavor. ## v0.9.0: auto-harvested memories + SessionEnd distiller [#v090-auto-harvested-memories--sessionend-distiller] ADDED * **Credentialed SessionEnd distiller (opt-in).** A second, deterministic memory-harvest path alongside the v0.9.0 in-agent harvester. `kimetsu plugin install claude-code` and `kimetsu plugin install codex` now run an interactive wizard (on a TTY; skip with `--no-setup`, force with `--setup-harvest`) that configures a cheap distiller model: Anthropic (recommended `claude-haiku-4-5`), OpenAI (recommended `gpt-5.4-mini`), or compatible endpoints via `ANTHROPIC_BASE_URL` / `OPENAI_BASE_URL`. The key + base URL are written to a gitignored `.env`; the selection lands in `[learning.distiller]` in `project.toml`. A new `SessionEnd` hook for Claude Code runs `kimetsu brain session-end-hook`; Codex uses its supported `Stop` hook with `--distill-on-stop`. When enabled + credentialed, the distiller reads the transcript with that model and records lessons through the confidence-gated `propose_or_merge_memory`. When the distiller is enabled, the Stop hook's end-of-session cue is suppressed (the distiller owns end-of-session; the mid-session PostToolUse resolved-failure cue stays). `AnthropicProvider` gained an optional base URL for the LiteLLM case, and the distiller gained an OpenAI Responses API provider. With `--scope global` the wizard configures the distiller once in `~/.kimetsu/` (config + `.env`); that global distiller then runs in every project and records into the user brain (`~/.kimetsu/brain.db`, available everywhere), with a per-project distiller taking precedence when one is configured. * **Auto-harvested memories (in-agent).** The hooks now drive memory *generation*, not just retrieval. When a command that failed earlier in the session succeeds (PostToolUse), or a non-trivial session ends with nothing recorded (Stop), Kimetsu emits a `[kimetsu-harvest]` cue telling the agent to dispatch a new background **`kimetsu-memory-harvester`** subagent (installed at `.claude/agents/` for Claude Code and `.codex/agents/` for Codex, pinned to a cheap model). The subagent distills 0-3 generalizable lessons and records them through the confidence-gated `kimetsu_brain_record` path: no separate API key or kimetsu-side model credentials, billed in-agent at the cheap model's rate, non-blocking. Cues are throttled (at most \~once per resolved failure / once per session) and can be disabled with `[learning] auto_harvest = false` in `project.toml`. CHANGED * **Cleaner help & tool menus.** Stripped internal version-history prefixes (`v0.x:`, `MP-…:`) from `--help` text and the MCP tool/argument descriptions so menus read as plain present-tense descriptions. (Internal code comments are unchanged.) FIXED * **Stop hook read the wrong field.** The Stop hook counted `kimetsu_brain_record` calls from a non-existent inline `transcript` array; Claude Code actually passes a `transcript_path` to a JSONL file. It now reads the JSONL (with the inline array kept as a fallback), counts both the bare and MCP-namespaced (`mcp__kimetsu__kimetsu_brain_record`) tool names, so the "lessons recorded" banner and end-of-session cue actually fire. The JSONL is now streamed line-by-line so a long session's multi-MB transcript never lands in memory at once. * **BOM-tolerant install.** `kimetsu plugin install` now strips a leading UTF-8 BOM before parsing an existing `settings.json` / `hooks.json` / `config.toml` / `.mcp.json`, so a config saved by a BOM-emitting editor (e.g. older Windows Notepad) no longer fails with "expected value at line 1 column 1". * **Install polish.** The installer now **merges** Kimetsu's guidance into an existing `CLAUDE.md` (workspace `.claude/CLAUDE.md` or the global `~/.claude/CLAUDE.md`) inside ``/`` markers, appending and upgrading in place, never overwriting the user's content. `--force` no longer overwrites `CLAUDE.md` (the whole install is idempotent and non-destructive; the flag is retained only for compatibility). A `--scope global` on the workspace-only `kimetsu` target warns instead of silently doing nothing; `--workspace` is canonicalized leniently so a global install doesn't fail on a missing workspace path. ## v0.8.4: non-destructive plugin install + global scope [#v084-non-destructive-plugin-install--global-scope] ADDED * **Global plugin install.** `kimetsu plugin install --scope global` installs the Kimetsu surface into the user's home for every session (`~/.claude/` + `~/.claude.json` (`mcpServers`) for Claude Code, and `~/.codex/` for Codex) instead of the workspace. `--scope` defaults to `workspace` (the prior behavior). Also exposed as the `scope` argument on the `kimetsu_plugin_install` MCP tool. FIXED * **Hook install no longer clobbers existing hooks.** `kimetsu plugin install` now *merges* its hooks into existing Claude `settings.json` / Codex `hooks.json` instead of replacing them. Hooks you already have, even on the same events Kimetsu uses (`UserPromptSubmit`, `PreToolUse`, …), are preserved, with Kimetsu's group added alongside. Re-running install is idempotent (no duplicate groups) and the MCP config + generated docs refresh without requiring `--force`. ## v0.8.3: npm distribution [#v083-npm-distribution] ADDED * **npm distribution.** Kimetsu now publishes to npm: `npm install -g kimetsu-ai` installs the prebuilt native binary for your platform, no Rust toolchain required. Uses the esbuild/turbo model: per-platform packages (`@kimetsu-ai/linux-x64`, `@kimetsu-ai/darwin-x64`, `@kimetsu-ai/darwin-arm64`, `@kimetsu-ai/win32-x64`) selected via `optionalDependencies`, with a thin `bin/cli.js` launcher that execs the matching binary. No postinstall, so it works under `npm install --ignore-scripts`. The semantic build is fetched on demand when `KIMETSU_NPM_FLAVOR=embeddings` is set. Published from the existing release pipeline (`publish-npm` job, gated on the `PUBLISH_NPM` repo variable + `NPM_TOKEN` secret, mirroring the crates.io gate). Sources live in [`npm/`](https://github.com/RodCor/kimetsu/tree/main/npm). Installs the `kimetsu` command (also available as `kimetsu-ai`). FIXED * **Windows npm package.** The `publish-npm` job now extracts the Windows archive with `7z` instead of `unzip` (PowerShell `Compress-Archive` uses backslash path separators that `unzip` flattens), and publishing is idempotent so a re-run after a partial failure skips already-published versions. ## v0.8.1, v0.8.2 [#v081-v082] Release-engineering releases on the road to the npm channel. crates.io and the prebuilt binaries shipped as usual in both. npm naming settled on the `@kimetsu-ai` scope / `kimetsu-ai` package (v0.8.1), and the complete, working npm packages (including Windows) ship in v0.8.3. ## v0.8.0: proactive recall, selectable embedding model, full MCP control [#v080-proactive-recall-selectable-embedding-model-full-mcp-control] The release that makes the brain **proactive** and gives the agent (and user) full control over it from inside Claude Code / Codex. ADDED * **Proactive recall (mid-work).** New `PreToolUse` / `PostToolUse` Bash hooks surface a relevant memory *while the agent works*, not just on prompt: * after a **failed** Bash command, surface a matching `failure_pattern` / `command` fix; * **before** a risky Bash command, warn from a matching `failure_pattern`; * on a **repeated** failing command (loop), lower the score floor and bypass the throttle so help arrives sooner. Retrieval is lexical-FTS-only (no embedding-model load), gated by a high score floor (0.45; loop 0.35), capped at one capsule, with per-session dedupe + a refractory throttle. Token cost stays \~0 (silent when nothing qualifies). Wired into both Claude Code (`.claude/settings.json`) and Codex (`.codex/hooks.json`) with a `matcher: "Bash"`; opt out with `kimetsu plugin install --no-proactive` (or `proactive:false` over MCP). Per-session state lives in `/.kimetsu/proactive/.json` and is garbage-collected after 7 days. * **Selectable embedding model.** New `[embedder]` table in `project.toml` (precedence: `KIMETSU_BRAIN_EMBEDDER` env > config > default). Inspect and change it with `kimetsu brain model list` / `kimetsu brain model set ` (the latter writes the config and re-embeds the corpus with the new model). Curated built-ins: `bge-small-en-v1.5` (384d, default), `bge-m3` (1024d), `jina-v2-base-code` (768d). * **Full MCP control surface.** New tools so an agent can manage the brain without leaving Claude Code / Codex: `kimetsu_brain_model_list` / `kimetsu_brain_model_set` (re-embeds in-process with the new model), `kimetsu_brain_reindex`, `kimetsu_brain_memory_search` (FTS over memory text), `kimetsu_brain_conflict_resolve`, `kimetsu_brain_prune`, and `kimetsu_brain_config_show`. `kimetsu_brain_memory_list` and `..._memory_proposals` gained `limit`/`offset` pagination. CHANGED * `reindex` can now run against an explicit embedder (`reindex_all_with_embedder`), so a model switch re-embeds with the chosen model regardless of the process's cached default embedder. FIXED * **Test isolation.** Tests created project roots under the system temp dir; on a machine whose `$HOME` is itself a git repo, `ProjectPaths::discover` climbed to `$HOME` and made parallel tests share one `brain.db` + `project.lock`. Each test root now gets its own git boundary, so plain `cargo test` is hermetic. ## v0.7.2: remove kimetsu-harbor-rs; first crates.io publish of the v0.7 line [#v072-remove-kimetsu-harbor-rs-first-cratesio-publish-of-the-v07-line] Maintenance + distribution release, layered on top of the v0.7.1 security hardening (path-traversal guards + URL-credential redaction). REMOVED * **`kimetsu-harbor-rs`**: the Terminal-Bench JSON-RPC transport adapter and its `kimetsu-harbor-agent` binary. The benchmark harness drives Harbor's built-in `claude-code` agent via `--mcp-config` (since the v0.5.5 refactor), so the custom transport binary was dead code. No published crate depended on it (`kimetsu-cli`, `-chat`, `-agent`, `-brain`, `-core` are unaffected); not a breaking change for `cargo install kimetsu-cli` users. CHANGED * Release workflow no longer builds or bundles `kimetsu-harbor-agent`. * First crates.io publish of the v0.7 series (v0.6.0 / v0.7.0 / v0.7.1 shipped binaries + GitHub Releases only). ## v0.7.0: semantic dedup, embeddings by default, session hooks [#v070-semantic-dedup-embeddings-by-default-session-hooks] The release that makes knowledge transfer reliable end-to-end: capture without duplication, retrieve without asking, and surface what was learned each session. ADDED * **Semantic dedup at capture.** `propose_or_merge_memory` (new in `kimetsu-brain`) runs before any memory is written. Exact dups short-circuit; near-dups (cosine ≥ 0.85, same scope) merge into the existing memory instead of spawning a near-twin. High-confidence novel lessons are accepted directly; the rest file as proposals. `kimetsu_brain_record` returns which branch was taken (`added | merged | duplicate | proposed`). This stops a brain from filling with ten rephrasings of the same lesson over a gauntlet. * **Embeddings on by default for the CLI.** `cargo install kimetsu-cli` now ships `--features embeddings` (fastembed-rs + ONNX, BGE-small-en-v1.5). Cosine retrieval, semantic dedup, and conflict detection all light up out of the box. Build lean with `--no-default-features`. Library crates (`kimetsu-brain`, `kimetsu-chat`) stay lean by default so downstream consumers don't inherit the ONNX runtime; only the binary opts in. * **`Stop` hook for session summary.** `kimetsu brain stop-hook` walks the transcript, counts `kimetsu_brain_record` calls, and prints a post-turn banner, confirming captures or nudging when a non-trivial session recorded nothing. `kimetsu init` now writes both the `UserPromptSubmit` and `Stop` hooks into `.claude/settings.json`. CHANGED * `kimetsu_benchmark_context` shares argument parsing with `kimetsu_brain_context` via an extracted `parse_retrieval_args` helper: \~50 lines of duplicated stage/budget/ambient handling removed. No behavior change for bench callers. NOTE * On Windows the embeddings flavor needs the VS2022 C++ runtime (ort prebuilts). The default model (\~24 MB) downloads to `~/.cache/huggingface/` on first embed call, then caches. ## v0.6.0: zero-overhead knowledge transfer [#v060-zero-overhead-knowledge-transfer] Retrieval and capture become silent by default and only speak up when they have something worth saying. ADDED * **`kimetsu_brain_context` zero-overhead contract.** When the brain has nothing relevant it returns `skipped: true` and injects nothing, so a host agent can call it on every non-trivial task without paying a context tax on cold brains. * **`kimetsu_brain_record` capture tool.** The host agent's path to persisting a concrete lesson (plus 2-5 domain tags) after solving a non-obvious problem. Pairs with `kimetsu_brain_context` as the intended two-call loop. * **`UserPromptSubmit` context hook.** `kimetsu brain context-hook` reads the prompt from stdin and injects a context bundle before each Claude Code turn, so retrieval happens whether or not the model remembers to ask. ## v0.5.5: delete kimetsu\_harbor/: harbor refactor arc complete [#v055-delete-kimetsu_harbor-harbor-refactor-arc-complete] Final commit of the v0.5.3-v0.5.5 harbor refactor arc. The Python Harbor adapter + benchmark glue moved to the internal kimetsu-bench repo in v0.5.4's sibling commit; this commit deletes the orphan directory from kimetsu and finishes the cleanup. DELETED FROM THIS REPO kimetsu\_harbor/ (entire directory) ├── codex\_kimetsu\_agent.py (311 LOC, Codex variant │ that diverged from the │ canonical adapter) ├── kimetsu\_agent.py (459 LOC, moved to │ kimetsu-bench/python/) ├── smoke\_test.py (145 LOC, replaced by │ crates/kimetsu-e2e in │ v0.5.3) ├── kimetsu-mcp-stdio.sh (1-line shim) ├── codex-kimetsu-mcp.wsl.json (Codex MCP config) ├── kimetsu-mcp-required.md (user-facing setup doc) ├── kimetsu-mcp-optional.md (user-facing setup doc) ├── README.md (Harbor adapter setup) ├── SETUP-WSL.md (WSL setup) ├── **init**.py (package marker) └── archive/ (one-shot scripts + historical orchestration) Net: \~900 LOC of glue + \~10 setup docs removed from the user-facing repo. The functional pieces (kimetsu\_agent.py) survive in kimetsu-bench/python/ where they belong; they're benchmark infra, not product code. ALSO REMOVED .gitignore: `/kimetsu_harbor/benchmark-logs/` rule (path no longer exists; bench logs land in kimetsu-bench/runs/ which has its own .gitignore in that repo). crates/kimetsu-harbor-rs/Cargo.toml: updated the `_rs` suffix comment (it used to explain a collision with kimetsu\_harbor/; now explains the legacy historical reason). WHAT SURVIVES IN KIMETSU REPO (unchanged) * crates/kimetsu-harbor-rs/: JSON-RPC transport + the `kimetsu-harbor-agent` binary. publish = false. The bench consumes it as a normal cargo path dep. * CI release matrix still builds `kimetsu-harbor-agent` for each platform (Linux, macOS-arm64, Windows × lean/embeddings) so a future bench operator can grab a prebuilt binary from a GH release archive instead of building from source. THE HARBOR REFACTOR ARC IS COMPLETE v0.5.3: Layer 1: in-process e2e suite + CLI smoke (+13 tests, all under 1s, no API keys / no Docker). v0.5.4: Doc consolidation: HOW-KIMETSU-WORKS.md replaces the 22-file docs/ sprawl; historical planning + ship docs moved to internal kimetsu-bench repo. v0.5.5: kimetsu\_harbor/ deleted; the Python Harbor adapter is now in the internal kimetsu-bench repo alongside the Layer 2 orchestrator + driver trait. THE NEW SHAPE Public kimetsu repo: docs/HOW-KIMETSU-WORKS.md one conceptual reference crates/ product code + e2e tests crates/kimetsu-harbor-rs/ JSON-RPC transport (publish=false) CHANGELOG.md, README.md, LICENSE-\* standard repo metadata Internal kimetsu-bench repo: src/ BenchmarkDriver + kbench CLI src/drivers/terminal\_bench.rs first driver (Terminal-Bench) python/kimetsu\_agent.py Harbor adapter shim docs/history/ v0.2-v0.5 planning + ship docs Pre-push gate: `cargo test --workspace` (258 tests, \~1s for e2e + cli smoke) Impact measurement: `cd bench && cargo run -- --driver tb ...` VERIFIED cargo test --workspace 258 / 258 passing (unchanged from v0.5.3) cargo build --workspace clean at 0.5.5 UPGRADE NOTES * If you had local scripts referencing `kimetsu_harbor/` paths, update them to point at the bench repo (or ping for access to the private repo). * The `kimetsu-harbor-agent` binary at `target/release/kimetsu-harbor-agent` is unchanged. Its source still lives at `crates/kimetsu-harbor-rs/src/bin/kimetsu-harbor-agent.rs`. ## v0.5.4: doc consolidation: HOW-KIMETSU-WORKS.md replaces the docs/ sprawl [#v054-doc-consolidation-how-kimetsu-worksmd-replaces-the-docs-sprawl] Second commit of the v0.5.3-v0.5.5 harbor refactor arc. Cleans up `kimetsu/docs/` so users see exactly one conceptual reference, not 22 files of planning, postmortems, and historical roadmaps. WHAT v0.5.4 ADDS * `docs/HOW-KIMETSU-WORKS.md` (\~600 lines). Single conceptual reference covering: the brain (events → projector → memories), the broker (scoring math + decay + MMR), citations + blame (v0.5.0), decay (v0.5.1), conflict detection (v0.5.2), the 18 kimetsu\_\* MCP tools, the bridge, doctor, config schema, and "what kimetsu is NOT." Consolidates the prior KIMETSU-CHAT, MEMORY-PROPOSALS, MEMORY-USEFULNESS, DEPENDENCIES into one self-contained reference. WHAT v0.5.4 DELETES FROM THIS REPO * `docs/V0.3.4-SHIP.md`, `docs/V0.3.5-PERF.md`, `docs/V0.4-ROADMAP.md`, `docs/V0.5-PLAN.md`, `docs/SWEBENCH.md`: historical planning + ship docs. * `docs/KIMETSU-CHAT.md`, `docs/MEMORY-PROPOSALS.md`, `docs/MEMORY-USEFULNESS.md`, `docs/DEPENDENCIES.md`: content folded into HOW-KIMETSU-WORKS.md. * `docs/archive/` entire subtree (14 files: MP-4 through MP-15 results, MVP, V0.2 plan/ship, V0.3 plan). WHERE THEY WENT * All 22 files were copied to `docs/history/` in the private `github.com/RodCor/kimetsu-bench` repo (v0.5.4 commit on that side: "Adopt historical planning + ship docs from kimetsu repo"). Their git history through v0.5.3 stays in this repo for bisects * archaeology. README + CHANGELOG TOUCHED * README's "Documentation Map" section now points at one file: `docs/HOW-KIMETSU-WORKS.md` + the per-release CHANGELOG + per-crate `src/lib.rs` doc comments. Stale references to deleted docs removed. * CHANGELOG's v0.5.0 + v0.3 + v0.2 + v0.1 entries dropped their "see X.md" references; the X.md files are gone. The notes below each version still stand alone. NET DELTA * kimetsu/docs/: 22 files → 1 file. * No code changes; no API change; no test count change. * cargo test --workspace 258 / 258 passing (unchanged from v0.5.3) * cargo build --workspace clean at 0.5.4 UPGRADE NOTES * If you've been bookmarking specific historical docs: * Need V0.5-PLAN.md, V0.4-ROADMAP.md, MP-\* results? They're in the private bench repo. Ping for access. * Need KIMETSU-CHAT / MEMORY-PROPOSALS / MEMORY-USEFULNESS / DEPENDENCIES content? It's all in `docs/HOW-KIMETSU-WORKS.md` now (sections 1, 4, 4, 10). * Pre-v0.5.4 commit hashes still reference the files in their original locations; `git log` + `git show` work normally on history. NEXT (in flight) * v0.5.5: Layer 2 driver implementation lands in kimetsu-bench (Python Harbor shim + BenchmarkDriver trait + Terminal-Bench impl + kbench CLI). The kimetsu\_harbor/ directory in this repo gets deleted in the same release pass. ## v0.5.3: Layer 1 of the harbor refactor: in-process e2e suite + CLI smoke [#v053-layer-1-of-the-harbor-refactor-in-process-e2e-suite--cli-smoke] First commit of the v0.5.3 harbor refactor arc. v0.5.0-v0.5.2 made the brain learn from outcomes; v0.5.3 makes it possible to verify the agent loop + brain pipeline still works *before pushing*, without API keys or Docker. Catches the wiring-level regressions that per-crate unit tests miss by construction. WHAT v0.5.3 ADDS * New workspace crate `kimetsu-e2e` (publish = false, integration test harness only). Provides `ScriptedProvider` (pure-Rust builder over `MockProvider`), `TempProject` (per-test scratch project that wraps `project::init_project` + auto-cleanup), and brain- state assertion helpers. * Four scenario files in `crates/kimetsu-e2e/tests/`: golden\_path.rs one tool call + done (the smallest viable smoke) citations.rs cite\_memory → recorded\_citations → memory\_citations decay.rs half-life ranking flip via the broker conflicts.rs list\_conflicts + resolve\_conflict wrappers 8 tests total. Runs in well under a second. * `crates/kimetsu-cli/tests/cli_smoke.rs`: 5 subprocess smoke tests that catch CLI argparse / subcommand / --help drift (no model calls, no network). * `KimetsuAgentOpts::for_tests()` is now `pub` (was `#[cfg(test)]`) so integration tests in `kimetsu-e2e` can use the same scripted-MockProvider-friendly settings as the harness's internal tests. LAYER-2 (BENCHMARK) BOOTSTRAP * `/bench/` added to .gitignore. The internal benchmark orchestrator lives in a separate private repo (`github.com/RodCor/kimetsu-bench`) cloned into `./bench/` of the kimetsu working tree. Not in kimetsu's workspace; not in any release archive; invisible to `cargo install kimetsu-cli`. Subsequent v0.5.3.x commits land the driver impls there, the Python Harbor adapter migrates over, and `kimetsu_harbor/` gets deleted from this repo. WHY TWO LAYERS * Layer 1 (this commit): in-process, deterministic, sub-second. Runs every push. Catches "did I break the wiring?" * Layer 2 (next commits, separate repo): real Claude Code / Codex against real Terminal-Bench tasks with kimetsu MCP attached vs detached. Comparative impact measurement. Runs on-demand. TESTS cargo test --workspace 258 / 258 passing (was 239 at v0.5.2; +13 from the new e2e + cli\_smoke layers) cargo build --workspace clean at 0.5.3 UPGRADE NOTES * No user-visible API changes. Pre-push gate gets stronger. NEXT (in flight) * v0.5.4: consolidate docs into a single HOW-KIMETSU-WORKS.md; historical planning + ship docs migrate to the internal kimetsu-bench repo. * v0.5.5: delete kimetsu\_harbor/ from this repo (Python Harbor shim moved to kimetsu-bench in v0.5.4). ## v0.5.2: conflict detection at ingest: contradictions surface, don't silently compete [#v052-conflict-detection-at-ingest-contradictions-surface-dont-silently-compete] Third and final beat of the v0.5 arc. v0.5.0 attributed which memories helped; v0.5.1 made stale boosters age out; v0.5.2 stops contradictory memories from accumulating in the first place. "Use anyhow" and "use thiserror" no longer both live in the brain quietly competing for retrieval slots: the second write surfaces the conflict at ingest time so the operator can decide which to keep. WHAT v0.5.2 ADDS * New module `kimetsu_brain::conflict`. Top-level surface: `find_potential_conflicts(conn, scope, text, embedder, top_k, threshold)` returns `ConflictHit` rows whose cosine >= threshold AND whose normalized text differs from the incoming text. Defaults: `DEFAULT_CONFLICT_THRESHOLD = 0.8`, `DEFAULT_TOP_K = 3`. * Embedder gating. `embedder.is_noop()` short-circuits to zero hits, so lean builds keep exact pre-v0.5.2 behavior. Cross-model rows (embedding\_model != active embedder id) are silently skipped: cosine across models is meaningless. A subsequent `kimetsu brain reindex` rehydrates them and the next ingest catches the conflict. * New schema: `memory_conflicts` table linking `(new_memory_id, existing_memory_id)` with `similarity`, `scope`, `kind`, `detected_at`, optional `resolved_at` + `resolution`. UNIQUE on the pair so re-scans stay idempotent. Created via `CREATE TABLE IF NOT EXISTS`; pre-v0.5.2 brain.db files pick it up on first open. * Wiring: both `project::add_memory` and `user_brain::add_user_memory` call `conflict::detect_and_record` after the post-insert embedding write. On a hit, one line to stderr; never blocks the write (surfacing > blocking; a blocked write loses user intent, a logged write loses nothing). USER SURFACE: conflicts * `kimetsu brain memory conflicts [--limit N] [--json]` CLI: lists open conflicts merged from project + user brains, sorted by detected\_at DESC. Each row shows similarity, scope, kind, and a one-line preview of both texts so the contradiction is visible at a glance. * `kimetsu brain memory conflicts --resolve <id> <kept_new| kept_existing|kept_both>`: settles a single conflict. With `kept_new` the existing memory is invalidated; with `kept_existing` the new memory is invalidated; with `kept_both` neither is touched (legit case where both apply in different contexts). Idempotent: a second resolve on the same id returns false without rewriting `invalidated_at`. * `kimetsu_brain_memory_conflicts` MCP tool (read-only): same backend, JSON-shaped for Claude Code / Codex. Resolution is deliberately CLI-only to keep the audit trail centralized. Brings the kimetsu\_\* MCP catalog to 18 tools. NEW BRAIN API * `conflict::find_potential_conflicts(...)`: pure detection. * `conflict::record_conflict(...)`: idempotent insert keyed on the memory pair. * `conflict::detect_and_record(...)`: convenience wrapper used by the ingest path, returns the count of newly-recorded hits. * `conflict::list_unresolved_conflicts(conn, limit)`: joined with both memories' text for rich display. * `conflict::resolve_conflict(conn, conflict_id, resolution)`: settles a row, invalidates the losing side, returns true if something changed. * `project::list_conflicts(start, limit) -> Vec` merges project + user brain rows with a `source` label. * `project::resolve_conflict(start, id, resolution)`: project DB first, user brain fallback. Acquires the project lock. TESTS (12 new in brain: 10 conflict module + 1 project integration + 1 wrapper) conflict::tests (10) noop\_embedder\_returns\_no\_conflicts cross\_model\_rows\_are\_skipped exact\_match\_is\_not\_flagged\_as\_conflict similar\_but\_different\_text\_is\_flagged record\_conflict\_is\_idempotent list\_unresolved\_excludes\_resolved\_rows resolve\_conflict\_invalidates\_loser\_side resolve\_conflict\_is\_idempotent detect\_and\_record\_noop\_writes\_nothing resolve\_conflict\_rejects\_invalid\_resolution\_strings project::tests (1) add\_memory\_distinct\_texts\_no\_conflicts End-to-end regression: NoopEmbedder path produces zero conflicts, exercises list\_conflicts + resolve\_conflict wrappers (unknown id returns false, invalid resolution string errors out). VERIFIED cargo test --workspace 239 / 239 passing (was 227 at v0.5.0, 239 now: +12 conflict tests) cargo build --workspace clean at 0.5.2 UPGRADE NOTES * Existing brain.db files: `memory_conflicts` table created idempotently on first open with the v0.5.2 binary. No backfill; conflicts are only detected at fresh ingest. * Lean (default) builds: conflict detection is a silent no-op. Build with `--features embeddings` to enable. (Same gate as semantic retrieval.) * Threshold tuning: 0.8 cosine is BGE-small-en-v1.5's empirical "same concept" floor. If you see false positives in `kimetsu brain memory conflicts`, the surfaced pairs are similar-but-correct (e.g. two legit preferences for different contexts): resolve as `kept_both` to silence them. If you see false negatives (a real contradiction sneaking through), raise the threshold via a future config knob (deferred until real data justifies the surface). * The MCP tool is read-only by design. Operators resolve from the CLI; the host harness can list and reason about open conflicts but cannot apply resolutions. This keeps the audit trail centralized and prevents an agent from silently "resolving" a real contradiction it should have surfaced. THE v0.5 ARC IS COMPLETE v0.5.0: citations: the brain knows *which* memories helped. v0.5.1: decay: stale "useful" boosters age toward neutral. v0.5.2: conflicts: contradictory writes surface, don't compete. Together: the brain learns from outcomes, ages out stale signal, and stops accumulating noise. Pitch sharpens from "memory that follows you" to "memory that follows you AND improves on its own." ## v0.5.1: usefulness decay: recency-weighted memory ranking [#v051-usefulness-decay-recency-weighted-memory-ranking] Second beat of the v0.5 arc. v0.5.0 gave us *which* memories helped; v0.5.1 makes "helped" age out. A memory that proved useful 6 months ago shouldn't outrank one that proved useful yesterday, yet under the v0.5.0 multiplier they tied, because the boost was permanent. Long-running repos accumulated stale boosters that crowded out fresh signal. WHAT v0.5.1 ADDS * New column `memories.last_useful_at TEXT NULL`. Bumped by the projector ONLY on `(memory cited) AND (run.finished)`: cited + run.failed doesn't count (the memory misled the model), silent passengers never bump regardless of outcome. Distinct from `last_used_at` which still bumps on every retrieval. NULL on pre-v0.5.1 rows and on rows never cited successfully; the broker falls back to `created_at` for those. * New broker config `[broker.weights] decay_half_life_days`, default 30.0. `#[serde(default)]` so pre-v0.5.1 project.toml files keep loading cleanly. Set to 0 to disable decay. * New helper `kimetsu_brain::context::usefulness_decay( last_useful_at, created_at, half_life_days) -> f32` returning `exp(-ln(2) * age_days / half_life)` clamped to `[0, 1]`. Fail-open: unparseable timestamps and non-positive half-lives return 1.0 so retrieval never silently drops rows. THE DECAY SHAPE decay attenuates the *deviation* from neutral, not the multiplier itself: effective = 1.0 + (raw\_multiplier - 1.0) \* decay At decay=1.0 a memory with the max +1.5 boost stays at +1.5. At decay=0.0 (very old) it slides back to 1.0 (neutral), same as a brand-new memory with zero history. Critically NOT zero: losing confidence in old signal shouldn't penalize a memory *below* a fresh one. Symmetric for the penalty side too: old penalties also fade toward neutral. CALL CHAIN PLUMBING * `retrieve_context_with_embedder` reads `weights.decay_half_life_days` and threads it through `memory_candidates` → `{latest, fts}_memory_candidates` → `memory_row_to_candidate`. * Both retrieval SQL queries now also SELECT `last_useful_at`. TESTS (7 new in brain, all in context.rs) context::tests:: usefulness\_decay\_disabled\_when\_half\_life\_is\_zero\_or\_negative Operator opt-out hatch: half\_life \<= 0 returns 1.0. usefulness\_decay\_returns\_one\_on\_unparseable\_timestamps Fail-open guard for corrupted rows. usefulness\_decay\_full\_at\_zero\_age Future-timestamp (negative age clamped to 0) returns 1.0. usefulness\_decay\_follows\_half\_life\_curve Asserts decay ≈ 0.5 at one half-life, ≈ 0.25 at two half-lives, computed against a real OffsetDateTime::now\_utc. usefulness\_decay\_falls\_back\_to\_created\_at\_when\_last\_useful\_is\_none Brand-new never-cited memories decay from their birthday, not from a hard 1.0 floor. aged\_cited\_memory\_ranks\_below\_recently\_cited\_memory End-to-end: two FTS-tied memories, one cited yesterday and one cited a year ago: recent must rank first under the default 30-day half-life. aged\_cited\_memory\_does\_not\_decay\_when\_half\_life\_is\_zero Companion regression: with decay off, the same two memories tie on score. Proves the v0.5.1 flip is caused by decay, not by some unrelated timestamp side effect. VERIFIED cargo test -p kimetsu-brain 86 / 86 passing (was 79) cargo build --workspace clean at 0.5.1 UPGRADE NOTES * Existing brain.db files: `last_useful_at` column added idempotently on first open with the v0.5.1 binary. All pre-v0.5.1 memories start at NULL → they decay from their `created_at` until the next successful citation refreshes them. No data loss; ranking will shift toward recently confirmed memories. * Existing project.toml files: no edit required. `decay_half_life_days = 30.0` applies automatically. To opt out, add `decay_half_life_days = 0.0` under `[broker.weights]`. * Tune the half-life per repo: lower (e.g. 14) for fast- moving codebases where knowledge ages quickly; higher (e.g. 90) for slow-evolving ones where old playbooks still apply. NEXT (in flight) * v0.5.2: conflict detection at ingest. (Shipped above.) ## v0.5.0: the brain learns from outcomes: citations + blame [#v050-the-brain-learns-from-outcomes-citations--blame] v0.5's north star: make the brain *get smarter over time* from real run data. v0.5.0 ships the foundation (per-memory attribution) that v0.5.1 (decay) and v0.5.2 (conflict detection) build on. The arc is summarized in `docs/HOW-KIMETSU-WORKS.md` sections 4-6; per-release detail is in the entries below. PROBLEM Until v0.4.x the brain's usefulness signal was per-run, all-or- nothing: every memory in a run's `context.injected` event got +1 on `run.finished` or -1 on `run.failed`. A run that succeeded thanks to 1 of 10 retrieved memories rewarded all 10 equally. Noise compounded over time: retrieved-and-ignored memories accumulated the same usefulness score as retrieved-and-pivotal ones. WHAT v0.5.0 ADDS * New tool `cite_memory(memory_id, rationale?)`. The model calls it during a turn when it consciously used a retrieved capsule. Best-effort metadata: forgetting to cite doesn't fail the turn. Multiple citations per turn are fine. * New `memory.cited` event kind. The agent loop accumulates `cite_memory` calls into `recorded_citations` (annotated with the turn index), and the transport surface (chat REPL, harbor binary) emits one `memory.cited` event per citation to the trace at run wrap-up. * New schema: `memory_citations` table linking `(run_id, memory_id, turn)` with `cited_at` + optional `rationale`. Idempotent migration via `CREATE TABLE IF NOT EXISTS`; pre-v0.5.0 brain.db files pick up the table on first open with the new binary. * Projector handler `apply_memory_cited` mirrors each event into the new table. * Usefulness scoring split: cited memories get the strong ±1.0 delta, silent passengers (retrieved-but-not-cited) get the weak ±0.1 delta. Encourages models to actually use `cite_memory` and keeps the strong signal aimed at memories that actually contributed. USER SURFACE: blame * `kimetsu brain memory blame [--json]` CLI: prints cited memories with rationale + turn, then silent passengers with their text previews. JSON output for hooks/CI. * `kimetsu_brain_memory_blame` MCP tool: same backend (`project::blame_run`), JSON-shaped for Claude Code / Codex to consume. Listed in the 16+1 = 17 kimetsu\_\* tools advertised by `tools/list`. NEW BRAIN API * `project::blame_run(start, run_id) -> BlameReport` walks `memory_citations` + `context.injected` events + the terminal run event, looks up each memory's text from project + user brains, returns `BlameReport \{ run_id, outcome, failure_category, cited, silent_passengers \}`. TESTS (3 new in brain, 1 net new since v0.4.11) brain::project::tests:: run\_finished\_increments\_usefulness\_for\_injected\_memories Updated: now emits `memory.cited` so the test demonstrates the strong +1.0 signal path. run\_failed\_decrements\_usefulness\_unless\_gate Updated: same, adds a citation so the failure penalty hits at strong -1.0. run\_finished\_gives\_weak\_signal\_to\_silent\_passenger\_memories (NEW) Asserts: retrieved + uncited memory ends up at +0.1, not +1.0, on run.finished. blame\_run\_separates\_cited\_from\_silent\_passengers (NEW) End-to-end: writes a run with 2 retrieved memories (1 cited, 1 silent), calls blame\_run, asserts the cited one appears under `cited` with rationale + turn, the silent one under `silent_passengers`. VERIFIED cargo test --workspace 227 / 227 passing cargo metadata --no-deps clean at 0.5.0 UPGRADE NOTES * Pre-v0.5.0 chat / harbor runs continue to work; they just won't emit `memory.cited` events, so all their retrieved memories will be treated as silent passengers (±0.1 each). If you want the old "everything in context gets ±1" behavior back, the rule lives in `kimetsu_brain::projector::apply_memory_usefulness_for_run`. * Existing brain.db files don't need migration beyond opening them with the v0.5.0 binary: the `memory_citations` table is created on first open. * `kimetsu brain memory blame` on a pre-v0.5.0 run will typically show 0 cited + all retrieved as silent passengers (since no `memory.cited` events fired). NEXT (shipped) * v0.5.1: usefulness decay. (Shipped above.) * v0.5.2: conflict detection at ingest. (Shipped above.) ## v0.4.11: drop x86\_64-apple-darwin from the release matrix [#v0411-drop-x86_64-apple-darwin-from-the-release-matrix] The v0.4.10 release pipeline got stuck because two GitHub Actions matrix jobs queued indefinitely: ``` build x86_64-apple-darwin (lean) : queued, never started build x86_64-apple-darwin (embeddings) : queued, never started ``` As of late 2026, `macos-13` (Intel) runners are deprecated on the GitHub Actions free tier and queue indefinitely without an SLA. Apple Silicon (`macos-14` and newer, arm64) is the dominant architecture and runs fine. Sitting in the queue for hours blocked the `release` job → blocked the `publish-crates` job → nothing actually shipped. Fix in v0.4.11: * `.github/workflows/release.yml` matrix drops the two `x86_64-apple-darwin` entries. The release matrix now ships 6 archives (down from 8): * x86\_64-unknown-linux-gnu (lean + embeddings) * aarch64-apple-darwin (lean + embeddings) ← Apple Silicon * x86\_64-pc-windows-msvc (lean + embeddings) * Users on Intel Macs can still `cargo install kimetsu-cli` (with or without `--features embeddings`): the source build is target-portable. They just don't get a pre-built binary. * If GitHub re-provisions `macos-13` capacity in the future, we add it back; if x86\_64 mac demand spikes, we can also cross- compile from `macos-14` (arm64 host): a v0.5 follow-up. No code changes. v0.4.9's SecretString + v0.4.10's harbor-rs publish exclusion both carry forward. OPERATOR ACTION Cancel the stuck v0.4.10 workflow run on GitHub Actions (it'll never complete with those queued macOS jobs): gh run cancel \ # or click "Cancel workflow" in the Actions tab UI [#or-click-cancel-workflow-in-the-actions-tab-ui] Then v0.4.11's tag push fires a fresh, clean run. ## v0.4.10: kimetsu-harbor-rs stays out of crates.io [#v0410-kimetsu-harbor-rs-stays-out-of-cratesio] The v0.4.9 publish pipeline included `kimetsu-harbor-rs` in the registry rollout. Reviewing pre-flight, that was wrong: * `kimetsu-cli` (the binary `cargo install kimetsu-cli` produces) does not depend on `kimetsu-harbor-rs`. End users never reach it through the registry path. * Harbor is a Terminal-Bench operator tool, still iterating internally. Publishing implies API stability we don't want to commit to yet. * The `kimetsu-harbor-agent` binary that benchmark operators actually use ships in every GH Release archive built by the matrix job (lean flavor). That stays. Fixes in v0.4.10: * `crates/kimetsu-harbor-rs/Cargo.toml` adds `publish = false`. A manual `cargo publish -p kimetsu-harbor-rs` now refuses outright with a clear error. * `.github/workflows/release.yml` drops the `publish kimetsu-harbor-rs` step. The publish-crates job now walks 5 crates (core → brain → agent → chat → cli), not 6. * Summary block updated: "Published 5 crates" + an explicit note that harbor-rs is intentionally not published. No code changes. No new tests. v0.4.9's SecretString + automated publish work all carries forward. ## v0.4.9: SecretString for provider tokens + automated crates.io publish [#v049-secretstring-for-provider-tokens--automated-cratesio-publish] SECURITY Both `ClaudeCodeProvider` and `AnthropicProvider` previously held `api_key: String` and derived `#[derive(Debug)]`. Any `{:?}` print of either struct (panic backtrace, `dbg!` left in a debug session, `tracing::debug!(?provider)` from a future telemetry pass) would have written the raw OAuth token / API key to stderr or the log sink. v0.4.9 introduces `kimetsu_core::secret::SecretString` whose `Debug` / `Display` / `serde::Serialize` impls all emit `"[REDACTED; len=N]"`. Cleartext is only reachable via `expose_secret()`: every caller is now greppable in code review. Provider fields converted: ClaudeCodeProvider.api\_key: String -> SecretString AnthropicProvider.api\_key: String -> SecretString Cleartext leak points (greppable, intentional): crates/kimetsu-agent/src/claude\_code.rs .env("CLAUDE\_CODE\_OAUTH\_TOKEN", self.api\_key.expose\_secret()) (2 sites) redact\_token(..., self.api\_key.expose\_secret()) (3 sites) crates/kimetsu-agent/src/anthropic.rs .header("x-api-key", self.api\_key.expose\_secret()) (1 site) Regression guards: kimetsu\_core::secret::tests debug\_format\_never\_includes\_inner\_value display\_emits\_redaction\_marker serialize\_emits\_redaction\_marker expose\_secret\_returns\_cleartext parent\_struct\_derive\_debug\_does\_not\_leak kimetsu\_agent::claude\_code::tests::debug\_format\_does\_not\_leak\_api\_key kimetsu\_agent::anthropic::tests::debug\_format\_does\_not\_leak\_api\_key Pre-existing v0.4.5 `kimetsu_brain::redact` already covers the ingest-side leak surface (token strings in memory text); this patch closes the in-memory-struct surface. DISTRIBUTION Per-crate Cargo.toml: every `path = "../kimetsu-X"` now also declares `version = "0.4.9"`. Required for `cargo publish` to resolve cross-crate deps via the registry instead of the local path. .github/workflows/release.yml gains a `publish-crates` job that runs after the binary matrix + GH Release succeed. The job uses `${{ secrets.CARGO_REGISTRY_TOKEN }}` and publishes the six crates in dependency order with a 30-second sleep between each so the crates.io index can propagate: kimetsu-core -> kimetsu-brain -> kimetsu-agent -> kimetsu-harbor-rs -> kimetsu-chat -> kimetsu-cli ONE-TIME SETUP (operator action): gh secret set CARGO\_REGISTRY\_TOKEN \< \<(cat path/to/token) Or via the GitHub UI: Settings -> Secrets -> Actions. The job hard-errors with an actionable message if the secret is missing, so a misconfigured pipeline fails fast. After this tag ships, end-users can: cargo install kimetsu-cli cargo install kimetsu-cli --features embeddings v0.4.7 + v0.4.8 GH Releases exist but were never published to crates.io (the workflow didn't have the publish job). v0.4.9 is the first crates.io-published version. NEXT Smoke-validate with `kimetsu doctor` against a fresh `cargo install kimetsu-cli` to confirm the registry flow works end-to-end. If anything breaks per-platform, cut v0.4.9.1. ## v0.4.8: release-pipeline patch [#v048-release-pipeline-patch] The v0.4.7 release workflow failed across every platform with: ``` error: the package 'kimetsu-cli' does not contain this feature: embeddings help: package with the missing feature: kimetsu-brain ``` Cargo doesn't auto-forward features across workspace dep chains: the `embeddings` feature lived on `kimetsu-brain` but the release matrix called `cargo build -p kimetsu-cli --features embeddings`, which can't propagate down to a dep. v0.4.8 adds a passthrough `embeddings` feature on every crate that depends on `kimetsu-brain`: `kimetsu-cli`, `kimetsu-chat`, `kimetsu-agent`, `kimetsu-harbor-rs`. Each one declares: ```toml [features] default = [] embeddings = ["kimetsu-brain/embeddings"] ``` `kimetsu-cli` in particular fans out to all four downstreams so `cargo install kimetsu-cli --features embeddings` builds the whole tree on the embeddings code path. No behavior change beyond unblocking the release pipeline. The v0.4.7 tag stays in git history but its corresponding GitHub Release was never published (the pipeline failed before upload). ## v0.4.7: distribution path [#v047-distribution-path] * **Per-crate `Cargo.toml` metadata** filled in for crates.io publish: `description`, `repository`, `homepage`, `documentation`, `readme`, `rust-version`, `keywords`, `categories`. Workspace `license` flipped from `UNLICENSED` (which crates.io rejects) to dual `MIT OR Apache-2.0`, matches the Rust ecosystem norm. * **`LICENSE-MIT` + `LICENSE-APACHE`** files added at repo root. * **`.github/workflows/release.yml`** ships tag-driven release pipeline: pushes a `v0.4.x` tag and CI builds release binaries for Linux/macOS/Windows × \{lean, embeddings} flavors, runs `kimetsu doctor --skip-mcp` against each, attaches the archives to the GitHub Release, and pulls release notes from this CHANGELOG. * **`kimetsu doctor` runs as a release gate** before any artifact uploads, so a broken build can never become a published release. ## v0.4.6: `kimetsu doctor` (automated wire-health) [#v046-kimetsu-doctor-automated-wire-health] * New `kimetsu doctor [--json] [--workspace PATH] [--skip-mcp]` CLI subcommand. Runs 8 hermetic checks (workspace, brain, safety, retrieval, mcp, plugin) and reports Pass / Warn / Fail / Skip per check with an actionable next-step on warns. * Live-validated against this repo: 6 pass / 1 warn / 0 fail / 1 skip, proving v0.4.1 (user brain), v0.4.4 (ambient), and v0.4.5 (redact) are all wired correctly end-to-end. * `kimetsu-cli` test count: 2 → 6 (+4 doctor tests). ## v0.4.5: secret redaction at ingest [#v045-secret-redaction-at-ingest] * New `kimetsu_brain::redact` module: `redact_secrets(text) -> RedactionResult` with non-overlapping greedy coverage across **13 secret kinds** (anthropic\_oauth, openai\_api\_key, github\_pat, slack\_token, aws\_access\_key, jwt, private\_key\_pem, google\_api\_key, generic\_bearer, generic\_api\_key, generic\_token, generic\_password). * Wired at every memory write boundary: `project::add_memory`, `user_brain::add_user_memory`, `propose_benchmark_memory`. Redaction is idempotent; double-call is safe. * On a hit, prints a one-liner to stderr (`kimetsu-brain: redacted 1 secret: anthropic_oauth`). Write proceeds with the redacted text; the surrounding context is preserved. * 12 unit tests + 1 end-to-end test proving `sk-ant-...` never reaches brain.db. ## v0.4.4: ambient pre-turn context [#v044-ambient-pre-turn-context] * New `kimetsu_brain::ambient` module: collects git branch, `git status --short` top entries, top-5 mtime-ordered recent files (via the `ignore` crate, `.kimetsu/` filtered). * `render_as_query_suffix(&ctx)` appends a short suffix like `\n[workspace: branch=X | recent: a.rs, b.rs | dirty: M ...]` to the explicit `query` before retrieval, so terse queries ("fix it", "continue") still surface useful capsules. * Wired into `kimetsu brain context [--no-ambient]` CLI and into the MCP `kimetsu_brain_context` + `kimetsu_benchmark_context` tools (per-call `include_ambient` parameter, default true; global kill-switch `KIMETSU_BRAIN_AMBIENT=off`). ## v0.4.3: fastembed-rs backend + `kimetsu brain reindex` [#v043-fastembed-rs-backend--kimetsu-brain-reindex] * `fastembed = "5"` added as an OPTIONAL dependency behind the `embeddings` Cargo feature. Default build stays dep-light; opt in with `cargo install kimetsu-cli --features embeddings`. * Three builtin models selectable via `KIMETSU_BRAIN_EMBEDDER`: `bge-small-en-v1.5` (default, 384 dim), `bge-m3` (1024 dim, multilingual), `jina-v2-base-code` (768 dim, code-tuned). * `open_default_embedder()` returns a cached embedder via process-static `OnceLock`: model loads once per process. * New `kimetsu brain reindex [--scope project|user|all] [--dry-run] [--force] [--limit N]` CLI subcommand backfills NULL embeddings AND rows whose `embedding_model` doesn't match the active embedder. ## v0.4.2: embeddings + hybrid retrieval scaffolding [#v042-embeddings--hybrid-retrieval-scaffolding] * New `kimetsu_brain::embeddings` module: `Embedder` trait, `NoopEmbedder` (production default through v0.4.2), `StubEmbedder` (deterministic test pseudo-embedder), cosine + little-endian f32 BLOB codec helpers. * `memories.embedding BLOB NULLABLE` + `embedding_model TEXT NULLABLE` schema columns. Migrated idempotently via `add_column_if_missing`. * `retrieve_context_with_embedder` blends cosine with FTS as `final = (1 - α) * lex + α * normalized_cos` with `α = 0.5`. Cross-model rows skip the cosine term safely. ## v0.4.1: user-scope brain at `~/.kimetsu/brain.db` [#v041-user-scope-brain-at-kimetsubraindb] * New `kimetsu_brain::user_brain` module. `MemoryScope::GlobalUser` writes now route to `~/.kimetsu/brain.db` (or `$KIMETSU_USER_BRAIN_DIR/brain.db` for tests / power users). * `BrainSession` opens both DBs and merges retrievals across them via the new `retrieve_context_multi` path. Repo memories stay per-project; user memories follow the user between repos. * Kill-switch: `KIMETSU_USER_BRAIN=0` falls back to v0.3.5 behavior. ## v0.3: chat client + bridge plugin + prompt-cache visibility [#v03-chat-client--bridge-plugin--prompt-cache-visibility] The v0.3 line introduced the chat client, the bridge plugin mode (MCP sidecar for Claude Code and Codex), and Anthropic prompt-cache visibility + the persistent claude subprocess that makes cache\_read actually land. v0.3.5 flipped the persistent path to default-on for chat. ## v0.2: Terminal-Bench validation [#v02-terminal-bench-validation] The v0.2 line ran the MP gauntlet from MP-4 through MP-18: broker design + retrieval scoring, the 20-tool surface, auto-orient pre-shell, parallel `tool_calls` envelope, record\_deviation + iterative verify. ## v0.1: initial scaffold [#v01-initial-scaffold] Brain + agent + pipeline foundations. > Per-release planning + ship docs for v0.1 through v0.4 (the MP-\* > gauntlet result notes, the MVP doc, the V0.2 / V0.3 / V0.4 plans, > the V0.5 plan) moved to the internal kimetsu-bench repo in v0.5.4. > They remained in this repo's git history through v0.5.3; check > commits prior to the v0.5.4 tag if you need them. # Code of Conduct (/docs/code-of-conduct) # Contributor Covenant Code of Conduct [#contributor-covenant-code-of-conduct] ## Our Pledge [#our-pledge] We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. ## Our Standards [#our-standards] Examples of behavior that contributes to a positive environment for our community include: * Demonstrating empathy and kindness toward other people * Being respectful of differing opinions, viewpoints, and experiences * Giving and gracefully accepting constructive feedback * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience * Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: * The use of sexualized language or imagery, and sexual attention or advances of any kind * Trolling, insulting or derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or email address, without their explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities [#enforcement-responsibilities] Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. ## Scope [#scope] This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. ## Enforcement [#enforcement] Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at @RodCor. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. ## Enforcement Guidelines [#enforcement-guidelines] Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: ### 1. Correction [#1-correction] **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. ### 2. Warning [#2-warning] **Community Impact**: A violation through a single incident or series of actions. **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. ### 3. Temporary Ban [#3-temporary-ban] **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. ### 4. Permanent Ban [#4-permanent-ban] **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within the community. ## Attribution [#attribution] This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at [https://www.contributor-covenant.org/version/2/0/code\_of\_conduct.html](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html). Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq). Translations are available at [https://www.contributor-covenant.org/translations](https://www.contributor-covenant.org/translations). # Contributing (/docs/contributing) # Contributing to kimetsu [#contributing-to-kimetsu] Thanks for helping improve kimetsu. This repo keeps a clean, secure `main` and `develop` through automated checks at two points: locally on every commit, and in CI on every pull request. ## Branches [#branches] * **`main`**: released, stable. Protected; changes land via PR. * **`develop`**: integration branch for in-flight work. Branch your feature work off `develop` and open PRs back into it. * Release tags (`vX.Y.Z`) are cut from `main` and drive the publish pipeline (`.github/workflows/release.yml`). ``` feature/your-thing -> develop -> main -> tag vX.Y.Z ``` ## One-time setup [#one-time-setup] Enable the pre-commit hook after cloning: ```bash ./scripts/install-hooks.sh # sets core.hooksPath -> .githooks ``` The hook enforces `cargo fmt --all --check` (blocking) and runs `cargo clippy --workspace` in advisory mode (prints findings, does not block) on staged Rust changes. Escape hatches when you need them: * `SKIP_CLIPPY=1 git commit …`: formatting only (faster). * `git commit --no-verify …`: skip the hook (discouraged; CI will still catch issues). ## The checks [#the-checks] Both the local hook and CI enforce the same quality bar so a green local commit means a green PR. | Check | Local (pre-commit) | CI (PR + push to main/develop) | Blocking? | | ---------------------------------- | :----------------: | :----------------------------: | :--------: | | `cargo fmt --all --check` | ✅ | ✅ | yes | | `cargo clippy --workspace` | ✅ (advisory) | ✅ | advisory\* | | `cargo test --workspace` | n/a | ✅ (ubuntu + macOS) | yes | | `cargo-audit` (RUSTSEC advisories) | n/a | ✅ | yes | | `cargo-deny` (licenses + bans) | n/a | ✅ | advisory\* | \* clippy and cargo-deny run on every PR but do not block merges yet (`continue-on-error` in `ci.yml`). main carries a small pre-existing clippy backlog; once it's cleared in a dedicated cleanup PR, flip these to hard gates (clippy: add `-D warnings`; deny: remove `continue-on-error`). Run the full suite locally before opening a PR: ```bash cargo fmt --all --check cargo clippy --workspace --all-targets # advisory; aim to keep it quiet cargo test --workspace cargo deny check # optional: cargo install cargo-deny ``` The semantic flavor is a separate build and CI gates on it, so run it too before opening a PR — a `#[cfg(feature = "embeddings")]` block cannot be compiled by any lean build, and defects there survive a fully green lean run: ```bash cargo clippy --workspace --all-targets --features embeddings -- -D warnings cargo test --workspace --features embeddings -j 4 -- --test-threads=1 ``` `-j 4` is not decoration. On a 16-core / 32 GB machine the default job count exhausts the page file linking the test binaries, and the failure arrives as `os error 1455` ("the paging file is too small") or as `STATUS_STACK_BUFFER_OVERRUN` inside `rustc` — which reads like a compiler bug and is not one. ## Pull requests [#pull-requests] * Target `develop` for features/fixes; target `main` only for releases or hotfixes. * Keep PRs focused; describe what changed and why. * All required CI checks must pass before merge. * Don't commit secrets. The brain redacts known token shapes, but treat `.env`, credentials, and API keys as never-commit. ## Security [#security] * Dependency vulnerabilities are caught by the `cargo-audit` CI job (RUSTSEC database). If it flags an advisory, bump or replace the affected crate before merging. * Report security issues privately rather than in a public issue. # Introduction (/docs)
Kimetsu logo # Kimetsu [#kimetsu] ### Give your coding agent a memory that gets sharper every run. [#give-your-coding-agent-a-memory-that-gets-sharper-every-run] *Kimetsu* (鬼滅), "demon slayer." It slays the demon every agent fights: amnesia. [![crates.io](https://img.shields.io/badge/crates.io-kimetsu--cli-orange)](https://crates.io/crates/kimetsu-cli) [![license](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue)](#license) [![rust](https://img.shields.io/badge/rust-1.85%2B-informational)](https://www.rust-lang.org) Kimetsu demo: one-command setup, selftest, record a lesson, retrieve it by meaning
*** ## What is Kimetsu [#what-is-kimetsu] Coding agents are brilliant and forgetful. Every session starts from zero: the same wrong turns, the same re-explained conventions, the same exploration you already paid for last week. Kimetsu is a sidecar brain for your agent. One Rust binary and one SQLite file per project, wired into Claude Code, Codex, Pi, OpenClaw, or Cursor over MCP, or driven from its own terminal chat. It captures the lessons an agent earns, learns which ones actually help, and hands them back before the next task. The memory pipeline calls no LLM: storage and retrieval are 100% local, free, and offline-capable. | | | | --------: | ---------------------------------------------------------------------------------- | | **89.4%** | LoCoMo, the long-conversation memory benchmark, full 1,540-question set | | **73.3%** | BEAM 100K memory benchmark, matching the prior public state of the art, model-free | | **66.0%** | BEAM 1M, ahead of mem0's self-reported 62% at the same bucket | | **83.0%** | LongMemEval, the public long-term-memory benchmark | | **13x** | cheaper per solved task: $0.19 vs $2.47 on a 16-task Terminal-Bench slice | | **\~1M** | memories held in \~3 GB RAM with sub-2s retrieval, one SQLite file | | **$0** | API cost to store and recall: zero LLM calls in the memory pipeline | *** ## Quickstart [#quickstart] ```bash npm install -g kimetsu-ai kimetsu npm-flavor embeddings # one-time: enable semantic retrieval cd /your/project kimetsu setup --host claude-code # or: codex | openclaw | pi kimetsu doctor --selftest # records a memory and retrieves it ``` Other install paths (cargo, prebuilt archives) and host-wiring details are in **[the install guide](/docs/install)**. *** ## What it does [#what-it-does] * **Remembers what matters.** Project conventions, failure patterns, the exact command that regenerates your schema. Captured once, retrieved by meaning, even when you phrase it differently. * **Speaks first.** Most memory waits to be asked. Kimetsu is proactive: a session-start digest, an episodic resume, and pre-task context mean the agent's first turn already knows the repo, your conventions, and what you were doing last time. * **Learns what helps.** Memories the model cites before solving a problem get promoted. Stale advice and silent passengers decay and get pruned. * **Answers, not just injects.** `kimetsu ask` composes a grounded, cited answer from memory using a local model: zero frontier tokens, works offline. Lessons cited often enough graduate into runnable skills. * **Pays for itself.** \~13x cheaper per solved task than a no-brain baseline on a recorded Terminal-Bench slice, and the ROI ledger shows the savings on your own work. * **Stays yours.** The whole brain is one SQLite file per project. No external vector DB, no cloud, no telemetry. Back it up with `cp`. *** ## How it works [#how-it-works] How Kimetsu works: the host agent asks the broker for context, the broker scores candidates from brain.db by relevance, usefulness, freshness, and scope, injects the top memories into the agent run, and the run cites what helped so cited memories rise and stale ones decay 1. **Before a task**, the broker walks your project brain and your cross-project user brain, scores every candidate, and injects the top few inside an adaptive token budget. 2. **While it works**, Kimetsu surfaces known pitfalls before the first attempt, and the model cites the memories that actually help. 3. **After the task**, cited memories get promoted, unused advice decays on a half-life curve, and non-trivial sessions auto-harvest their lessons. Full mechanics: scoring, citations, decay, conflict detection, retrieval levels, and the daemon, in **[How Kimetsu Works](/docs/how-kimetsu-works)**. *** ## Share your brain [#share-your-brain] A brain is a portable file. Export it as a pack, hand it to a teammate, merge theirs into yours, or swap a whole brain in and out. Onboard a new machine or a new hire with one import. ```bash # export a shareable pack (always gzip-compressed, always security-scrubbed) kimetsu brain export onboarding.json.gz --name rust-conventions --version 1.0.0 # merge a pack into your brain (additive, dedups against what you already know) kimetsu brain import onboarding.json.gz # install straight from a URL kimetsu brain import https://example.com/packs/rust-conventions.json.gz # swap: replace your current memories in the pack's scope (reversible) kimetsu brain import other-brain.json.gz --mode replace --yes ``` Every export is scrubbed before it leaves your machine: credentials and PII are redacted automatically, and `--strict` aborts the export if anything was found. Merge is idempotent, so re-importing is safe. Replace supersedes rather than deletes, so a swap can always be undone. For continuous sharing, `kimetsu brain sync` replicates a brain across machines with no server, and **[Kimetsu Remote](/docs/remote)** serves one brain per repository to a whole team. *** ## Benchmarks vs other memory systems [#benchmarks-vs-other-memory-systems] Kimetsu's memory pipeline (ingest, store, retrieve, rerank) makes **zero LLM calls**: FTS5 + local embeddings + a local cross-encoder. mem0 / Cognee / Zep / Letta call a model to distill memories at write time **and** keep an LLM in the retrieval loop (mem0's own 2026 figures report \~7,000 tokens per retrieval call, a metered cost on every question). Kimetsu lands in the same accuracy band without the LLM, the bill, or the cloud. | benchmark | Kimetsu (local, model-free) | mem0 | Cognee | | ---------------------------- | ------------------------------------ | ------------------------------ | ------------ | | **BEAM 1M** (matched bucket) | **66.0%** | 62% | not reported | | BEAM 100K | **73.3%** | n/a | 79% | | BEAM 10M | future work | 48.6% | 67% | | LongMemEval (`_s`) | **83.0%** (200-q) · \~80.9% weighted | 94.4% (full set, their reader) | not reported | Honest, not cherry-picked: our LongMemEval is a 200-question slice (not the full 500), our BEAM-1M is 15 of 35 conversations with a Codex reader vs mem0's full set on their own harness, Cognee (a knowledge-graph system with an LLM in the loop) leads at 100K/10M, and vendor numbers are self-reported. We ship the exact harness, reader, and settings so ours can be checked. Per-ability tables, caveats, and reproduction steps: **[the memory benchmark](/docs/memory-benchmark)**. Retrieval itself is benchmarked too: recall\@4 0.949 and MRR 0.914 at \~138 ms with the default reranker (up to 0.975 / 0.933 with the quality-best one), on a 210-case dataset of real exported memories. Reproduce or re-tune on your own corpus with `kimetsu brain bench`. *** ## Command reference [#command-reference] | Command | What it does | | --------------------------------------- | ------------------------------------------------------------ | | `kimetsu setup --host ` | Wire the brain into a host agent (init + install + selftest) | | `kimetsu chat` | Standalone terminal coding assistant with the same brain | | `kimetsu brain memory add` | Record a durable lesson by hand | | `kimetsu brain context ""` | Broker-ranked context bundle for a query | | `kimetsu ask ""` | Grounded, cited answer from memory (local model) | | `kimetsu resume` / `kimetsu checkpoint` | Pick up where the last session left off | | `kimetsu brain export` / `import` | Share brains: scrubbed packs, merge or replace, file or URL | | `kimetsu brain sync` | Replicate your brain across machines, no server | | `kimetsu brain skills` | Turn often-cited lessons into runnable skills | | `kimetsu brain insights` / `roi` | Is the brain helping, and did it pay for itself | | `kimetsu brain tune` | Self-tune retrieval against your own query history | | `kimetsu brain bench` | Benchmark retrieval on your own corpus | The full command surface, configuration keys, and maintenance commands are in **[How Kimetsu Works](/docs/how-kimetsu-works)** and **[the install guide](/docs/install)**. *** ## Kimetsu Remote (beta) [#kimetsu-remote-beta] Share one brain per repository from a server over HTTP MCP, for a team or for yourself across machines: ```bash # server kimetsu-remote serve --addr 0.0.0.0:8787 --data /srv/kimetsu-brains --token # each client kimetsu plugin install claude-code --remote https://kimetsu.example.com:8787 ``` Bearer auth, per-repo brains, an optional shared org-brain, server-side repo ingest, TLS, Prometheus metrics, and a server-side reranker. Full setup in **[the Kimetsu Remote guide](/docs/remote)**. *** ## Docs [#docs] * **[Install & host wiring](/docs/install)**: every install path, host wiring, auto-harvest and distiller setup, maintenance commands. * **[How Kimetsu Works](/docs/how-kimetsu-works)**: the brain, the broker, citations, decay, conflict detection, the MCP surface, retrieval models and benchmarking, configuration, the bridge, and doctor. * **[Local models](/docs/local-models)**: run fully local with Ollama. * **[Kimetsu Remote](/docs/remote)**: server setup, org brain, TLS, clients. * **[CHANGELOG](/docs/changelog)**: what shipped in each release. *** ## License [#license] Dual-licensed under [MIT](https://github.com/RodCor/kimetsu/blob/main/docs/LICENSE-MIT) or [Apache-2.0](https://github.com/RodCor/kimetsu/blob/main/docs/LICENSE-APACHE), your choice. # Install & Host Wiring (/docs/install) # Installing Kimetsu [#installing-kimetsu] Kimetsu is a single Rust binary. There's really only one choice to make at install time, **lean vs semantic (embeddings)**, because that's the only part baked into the binary. *Which host agents you use* (Claude Code, Codex, Pi, OpenClaw) is a **runtime** choice you change anytime with `kimetsu plugin install`/`uninstall`, with no reinstall. The official prebuilt + npm binaries include all six host integrations; a bare source `cargo install` is minimal and adds them with `--features pi,openclaw`. ## cargo [#cargo] ```bash # Default lean build: fast lexical (FTS) retrieval, no model download cargo install kimetsu-cli # Semantic build: fastembed + ONNX; first run downloads the embedding model cargo install kimetsu-cli --features embeddings # Add the Pi + OpenClaw host integrations to a source build (prebuilts already have them) cargo install kimetsu-cli --features pi,openclaw # Everything: cargo install kimetsu-cli --features embeddings,pi,openclaw # From source cargo install --path crates/kimetsu-cli # add --features embeddings,pi,openclaw for full build ``` ## npm [#npm] Installs the prebuilt binary for your platform, no Rust required: ```bash npm install -g kimetsu-ai # lean build (all host integrations included) kimetsu npm-flavor embeddings # one-time: switch to the semantic build (it persists) ``` npm pulls only the matching per-platform package (`@kimetsu-ai/*`) via optionalDependencies, so there's no postinstall download, and it works under `npm install --ignore-scripts`. **`kimetsu npm-flavor embeddings`** fetches the semantic build once and remembers the choice (no env var to keep exported); `kimetsu npm-flavor lean` switches back, and `kimetsu npm-flavor status` shows the current one. (The `KIMETSU_NPM_FLAVOR` env var still works as a per-run override.) The embeddings build is available where ONNX Runtime prebuilts exist (Linux x64, macOS Apple Silicon, Windows x64); elsewhere it stays lean. See [`npm/`](https://github.com/RodCor/kimetsu/tree/main/npm) for details. ## Pre-built archives [#pre-built-archives] For **Linux / macOS / Windows** on every [GitHub Release](https://github.com/RodCor/kimetsu/releases). Extract the archive and put `kimetsu` / `kimetsu.exe` somewhere on `PATH` (`~/.local/bin`, `/usr/local/bin`, or `%USERPROFILE%\.cargo\bin`). Every prebuilt archive, lean and embeddings, bundles all six host integrations, so switching hosts never needs a reinstall. Lean archives are published for Linux, macOS Intel, macOS Apple Silicon, and Windows. Embeddings archives are published where ONNX Runtime prebuilts are available: Linux x86\_64, macOS Apple Silicon, and Windows x86\_64. ## Health check, updates, uninstall [#health-check-updates-uninstall] ```bash kimetsu --version kimetsu doctor # checks paths, brain.db, embedder, MCP, bridge kimetsu update --check kimetsu update # updates discovered kimetsu binaries on PATH/current install kimetsu uninstall --dry-run kimetsu uninstall --yes # removes discovered kimetsu binaries ``` `kimetsu update` downloads the matching GitHub Release archive for your platform and flavor, then updates the current executable plus verified `kimetsu` copies in known install locations such as Cargo bin, `~/.local/bin`, `/usr/local/bin`, or `%USERPROFILE%\.cargo\bin`. It does not scan the whole disk. `kimetsu uninstall` removes those same verified binaries; it leaves project `.kimetsu/` directories and the user brain intact unless you explicitly pass `--delete-user-data`. **Prerequisites:** Rust 1.85+ (stable, source builds only) and a model credential for the surface you use (`CLAUDE_CODE_OAUTH_TOKEN`, `ANTHROPIC_API_KEY`, or `OPENAI_API_KEY`). On AWS Bedrock, set `[model] provider = "bedrock"` and authenticate with `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` (+ optional `AWS_SESSION_TOKEN`) and `AWS_REGION`: the agent and the auto-harvester both support it, and can be pointed at different providers. That's it for chat; Docker, Harbor, and Python are only needed for benchmark runs. ## Wiring host agents [#wiring-host-agents] Wire Kimetsu into any supported host. The built-in installers cover Claude Code, Codex, Pi, OpenClaw, and Cursor: ```bash kimetsu plugin install claude --workspace . # writes .mcp.json + .claude/settings.json kimetsu plugin install codex --workspace . # writes .codex/config.toml + .codex/hooks.json + skill + agent kimetsu plugin install openclaw --workspace . # MCP server + hooks plugin + skill in .openclaw/ (requires --features openclaw on source builds) kimetsu plugin install pi --workspace . # TS extension (Pi has no MCP) + skill in .pi/ (requires --features pi on source builds) kimetsu plugin install cursor --workspace . # writes .cursor/mcp.json + .cursor/rules/kimetsu-brain/rule.md # Install globally for every project (writes to the host's home config dir): kimetsu plugin install claude --scope global # See what's wired where, or remove just the wiring (keeps the binary + brain): kimetsu plugin status kimetsu plugin uninstall codex --yes # Or do init + install + selftest in one shot: kimetsu setup --host claude-code # Switched editors? Move your wiring, no reinstall (prebuilt/npm binaries # include every host; on a source build add `--features pi`): kimetsu plugin uninstall claude-code --yes # drop the old host's wiring kimetsu plugin install pi # wire the new one ``` **Cursor:** this host has no `UserPromptSubmit`-style hook system, so MCP + an always-on guidance file are the complete integration surface (no automatic prompt-time context injection; the model must call `kimetsu_brain_context` manually). The config schema for Cursor (`.cursor/mcp.json`) matches the host's current official MCP documentation (re-verified June 2026): Cursor uses `mcpServers` with `type: "stdio"`, `command`, and `args`. The installer merges non-destructively, so any existing servers are preserved. `--scope` defaults to `workspace`. The installer **merges** into existing config: if you already have hooks (even on the same events Kimetsu uses: `UserPromptSubmit`, `PreToolUse`, …), your hooks are kept and Kimetsu's are added alongside them. Re-running is idempotent and never needs `--force`. Now your host agent gets the `kimetsu_*` MCP tools (brain context, memory add/list, citations, repo ingest, the cross-harness skill bridge) and starts banking memories across every session. ## Auto-harvest and the SessionEnd distiller [#auto-harvest-and-the-sessionend-distiller] Memories get **auto-harvested**: when you fix a command that was failing, or finish a non-trivial session without recording anything, a Kimetsu hook cues the agent to dispatch a background `kimetsu-memory-harvester` subagent (a cheap in-agent distiller) that records the lesson for next time, with no extra API key. Turn it off with `[learning] auto_harvest = false` in `.kimetsu/project.toml`. For a deterministic harvest that doesn't depend on the agent, `kimetsu plugin install claude-code` and `kimetsu plugin install codex` offer to set up a **SessionEnd distiller**: a cheap configured model (Anthropic `claude-haiku-4-5`, OpenAI `gpt-5.4-mini`, or a compatible endpoint via `ANTHROPIC_BASE_URL` / `OPENAI_BASE_URL`) that distills each session itself at the end and records the lessons. Claude Code runs it from `SessionEnd`; Codex runs it from the supported `Stop` hook with `--distill-on-stop`. The wizard stores the key in a gitignored `.env`; skip it with `--no-setup`. Run it with `--scope global` to configure the distiller once in `~/.kimetsu/`: it then distills every project's sessions into your user brain (available everywhere), unless that project has its own distiller. ## Retrieval levels [#retrieval-levels] Kimetsu ships a single retrieval knob so you do not have to tune the embedder, reranker, and query expansion by hand. Pick a `level` and the pipeline is configured for you; override it later if you want. Swapping levels is a one-line change in `.kimetsu/project.toml`: ```toml [retrieval] level = "deep" # basic | flexible | deep | advanced | custom ``` | Level | What it does | What it needs | When to use | | ----------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- | | `basic` | Lexical (FTS) retrieval only. No semantic embeddings, no reranking. | No model and no downloads. | Fastest setup, air-gapped or tiny machines, or when you only want keyword recall. | | `flexible` | Semantic retrieval, no reranking. | The embedding model (downloaded on first run). | You want semantic recall but want to skip the rerank stage. | | `deep` | Semantic retrieval plus a cross-encoder reranker. Recommended default. | The embedding model plus the reranker model. Works locally and remote. | The best balance of quality and cost. This is what new projects ship on. | | `advanced` (Beta) | Everything in `deep` plus HyDE query expansion. | A capable cheap model. A small 3B local model will not help here: use OpenAI or Anthropic, or a larger Ollama model such as `qwen2.5:14b`. | Hard or sparse queries where a hypothetical answer improves recall. | | `custom` | Uses your individual `[embedder]` settings for manual control. | Whatever you configure. | You want to tune `embedder.enabled` and `embedder.reranker` yourself. | The level resolves into `[embedder]` at config-load time, so every retrieval consumer sees the same resolved settings. New projects from `kimetsu init` ship on `deep`. Existing `project.toml` files that have no `[retrieval]` section default to `custom`, so they keep using their `[embedder]` values exactly as before. For `advanced`, set a cheap model under `[cheap_model]`; without one, HyDE falls back to the raw query and prints a one-line note. ## Configuration toggles [#configuration-toggles] Every optional feature is turn-off-able in `.kimetsu/project.toml`: embeddings (`[embedder] enabled`), ambient workspace context (`[broker] ambient`), the global user brain (`[kimetsu] use_user_brain`), auto-harvest, the distiller, secret redaction. The precedence is **env override > config > default**, and `kimetsu config edit` opens the file in `$EDITOR` and re-validates on save. Re-installing merges, so your toggles survive. ## Maintenance & lifecycle [#maintenance--lifecycle] ```bash kimetsu config set embedder.enabled false # flip any toggle (config get reads one) kimetsu brain export mem.json # move memories between brains (import reads them) kimetsu brain memory edit --text "…" # fix a recording in place (undo retires the last one) kimetsu runs prune --older-than 30d # drop old run dirs; brain compact VACUUMs brain.db kimetsu ps # see running MCP servers; stop clears a stale one kimetsu uninstall # tiered: binary / + plugin wiring / + brains ``` `.kimetsu/` stays lean: just `brain.db` + `project.toml`; transient proactive/chat/bench output lives under `~/.kimetsu/cache/`. For retrieval model selection (embedder/reranker swapping, benchmarking your own corpus), see [Retrieval models & benchmarking in HOW-KIMETSU-WORKS](/docs/how-kimetsu-works). # Local Models (/docs/local-models) # Fully-local Kimetsu: zero external network calls [#fully-local-kimetsu-zero-external-network-calls] Kimetsu can run entirely on-device: no cloud embedder, no cloud reranker, no cloud distiller. This guide shows how to achieve that with Ollama as the cheap-model backend. ## What "fully local" means [#what-fully-local-means] | Component | Cloud default | Local alternative | | ----------------------------------- | --------------------------------------------- | --------------------------------- | | Embedder | `jina-v2-base-code` (fastembed, local binary) | same (already local) | | Reranker | `ms-marco-tinybert-l-2-v2` (fastembed, local) | same (already local) | | Cheap model (distiller / harvester) | Anthropic / OpenAI API | **Ollama** (runs on your machine) | When all three are local, no bytes leave your machine during normal operation (brain context injection, session-end distillation, consolidation distillation). ## Requirements [#requirements] * **Ollama** installed and running: [https://ollama.com](https://ollama.com). Start the server with `ollama serve`. * A small instruct model pulled locally. Recommended options: * `ollama pull qwen2.5:3b` (\~2 GB, fast, excellent instruction following) * `ollama pull llama3.2:3b` (\~2 GB, strong general reasoning) * `ollama pull qwen2.5:7b` for higher quality at \~4 GB The embedder and reranker are already local (fastembed bundles them); no additional setup is needed for those. ## Configuration [#configuration] ### Option A: new install (wizard) [#option-a-new-install-wizard] ``` kimetsu plugin install claude # or codex ``` When asked "Which model should run the harvester?", enter `ollama`. The wizard will ask for an optional base URL (leave blank for the default `http://localhost:11434/v1`) and set the model to `qwen2.5:3b`. ### Option B: edit `project.toml` manually [#option-b-edit-projecttoml-manually] Add a `[cheap_model]` section to your `.kimetsu/project.toml`: ```toml [cheap_model] enabled = true provider = "ollama" # Recommended small instruct models: qwen2.5:3b, llama3.2:3b model = "qwen2.5:3b" # Optional: override the endpoint via env var (default: http://localhost:11434/v1) base_url_env = "OLLAMA_BASE_URL" # Optional: only needed for authenticated / remote Ollama deployments api_key_env = "OLLAMA_API_KEY" ``` No API key is required for a standard local Ollama install. Leave the env var unset or empty. ### Back-compat: existing `[learning.distiller]` configs [#back-compat-existing-learningdistiller-configs] If you already have `[learning.distiller]` configured in your project, it continues to work unchanged: `[cheap_model]` and `[learning.distiller]` are equivalent; the former takes precedence when both are present. ## Verifying the setup [#verifying-the-setup] ``` kimetsu doctor ``` When the cheap model is configured with `provider = "ollama"`, doctor probes the endpoint and reports `reachable` or `unreachable` (informational; does not fail doctor if Ollama is not currently running). ## How it works [#how-it-works] Ollama exposes an OpenAI-compatible REST API at `http://localhost:11434/v1`. Kimetsu's cheap-model client reuses the existing OpenAI provider path: the `ollama` provider value simply sets the base URL to `http://localhost:11434/v1` (or the `OLLAMA_BASE_URL` env-var override) and makes the API key optional. At session end (the `SessionEnd` / Codex `Stop` hook), the configured cheap model reads a bounded transcript view (≤12 000 characters), extracts 0-3 durable lessons, and records them via the confidence-gated brain API. With Ollama this call is entirely local. ## Quality and latency expectations [#quality-and-latency-expectations] Kimetsu's distillation prompt is simple (structured JSON extraction), so a 3B instruct model is sufficient for most users. Expect: * **Latency**: 3-10 seconds per session end on a modern machine (CPU or GPU). * **Quality**: comparable to cloud Haiku for straightforward lesson extraction; may miss subtle anti-patterns on complex sessions. Use `kimetsu brain bench` or `kimetsu brain eval` to measure retrieval quality on your own corpus. ## TODO (future work) [#todo-future-work] * `kimetsu ask` latency/quality benchmark with local vs. cloud cheap models (deferred to Flagship 3; `kimetsu ask` does not exist yet). * Automatic Ollama model-presence check in `kimetsu doctor` (currently doctor only probes TCP reachability, not whether the specific model is pulled). # Kimetsu Remote (/docs/remote) # Kimetsu Remote (beta) [#kimetsu-remote-beta] Run the brain on a server and connect over **HTTP MCP**, so a team (or you across machines) shares one brain per repository, with no local checkout. > **Beta.** Kimetsu Remote is under active testing and may have rough edges or > breaking changes before the stable release. The `kimetsu-remote` **server is a > separate package**: `cargo install kimetsu-cli` / `npm i -g kimetsu-ai` do > **not** install it. Install it on the server when you want it: > > ```bash > npm install -g kimetsu-remote # prebuilt server binary > cargo install kimetsu-remote --features embeddings # or from source > ``` > > (or grab the standalone `kimetsu-remote` archive from a GitHub Release). The > `kimetsu plugin install --remote` *client* wiring is part of the normal > `kimetsu` binary, so no separate install is needed to point a host at a server. ## Server + client setup [#server--client-setup] ```bash # On the server (build with --features embeddings for semantic retrieval): kimetsu-remote serve --addr 0.0.0.0:8787 --data /srv/kimetsu-brains \ --token --rate-limit 120 # 120 req/min per token (0 = off) # one brain per repo under //; bearer-auth; plain HTTP. Put a # TLS proxy (nginx/Caddy) in front, or build `--features tls` and pass # --tls-cert/--tls-key for in-process HTTPS. `GET /healthz` and `GET /metrics` # (Prometheus text, aggregate-only) are unauthenticated. Prebuilt # kimetsu-remote binaries are built with embeddings + TLS support. # # Add --org-brain /srv/kimetsu-org for a shared team brain: memories recorded # at `global_user` scope land there and merge into EVERY repo's retrieval # (project-scoped memories stay per-repo). Must be outside --data. # # Add --repos-file repos.toml --checkout-dir /srv/checkouts to let the server # clone registered repos and ingest their files (remote file-capsule retrieval). # On each client, wire a host at the remote instead of the local stdio command: kimetsu plugin install claude-code --remote https://kimetsu.example.com:8787 kimetsu plugin install openclaw --remote https://kimetsu.example.com:8787 ``` The repo id is derived from your git remote (`--repo ` to override), so the endpoint becomes `https://…/mcp/`. By default the host config references `${KIMETSU_REMOTE_TOKEN}` (set that env var where your agent runs) rather than writing the token to disk. Pass `--token ` to embed a literal. The remote surfaces the memory/retrieval/curation tools by default. ## Team writes and attribution [#team-writes-and-attribution] Give each teammate their own bearer token (`--token` is repeatable, or use `--tokens-file` for a TOML of global and per-repo tokens). Writes are attributed to the token that made them, so `memory blame` on a shared brain answers who recorded what. Rate limiting is per token. You can also write to the shared brain from the CLI without wiring a host: ```bash kimetsu brain memory add "prefer sqlx over diesel here" \ --remote https://kimetsu.example.com:8787 --repo my-org/my-repo ``` Concurrent writers are safe: the event log gives every write a stable order, conflicting facts are detected and resolved the same way as locally, and surviving conflicts are surfaced for review rather than silently dropped. ## Retrieval quality [#retrieval-quality] The server reranks `kimetsu_brain_context` results with a cross-encoder (`--reranker`, default `jina-reranker-v1-tiny-en`, operator-level: `"off"` disables, any curated/HF id accepted). Benchmark results on the 100-memory dataset (production floors active, jina-tiny reranker): | embedder | MRR | seq mean | rps | peak RSS | | ----------------- | ----- | -------- | --- | -------- | | jina-v2-base-code | 0.906 | 416ms | 5.0 | 1.2 GB | | bge-small-en-v1.5 | 0.909 | 700ms | 3.8 | 697 MB | The embedder is set per-repo via config or `KIMETSU_BRAIN_EMBEDDER`; the reranker is operator-owned and cannot be overridden by a repo's `project.toml`. See §7a "Retrieval models on the server" in [HOW-KIMETSU-WORKS.md](/docs/how-kimetsu-works) for the full table and how to re-run the benchmark. ## Server-side ingest (optional) [#server-side-ingest-optional] To make file-capsule retrieval work remotely, let the server keep a managed clone of each repo. The operator pre-registers repos in a TOML file (so clients can't make the server clone arbitrary URLs): ```toml # repos.toml [repos] github-com-org-api = { url = "https://github.com/org/api.git", branch = "main" } github-com-org-web = "https://github.com/org/web.git" ``` ```bash kimetsu-remote serve --data /srv/kimetsu-brains --token \ --repos-file /etc/kimetsu/repos.toml --checkout-dir /srv/kimetsu-checkouts ``` Then `kimetsu_brain_ingest_repo` clones/refreshes the registered repo and indexes its files into that repo's brain, so `context` retrieval includes file capsules. Private repos use the server's own git auth (credential helper / SSH / a token in the URL). The repo-id keys must match the ids clients connect with. For the architecture (auth, rate limiting, org brain, the tool allowlist, the write-tools gate), see §7a in [HOW-KIMETSU-WORKS.md](/docs/how-kimetsu-works). # Kimetsu Algorithm (/docs/roi-methodology) # Kimetsu Algorithm [#kimetsu-algorithm] How Kimetsu turns memory into measurable savings: every cited memory is credited with the tokens it saved, every injection is charged for the tokens it cost, and `kimetsu brain roi` reports the net. This page documents the exact accounting so the ledger can be audited rather than trusted. > **Source of truth for the per-kind constants:** > `crates/kimetsu-brain/src/roi.rs`, `SAVED_TOKENS_PER_CITATION` *** ## Formula [#formula] ``` estimated_saved_tokens = Σ (citations_of_kind × saved_tokens_per_kind) net_tokens = estimated_saved_tokens − injected_tokens net_usd = net_tokens / 1_000_000 × price_per_mtok ``` * **`citations`**: rows in `memory_citations` for the selected window (attributed to runs via `runs.started_at` or to the hook sentinel via `memory_citations.cited_at`). * **`injected_tokens`**: sum of the `used_tokens` field across `context.injected` events in the window. This is the actual token cost the brain added to each prompt: the "spent" side of the ledger. * **`price_per_mtok`**: resolved from `[model] price_per_mtok` in `project.toml` (user override), falling back to the built-in approximate table in `roi.rs`. Unknown models produce `usd: null` in the JSON output rather than a potentially-wrong number. *** ## Per-kind constants [#per-kind-constants] | Kind | Saved tokens / citation | Reasoning | | ----------------- | ----------------------: | ----------------------------------------------------------------------------------------------- | | `failure_pattern` | 1 500 | Avoids the "try → fail → diagnose → fix" loop. Estimated at \~3 tool calls × \~500 tokens/call. | | `fact` | 500 | Avoids a docs lookup or user question. \~1 exchange. | | `command` | 400 | Avoids a `--help` trial or web search. \~1-2 tool calls. | | `convention` | 300 | Avoids a code-search to find the project pattern. \~1-2 searches. | | `preference` | 200 | Avoids one clarifying question. \~1 exchange. | **These are deliberate under-estimates.** The goal is for every "net positive" result to be *credible*, not just flattering. A user who sees a positive number should be able to believe it. *** ## Why under-claiming is deliberate [#why-under-claiming-is-deliberate] Kimetsu's ROI story is built on honesty: 1. **Net CAN be negative**, and is shown as such. If the brain injected more tokens than it saved (e.g. every retrieved memory was a silent passenger), the ledger says so. 2. **Constants are calibrated low**: the actual avoided cost of re-discovering a `failure_pattern` is often much higher (the model might run the same broken command five times before giving up). We use a conservative floor. 3. **Citations are sparse in MCP hosts**: Claude Code currently has no `kimetsu_brain_cite` tool, so the `memory_citations` table is populated only when the pipeline (`run coding`) is in use. The ledger will under-count savings in pure MCP-host sessions until the cite tool ships. That's fine: under-counting keeps the results trustworthy. *** ## Sanity anchor: Terminal-Bench calibration evidence [#sanity-anchor-terminal-bench-calibration-evidence] The 16-task slice recorded in internal bench runs shows: | Condition | Cost/win | | --------------------- | -------: | | Without brain context | $2.47 | | With brain context | $0.19 | This \~13× difference is the *observed* cost difference, not a model. > **v2.6.0 re-measurement did not reproduce this.** A 12-task slice stratified > across all nine families of `prog-families-v1`, run on Claude Opus 5 (24 > trials, no grading or quota errors), came out: > > | | wins | cost | cost/win | input tokens | > | ----------- | ---- | ------ | ---------- | ------------ | > | `claude+km` | 8/12 | $82.19 | **$10.27** | 13.9M | > | `claude` | 9/12 | $67.32 | **$7.48** | 11.4M | > > Read this carefully in both directions. The **win-rate** difference is one > task and is not a result: the discordant pairs are 1 vs 2, a single flip > reverses the ranking, and a repeat of `cancel-async-tasks` in this same > session scored differently between runs. "No detectable difference in win > rate" is what n=12 supports — not that Kimetsu is worse. > > The **cost** difference is more solid, because token counts are measured > rather than sampled: Kimetsu used 22% more total tokens and 37% more per win. > That direction is the opposite of the table above. > > Three things separate the two measurements, and none of them rescues the 13× > figure: different model (Opus 5 vs Sonnet 3.5), different and unenumerated > task slice, and cost here is reconstructed from recorded token counts at > published pricing because Harbor reports a null `cost_usd` under > subscription auth. > > The honest reading is that **13× is not a claim this project can currently > support**. It is retained above as the historical measurement it was, with > this caveat attached, until a matched re-run replaces it. It should not be > quoted without this paragraph. > > There is one structural point worth stating, and it cuts both ways: > Terminal-Bench gives each task a fresh container and the tasks are unrelated, > so there is almost no prior-session knowledge for a cross-session memory > system to retrieve — the weakest possible setting for Kimetsu's actual > thesis. That is a fair explanation of the null. It is *not* a defence of the > 13× number, because that number was measured on the same instrument. The per-kind constants were back-derived from this data: if a typical winning run uses \~2 citations of mixed kinds, the implied saving is roughly ($2.47 − $0.19) / 2 ≈ $1.14/citation at Claude Sonnet 3.5 pricing (≈$3/MTok → \~380k tokens / citation). Our constants sum to far less than that for a 2-citation session, confirming that we are well inside the conservative zone. *** ## Limitations [#limitations] 1. **Citations are sparse in MCP-host sessions.** Until `kimetsu_brain_cite` is deployed, the ledger only counts citations generated by the autonomous pipeline. The `net_tokens` figure may appear falsely negative for users who work exclusively via the Claude Code plugin. 2. **Counterfactuals are estimates, not measurements.** We cannot observe what the model *would* have done without the brain context. The constants are conservative estimates based on tool-call patterns, not A/B experiments. 3. **Price table is approximate.** The built-in $/MTok figures are rounded retail/API-key prices as of June 2026. Set `[model] price_per_mtok` in `project.toml` for accurate billing data. 4. **Injection cost uses input-token pricing.** The model also produces output tokens in response to the injected context; those are not counted here (they depend on the model's response length, which varies). *** ## Config reference [#config-reference] ```toml # project.toml: override the built-in price table for this project [model] model = "claude-sonnet-5" price_per_mtok = 3.0 # optional; defaults to built-in table ``` ``` # CLI kimetsu brain roi # last 30 days (default) kimetsu brain roi --window 7d # last 7 days kimetsu brain roi --window all # all time kimetsu brain roi --json # machine-readable RoiReport ``` # Configuration (/docs/how-kimetsu-works/configuration) Every knob in `project.toml`, the off-switches, and the environment overrides. ## v2.8.0 fact guard (opt-in) [#v280-fact-guard-opt-in] On builds containing structured fact evidence, `broker.explicit_fact_guard` defaults to `false`. Enable with `kimetsu config set broker.explicit_fact_guard true`. It adds scoped supported/missing/conflicting evidence without extra model calls; injected context still consumes tokens. See [results, storage behavior and limitations and publication status](/docs/memory-benchmark/answerability). Requires v2.8.0 or a source build containing the merged changes; it is separate from the historical configuration example below. Project config lives in `/project.toml`: ```toml [kimetsu] project_id = "my-project" schema_version = 1 # config-format version, NOT the brain.db schema use_user_brain = true # false: per-project opt-out of the global brain # tier = "free" # omit for auto; see "Free and Deep" below [model] provider = "anthropic" # or "claude_code", "openai", "bedrock" model = "claude-opus-4-8" # bedrock: the full id api_key_env = "ANTHROPIC_API_KEY" region_env = "AWS_REGION" # bedrock only max_output_tokens = 8192 temperature = 0.2 request_timeout_secs = 120 [embedder] enabled = true # false: FTS-only, no vectors model = "bge-small-en-v1.5" # or "bge-m3", "jina-v2-base-code" [broker] default_budget_tokens = 6000 # flat fallback; the adaptive budget supersedes it ambient = true # false: no workspace context appended to queries max_capsules = 8 # hard cap on capsules per prompt min_semantic_score = -1.0 # AUTO (bge: 0.35, others: off); >0 sets a floor fusion = "linear" # "linear" | "rrf" — how the lexical and semantic # rankings are merged; swept by `brain tune` budget_floor_tokens = 1500 # small tasks are never starved budget_run_cap_tokens = 8000 # per-run ceiling on injected tokens compress_capsules = true # strip tags, cap at 3 sentences; ranking unaffected session_dedupe = true # skip capsules already injected this session warm_start = true # SessionStart injects the digest + episodic resume answer_grade_min_score = 0.92 # relevance marker; not independent verification proactive_prefetch = false # opt-in trajectory-based pre-fetch at PreToolUse [storage] backend = "graph-lite" # "flat" | "graph-lite" | "graph" (remote only). # Switching re-projects from the event log. [cheap_model] # one optional model for digest / resume / ask / enabled = false # distiller / consolidation; absent = graceful provider = "ollama" # rule-based degradation everywhere model = "qwen2.5:3b" # anthropic: claude-haiku-4-5 api_key_env = "ANTHROPIC_API_KEY" # not required for ollama base_url_env = "OLLAMA_BASE_URL" [sync] # server-less multi-machine sync dir = "" # a shared folder (Dropbox/Syncthing/NAS); empty = off machine_id = "" # stable per-machine id; empty = generated [broker.weights] relevance = 0.50 confidence = 0.20 freshness = 0.20 scope = 0.10 decay_half_life_days = 30.0 # 0 to disable # per-stage overrides: [broker.weights.localization], .patch_plan, # .verification, .review [shell] default_timeout_secs = 60 max_timeout_secs = 600 env_allowlist_extra = ["RUSTFLAGS", "CARGO_HOME"] redact_secrets = true [ingestion] max_file_bytes = 524_288 extra_skip_dirs = [] max_total_files = 50_000 [run] max_total_tool_calls = 60 max_total_model_turns = 30 max_total_cost_usd = 250.0 # advisory under subscription providers [learning] auto_harvest = true store_queries = true # raw query text in telemetry (on-machine only) [learning.distiller] enabled = false provider = "anthropic" # or "openai", "bedrock" model = "claude-haiku-4-5" # OpenAI default: "gpt-5.4-mini" api_key_env = "ANTHROPIC_API_KEY" base_url_env = "ANTHROPIC_BASE_URL" ``` The agent model and the distiller are configured independently: the agent can run on AWS Bedrock while the harvester stays on direct Claude or OpenAI. ## Free and Deep [#free-and-deep] `[kimetsu] tier` picks which of two pipelines the brain runs. **Free** is the default and what the published benchmarks measure: **zero LLM calls anywhere in the memory pipeline.** Ingest, store, retrieve and rerank are FTS5 + local embeddings + a local cross-encoder, and every capability has a deterministic or statistical implementation. **Deep** adds a local small model to the handful of features that are genuinely better with one. Every Deep feature falls back to the Free behaviour, so switching tiers can add quality but never removes a capability: | Feature | Free | Deep | | ------------------------------- | ------------------- | ------------------------------ | | write-time lesson capture | rule-based | model-distilled lessons | | repo digest | rule-based assembly | model-distilled summary | | reflection over memory clusters | not run | synthesized general principles | | contradiction detection | cosine proximity | entailment adjudication | | HyDE query expansion | not run | hypothetical-answer expansion | Leave `tier` unset for **auto**: a brain with a cheap model configured is already making model calls, so it resolves to Deep; a brain without one resolves to Free. That keeps every pre-v2.6 config behaving exactly as before. Set it explicitly to force the choice — `tier = "free"` is a durable opt-out of model calls even when credentials are present, and `tier = "deep"` with no reachable model resolves back down to Free and says so in `kimetsu doctor` and `kimetsu brain status`. Commands you invoke by name (`kimetsu ask`, `brain reflect`, `brain distill`, `brain skills --draft`) are explicit requests, not pipeline behaviour, and are not gated by the tier. **Off-switches.** Every optional feature can be turned off in `project.toml`, with precedence env override > config > default. Every field is `#[serde(default)]`, so a partial or older file loads cleanly and gains new defaults on upgrade. Edit with `kimetsu config edit` (opens `$EDITOR`, re-validates on save); re-installs merge, so toggles survive. Environment overrides: | Variable | Effect | | ------------------------------------------------------------------------------------ | --------------------------------------- | | `ANTHROPIC_API_KEY` / `CLAUDE_CODE_OAUTH_TOKEN` / `OPENAI_API_KEY` / AWS credentials | Provider credentials | | `KIMETSU_USER_BRAIN=0` | Disable the user brain | | `KIMETSU_BRAIN_EMBEDDER=noop\|bge\|jina-v2-base-code\|...` | Pick or disable the embedder | | `KIMETSU_BRAIN_AMBIENT=off` | Disable ambient workspace context | | `KIMETSU_TIER=free\|deep` | Force the product tier for this process | # Overview (/docs/how-kimetsu-works) Kimetsu is a sidecar brain for coding agents. It runs alongside supported host agents through MCP (including Claude Code and Codex), or as a standalone chat REPL. It watches what the model does, learns which memories actually help, and feeds higher-signal context into future runs. This document explains the moving parts, in the order you'll encounter them. ## Ways to use it [#ways-to-use-it] **As a sidecar via MCP.** Run `kimetsu mcp serve` directly, or let `kimetsu plugin install ` write the host config for you. The host agent gets `kimetsu_*` tools (brain context + record, citations, memory add/list/blame/conflicts, repo ingest, the bridge to other supported hosts). Memories carry across sessions; learning compounds. The intended loop is two calls: **`kimetsu_brain_context`** early on a non-trivial task (zero overhead when the brain has nothing), then **`kimetsu_brain_record`** after solving a problem worth remembering. `kimetsu plugin install ` wires both automatically for **Claude Code**, **Codex**, **Pi**, and **OpenClaw**, writing each host's native config (hooks plus MCP; a TypeScript extension for Pi, which has no MCP). Hosts with a stop event also get a session summary hook. **As a standalone REPL.** Run `kimetsu chat`. Same brain, same tools, only without a host harness. Useful for debugging a brain or running short tasks where you don't want a second agent in the loop. **As a shared server (Kimetsu Remote, beta).** Run the brain on a server and connect over HTTP MCP: one brain per *repository*, shared across machines or a team, with no local checkout. See §7a. The CLI also has admin commands (`kimetsu brain ...`, `kimetsu doctor`, `kimetsu bridge ...`) that you'll use for maintenance, described below. *** # Interfaces (/docs/how-kimetsu-works/interfaces) The MCP tool surface, the host hooks that make the loop reliable, and proactive mid-work recall. ## The MCP surface [#the-mcp-surface] Run `kimetsu mcp serve` and the host gets \~28 `kimetsu_*` tools. The ones you will actually reach for: | Tool | What it does | | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | | `kimetsu_brain_context` | Retrieve a context bundle (returns `skipped: true` when nothing relevant, at zero overhead) | | `kimetsu_brain_record` | Capture a lesson; runs semantic dedup | | `kimetsu_brain_status` | Brain health + memory counts | | `kimetsu_brain_insights` | Effectiveness analytics over recent runs | | `kimetsu_brain_memory_add` / `_list` / `_top` / `_search` | Direct memory CRUD and search | | `kimetsu_brain_memory_proposals` / `_accept` / `_reject` | Review pending proposals | | `kimetsu_brain_memory_invalidate` | Retire a memory | | `kimetsu_brain_memory_blame` | Per-run citation attribution | | `kimetsu_brain_memory_conflicts` / `kimetsu_brain_conflict_resolve` | List / settle ingest conflicts | | `kimetsu_brain_prune` | List (or invalidate) net-negative memories | | `kimetsu_brain_model_list` / `_set` / `kimetsu_brain_reindex` | Inspect / switch / re-embed the embedding model | | `kimetsu_brain_ingest_repo` | Index repo files + manifests | | `kimetsu_benchmark_context` / `_record_outcome` | Task-aware playbook + outcome recording | | `kimetsu_bridge_*` / `kimetsu_skills_search` | Skill registry discovery, import, export, sync | | `kimetsu_brain_cite` | Record that a memory materially helped | | `kimetsu_brain_answer` | Grounded, cited answer composed from memory (local model) | Every tool returns `{"ok": true, "usage": {...}}` so the host gets guidance on how to use the output, not just raw data. ### Host hooks [#host-hooks] The MCP tools work whether or not the model decides to call them. The plugin installers make the loop reliable by writing host-native hook config (`.claude/settings.json` + `.mcp.json` for Claude Code, `.codex/` for Codex, `openclaw.json` for OpenClaw, a TypeScript extension for Pi): * **`UserPromptSubmit` -> `kimetsu brain context-hook`** fires before each turn, retrieves a bundle, and injects it. On embeddings builds it asks the warm embedder daemon (`kimetsu brain embed-daemon`, pre-warmed on SessionStart) for semantic retrieval within a 300ms budget, falling back to lexical FTS if the daemon is unreachable, so the prompt is never blocked. The daemon holds the ONNX models in memory and finishes with a cross-encoder rerank (see [Retrieval models](/docs/how-kimetsu-works/retrieval-models)). With `--warm-on-first-prompt` the hook also prepends the warm-start block (digest + resume) to the session's first turn — see below. * **`Stop` -> `kimetsu brain stop-hook`** prints a one-line post-turn banner: how many lessons were captured, or a nudge to record one after a non-trivial session. * **`SessionEnd` -> `kimetsu brain session-end-hook`** runs the optional credentialed distiller (Codex uses `Stop` with `--distill-on-stop`). These are plain CLI subcommands, so the same pattern works under any harness that can run a command on a prompt, stop, or session-end event. ### Warm start, on every host [#warm-start-on-every-host] The warm-start block — the \~400-token repo digest, your standing preferences, your episodic resume, and anything the skills loop is waiting on — is what makes the agent's first turn already know the repo. Every host gets it, by whichever route that host actually has: | Host | Route | | ------------------- | ------------------------------------------------------------------------------------------------------------------------- | | Claude Code | `SessionStart` -> `kimetsu brain session-start-hook` | | Codex, Pi, OpenClaw | per-turn hook with `--warm-on-first-prompt`: prepended to the session's first prompt, once | | Cursor | no hooks at all — the first `kimetsu_brain_context` call of a session returns a `warm_start` field alongside the capsules | The **standing preferences** section is why the block carries more than repo state. Preference following is Kimetsu's second-weakest measured ability (LongMemEval 66.7%), and the diagnosis is that a preference is a small aside semantically far from the question — which rules out fixing it by re-ranking, because the candidate never enters the pool. So preferences are *delivered* rather than retrieved: the top few `preference` memories by proven usefulness, project ones first, framed as instructions to follow without being asked. They are excluded from the digest above them so the same line never prints twice. The last section closes the **skills loop**. A memory cited across three distinct runs has earned skill status; detection is a pure query and has run on the maintenance schedule since the daemon landed — but its result went into a log file nobody opens, so a memory could cross the threshold and sit there forever. (`find_synthesis_candidates` having exactly one caller, the `brain skills` CLI, was that same fact stated as a call graph.) The warm start now carries one line naming what is waiting and the command that acts on it: candidates with no draft yet, and drafts awaiting an accept or reject. A candidate that already has a pending or accepted proposal is not reported as a candidate — the loop has moved on. When there is nothing to act on, which is the common case, the section is absent entirely. Only one route fires per host, so the block is never delivered twice. It is gated by `[broker] warm_start` (default on) everywhere. A cached digest is served immediately even when the corpus has moved under it, and the rebuild runs detached, so a stale digest never puts a build in front of your first turn. Pi and OpenClaw are driven by a generated TypeScript extension rather than a hook file: it feeds the hook payload to the CLI on stdin and reads the injected context back off stdout (Pi returns it from `before_agent_start`, OpenClaw as `prependContext` from `agent_turn_prepare`). A missing, hung, or failing `kimetsu` binary is always a silent no-op — the sidecar must never break the host. ### Proactive recall (mid-work) [#proactive-recall-mid-work] `UserPromptSubmit` only fires between turns. Two tool-level hooks surface a memory while the agent works, the way a memory comes to you rather than you fetching it. Both match only Bash commands and never block: * **`PreToolUse` -> `kimetsu brain pretool-hook`**: if the command strongly matches a stored `failure_pattern` or `convention`, warn first. * **`PostToolUse` -> `kimetsu brain posttool-hook`**: when a command actually failed, surface a matching fix. "Actually failed" is decided by the strongest evidence available — the exit code when the harness reports one, else a toolchain summary line (cargo, pytest, jest/vitest, go test, tsc, npm, make), else a substring scan that an explicit `0 failed` / `test result: ok` can veto. A passing test suite is not a failure just because its summary line contains the word "failed". Discipline keeps this near-zero-cost: lexical-FTS-only retrieval, one capsule max, per-session dedup, and a refractory window between injections. When nothing clears the bar, the hook prints nothing. Per-session state lives outside the repo under `~/.kimetsu/cache/` and is GC'd after 7 days. **Whether to speak is a learned decision.** The score threshold used to be a constant (0.45, or 0.35 when the agent was visibly looping) that applied to every brain and never moved. It is now a small logistic policy over the score, loop mode, capsule kind, how much has already been injected this session, how long since the last injection, how often this command has already failed, and how strong the evidence of failure was. Its prior is pinned to *exactly* the old thresholds, with every other weight at zero — so an untrained brain behaves precisely as it did before, and there is no cold-start regression to trade against the eventual gain. Each decision is recorded with its features, and labelled by whether the agent went on to cite the memory it was handed. `kimetsu brain policy` prints the weights and how the fit compares to the legacy rule on your own history; `--train` refits; `--reset` returns to the constant. Model-free, so it runs on the Free tier. It also prints **acceptance per hook surface** — how often an injection from each surface was followed by a citation of the memory it handed over. The three surfaces are not equivalent bets: `posttool` reacts to a command that observably failed, while `pretool_prefetch` predicts from a file path alone. That is the weakest signal Kimetsu acts on and the reason `broker.proactive_prefetch` is default-off — a flag whose own documentation said graduation "waits for regret data" while nothing recorded which surface an injection came from, so the data could never accumulate and the flag could never graduate. It now does, scored per surface so a strong one cannot launder a weak one's noise. The default stays off until the comparison is made on a real brain; what changed is that it can be. Proactive hooks install by default; pass `--no-proactive` to skip them. *** ## Kimetsu Remote (beta) [#kimetsu-remote-beta] Everything above assumes a local brain over stdio MCP. Kimetsu Remote runs the brain on a server over HTTP MCP: the identity becomes the repository, so any checkout on any machine (or a teammate's) hits the same brain. One brain per repo, bearer auth with per-user tokens and attribution, an optional shared org brain, server-side repo ingest, TLS, Prometheus metrics, and a server-side reranker. Setup, hardening, and benchmarks: [Kimetsu Remote](/docs/remote). # The learning loop (/docs/how-kimetsu-works/learning-loop) Citations, decay, dedup, conflict detection, and the analytics that prove the brain is helping. ## Citations + blame [#citations--blame] The strongest signal is which memories the model actually used. The flow: 1. The broker injects N capsules (recorded as a `context.injected` event). 2. Mid-run, the model cites a memory it leaned on: **`cite_memory`** inside the autonomous agent pipeline (`kimetsu run`), or the **`kimetsu_brain_cite`** MCP tool from a host agent. Both land in the same place. 3. At run end, one `memory.cited` event per citation lands in `memory_citations`. 4. On `run.finished`, usefulness updates: **cited memories** get the strong delta (+1.0, and `last_useful_at` bumps); **silent passengers** get a weak one (±0.1). On `run.failed`, the cited penalty is **scaled by the memory's citation history** (`-1.0 / (1 + prior citations / 3)`), so a proven memory absorbs an unlucky flaky run while an unproven one takes the full hit. A `run.failed` with `category = "Gate"` (the plan-stage existence guard) is no signal at all. Inspect any run with `kimetsu brain memory blame ` (cited first, then passengers; `--json` for CI). The same surface is the `kimetsu_brain_memory_blame` MCP tool. *** ## Decay [#decay] A memory useful six months ago should not outrank one useful yesterday. The broker applies a half-life curve (default 30 days) to `last_useful_at`: ```toml [broker.weights] decay_half_life_days = 14 # faster-moving repo; 0 disables ``` Decay attenuates the deviation from neutral, not the score itself: a max-boosted memory decays toward neutral, never below a brand-new one. *** ## Semantic dedup + conflict detection at ingest [#semantic-dedup--conflict-detection-at-ingest] `kimetsu_brain_record` runs semantic dedup before writing: 1. **Exact dup** (same normalized text, scope, kind): bump the existing memory, write nothing. 2. **Near dup** (cosine >= 0.85 in scope): merge into the existing memory rather than creating a near-twin. 3. **High confidence** (>= 0.7) with no near-dup: accepted directly. 4. **Lower confidence**: filed as a proposal for review. Separately, each write scans for contradictions: memories in scope whose embedding is close (cosine >= 0.8) but whose text differs. Hits land in `memory_conflicts`; the write is never blocked, because a blocked write loses user intent. Review from the CLI: ```bash kimetsu brain memory conflicts # list open conflicts kimetsu brain memory conflicts --resolve kept_new | kept_existing | kept_both ``` Resolution is CLI-only so the audit trail stays centralized; the MCP conflicts tool is read-only. Both dedup and conflict detection need the embeddings build. *** ## Analytics: is the brain actually helping? [#analytics-is-the-brain-actually-helping] `kimetsu brain insights` (CLI and MCP) computes proof-of-value metrics over a recent-runs window (`--last-n-runs`, `--since`, `--json`): retrieval hit-rate and skip-rate, citation rate, proposal acceptance, usefulness trend, harvest yield, corpus health (active vs invalidated, prune candidates, open conflicts), and token economy. The numbers are real counts, backed by `context.served` (every retrieval, hit or miss) and the injected-token count on `context.injected`. ### ROI ledger [#roi-ledger] `kimetsu brain roi [--window 7d|30d|all]` estimates savings: conservative per-kind token credits for each citation, minus injected-token overhead, with a net verdict. Dollar values appear when the model is in the price table or `[model] price_per_mtok` is set. Honest negatives are shown as-is. Methodology: [Kimetsu Algorithm](/docs/roi-methodology). ### Consolidation and triage [#consolidation-and-triage] `kimetsu brain consolidate` merges near-duplicates (cosine >= 0.92); the survivor keeps its id, members get `superseded_by`, citations reassign. `--distill` feeds looser clusters to the distiller as proposals; `--dry-run` prints the plan. `kimetsu brain triage` walks low-usefulness, long-unused memories interactively (`--prune-all --yes` for batch). ### Trust and audit [#trust-and-audit] A poisoned memory is not a prompt injection. Prompt injection is session-scoped and resets; a memory written into the brain persists and influences every future session until someone notices. MINJA reports >95% injection success against memory-backed agents through ordinary, unprivileged interaction. Kimetsu's exposure is narrower than a hosted service's — the brain is a local file — but it grows with exactly the features that make the product good: `brain import` from a URL, `brain sync`, and Remote's shared org brain. So retrieval discounts a memory by where it came from: | origin | multiplier (uncorroborated) | | ------------------------- | --------------------------- | | local, derived | 1.00 | | distilled (model-written) | 0.95 | | remote / synced | 0.90 | | pack (imported) | 0.85 | **Corroboration erases the discount entirely.** Once a memory has been cited in a successful run on this machine — which is exactly what `last_useful_at` records — it has been tested here, and where it was written stops being the most informative thing about it. Otherwise an imported pack, whose whole point is to share knowledge, would stay second-class forever. Trust is a weight, never a gate: a bad import must not be able to silently delete your working knowledge. Memories written before provenance existed read as local, so upgrading does not make an existing brain untrusted overnight. **Quarantine is the gate the weight is not.** Discounting a poisoned pack ranks it lower; it still influences sessions. So `kimetsu brain import` holds an imported pack in the review queue — the same one `brain memory proposals` already drives — and nothing in it can reach a session until you accept it. On by default for `http(s)://` sources, since content authored elsewhere and fetched over the network is the widest attack surface here; off for a local file or stdin, which you chose and can open. `--quarantine` / `--no-quarantine` override either way, and `--mode replace` is refused alongside quarantine — superseding memories you have in favour of content you have not read is the worst of both. Entries matching a memory you already hold are deduped rather than proposed: a review queue nobody can face is not a safety mechanism. Nothing reaches back. A pack imported before quarantine existed stays where it is, discounted by origin — pulling working memories out of retrieval on an upgrade is a worse failure than the one quarantine prevents. ### Framing, not deference [#framing-not-deference] MemSyco-Bench reports that most memory systems score *worse* on their sycophancy track than using no memory at all. The mechanism is not that retrieved memories are wrong more often than right — it is that a memory arrives looking like ground truth, so the model defers to it over evidence directly in front of it. A memory saying the config lives at `config/app.toml` beats the agent's own `ls` showing it does not, because nothing in the injection said which of the two wins. Kimetsu's header used to read "relevant knowledge for this task". *Knowledge* is the wrong word: what the brain holds is what was recorded, at some past moment, by someone who believed it then. The injection now says so, and says which questions memory settles: * Memory **is** the authority on what was decided, learned, or preferred. There is no other source for those — the repository does not record why. * Memory is **not** the authority on what the code currently is. The working tree is, and it has moved. Every memory-versus-reality conflict is this kind. So the framing is a rule about conflicts rather than a disclaimer: prefer what you can check now over what was recorded then. Hedging would be the wrong fix — an agent told "this might be wrong" ignores memory, which is the whole product — so the memory itself is never qualified, only outranked. The proactive hook gets a short suffix instead of a preamble: it interrupts work already underway on a one-capsule budget, and framing longer than the memory reads as noise. MCP clients, which have no fixed render, get the same rule as guidance in `usage.how_to_use`. `kimetsu brain audit` groups the active corpus by origin, shows how much of it has never been corroborated, and flags write bursts — clusters that arrived faster than anyone types, which is the shape both a bulk import and induced poisoning leave. Read-only on purpose: an automated purge keyed on that heuristic would delete a legitimate import. ### Session drift [#session-drift] Nautilus Compass reaches ROC AUC 0.83 detecting behavioural drift on real Claude Code traces using nothing but cosine against a behavioural anchor — no model, no labels, no training. `kimetsu brain drift` computes the Kimetsu-shaped version of that signal: cosine of each turn in a session against the session's *first* prompt, which is what it set out to do. Be precise about what it sees. Compass reads agent traces — the actions taken. A memory sidecar has no such thing; what Kimetsu has is the sequence of user prompts, logged per session in `context.served`. So this says how far a session moved from the question it opened with, not whether an agent drifted from its instructions. Weaker than the paper's claim, and the honest one. The signal is sustained by construction: three consecutive turns below the threshold, never a single one. One tangential question is a question. Anchoring on the opening turn rather than a rolling window is deliberate — a rolling anchor lets a session walk anywhere one small step at a time without ever registering, which is the case worth catching. It matters to a memory system because retrieval anchors on the session: once a session has turned, its opening turns are steering results toward a task nobody is working on. Report-only, like `prune` and `audit` — a signal that silently re-anchors retrieval is one whose false positives are invisible, and this one has no measured operating point on a Kimetsu corpus yet. Needs an embeddings build; on a lean build the command says so rather than reporting a number computed on a different scale. *** ### Self-tuning [#self-tuning] `kimetsu brain tune` sweeps the retrieval floors against eval cases built from your own query history (`context.served` + citations), with a deterministic 20% holdout guarding against regressions. `--apply` writes only the floor parameters; `--revert` restores. Dry-run by default. # Operations (/docs/how-kimetsu-works/operations) The bridge, brain sharing, doctor, and what Kimetsu is not. ## The bridge [#the-bridge] Kimetsu also runs as a cross-harness skill bridge. `kimetsu bridge` discovers skills installed in supported hosts (Claude Code, Codex, Pi, OpenClaw, the local kimetsu installation), exports a skill from one host into another, and keeps a unified registry so the same skill works everywhere. `kimetsu bridge status` shows what is installed where; `kimetsu bridge export --to ` does the install. *** ## Sharing brains [#sharing-brains] The bridge moves skills. Memories move as **packs**: a brain exported to one portable file that another brain can install. ```bash kimetsu brain export team.json.gz --name rust-conventions --version 1.0.0 kimetsu brain import team.json.gz # merge (default) kimetsu brain import https://example.com/pack.json.gz # install from a URL kimetsu brain import other.json.gz --mode replace --yes # swap ``` * **Export** always compresses (gzip) and always scrubs: credentials and PII are redacted before the pack is written. `--strict` aborts on a finding; `--name` / `--version` / `--description` stamp a manifest. * **Import** reads a file, stdin, or a URL, and detects gzip on its own. `merge` (default) dedups against what you have, so importing twice is safe. `--mode replace` supersedes your memories in the pack's scope first; it needs `--yes` and invalidates rather than deletes, so a swap is reversible. Imports are scrubbed again on the way in. For continuous replication, `kimetsu brain sync` exports and imports the durable event log (idempotent per event), converging two brains without copying SQLite files. Kimetsu Remote serves a shared brain per repository. *** ## Background upkeep [#background-upkeep] The brain has a shelf of maintenance passes — consolidation, query-route rebuilding, prune-candidate detection, digest refresh, skill-candidate detection. Every one of them used to be a command a human had to remember to run, which in practice meant none of them ran. `kimetsu brain maintain` runs whatever is overdue, each pass on its own interval (reinforce and skills daily, digest twice daily, prune weekly), with the last-run times in `.kimetsu/maintenance.json`. The session-start and session-end hooks fire it **detached** when something is due, so it never sits in front of a prompt, and there is no resident scheduler to supervise — the same shape as the detached digest rebuild. ```bash kimetsu brain maintain --status # what is overdue kimetsu brain maintain # run the overdue passes kimetsu brain maintain --force # run everything now kimetsu brain maintain --only reinforce # one pass ``` Every pass is model-free, so upkeep runs on the Free tier. Reflection is deliberately not among them: it is a model call, and a background model call is the kind of surprise bill this project exists to avoid. Pruning here only *reports* candidates — retiring a memory stays a human decision. *** ## Doctor [#doctor] `kimetsu doctor` validates that every subsystem works against the current workspace: paths resolve, brain.db opens with a matching schema, the user brain is reachable (or correctly disabled), the embedder loads, the MCP server spawns, the bridge can scan hosts. Hermetic, safe in CI, `--json` for hooks. `kimetsu doctor --selftest` is the end-to-end proof: in a throw-away temp project it records a memory and retrieves it back, exiting non-zero if any step fails. *** ## What kimetsu is NOT [#what-kimetsu-is-not] * Not a model. It runs through a host agent or a configured provider. * Not a sandbox. Tools run on the host machine. * Not an external vector DB. The brain is one SQLite file per project; on the embeddings build the ANN index is a `brain.usearch` sidecar next to it. Backups are `cp brain.db`, and the brain auto-backs-up before any schema migration. *** ## Where to go next [#where-to-go-next] * `kimetsu doctor` to verify your install. * The **CHANGELOG** for when each piece landed. * Per-crate `src/lib.rs` doc comments for module-level detail. # Retrieval models (/docs/how-kimetsu-works/retrieval-models) Which embedder and reranker Kimetsu ships, why, and how to swap or re-benchmark them. The local retrieval stack is an embedder plus a cross-encoder reranker, both warm inside the embed daemon. Defaults were chosen with `kimetsu brain bench`, a benchmark seeded from real exported memories (100 memories in confusable topic clusters, 210 cases: keyword, paraphrase, oblique, confusable, no-answer, multi-answer): | embedder | reranker | recall\@2 | recall\@4 | MRR | mean ms | peak RSS | | --------------------- | ---------------- | --------- | --------- | ----- | ------- | -------- | | jina-v2-base-code | jina-turbo | 0.954 | 0.975 | 0.933 | 552 | 2.0 GB | | jina-v2-base-code | jina-tiny | 0.949 | 0.975 | 0.931 | 414 | 2.0 GB | | jina-v2-base-code | minilm-l-4 | 0.949 | 0.959 | 0.927 | 372 | 2.3 GB | | **jina-v2-base-code** | **tinybert-l-2** | 0.914 | 0.949 | 0.914 | **132** | 1.5 GB | | jina-v2-base-code | off | 0.929 | 0.939 | 0.915 | 106 | 1.5 GB | | bge-small-en-v1.5 | off | 0.931 | 0.966 | 0.911 | 446 | 359 MB | The default (**jina-v2-base-code + ms-marco-tinybert-l-2-v2**) is the fastest reranked combo, within \~2% MRR of the grid best, and fits the hook's 300ms budget. jina-v2 beats bge-small across every reranker on this corpus; any reranker beats none. The lean-RAM option is `bge-small-en-v1.5` (\~360-525 MB at \~1-3% lower MRR). **Swapping models** (takes effect after a daemon restart): ```bash kimetsu config set embedder.model bge-small-en-v1.5 kimetsu config set embedder.reranker jina-reranker-v1-tiny-en # or off, any HF ONNX id kimetsu brain reindex # REQUIRED after an embedder change kimetsu brain daemon stop # next prompt spawns a daemon with the new models ``` `KIMETSU_BRAIN_EMBEDDER` overrides per process. **Re-judging as your brain grows**: ```bash kimetsu brain export bench/memories-export.json # refresh the dataset source kimetsu brain bench # full grid -> summary.md kimetsu brain eval # fixture-based quick check ``` Watch-item: the semantic floor (`broker.min_semantic_score`, 0.35) was calibrated on bge-family cosine distributions; re-tune it against `kimetsu brain eval` after an embedder change. The remote server runs its own operator-configured reranker; see [Kimetsu Remote](/docs/remote). # The brain (/docs/how-kimetsu-works/the-brain) brain.db: the event-sourced SQLite file that holds everything Kimetsu remembers, and how it migrates safely. Everything kimetsu remembers lives in **brain.db**, a single SQLite file per project at `/.kimetsu/brain.db`. A global user brain at `~/.kimetsu/brain.db` holds memories that follow you across projects (disable with `KIMETSU_USER_BRAIN=0` or `[kimetsu] use_user_brain = false`). `.kimetsu/` stays lean: just `brain.db` (plus WAL and migration backups) and `project.toml`. Transient working dirs live under `~/.kimetsu/cache//`, never in your tree. The brain is event-sourced: the **`events` table is the durable log**, and a projector replays it into materialized tables the broker queries fast. `kimetsu brain rebuild` re-derives every projection from the log. The tables: * `runs`: one row per agent run. * `events`: every event ever written; the source for rebuild. * `memories`: the durable knowledge, with scope, kind, text, confidence, use\_count, usefulness\_score, and last\_useful\_at. * `memory_proposals`: pending suggestions awaiting review. * `memory_citations`: which memories the model cited, in which run. * `memory_conflicts`: ingest-time contradiction hits. * `repo_files*`, `repo_manifests*`: file indexes from `brain ingest repo`. * `memories_fts`: FTS5 index for lexical retrieval. * `memory_entities`: tags and salient terms per memory, so the graph layer can find "what else mentions this" with an index lookup instead of a scan. * `memory_edges`: typed relations between memories (`relates_to`, `supersedes`), written as each memory lands and traversed by the `graph-lite` backend. ## Two clocks: what was true, and what we knew [#two-clocks-what-was-true-and-what-we-knew] Every memory carries two independent timelines: * **Valid time** — when the fact was true in the world (`valid_from` / `valid_to`). Default retrieval filters on this: an expired memory is excluded. * **Transaction time** — when the brain *learned* it (`created_at`) and when it retracted it (`invalidated_at`, or the loser's stamped `valid_to`). Nothing is ever destroyed — supersession, invalidation and automatic contradiction resolution all stamp a tombstone rather than delete — so the brain can answer what it believed at any past moment: ```bash kimetsu brain as-of 2026-03-01 # the view then kimetsu brain as-of 2026-06-01 --since 2026-03-01 # what changed between ``` This is the question that matters when a past decision looks wrong: it separates a bad call from missing information. A memory that has since been retracted still appears in a view from before its retraction, annotated with what became of it, and a memory merged into a survivor still counts as the live belief it was at the time. *** ## Durable upgrades: schema migrations [#durable-upgrades-schema-migrations] brain.db carries a schema version, and a forward-only migration runner brings it up to the binary's target on every read-write open. Each migration runs in one transaction, so a crash leaves the DB cleanly stamped at an intermediate version, never half-applied. Before any migration the runner snapshots to a `brain.db.bak-*` sidecar (three newest kept). A read-only open of an un-migrated brain reports "needs migration" instead of failing. The DB schema version is decoupled from the `project.toml` config version, so the database can evolve without rewriting every project's config file. ## Memory kinds [#memory-kinds] | Kind | Use | | ----------------- | ---------------------------------------------------------- | | `preference` | User-stated style choices ("prefer thiserror") | | `convention` | Repo conventions ("always run cargo fmt") | | `command` | Useful shell incantations ("regen with `cargo xtask gen`") | | `failure_pattern` | "Don't do X, it caused Y last time" | | `fact` | Domain knowledge: APIs, gotchas, architectural notes | ## Memory scopes [#memory-scopes] | Scope | Lives | Use | | ------------- | ---------------------------- | --------------------------------------------- | | `run` | This run only | Ephemeral notes, discarded at end | | `repo` | This repo | Project conventions, code-specific facts | | `project` | This project (== repo today) | Synonym for repo | | `global_user` | User-wide brain | Personal preferences, cross-project knowledge | # The broker (/docs/how-kimetsu-works/the-broker) How the broker scores, selects, and budgets the memories injected into each run. When a run starts, the **broker** assembles a context bundle: it walks both brains, scores candidates, and returns the top-N inside a token budget. **Candidate generation.** Lexical FTS5 always provides candidates. On the embeddings build the broker also queries a **usearch HNSW** index (a `brain.usearch` sidecar, f16-quantized, O(log N)) and unions those hits with the FTS set, so a memory whose meaning matches can surface without sharing a word with the query. The default backend is **graph-lite**: on top of that flat set it walks up to two hops over `memory_edges`, so a memory one edge from the best hit can be pulled in even when the query never mentions it. Graph-reached candidates enter at a hop-decayed share of the seed's relevance (`×0.6` per hop), so they rank below the hit that surfaced them. The candidate set is a strict superset of flat's, which is why the default is safe: broader recall, never a displaced result. Edges are written as each memory lands, from the entities it shares with the existing corpus — no `kimetsu brain graph build` required, though that command still rebuilds the whole graph if you want it re-derived. The score is a weighted sum plus two multipliers: ``` raw_relevance = (1 - α) * lexical_match + α * cosine_similarity (α = 0.5) multiplier = usefulness_multiplier(score, use_count) ∈ [0.5, 1.5] decay = exp(-ln 2 · age_days / half_life_days) (default 30d) effective = 1.0 + (multiplier - 1.0) · decay final_score = w.relevance · raw_relevance + w.confidence · confidence + w.freshness · freshness + w.scope · scope_weight ``` Weights are tunable per stage (`localization`, `patch_plan`, `verification`, `review`) via `[broker.weights.]`. **Selection.** Embedding-MMR (lambda 0.7) collapses paraphrase near-duplicates; an absolute semantic floor (`min_semantic_score`, AUTO by default) drops off-topic candidates before budgeting, so an irrelevant query returns nothing rather than padding the prompt. Key knobs in `[broker]`: `max_capsules` (8), `budget_floor_tokens` (1500), `budget_run_cap_tokens` (8000). **Abstention.** A bundle carries `evidence_coverage`: the IDF-weighted share of the query's discriminating terms the returned capsules cover *collectively*. Below 0.5 the injection is followed by an explicit line naming what none of them mention — "nothing above covers kubernetes, rollout. Treat the rest as unknown rather than inferring it." Kimetsu already abstained at the bundle level (top score below `min_score` → empty bundle, zero tokens); this is the signal for a bundle it *does* return, so a reader handed three capsules that touch half the question can tell that from three that answer it. The same fields are exposed on `kimetsu_brain_context`. The weighting is deliberately not the one the per-memory floor uses: there a query term absent from the whole corpus is zeroed (it would sink every candidate), while here it is the *strongest* evidence of a gap, and weighs most. **Event ordering.** Memories carry `created_at`; capsules did not, so a bundle rendered in score order with no dates gave a reader asked "did we switch to `thiserror` before or after the migration?" nothing to order the answer *by*. At two events that is a coin flip, which is roughly what the 32.5% BEAM ordering score looked like. Nothing about retrieval was wrong — the memories were found and selected, and then the ordering information was thrown away at render time. So when the query contains an ordering marker (`before`, `after`, `first`, `when`, `timeline`, …), the bundle is re-rendered oldest-first with each memory's date in front of its text, under a line telling the reader that is what they are looking at. Repo files and manifests have no position in the memory timeline; they keep their relative order after the dated ones rather than being dropped or given a date they do not have. This runs **after** the budget loop, so it is presentation and not selection: it cannot admit a capsule the broker rejected or drop one it chose. `used_tokens` is recomputed because the dates are real tokens. The marker gate is deliberately narrow — timestamping every capsule on every query would spend tokens on the large majority of questions that are not about time, and reordering an ordinary bundle away from relevance would bury the best answer. `chronological` and `chronological_note` are exposed on `kimetsu_brain_context`. **Budgeting.** Capsules are filled greedily in score order against **half** of the requested `budget_tokens` — the other half is headroom for the rest of the bundle (repo files, manifests, the render-time framing) and for the chars/4 token estimate being an approximation rather than a count. So a request for 2000 tokens fills capsules up to \~1000. Overflow lands in `excluded` rather than being dropped silently, and `max_capsules` caps the count before the token check. ## Embeddings vs lean builds [#embeddings-vs-lean-builds] * **Embeddings** (the CLI default): ships fastembed + ONNX. Cosine retrieval, semantic dedup, and conflict detection all light up. Three curated models: `bge-small-en-v1.5` (384d, default), `bge-m3` (1024d, multilingual), `jina-v2-base-code` (768d, code-tuned). Precedence: `KIMETSU_BRAIN_EMBEDDER` env > `[embedder]` config > default. `kimetsu brain model set <id>` re-embeds the corpus; cross-model rows fall back to FTS until reindexed, so retrieval never breaks mid-migration. * **Lean** (`--no-default-features`): no embedder, no model download. Retrieval is FTS-only; semantic dedup and conflict detection become silent no-ops. Library crates default to lean so downstream consumers stay slim. *** ## The agent brain (proactive + cost-shrinking) [#the-agent-brain-proactive--cost-shrinking] For the autonomous agent pipeline (`kimetsu run`), an adaptive layer sits on top of retrieval. The tools named below (`expand_capsule`, `cite_memory`) are that pipeline's own tools, not part of the MCP surface a host agent sees: * **Task-kind routing.** A cheap deterministic classifier sorts each task into Debug / Feature / Refactor / Docs / Investigation, and a weight layer biases recall accordingly: Debug leans on recent `failure_pattern`s, Refactor on conventions, Investigation on broad facts. * **Proactive "Known pitfalls".** Before the first attempt, a tight `failure_pattern` retrieval surfaces known mistakes, at \~zero tokens when nothing matches. A per-run ledger stops re-surfacing on retries. * **Cross-stage dedup.** A capsule rendered once is back-referenced in later stages, so brain overhead shrinks as a task spans more stages. * **Lazy expansion.** Top capsules inject in full; the tail injects as one-line headlines the agent expands on demand via `expand_capsule`. * **Adaptive budget.** The per-stage budget scales sublinearly with task size (`floor + k·√task_size`), floored and capped per run. Doubling task size grows the budget \~41%. # Structured answerability (v2.8.0) (/docs/memory-benchmark/answerability) These are **v2.8.0 opt-in evidence-delivery results**, not a new overall BrainBench score or a claim about generated-answer accuracy. It adds source-bound configuration facts and reports which requested attributes are supported, missing or conflicting. **Released September 9, 2026:** [v2.8.0 is available](https://github.com/RodCor/kimetsu/releases/tag/v2.8.0). These measurements use implementation `3ae8329` and harness `2c74dad`; they are not a new run of a tagged v2.8.0 binary or a v2.7.0-versus-v2.8.0 comparison. ## v2.8.0 metric summary [#v280-metric-summary] Frozen structured-fact fixture: 45 cases, repeated twice. | Metric | Baseline | Candidate | Interpretation | | ----------------------- | ------------- | ---------------------- | ------------------------------------------------ | | Unwanted injections | 15/18 (83.3%) | 3/18 (16.7%) | 80% fewer failures; 66.7 percentage points lower | | Positive retrieval hits | 24/27 (88.9%) | 24/27 (88.9%) | No positive-hit loss | | Exact evidence metadata | Not emitted | 36/45 (80%) per repeat | Not generated-answer accuracy | | Subsequent-query p95 | 376.6 ms | 386.6 ms | +10.0 ms (+2.7%) | | Mean MCP response bytes | 613.5 | 651.2 | +37.8 bytes (+6.2%) | ## Paired results — September 7, 2026 [#paired-results--september-7-2026] The campaign contains 688 observations over 299 distinct scenario/query cases. Both sides enable the fact guard; the baseline is the preceding answerability build and the candidate adds structured evidence. No positive-hit losses or execution errors were observed. | Fixture | Positive hits, old → new | Unwanted injections, old → new | Subsequent p95, old → new | | --------------------------------------------- | ------------------------ | ------------------------------ | ------------------------- | | Development: 210 queries | 169/197 → 169/197 | 7/13 → 7/13 | 1,111.7 → 1,094.0 ms | | Prior answerability: 44 queries | 24/24 → 24/24 | 0/20 → 0/20 | 409.1 → 380.7 ms | | New structured facts: 45 queries, two repeats | 24/27 → 24/27 | 15/18 → 3/18 | 376.6 → 386.6 ms | On the new fixture, **80% fewer unwanted injections** means 15 failures became 3, or 83.3% → 16.7% of the 18 negative cases. Exact status, values, missing attributes and conflicts matched **36/45 cases in each repeat**: 33/42 direct fact questions and all three broad controls. Rankings and metadata meaning were stable across repeats. The new-fixture p95 increased about **2.7%**, and mean MCP result size increased from **613.5 to 651.2 bytes** (6.2%). Peak MCP working set remained about 653.5 MiB. These short runs do not establish zero overhead or a statistically significant speed change. All runs used cached BGE-small embeddings, default thread settings and a 6,000 output budget. Development used TinyBERT with cutoff 0.30; the other fixtures used the optional quantized mMARCO reranker with cutoff 0.55. No model default was promoted. The byte budget includes serialization and is not billed tokens. ## What changes for an agent [#what-changes-for-an-agent] With `Orchid staging gateway port is 7319.` recorded, a recognized port-and-timeout question can return port evidence and identify timeout as missing. Production evidence cannot fill a staging request. Conflicting eligible values stay marked as conflicting even when a capsule cap or budget removes one source. Exact unit comparison treats `30 seconds` and `30000 ms` as equivalent. On a build containing this change, enable it with: ```sh kimetsu config set broker.explicit_fact_guard true ``` The default is `false`; set it back to `false` to disable it. Use v2.8.0 or a source build containing the merged changes; v2.7.0 packages lack this feature. An older warm daemon must be restarted with the updated build to use its new behavior. Schema 15 maintains a rebuildable SQLite projection bound to claim revisions, source events, validity and exact evidence excerpts. Corrections and replay refresh the projection; the tagged agent record path is covered. Ordinary retrieval skips fact hydration when the guard is disabled, but writes still maintain the projection. No extra model calls are needed; evidence sent to an agent still consumes context tokens. ## Remaining gaps and measurement limits [#remaining-gaps-and-measurement-limits] Six compound-question cases per repeat omitted port evidence: three retrieved nothing and three retrieved retries alone. Hit\@4 counts the latter as hits, which shows why retrieval hit rate is not complete answerability. Three cases using the subject word `Unknown` fell outside the conservative grammar and returned unrelated evidence through legacy fallback. These account for the remaining unwanted injections. The fixture is assistant-authored and repeats templates across three project names. It is not 45 independent task families, does not measure an LLM reader, and cannot certify corpus-wide conflict detection. No grammar, parameters or expectations changed after these results. Retrieval per requested attribute and safer unsupported-subject handling remain follow-up work. The measured implementation passed 1,470 workspace tests (six ignored), 132 benchmark Rust tests, 18 Python tests and six release CLI/MCP probes. Separate v2.8.0 release-preparation validation passed **1,500 workspace tests**, six ignored, plus **132 benchmark Rust tests** after the dependency refresh. [Release validation and security scope](https://github.com/RodCor/kimetsu/blob/785c3df/docs/audits/2026-09-08-release-security.md). Source: [full report, frozen fixtures, raw observations and hashes](https://github.com/RodCor/kimetsu/blob/281c6df/docs/audits/2026-09-07-structured-facts.md). # BEAM (/docs/memory-benchmark/beam) How Kimetsu scores on BEAM, the ten-ability long-term-memory benchmark, at the 100K and 1M token buckets. [BEAM](https://github.com/mohammadtavakoli78/BEAM) probes ten memory abilities (information extraction, multi-session reasoning, knowledge update, temporal reasoning, abstention, contradiction resolution, event ordering, instruction following, preference following, summarization) over conversations from 128K to 10M tokens, graded by an LLM judge against per-question rubrics. The `kbench beam` driver ingests each conversation into a fresh brain, retrieves per probe, answers with the Codex reader, and judges against the rubric. ## Results: 100K bucket [#results-100k-bucket] The full 100K bucket (20 conversations, 400 probes), v2.5 graph-lite backend, 96k retrieval budget. | ability | accuracy | | ------------------------ | ------------------- | | contradiction resolution | 40/40 (100%) | | preference following | 38/40 (95%) | | information extraction | 36/40 (90%) | | summarization | 34/40 (85%) | | temporal reasoning | 31/40 (77.5%) | | multi-session reasoning | 30/40 (75%) | | instruction following | 29/40 (72.5%) | | knowledge update | 24/40 (60%) | | abstention | 18/40 (45%) | | event ordering | 13/40 (32.5%) | | **overall** | **293/400 (73.3%)** | Three notes on what drives the result: * **Graph ranking moved the number, model-free.** The flat baseline scored 62.3% on the same set. Graph-lite lets a probe's top hits pull in their edge-connected neighbours with hop-decayed relevance, lifting the abilities that stitch facts across sessions (multi-session 35 → 75%, preference 72.5 → 95%). * **Global abilities need budget.** Summarization, contradiction resolution, and temporal reasoning need the whole arc. At 48k tokens they scored near zero; at 96k they reach 100% / 85% / 77.5%. The fix is a knob, not a redesign. * **The reader and judge are LLMs; the memory is not.** The pipeline feeding the reader makes zero model calls. The two laggards, abstention (45%) and event ordering (32.5%), are reader-behavior limits, not retrieval gaps. Reproduce with `kbench beam --dataset beam-100k.json --reader-backend codex`; the converter that builds the dataset from the BEAM repo ships in the bench tooling. ## Results: 1M bucket [#results-1m-bucket] A 1M-token conversation exceeds any context window, so this bucket tests retrieval ranking: the 96k budget surfaces \~10% of the conversation. Run on 15 of the 35 conversations (300 probes), uniform 96k budget. | ability | accuracy | | ------------------------ | ------------------- | | contradiction resolution | 27/30 (90%) | | knowledge update | 26/30 (86.7%) | | preference following | 25/30 (83.3%) | | information extraction | 24/30 (80%) | | summarization | 23/30 (76.7%) | | instruction following | 20/30 (66.7%) | | multi-session reasoning | 20/30 (66.7%) | | temporal reasoning | 15/30 (50%) | | event ordering | 9/30 (30%) | | abstention | 9/30 (30%) | | **overall** | **198/300 (66.0%)** | * **Kimetsu scores 66.0%; mem0 reports 64.1% in the 1M bucket.** The readers and conversation samples differ. Sources and test differences are recorded in [How Kimetsu compares](/docs/memory-benchmark/comparison). * **Global and temporal abilities degrade with scale, as expected.** When the conversation is \~10x the budget, whole-arc tasks lose ground that local-fact tasks keep. * **The buckets are not a controlled A/B**: different conversations, and the 100K run used a smaller budget for the localized abilities. Each overall is a standalone, reproducible figure. Reproduce with `kbench beam --dataset beam-1m.json --limit 15 --reader-backend codex`. The 10M bucket is future work: a faithful run needs the write-time distiller in the loop rather than raw per-turn ingest. mem0 reports 48.6% there; Cognee reports 67%. # BrainBench (/docs/memory-benchmark/brainbench) BrainBench is Kimetsu's own reader-free capability benchmark: it drives the real binary across difficulty tiers and scores dedup, forgetting, importance, and calibration with no LLM in the loop. The other pages measure parts of the brain. BrainBench measures the brain as a whole: a tiered benchmark that drives the real Kimetsu binary against authored fixtures, with a fresh brain per scenario and **no LLM reader in the loop**. The score reflects what the brain does, not what a frontier model can reason around it. A full run of the four live dimensions over 142 scenarios scores an **Overall Brain Quality Index of 80.0%**. By capability: | capability | what it tests | result | | --------------------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | retrieval correctness | recall / MRR / stale-suppression / contradiction resolution | strong (see [Retrieval & correctness](/docs/memory-benchmark/retrieval-and-correctness), 232 cases) | | **dedup** | detects near-duplicates without flagging distinct memories | **77%** (98 decisions) | | **forgetting** | forgets noise while keeping signal, scored after a real forget pass | **88%** | | **importance** | a salient, proven memory outranks equally relevant peers | **76%** | | **calibration** | confidence tracks proven usefulness | **82%** (newly instrumented) | ## v2.6.0 re-measurement (264 scenarios) [#v260-re-measurement-264-scenarios] For the v2.8.0 paired evidence-delivery measurements, see [Structured answerability](/docs/memory-benchmark/answerability). Its synthetic 45-query result is separate from the historical overall indices on this page. Re-run on the semantic build, all 264 scenarios of the comprehensive set, none skipped: | dimension | published | v2.6.0 | n | 95% CI | | ----------- | --------- | --------- | --- | ------ | | dedup | 77% | **77.0%** | 50 | ±7.5% | | forgetting | 88% | **87.8%** | 49 | ±8.3% | | importance | 76% | **92.1%** | 38 | ±8.7% | | calibration | 82% | **99.7%** | 122 | ±0.3% | | retrieval | — | 56.6% | 5 | ±33.6% | **dedup and forgetting reproduce almost exactly** — 77.0 against 77, and 87.8 against 88. That is the useful part of a re-run: two independent measurements of the same behaviour landing on the same number is evidence the harness and the brain are both stable. **Importance gained \~16 points**, which is outside its confidence interval and looks real. **Calibration reads 99.7%**, and that is a *problem*, not a win. This page's own standard is that a benchmark returning \~100% measures nothing; a track with a ±0.3% interval at n=122 has stopped discriminating. The calibration scenarios are synthesized from a retrieval pool rather than authored, and they have become too easy to be informative. Authoring hard calibration cases is the next investment there. ### The Overall Brain Quality Index is not comparable across these runs [#the-overall-brain-quality-index-is-not-comparable-across-these-runs] This run reports 91.3% against the 80.0% above, and **that delta should not be quoted as an improvement.** The index is an unweighted mean over whatever scenarios ran, and the mix changed: 264 scenarios versus 142, with calibration alone now 122 of them — 46% of the run, at 99.7%. A mean dominated by a saturated dimension goes up whether or not anything got better. Compare per dimension, where the scenarios are the same thing measured twice. The headline 80.0% is retained above as the figure it was, over the set it was measured on. ## Safety tracks (new in v2.6.0) [#safety-tracks-new-in-v260] Two dimensions that did not exist before. The v2.6 RFC claimed they did; that claim was withdrawn, and this is the real thing. | dimension | score | n | what it checks | | --------------- | ----- | - | -------------------------------------------------------------------------------------------- | | poisoning | 100% | 3 | quarantine holds; corroborated local outranks imported; `brain audit` surfaces a write burst | | render-contract | 100% | 2 | prior-conclusion framing + conflict rule; ordering carries dates | These confirm three shipped defences work: 4b import quarantine, 4a trust-weighted ranking (the local memory *outranks* the imported one rather than excluding it — trust is a weight, never a gate), and burst detection. **Both scoring 100% is a weakness.** By the standard above, a track that never breaks is not yet measuring anything; these five scenarios cover the straightforward case and have no adversarial case that fails. Treat them as evidence the mechanisms are wired, not as a safety score. **`render-contract` is deliberately not called "sycophancy".** MemSyco-Bench measures a *reader* over-deferring to memory against evidence in front of it. BrainBench has no reader, so that property is not measurable here — what is measurable is whether the injected text carries the preconditions for not deferring. A perfect score means the contract is intact, not that the brain resists sycophancy. Neither safety dimension is included in any Overall Brain Quality Index figure on this page. Two things keep it honest: 1. **It discriminates.** Easy tiers pass, hard tiers break. Dedup, importance, and forgetting all show a clean gradient from easy to complex; a benchmark that returns \~100% measures nothing. 2. **It exists to surface weaknesses.** The forgetting score caught that pruning by usefulness alone can drop a rarely cited but still useful memory. Calibration is the thinnest track and the next investment. We publish these before claiming them solved. Run it with `kbench brainbench`. The relationship to the public benchmarks: **LongMemEval is comparable, BrainBench is deeper.** It scores the write path and lifecycle behaviour a reader-driven benchmark hides. # How Kimetsu compares (/docs/memory-benchmark/comparison) How Kimetsu compares to mem0, Cognee, Zep, and Letta on the shared public benchmarks, and what we do not yet claim. ## How Kimetsu compares [#how-kimetsu-compares] mem0, Cognee, Zep, and Letta share a design: an LLM distills what to remember at write time, and most keep an LLM in the retrieval loop too. That buys accuracy at the cost of metered API spend on every question (mem0's own 2026 figures report \~7,000 tokens per retrieval call). **Kimetsu's memory pipeline makes zero LLM calls.** Ingest, store, retrieve, and rerank are FTS5 + local embeddings + a local cross-encoder. The claim is not "more accurate"; it is **the same accuracy band, without the LLM, the bill, or the cloud.** | benchmark | Kimetsu (local, model-free) | mem0 (self-reported) | Cognee (self-reported) | | ------------------ | ------------------------------------------ | ------------------------------ | ---------------------- | | LongMemEval (`_s`) | **83.0%** (200-q slice) · \~80.9% weighted | 94.4% (their reader + harness) | not reported | | LoCoMo (1,540 q) | **89.4%** | 92.5% | not reported | | BEAM 100K | **73.3%** (400 probes) | n/a | 79% | | BEAM **1M** | **66.0%** (300 probes) | 64.1% (700 probes) | not reported | | BEAM 10M | future work | 48.6% | 67% | Caveats, because the table is not apples-to-apples: * **The 1M row uses the same token bucket, with different setups.** Kimetsu's 66.0% covers 15 of 35 conversations; mem0 reports 64.1% over 700 probes. The readers and samples differ, so the score difference does not establish a head-to-head win. * **Cognee leads at 100K/10M.** Our 73.3% matches the prior public state of the art on 100K (the 0.735 Cognee cites as the number it beat), model-free. Cognee needs an LLM key on both the write and read paths. * **Vendor numbers are self-reported and often do not reproduce** (a published LoCoMo 91.6% re-ran closer to 58-66% in the 2026 roundups). We ship the exact harness and settings so ours can be checked. Bottom line: **the same accuracy band as the leading LLM-backed systems, with the entire memory pipeline local, free, and model-free.** For a head-to-head, run your system through the same `kbench` harness. Sources: mem0's [2026 benchmark roundup](https://mem0.ai/blog/ai-memory-benchmarks-in-2026), Cognee's [BEAM figures](https://github.com/topoteretes/cognee), the [LongMemEval](https://arxiv.org/abs/2410.10813) and [BEAM](https://github.com/mohammadtavakoli78/BEAM) papers. Mem0's BEAM 1M figure was checked on September 12, 2026. Its current reported 64.1% replaces the 62% previously quoted here. ## What we do not yet claim [#what-we-do-not-yet-claim] * Multi-hop retrieval of obliquely relevant memories is v2.6 work; the LongMemEval preference result (63%) is that ceiling on a public benchmark. * The LongMemEval number is a 200-question stratified slice with a specific reader, not the full 500. * BEAM covers the 100K and 1M buckets; 10M needs the write-time distiller in the loop and has not been run. * BrainBench's calibration track has the fewest scenarios and is still being scaled; read the scores per dimension. * Output-token savings in the ROI ledger are estimated, not metered. # Overview (/docs/memory-benchmark) Kimetsu's house rule is that every claim ships with a measurement. This section documents how we measure the brain and what the numbers are, so you can check them rather than take our word for it. ## The headline numbers [#the-headline-numbers] The [v2.8.0 structured-answerability study](/docs/memory-benchmark/answerability) reports a separate paired experiment: unwanted injections 15/18 → 3/18, with 24/27 positive hits retained and exact evidence metadata matching 36/45 cases per repeat. P95 changed from 376.6 to 386.6 ms; mean response size from 613.5 to 651.2 bytes. The linked study records build provenance and release status. It does not replace the historical published scores below or remeasure them on v2.8.0. | benchmark | result | | ------------------------ | ----------------------------------------------------------------- | | LoCoMo | **89.4%** (1,540 questions, LLM-judged accuracy) | | BEAM 100K | **73.3%**, matching the prior public state of the art, model-free | | BEAM 1M | **66.0%** (300 probes, 15 of 35 conversations) | | LongMemEval (`_s`) | **83.0%** (200-question stratified slice) | | BrainBench quality index | **80.0%** (142 scenarios, reader-free) | | retrieval quality | recall\@4 **0.949**, MRR **0.914** at \~138 ms | | stale-hit rate | **0.091** (was 0.500 on flat retrieval) | | cost per solved task | **\~13x cheaper** than a no-brain baseline | The historical results in the table use `jina-v2-base-code` + the `ms-marco-tinybert-l-2-v2` cross-encoder reranker unless noted, and the memory pipeline makes zero LLM calls: the reader in the public benchmarks answers questions, it never stores or retrieves. ## How this section is organized [#how-this-section-is-organized] We measure on three layers, one page each plus the comparison: 1. **[Retrieval and correctness](/docs/memory-benchmark/retrieval-and-correctness)**: the in-repo bench that gates every release. Recall, MRR, latency, stale-hit rate, and contradiction resolution, runnable with `kimetsu brain bench`. 2. **[BrainBench](/docs/memory-benchmark/brainbench)**: our own reader-free capability benchmark. It drives the real binary across difficulty tiers and scores dedup, forgetting, importance, and calibration, the write-path behaviour a reader-driven test can't see. 3. Public benchmarks, directly comparable to other memory systems: **[LongMemEval](/docs/memory-benchmark/longmemeval)** (chat-domain, per-question-type) and **[BEAM](/docs/memory-benchmark/beam)** (ten memory abilities over long multi-session chats). 4. **[How Kimetsu compares](/docs/memory-benchmark/comparison)**: the honest side-by-side against mem0, Cognee, Zep, and Letta, including where they lead. # LongMemEval (/docs/memory-benchmark/longmemeval) How Kimetsu scores on LongMemEval, the public long-term-memory benchmark, with the exact setup so the number can be reproduced and compared. [LongMemEval](https://github.com/xiaowu0162/LongMemEval) covers single-session, multi-session, temporal-reasoning, knowledge-update, and preference questions over long chat histories. The `kbench longmemeval` driver ingests the haystack into a Kimetsu brain, retrieves per question, answers with an LLM, and scores per question type. It is a chat-domain benchmark, so it tests Kimetsu's correctness machinery (temporal validity, supersession, multi-session recall) on a public standard. ## Results [#results] Setup: `longmemeval_s`, a 200-question stratified slice (round-robin across the six types), `jina-v2-base-code` for retrieval, Codex (`gpt-5.5`) as reader and judge. Each turn is ingested as its own memory tagged with its session date; retrieval runs through `kimetsu brain context` at a \~48k-token budget; the reader uses the date tags for time reasoning and prefers the most recent value when a fact changed. | question type | accuracy | | ------------------------- | ------------------- | | knowledge-update | 34/34 (100%) | | single-session-user | 32/34 (94.1%) | | single-session-assistant | 32/34 (94.1%) | | temporal-reasoning | 28/34 (82.4%) | | single-session-preference | 20/30 (66.7%) | | multi-session | 20/34 (58.8%) | | **overall** | **166/200 (83.0%)** | The slice samples types evenly, so we also report a population-weighted overall of **\~80.9%**, the better estimate of a full 500-question run (the full set is 53% temporal + multi-session, the two hardest types). The run had zero reader errors. Earlier runs on the same setup scored 79.5% (with three reader timeouts counted as misses) and, on a small 60-question slice, 86.7%; the error-free 200-question run is the number we stand behind. What the split shows: * **knowledge-update 100% and temporal 82.4%** validate the v2.5 correctness work. Both depend on the session-date tags: temporal scores near zero without them. * **Single-session recall is strong** (94% / 94%). * **Multi-session 58.8% and preference 66.7% are the weakest.** Cross-session counting needs every contributing turn retrieved; a preference is a small aside semantically far from the question. Both are the multi-hop retrieval work flagged for v2.6. Reproduce with `kbench longmemeval --dataset longmemeval_s.json --reader-backend codex --limit 200`. ## How we compare [#how-we-compare] On `longmemeval_s`, strong retrieval-based systems with a capable reader land in roughly the **60-80% band**; \~90%+ appears only under oracle retrieval, where the evidence is handed to the reader ([arXiv:2410.10813](https://arxiv.org/abs/2410.10813)). Kimetsu's 83.0% sits just above that band. We do not print a head-to-head table here because published figures vary by dataset variant, reader model, and budget; run your system through the same `kbench` harness for a direct comparison. ## Why this is not our best measure of the brain [#why-this-is-not-our-best-measure-of-the-brain] 83.0% understates the memory, for three reasons: 1. **It bypasses the write path.** The harness ingests raw turns, skipping the distiller, dedup, and write-time contradiction resolution, the parts of Kimetsu that are actually differentiated. 2. **A strong reader does much of the work.** A frontier reader over \~100 retrieved turns can brute-force answers a weaker memory would need to surface precisely. 3. **It is chat-domain, not ours.** The [retrieval and correctness numbers](/docs/memory-benchmark/retrieval-and-correctness) are the sharper signal for coding agents. Treat LongMemEval as the comparable number and [BrainBench](/docs/memory-benchmark/brainbench) plus the correctness metrics as the truer measure of the brain itself. # Retrieval & correctness (/docs/memory-benchmark/retrieval-and-correctness) Kimetsu's retrieval and correctness numbers: recall, MRR, latency, stale-hit suppression, and contradiction resolution, all reproducible from the shipped CLI. ## Retrieval quality [#retrieval-quality] On a 100-memory / 210-case dataset seeded from real exported memories (keyword, paraphrase, oblique, confusable, in-domain-no-answer, multi-answer): | metric | value | | --------- | ----------------------------------------- | | recall\@4 | **0.949** (default reranker), up to 0.975 | | MRR | **0.914** (default), up to 0.933 | | latency | \~138 ms per retrieval + rerank | The default (`ms-marco-tinybert-l-2-v2`) is the fastest reranked combo; the quality-best rerankers reach recall\@4 0.975 / MRR 0.933 at higher latency. Swap embedder and reranker with one config key each and re-judge on your own corpus. ## Memory correctness (v2.5) [#memory-correctness-v25] v2.5 ("The best memory") added a temporal validity model, automatic contradiction resolution, and validity-aware retrieval. We measure two things a plain vector store cannot do, on a correctness dataset of knowledge-update, contradiction, and temporal cases: * **stale-hit rate**: how often a superseded / outdated memory still shows up in the top-k. Lower is better. * **resolution accuracy**: on contradiction and knowledge-update cases, how often the *current / correct* memory outranks the stale one. Higher is better. | metric | before (flat retrieval) | v2.5 | change | | ------------------- | ----------------------- | --------- | ------ | | stale-hit rate | 0.500 | **0.091** | −82% | | resolution accuracy | 0.364 | **0.909** | +0.545 | A plain semantic store returns both the old and new fact because cosine similarity does not track recency or supersession, so a stale fact surfaces about half the time, and contradictions resolve barely better than chance. With v2.5, superseded facts are excluded from default retrieval (still queryable for history), and a new memory that contradicts an old one is resolved automatically by confidence × recency, with the loser invalidated-as-of (lineage preserved, never destroyed). ### No regression [#no-regression] The correctness work did not cost retrieval quality. The v2.0 retrieval baseline is unchanged in v2.5: on the 18-memory / 100-case set, recall\@4 0.977 / MRR 0.941 before and after. ## v2.6 re-measurement [#v26-re-measurement] v2.6 is the first release whose `--features embeddings` build actually compiles (see the RFC's Status section for why it did not), so it is the first chance to re-run these numbers on the semantic flavor rather than assert them. Same fixtures, same combos, binary reporting `kimetsu 2.6.0 (embeddings)`: | fixture | metric | published | v2.6.0 | | --------------------- | ---------------------------- | --------- | --------- | | 100-memory / 210-case | recall\@4 (default reranker) | 0.949 | 0.944 | | 100-memory / 210-case | MRR (default reranker) | 0.914 | 0.910 | | 100-memory / 210-case | recall\@4 (quality-best) | 0.975 | 0.970 | | 100-memory / 210-case | MRR (quality-best) | 0.933 | 0.930 | | 100-memory / 210-case | latency (default) | \~138 ms | 130 ms | | correctness (18 / 22) | stale-hit rate | 0.091 | **0.091** | | correctness (18 / 22) | resolution accuracy | 0.909 | **0.909** | The correctness numbers reproduce exactly. The retrieval numbers land within 0.005 of published on every metric — below the noise floor of an approximate-NN index, where HNSW traversal and MMR tie-breaking can reorder candidates that score within a rounding error of each other. **The published figures stand**: the house rule is that a published number is superseded only by a clean run that surpasses it, and a 0.005 shortfall is not a measurement that the number was wrong. What this run is evidence *for* is narrow and worth stating plainly: the semantic build does not retrieve worse than the flavor these numbers were measured on. It is not evidence for any ranking default. The two ranking rules added in v2.6 — `[broker] fusion = rrf` and `[broker] normalization = global` — are both still defaulted off, because this fixture cannot settle either: it is single-kind, which makes per-kind and global normalization arithmetically identical, and too small and uniform to be a fair test of rank fusion. ### Which combination to run [#which-combination-to-run] The full 2 × 5 embedder × reranker grid, on the 100-memory / 210-case set, binary `kimetsu 2.6.0 (embeddings)`. Sorted by MRR: | embedder | reranker | recall\@2 | recall\@4 | MRR | mean ms | peak RSS | | --------------------- | ---------------------------- | --------- | --------- | ----- | ------- | ---------- | | jina-v2-base-code | jina-reranker-v1-turbo-en | 0.949 | 0.970 | 0.930 | 565 | 2002 MB | | jina-v2-base-code | ms-marco-minilm-l-4-v2 | 0.954 | 0.959 | 0.930 | 363 | 2352 MB | | jina-v2-base-code | jina-reranker-v1-tiny-en | 0.944 | 0.970 | 0.926 | 415 | 1982 MB | | bge-small-en-v1.5 | ms-marco-minilm-l-4-v2 | 0.944 | 0.959 | 0.926 | 729 | 1331 MB | | bge-small-en-v1.5 | jina-reranker-v1-tiny-en | 0.944 | 0.964 | 0.925 | 785 | 1060 MB | | bge-small-en-v1.5 | jina-reranker-v1-turbo-en | 0.934 | 0.964 | 0.923 | 943 | 1079 MB | | **jina-v2-base-code** | **ms-marco-tinybert-l-2-v2** | 0.914 | 0.944 | 0.910 | **125** | 1551 MB | | bge-small-en-v1.5 | ms-marco-tinybert-l-2-v2 | 0.919 | 0.949 | 0.909 | 484 | **521 MB** | | jina-v2-base-code | off | 0.827 | 0.878 | 0.824 | 101 | 1467 MB | | bge-small-en-v1.5 | off | 0.812 | 0.863 | 0.810 | 462 | 361 MB | **The recommendation is the shipped default** — `jina-v2-base-code` × `ms-marco-tinybert-l-2-v2`, which is what `[retrieval] level = "deep"` resolves to. It gives up 0.020 MRR against the best combination and runs **2.9× faster** for it. Nothing in the grid dominates it: every combination that scores higher costs at least 3× the latency, and the two that also want less RAM cost 4–8×. Three things the grid says that are worth more than the ranking: 1. **The reranker is the whole game.** Turning it off costs \~0.10 MRR — five times the spread between the best and worst *reranked* combination. If you tune one thing, tune this. `level = "flexible"` (embedder, no reranker) is the configuration to avoid unless RAM is genuinely scarce. 2. **The embedder barely matters once a reranker is present.** Every reranked pair lands in 0.909–0.930. Picking `bge-small` buys a 3× smaller resident set at \~0.001 MRR — a real trade for a constrained host, and close to free in quality terms. 3. **bge-small is not the fast option on this corpus, despite being the small model.** It is faster on the 18-memory fixture (18 ms vs 32 ms unreranked) and 4× *slower* on the 100-memory one (462 ms vs 101 ms). Two independent runs agree to within 2%, so the effect is real; the cause is not established here, and the note is left as a measurement rather than dressed up as an explanation. Choose `bge-small` for memory footprint, not for speed, and re-measure on your own corpus if latency is what you care about. None of this settles `[broker] fusion` or `[broker] normalization`. Both fixtures are single-kind, which makes the normalization rules arithmetically identical and leaves fusion with too little to fuse. ### Cold start, measured [#cold-start-measured] The steady-state latencies above are all *warm*. The first semantic retrieval in a **fresh brain** is a different number entirely, and v2.6 is the first release able to measure it: | call | fresh brain | same brain, second call | | ----------------------------------- | ----------- | ----------------------- | | `brain context` (jina-v2-base-code) | **122 s** | 1.5 s | | `brain context` (bge-small-en-v1.5) | **57 s** | — | | `brain context` (lean / FTS-only) | 0.3 s | 0.3 s | The cost is per *brain*, not per process: a second workspace pays it again even with a model already resident from the first. This is why the `UserPromptSubmit` context hook is FTS-only by deliberate design — the code comments say a cold ONNX load "can exceed the host's 30s hook timeout", and on this hardware it exceeds it by four times over. The daemon exists to absorb exactly this, and the hook never waits on a cold one. It is worth knowing before running any harness that seeds a fresh brain per case. BrainBench does, which puts a 264-scenario run in the ten-hour range on the semantic build; the harness refuses a lean binary outright, because FTS-only retrieval would crater the scores rather than measure them. ## Cost [#cost] On a recorded 16-task Terminal-Bench slice, runs with the brain cost about 13× less per win than the no-brain baseline ($0.19 vs $2.47), measured on Claude Code at Claude pricing. See `docs/ROI-METHODOLOGY.md` for the methodology and the `kimetsu brain roi` ledger for per-memory savings on your own work. ## How to reproduce [#how-to-reproduce] ```bash # retrieval quality + correctness metrics (semantic build, cached models) kimetsu brain bench --dataset .json \ --embedders jina-v2-base-code --rerankers ms-marco-tinybert-l-2-v2 # the summary table reports recall@2/4, MRR, latency, and (when the fixture # has temporal/contradiction cases) stale_hit_rate + resolution_accuracy. ``` The eval fixtures live in the bench tooling; the harness (`kimetsu brain bench`) ships in the CLI, so you can run the same metrics against your own exported memories.