Wisdom Knowledge System
- Role
- Product architecture and retrieval engineering
- Ownership
- Designed, built, tested, and operated independently
- Stack
- Python, SQLite FTS5, Sentence Transformers, Markdown
- Status
- Operating private CLI on a home server; no web service
I built Wisdom to query a private Markdown corpus while keeping retrieved records separate from generated interpretation. The application runs on my home server and returns bounded evidence packets to an answering agent. A deterministic validator controls what can become a displayed answer.
Records carry an explicit contract
Each record has a stable identity and schema-defined metadata. Record kind describes its role, while content kind, origin, and attribution describe the material and how an answer should name it. The records live in one flat collection, so folder location does not silently determine meaning.
Application contracts remain outside the searchable record set. Operational notes and production work stay in a separate vault. A catalog validator checks records before indexing, and the query runtime searches only the admitted corpus. The metadata does not rate a record's credibility or truth.
Neutral retrieval comes first
SQLite FTS5 combines weighted lexical search with named-entity and phrase matching. Local MiniLM embeddings rerank lexical candidates, and reciprocal-rank fusion combines those two orders. The initial pass uses only the question, without a preference for one record kind or an interpretive perspective.
Separate passes retrieve attributed sources and contrasting material already present in the corpus. An optional interpretive layer enters after neutral retrieval and can use only the supplied passages. It cannot add facts or alter the initial ranking.
Vectors are keyed by passage-content hash. Incremental updates preserve unchanged embeddings even when metadata or file locations change. The semantic model loads from a local cache, and the runtime keeps generated databases outside the notes vault.
Answer validation is executable
The evidence packet includes ranked passages, attribution, stable record identity, and file-and-line provenance. A packet-specific citation catalog connects short citation IDs to those records. A packet identifier binds the draft to the question and governing answer contract.
The answering agent returns typed blocks for record summaries, multi-record synthesis, or grounded interpretation. The validator rejects mismatched packets, unknown citations, invalid block shapes, and improper ordering. It also enforces citation requirements and the number of records needed for each block type. A failed draft is withheld rather than displayed as an answer.
When retrieval cannot support the question, the runtime renders a fixed insufficient-corpus response. Match-quality gates measure relevance to the question; they do not certify that a source is correct. Structural validation also cannot prove that a cited passage supports a generated claim. Subject and claim alignment still require review.
Private operation and recovery
The Python CLI runs only on my home server. Workstations invoke it over SSH; there is no daemon, HTTP API, or public web interface. SQLite and local model files are derived machinery, while Markdown remains the durable record.
Incremental sync reconciles changes transactionally. Full index builds install atomically, and content-addressed vectors can be reused. Tests cover record admission, retrieval behavior, packet binding, and answer rendering. Rejection cases exercise missing citations and invalid synthesis as well as insufficient-corpus output.
What this demonstrates
- Schema-driven content modeling with stable identity and explicit attribution
- Hybrid lexical, entity, and semantic retrieval with an inspectable neutral-first flow
- Executable answer contracts that bind generated drafts to retrieved evidence before rendering
- Transactional indexing, reusable local embeddings, and recoverable private operation