canonic knowledge operates on knowledge/**/*.md pages directly: independent of connectors and canonic ingest.
knowledge search
Hybrid search over knowledge/**/*.md pages: a lexical (BM25, tantivy) arm that’s always on, fused with an optional vector (cosine similarity) arm when the canonic[embeddings] add-on is installed. See Knowledge and LLM & embeddings runtime for how the two arms combine and degrade.
Each hit shows a human-readable match label, its RRF-fused
score, which arm(s) matched (via=lexical, via=vector, or via=lexical+vector), and the page’s usage_mode:
match (strong / good / weak) is computed by comparing each hit’s score against the top hit’s score in this same result set. It’s a CLI-only presentation aid (not present in --json/MCP output) and, like the score itself, only meaningful relative to the other hits in this one search.
--json output matches the MCP search_knowledge tool payload byte-for-byte.
Without the
embeddings add-on installed, search runs lexical-only, never a failure, just a narrower match. When embeddings are available, page vectors are cached under .canonic/knowledge-index/ and only re-embedded when a page’s content actually changes, so repeated searches don’t re-run the model over the whole knowledge base.Reading score
score is not a confidence percentage or a “how relevant is this, 0–100%” number: a 0.033 next to a hit is not “3.3% relevant.” It’s a Reciprocal Rank Fusion (RRF) score: each arm (lexical, vector) ranks the pages it matched, and a page’s contribution from an arm is 1 / (60 + rank), where 60 is a fixed damping constant and rank is 0 for that arm’s top hit, 1 for its second, and so on. A page matched by both arms sums both contributions.
That makes the scale small and bounded on purpose:
- Best possible score for a single-arm match (rank 0 in that arm):
1/60 ≈ 0.017. - Best possible score for a hit both arms rank first:
2/60 ≈ 0.033.
score=0.033 is actually the ceiling: it means this hit was the top result in every arm that matched it, not a weak 3% match. What the number is for is ordering results against each other in this one search, not judging any single hit in isolation, and it isn’t comparable across different queries or projects. See Knowledge → Retrieval for how the two arms combine.
knowledge add
Fetch one external document and write it as a knowledge page, the one-shot counterpart to registering a recurring connections: entry and running canonic ingest.
The fetched content is classified the same way
canonic ingest classifies evidence: usage mode (reference / caveat / policy / definition) and candidate topic references are inferred and matched against your live semantics. The rendered page is shown before writing. An unmatched candidate reference is surfaced as a note, never silently linked. Every page written this way has meta.provenance: inferred, so it’s clear it hasn’t been hand-reviewed yet.