Skip to content

v1.0.0 — durable migrations, analytics, semantic retrieval (usearch HNSW), Kimetsu Remote#19

Merged
RodCor merged 137 commits into
mainfrom
release/v1.0.0
Jun 10, 2026
Merged

v1.0.0 — durable migrations, analytics, semantic retrieval (usearch HNSW), Kimetsu Remote#19
RodCor merged 137 commits into
mainfrom
release/v1.0.0

Conversation

@RodCor

@RodCor RodCor commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Ships Kimetsu v1.0.0: the brain becomes durable, measurable, semantically sharp, shareable over the network — and proven to scale to ~1M memories.

Highlights

  • Durable schema migrationsbrain.db migrates forward automatically on open (versioned, forward-only, one transaction per migration, backup sidecar before any version-advancing migration).
  • Proof-of-value analyticskimetsu brain insights (+ MCP tool): hit/skip rate, citation rate, proposal acceptance, usefulness trend, corpus health, token economy.
  • Semantic retrieval (usearch HNSW) — meaning-based recall on the embeddings build, O(log N) per query; embedding-MMR + absolute relevance floors. Lean (FTS-only) build unchanged.
  • Warm embedder daemon — a single per-user daemon holds the ONNX models in memory and serves semantic retrieval to the UserPromptSubmit hook over a local socket / named pipe; ≤300ms budget with hard FTS fallback (the prompt is never blocked); pre-warmed at harness SessionStart.
  • Cross-encoder reranking — final-stage rerank of the candidate pool (fastembed curated models or any HF ONNX repo via hf-hub). Wired into the local daemon and the Remote server.
  • Proactive & cost-shrinking recall — "known pitfalls" before the first attempt, task classification, per-run dedupe ledger, on-demand capsule expansion (adaptive sublinear budget).
  • Kimetsu Remote (beta) — share one brain per repo over HTTP MCP; bearer auth; optional org-brain + server-side ingest; TLS via proxy or in-process; ANN pre-warm at startup; operator-level --reranker stage.

Retrieval quality — measured, not vibes

New measurement tooling drove every ranking default in this release:

  • kimetsu brain eval — recall@2/4 + MRR across fts / semantic / semantic+rerank modes against a committed fixture.
  • kimetsu brain bench — full embedder × reranker grid over a 100-memory / 210-case dataset built from real exported memories (confusable clusters, oblique phrasings, in-domain no-answer, open multi-answer cases); per-case expected-vs-obtained, latency, and per-combo RAM (process-isolated). --remote drives the same dataset through a real kimetsu-remote server over HTTP (sequential + concurrent) and measures server RSS + throughput.
  • Benchmark-chosen defaults: local = jina-v2-base-code + ms-marco-tinybert-l-2-v2 (MRR 0.914 @ ~132ms retrieval+rerank — the fastest reranked combo, within ~2% of the grid best); remote = same embedder + --reranker jina-reranker-v1-tiny-en (no latency budget there). FTS-only baseline: MRR ~0.81.
  • Relevance floors that actually fire: an IDF-weighted lexical coverage floor (kills "matches only the project name" noise, with query-side stemming so inflected words still match), and a model-aware AUTO cosine floor (0.35 on bge-family, off elsewhere — the remote benchmark caught the bge-calibrated floor deleting relevant jina-v2 results, MRR 0.90 → 0.77).

Agent-loop fixes (found via real-world usage)

  • Stop hook emits valid hook JSON — bare-text banners tripped Claude Code's "invalid stop hook JSON output"; the harvest cue now actually reaches the model via decision: "block".
  • First-prompt hang fixed — the lazily-spawned daemon inherited the hook's stdout handle on Windows and could stall the harness until its hook timeout; the daemon now binds before loading models and the hook clears HANDLE_FLAG_INHERIT before spawning.
  • Write tools work out of the box locallykimetsu.mcp_write_tools (default on) replaces the env-only gate that contradicted the brain's own "record a lesson" workflow every session. Remote stays env-only, default-deny (cloned-repo config is untrusted).

Performance & scale (this release's deep-dive)

The vector path went from a brute-force O(N) scan to a real ANN index, validated at 1,000,000 memories:

  • usearch HNSW replaces sqlite-vec (dropped) for both retrieval and conflict-detection-on-write — both now O(log N).
  • Batched embedding for bulk ingest; parallel index build across cores; incremental maintenance + reconcile-on-hit (never stale); sidecar persistence (a restarted server loads instead of rebuilding) + startup pre-warm on Remote.
  • f16 index quantization by default (KIMETSU_ANN_QUANTIZATION=i8|f32 to tune) — the index is candidate-generation only, with an exact f32 cosine rerank from SQLite, so quantizing is near-lossless (recall@10 0.994 f16 / 0.966 i8).
  • Measured at 1M (bge-small, ext4): ~1.8 s p99 semantic retrieval; ~3.1 GB RAM (f16) / ~2.8 GB (i8) — fits a 3–4 GB container. Remote no longer collapses at scale (0 errors, isolation enforced).
  • Remote at 100 memories (HTTP, concurrency 4): ~0.906-0.909 MRR, ~420-700ms/request, ~4-5 rps depending on embedder.

Design + plan: docs/superpowers/specs/2026-06-06-tier3-hnsw-usearch-design.md, docs/superpowers/plans/2026-06-06-tier3-hnsw-usearch.md.

Verification

Every change gated on cargo fmt, clippy -D warnings (lean and embeddings flavors), the workspace failure-audit (empty), and cargo tree -p kimetsu-cli -i usearch empty (the native ANN dep never reaches the lean CLI). 802 workspace tests pass (lean build; the daemon/reranker/ANN suites additionally run under --features embeddings). Retrieval defaults validated on three datasets (synthetic fixture, 18-real-memory corpus, 100-memory confusable-cluster corpus) plus live latency smokes on the real brain.

🤖 Generated with Claude Code

RodCor and others added 30 commits June 3, 2026 12:05
Introduce KIMETSU_CONFIG_VERSION (the project.toml format version),
separate from KIMETSU_SCHEMA_VERSION (the brain.db schema). The DB schema
can now advance via migrations without forcing project.toml rewrites or
breaking existing projects on open. Prep for the schema-migration runner.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add kimetsu-brain/src/migrate.rs: a forward-only migration runner that
advances brain.db from its stored schema_info version to the binary's
target, each migration applied with its schema_info bump inside one
transaction (crash-safe, resumable). Empty migration set for now; the
v1->v2 fold and the initialize wiring land next.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Split schema::initialize into create_baseline + the migration runner. The
historical add_column_if_missing patches, citations/conflicts tables, and
FTS reshapes now live in a single idempotent v1->v2 migration; existing
brain.db files (all stamped v1) and fresh ones converge to the v2 shape and
are version-stamped. Replaces the old run kimetsu brain rebuild hard-error
with automatic forward migration on open.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
run_with snapshots the live DB to a brain.db.bak-<from>-<to>-<ts> sidecar
(SQLite online backup, WAL-consistent) before applying any version-
advancing migration, and prunes to the newest 3 backups on success. No
backup for in-memory DBs or no-op opens. Recoverable if a migration fails.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ration)

schema::validate now hard-errors only when the DB is NEWER than the binary;
an OLDER DB returns a typed SchemaNeedsMigration. open_user_brain_readonly
treats that as Ok(None) (a stale user brain no longer breaks unrelated
read-only ops; the next read-write open migrates it); load_project_readonly
surfaces it so the next read-write load_project migrates.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
apply_event now dispatches through upcast_event, the localized point where a
future EVENT_SCHEMA_VERSION bump normalizes older payloads to the current
shape (identity today). Lock the projector's missing-field durability with
per-kind tests: every event kind replays from an empty payload without panic,
so old/sparse trace events project losslessly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ackup

Skip the pre-migration backup when the brain has no memories to protect (no
more useless brain.db.bak on fresh installs); log the migration via tracing;
add the brain.db schema version to `brain status`; reframe `brain rebuild`
help (schema upgrades are automatic on open). End-to-end test: an existing
populated project brain AND user brain upgrade v1->v2 with a backup sidecar
and preserved data.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Golden tests for every install merge writer (Claude/Codex hooks, MCP config,
CLAUDE.md): pre-existing user entries survive, Kimetsu's are added alongside,
and re-install is byte-idempotent. Full install-path tests per target x scope
preserve seeded user content; an upgrade-idempotency test proves a second
install can't corrupt managed files. Add windows-latest to the PR test matrix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add kimetsu-brain/src/analytics.rs: read-only proof-of-value metrics
(proposal acceptance, corpus health, harvest yield, usefulness trend,
citation rate, token economy) over a recent-runs window. Extend the
context.injected event with used_tokens + capsule_count so token economy is
measurable. Retrieval hit-rate / skip-rate land with context.served (C7).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Surface the analytics module as a CLI command (human table + --json,
--last-n-runs/--since/--top) and a matching MCP tool with an interpretation
string. Retrieval hit-rate shows n/a until context.served lands (C7).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Log every retrieval (hit or miss) as a context.served event: from the
UserPromptSubmit context-hook (best-effort, hashed query, opt-out via
KIMETSU_BRAIN_LOG_RETRIEVAL=0) and from the autonomous pipeline. Analytics now
computes retrieval hit-rate, avg top score, and skip-rate over a time window
(hook events have no run, so they're counted by timestamp). Removes the
n/a-until-C7 placeholders.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the sqlite-vec dependency under the embeddings feature and register it
once before every brain DB open. Proven on the MSVC host: a vec0 virtual
table creates and a KNN MATCH query runs. No-op on the lean build. Foundation
for ANN candidate generation (D1b-D1c).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a derived vec0 index (memory_vec) reconciled on demand from memories,
and union a KNN semantic-recall pass into memory_candidates on embeddings
builds — finding memories whose meaning matches the query even when no words
overlap (replacing the recency-bounded fallback). Rebuilds on embedder
change; lean (FTS-only) retrieval is unchanged. Derived structure, not a
numbered migration, so lean/embeddings DB schema stays identical.

D1b: ensure_vec_index() creates memory_vec (vec0, TEXT PRIMARY KEY mapping
via approach 1: vec0(memory_id TEXT PRIMARY KEY, embedding float[D])) plus
memory_vec_meta tracking the active (model_id, dim). Drops and recreates on
embedder change; incremental INSERT/DELETE reconciliation on each call.

D1c: memory_ann_candidates() runs a KNN query (MATCH + ORDER BY distance +
LIMIT 80) on the vec0 index, fetches full memory rows, builds Candidates via
memory_row_to_candidate. memory_candidates() on embeddings builds now unions
FTS + ANN candidates, deduping by memory_id (higher raw_relevance wins).

D1d: four new tests — ANN semantic match FTS misses (oracle embedder), vec
index rebuild on model-id change, dedup guarantee, lean-unchanged path with
NoopEmbedder. 151/151 tests pass on embeddings build; all workspace tests
green; lean build clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Embedding-MMR collapses true paraphrase near-duplicates (cosine redundancy,
Jaccard fallback); an absolute semantic-relevance floor drops genuinely
off-topic candidates so irrelevant queries hit the zero-capsule path. Render
caps honor the configured budget/max_capsules instead of a hard-coded 12, and
defaults drop now that selection is more precise. Lean (FTS-only) retrieval
unchanged. Token economy proven lower for the same queries with the relevant
capsule preserved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
No not_implemented subcommands ship in 1.0: `config edit` opens $EDITOR on
project.toml and re-validates on save; `run abort <id>` cleanly finalizes a
dangling run (run.aborted event + lock release), erroring on unknown/terminal
runs. `kimetsu doctor --selftest` proves the brain works end-to-end (record →
retrieve) hermetically, and the README gains a 5-minute quickstart.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fix all workspace clippy warnings on the lean and embeddings builds
(derivable impls, doc indentation, idiomatic iterator/string fixes, a real
MSRV-1.85 portability fix, targeted allows on retrieval arg-count). Flip the
CI clippy job from advisory to a hard gate denying warnings on both flavors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
In-memory per-run bookkeeping of what the brain has surfaced/injected:
is_injected/mark_injected with once-counted token accounting (F1 cross-stage
dedup) and is_surfaced/mark_surfaced (E1/E2 proactive dedup). Pure leaf data
structure; consumers wire it into the pipeline next.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A brain capsule rendered into an earlier stage's prompt is back-referenced
(not re-rendered in full) in later stages of the same run, and its token cost
is counted once. Brain overhead now shrinks as a task spans more stages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…mpt (E1)

Before the first implementation attempt, a tight failure_pattern/convention
retrieval surfaces known pitfalls for the task as a "Known pitfalls" prompt
block — proactive recall, not just post-failure. ~Zero tokens when nothing
matches (high min_score + kind filter); the run recall ledger stops a pitfall
being re-surfaced on retries.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Classify each task once (deterministic keyword classifier, no model call) as
Debug/Feature/Refactor/Docs/Investigation, threaded on ContextRequest. A
task-kind weight layer composes over the stage weights (renormalized) and
biases kind preference (Debug→failure_pattern, Refactor→convention,
Investigation→fact/preference) so recall fits the task. Feature is the neutral
default — existing retrieval behavior is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… (F2)

Inject top-confidence capsules in full and the long tail as ~1-line headlines
the agent expands on demand via a new expand_capsule(handle) tool (resolves
memory:/file: handles to full text, emits capsule.expanded for measurement).
Up-front tokens drop sharply while recall stays high — the marginal cost of
breadth approaches zero. Composes with F1 (no double-charge).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Capsule sort tiebreaks used capsule.id, a fresh random ULID minted per
retrieval, so two retrievals over the same corpus could order score+freshness
ties differently — non-reproducible retrieval. Tiebreak on expansion_handle
(memory:<id> / file:<path>), the stable identity, matching search_repo_files.
Surfaced by the E3 task-kind-neutral test flaking under feature-unified runs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…io (F3)

Replace the flat 6000/stage budget with one that grows sublinearly with a
defined task-size signal (task + localized-context tokens), floored so small
tasks aren't starved and globally capped per run via the recall ledger so
total brain tokens grow far slower than task size. TokenEconomy exposes the
overhead ratio (brain tokens / total run tokens); on the small vs 5x-larger
fixtures brain tokens grow <2x and the ratio strictly falls — the measured
form of "cheaper on larger tasks."

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bump workspace + inter-crate versions 0.9.0 -> 1.0.0 and document the v1.0.0
release: durable schema migrations, proof-of-value analytics, sqlite-vec
semantic retrieval, proactive + cost-shrinking agent recall, install
hardening, and polish (implemented subcommands, doctor --selftest, enforced
clippy).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…1.1/W1.2)

reset_projection no longer wipes events (and now also clears the previously-
missed citations/conflicts); add rebuild_in_place that replays the events
table into the derived tables without re-inserting (no duplication). Factor
project_event out of apply_event. Foundation for dropping per-write run dirs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
kimetsu brain rebuild now replays brain.db's events table in place, with a
--from-traces flag (and an auto-fallback when the table is empty but on-disk
traces exist) to recover history from legacy run traces.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
add_memory/propose/ingest/accept/invalidate/reject stop creating a TraceWriter
run directory — their events persist to brain.db's durable events table (and
the runs-table row, blame, usefulness are all kept). A brain-only .kimetsu/ no
longer fills with per-write run dirs. Also fixes an orphan empty-dir on dedup.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stop eagerly creating the runs/ dir on init; create the .kimetsu/ dir itself
(needed for project.toml + brain.db). runs/ is now created lazily only by the
agent pipeline. A brain-only install never grows a runs/ tree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Lock the core invariant of the durable-events-log change: a pipeline run's
events land in brain.db and survive rebuild_projection (which now replays the
events table, not trace.jsonl).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add [embedder] enabled, [broker] ambient, and [kimetsu] use_user_brain
project.toml fields (serde-default true) so every optional feature can be
turned off durably, honored at runtime with env override > config > default.
Existing/partial project.toml files load unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
RodrigoCordoba and others added 26 commits June 9, 2026 13:51
The UserPromptSubmit hook now tries the warm embedder daemon first
(semantic retrieval) and falls back to floored-FTS when the daemon is
disabled, unreachable, or cold. The `retrieval_path` field (daemon or
fts_fallback) is recorded in the `context.served` telemetry event.
Adds `ContextCapsule::wire_minimal` for constructing render-only capsules
from daemon wire data, and a unit test covering the adapter.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wire `kimetsu brain warm` to each harness startup event so the embedder
daemon pre-warms when the harness starts:
- Claude Code: SessionStart hook group (upsert_kimetsu_hook, idempotent)
- Pi: kimetsuExec([brain,warm]) prepended in the session_start handler
- OpenClaw: kimetsuExec([brain,warm]) called at plugin registration time
- Codex: no session-start event; daemon warms lazily on first prompt (comment)

Three new tests (claude_hooks_include_sessionstart_warm,
pi_extension_ts_session_start_includes_warm,
openclaw_plugin_ts_register_includes_warm) all pass; 122 total pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- gate brain_warm() on config.embedder.warm_on_start before resolving model
- self-connect after Shutdown to unblock accept() without a manual nudge
- treat PermissionDenied/AlreadyExists as benign Windows race exits (exit 0)
- add 50ms backoff in accept-loop error arm to avoid busy-spin
- spawn_daemon directly on retrieval miss instead of re-pinging via ensure_daemon

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…capsules

Adds v1.0.0 cross-encoder reranking to the kimetsu-brain retrieval pipeline:
- `Reranker` trait (Send+Sync, doc-order scores) + `StubReranker` (token-overlap
  based, deterministic, no-model-download) near existing `Embedder`/`StubEmbedder`
- `FastembedReranker` (behind `#[cfg(feature="embeddings")]`) wrapping
  `Mutex<TextRerank>` for the 4 curated BGE/JINA models; sigmoid-normalizes
  raw logits, maps results back to document order via `.index`
- `open_reranker_for_model`: ungated signature, gated body mirroring
  `open_embedder_for_model`; off/none/empty → None, lean → always None
- `rerank_capsules` in context.rs: final-stage rerank by summary, overwrites
  score, stable-sort descending, floor filter, cap truncation, fail-open on error
- 9 new tests (5 rerank_capsules + 4 StubReranker), all passing; clippy clean

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- config: add `embedder.reranker` field (default `jina-reranker-v1-turbo-en`,
  serde-defaulted so older configs load cleanly with the reranker on)
- server: `DaemonState` gains `reranker: Option<Box<dyn Reranker>>`;
  `retrieve` over-fetches a 12-capsule pool when reranking, bumps budget
  to ≥6000 tokens, then applies `rerank_capsules` with a 0.30 floor
- cli: `EmbedDaemonArgs` gains `--reranker`; `brain_embed_daemon` opens
  the reranker inside the timed block; new `resolve_daemon_reranker`
  reads config; `brain_warm` and `try_daemon_retrieve` pass the reranker
  through `ensure_daemon` / `spawn_daemon`
- client: `REQUEST_BUDGET` 750 → 300ms (embed ~10ms + ANN + rerank-of-12
  ~30–80ms fits; anything slower falls back to FTS by design)
- test: `retrieve_with_stub_reranker_reorders_and_caps` — hermetic temp
  brain, NoopEmbedder + StubReranker, verifies the rust/tokio memory
  beats the python/django one and exactly 1 capsule returns

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tually wired

min_semantic_score defaulted to 0.0 AND was never populated from config in any
production path, so the cosine floor was dormant. Default it to 0.35 and wire
it from BrokerSection into the two embeddings-capable retrieval paths (MCP
tool + warm daemon), same if-zero-then-config pattern as min_lexical_coverage.
Set 0.0 in project.toml to restore keep-everything behaviour.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tic|rerank

Adds `kimetsu brain eval` which measures recall@2, recall@4, and MRR for
three retrieval modes (lexical-FTS, semantic ANN+cosine, semantic+rerank)
against a committed 42-memory/26-case fixture, giving a quantitative signal
for threshold and ranking changes instead of vibes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ness

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three measured fixes from the latency investigation:
- Bind the socket BEFORE loading models in the daemon entrypoint, so a
  redundant spawn exits in milliseconds instead of after a multi-second
  model load.
- Windows: clear HANDLE_FLAG_INHERIT on the hook's std handles before
  spawning the daemon. The long-lived child otherwise inherits the
  harness's stdout pipe and holds it open forever, stalling the first
  prompt of a session until the host's hook timeout.
- Default `[embedder] reranker` to "off": full-fidelity reranking costs
  ~0.5-1s (beyond the 300ms hook budget) and forcing it under budget via
  snippet truncation + smaller pools regressed eval recall@4 from 0.83 to
  0.66 (below FTS). The default hook path is semantic + the 0.35 cosine
  floor (recall@4 0.90, MRR 0.91, ~230ms warm end-to-end); reranking
  stays as a quality-over-latency opt-in at quality-optimal settings
  (full summaries, pool 12).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds HuggingFace Hub download path for non-curated reranker models
(jina-tiny, ms-marco TinyBERT-L-2-v2, ms-marco MiniLM-L-4-v2) and a
--rerankers flag to `kimetsu brain eval` that measures load latency,
per-query rerank latency (mean + max), recall@2/4, MRR, and noise
suppression side-by-side for all four cross-encoder candidates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…fault

Benchmark (eval --rerankers, release build): jina-reranker-v1-tiny-en beats
turbo on both quality (recall@4 0.896 / MRR 0.938 vs 0.833 / 0.875) and
speed (~95ms vs ~137ms/query). On the real brain's long memories a pool-12
rerank still exceeds the 300ms hook budget (measured ~670ms+ totals =
timeout fallbacks), and semantic+floor already matches tiny's recall@4 at
~230ms warm — so the default stays off and tiny becomes the documented
opt-in recommendation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The pool-6 experiment closed the loop: with FULL summaries, pool 6 matches
pool-12 quality exactly on the eval fixture (recall@2/4 0.882/0.896, MRR
0.938, noise 0) at half the rerank latency (~44ms/query), and on the real
brain a warm pool-6 jina-tiny rerank answers inside the 300ms hook budget
(~265ms measured; totals 422-473ms end-to-end and descending). The earlier
pool-shrink regression was the snippet truncation, not the pool.

- default [embedder] reranker: "off" -> "jina-reranker-v1-tiny-en"
- daemon RERANK_POOL: 12 -> 6 (quality-equal, half the cost)
- eval gains --pool for pool-size sweeps

Slower machines degrade gracefully to floored-FTS for the turn; set
reranker = "off" to opt out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…path

Two gaps surfaced by real-world usage:

- Inflected query words matched nothing: FTS prefix (benchmarked*) and the
  IDF document-frequency LIKE both miss "benchmark", so the query's one
  discriminating token got df=0/zero weight and the relevance floor went
  blind ("how is kimetsu benchmarked?" surfaced off-topic memories that
  merely shared "kimetsu"). Light query-side stemming (strip ing/ed/es/s,
  keep >=4-char stems, haystacks raw) fixes FTS, lexical scoring, and IDF
  at once. Eval fixture improves: FTS recall@4 0.715 -> 0.778, MRR 0.812 ->
  0.875; semantic MRR 0.910 -> 0.931.

- retrieve_proactive (PreToolUse/PostToolUse recall) never got the lexical
  floor, so an off-topic memory sharing a ubiquitous token with the command
  line could take the single proactive slot. Wire min_lexical_coverage from
  config like the other retrieval paths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The brain's prescribed workflow (record lessons via kimetsu_brain_record,
Stop-hook harvest cue) contradicted the default-deny write gate: agents were
nagged into a hard-blocked call every session. Make the gate config-driven
for the local stdio server via kimetsu.mcp_write_tools (default true,
settable with `kimetsu config set kimetsu.mcp_write_tools false`).

Precedence is a pure, unit-tested decision: env var when set always wins
(both directions) > remote deny > local config (default allow). The remote
server stays env-only default-deny — a cloned repo's project.toml is
untrusted input and must never be able to enable writes (covered by a
dispatch-level test using allowed_tools as the remote marker).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…/RAM grid

Adds `kimetsu brain bench` subcommand (embeddings-gated; lean build prints a
notice). Orchestrator mode spawns one child process per embedder×reranker combo
for honest per-combo RSS measurement; each child writes a JSON file then exits.
After all combos finish the orchestrator reads the JSON files, sorts by MRR, and
writes bench/results/summary.md.

Per-combo worker: loads embedder + reranker (measuring Windows WorkingSet RSS
via K32GetProcessMemoryInfo), seeds a hermetic temp brain with KIMETSU_BRAIN_EMBEDDER
set to the combo embedder so stored vectors match query vectors, then runs all 45
dataset cases with min_score=0.0/min_lexical_coverage=0.0 for unfiltered recall.

Cargo.toml: adds Win32_System_ProcessStatus + Win32_System_Threading to
windows-sys features for K32GetProcessMemoryInfo / GetCurrentProcess.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nchmark

Defaults chosen by kimetsu brain bench on real exported memories: the
code-tuned embedder recovers oblique dev-phrased queries bge-small never
gets into the candidate pool and injects ~4x less off-topic noise; TinyBERT
reranks the pool in ~43ms (any reranker beats none; reranker-vs-reranker
deltas are within noise at this corpus size). Docs: new "Retrieval models &
benchmarking" section in HOW-KIMETSU-WORKS with the grid table + model-swap
instructions (reindex required on embedder change), README results blurb.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-remote

Adds `kimetsu brain bench --remote` which benchmarks the kimetsu-remote
HTTP MCP server with the same 100-case dataset.json used by the local bench.
Measures per-case recall@2/4 and MRR (sequential), HTTP latency (sequential
and 4-way concurrent), server-process RSS (warm + peak), across embedders.
Writes per-embedder remote-<emb>.json and remote-summary.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… over-filtering

The 0.35 cosine floor was calibrated on bge-family distributions; the new
kimetsu-remote benchmark showed it killing relevant jina-v2 results outright
on every production path (MRR 0.90 -> 0.77, recall@2 == recall@4). The
config default becomes -1.0 = AUTO, resolved per session embedder: 0.35 for
bge-family, disabled for others (jina-v2's own precision already keeps noise
at ~1.2 capsules). Explicit non-negative config values are respected as-is.
Re-run confirms jina-v2 remote recovers to MRR 0.903 / recall@4 0.966.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lt jina-tiny

Add a cross-encoder rerank stage to kimetsu-remote. The server now
reranks every kimetsu_brain_context call with a configurable cross-encoder
(--reranker, default jina-reranker-v1-tiny-en, off disables).

Implementation:
- kimetsu-chat: refactor kimetsu_brain_context into pub brain_context_tool()
  taking Option<&dyn Reranker>; None path (stdio) is byte-identical.
  Exports REMOTE_RERANK_POOL=6, REMOTE_RERANK_FLOOR=0.30 mirroring the
  embed daemon constants.
- kimetsu-remote: add --reranker ServeArgs field (default jina-tiny),
  load once at startup into AppState::reranker (Arc<dyn Reranker>),
  intercept tools/call for kimetsu_brain_context in rpc.rs when the
  reranker is present (same pattern as the ingest interception).
- Tests: brain_context_tool_with_stub_reranker_reorders_and_caps (unit),
  reranker_in_appstate_intercepts_brain_context (roundtrip). All 141 pass.
- Docs: HOW-KIMETSU-WORKS §7a "Retrieval models on the server",
  README results blurb, CHANGELOG v1.0.0 entry.
- Bench: re-ran 100-case remote benchmark WITH reranker; results:
  jina-v2-base-code MRR 0.906 (+0.002), bge-small MRR 0.909 (+0.008).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…guard

Truthfulness audit: README + HOW-KIMETSU-WORKS quoted 18-memory-corpus
metrics (0.938/0.966/43ms) as 100-memory results — replaced with the real
100-memory grid (0.914/0.949/132ms for the default combo, full table);
CHANGELOG had sed-duplicated entries in every release section (deduped to
v1.0.0), a stale "off" reranker default, pre-reranker remote numbers, and
the old 750ms budget.

Code audit (no criticals): rerank_capsules now fails open on a score-count
mismatch from a custom reranker instead of silently dropping the unscored
tail; the remote bench wraps its spawned server in a kill-on-drop guard so
error paths can't orphan a live server holding the port and temp dir.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fmt was never run during the retrieval/daemon/bench work (13 files
reformatted). The lean --no-default-features --all-targets clippy flagged
embeddings-only items compiled ungated: gate the daemon wire protocol
(proto, PROTOCOL_MAJOR) and the bench RSS helpers behind the embeddings
feature.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CI clippy runs on Linux, where the Windows-only update preflight
(decide_preflight_action, PreflightAction, the Scheduled outcomes,
stopped_mcp counter) and the WMI/CSV process parsers are dead code.
Annotate them with #[cfg_attr(not(windows), allow(dead_code/unused_mut))]
— the established pattern here — instead of cfg-gating the fns, so
cross-platform unit tests keep compiling everywhere.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@RodCor
RodCor merged commit 2041f1b into main Jun 10, 2026
13 checks passed
@RodCor
RodCor deleted the release/v1.0.0 branch June 10, 2026 17:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants