Skip to main content
Concept · Explanation

Knowledge base

Project entities, decisions, and links live in .senkani/knowledge/*.md — markdown as source of truth. SQLite is a rebuilt index. KBLayer1Coordinator detects staleness and recovers from corruption.

Why markdown + rebuilt index

Markdown is diff-able, review-able, and human-editable. SQLite is fast. Senkani keeps the markdown as the source of truth and the SQLite index as a derivable artifact — if the index gets corrupt or stale, rebuild it from markdown. This is the inverse of the usual pattern ("DB is truth, exports are stale") and it prevents whole classes of data-loss bugs.

Entity → link → decision

FTS5 search

search_knowledge hits the FTS5-indexed body text. BM25 ranking. Queries are sanitized (FTS5 operator syntax stripped) before execution.

Enrichment + validation

High-mention entities (≥ 5× per session) get queued for Gemma enrichment via MLX. EnrichmentValidator flags information loss (enrichment shorter than original body), contradiction (enrichment contains negation of source claims), and excessive rewrite (low Jaccard similarity) before commit. The goal is strict drift detection — enrichment is additive, not editorial.

Rollback + timeline

Every enrichment commit creates an append-only history row. senkani kb rollback <id> reverts the latest enrichment; senkani kb history <id> lists prior versions; senkani kb timeline is a chronological view of all KB mutations across the project.

Layer 1 coordinator

KBLayer1Coordinator detects SQLite index staleness (markdown newer than indexed) and corruption (unreadable pragmas). In either case it rebuilds from markdown without stopping the MCP server. Hand-edits to .senkani/knowledge/*.md are safe — the index follows.

Portable vault (Phase V.7)

The markdown vault is project-local by default but relocatable. Set kb_vault_path in ~/.senkani/config.json (or pass senkani kb migrate --to <path> — the CLI persists the path for you) to keep the vault next to other Obsidian vaults instead of inside the project tree. The resolver appends <project-slug> per-project so multiple repos sharing one vault root never collide on entity name. senkani kb migrate and senkani kb unmigrate move files in either direction; both are content-hash idempotent (running twice is a no-op) and surface conflicts (dest content differs) as a non-zero exit instead of silently overwriting. WikiLinkResolver handles click-through resolution for [[Name]] with folder-hint disambiguation ([[skills/auth/Login]] vs [[skills/admin/Login]]).

Bridge to compound learning

See compound learning for the KB ↔ learning bridge: entity-mention counts boost proposal confidence; applied context docs seed entity stubs; rolling back an entity invalidates derived context docs.