v0.12.0
0.12.0
- feat:
recallgainshops=2— walk one more level of graph relations in the same direction, tagging hop-2 items withvia(the hop-1 id they were reached through) instead of resolving a title, since a hop-2 item is a navigation breadcrumb, not read content - feat:
searchfuses a third RRF channel —_exact_match_search, an IDF-weighted literal title/tag token match. BM25 and embeddings both dilute a proper noun among lexically-similar distractors on a larger corpus; this channel recovers it by literal substring match, weighted so a rare token counts more than one shared by dozens of entries, and abstains belowMIN_EXACT_DISCRIMINATING_TOKENSmatching tokens rather than let SQL row order decide ties. MRR improved 0.851 → 0.857 and recall@5 improved 0.851 → 0.869, with no regression on any language slice - feat:
searchresults drop the volatileaccess_count/last_accessed/stalenessfields — display-only, drift with wall-clock time on every call — so identical repeated searches stay byte-identical for prompt-cache reuse; still exposed viarecall/doctor - refactor:
ENGRAM_*CLI/env resolution (duplicated betweenserver.pyanddashboard/__main__.py) and tuning constants (write-gate/staleness thresholds, RRF/exact-match knobs, pagination/duplicate-detection defaults — previously scattered acrosssearch_backend.py/database.py, including a cross-import between them just to share two of them) consolidated intosrc/config.py. No behavior change — same env var names, same defaults - docs: README documents the exact-match channel and
hops=2, and adds a comparison against the same content packaged as a conventional Markdown wiki — Engram answers with fewer tool calls, less total context, and less wall time for equivalent fact coverage
0.11.1
- fix: dashboard
/api/graphnow includespart_ofmembership as edges — after thepart_ofmigration (kb:// hub back-links replaced by the structural frontmatter field), members whose only connection was a stripped back-link rendered as isolated nodes.KnowledgeBase.get_graph()adds apart_of/part_of-typed edge per membership, skipping any hub already reachable via a keptkb://link (e.g.patternentries)
0.11.0
- feat: entry taxonomy moves into
schema.json— per-type rules (required frontmatter, template body fields,part_ofmembership, usage-boost/digest behavior) are data, not Python. A generatedentry_typeenum enforces it client-side onremember, and a newdoctorMCP tool audits every entry against it (dangling/supersededkb://links, undeclared types, missing fields, supernodes, tag/type collisions).part_ofadds structural membership from a detail entry to its hub, filterable onsearch/listand grouped in a hub'srecalldigest - feat: BM25 now retries with OR when an implicit-AND match returns nothing; retrieval-ranking quality (hit@k/recall@k/MRR) is now tracked internally, and optional
ENGRAM_QUERY_LOGtracessearch/recallcalls to JSONL to support it - fix: hub entries no longer skew search ranking from their own read count; the schema's
edgeslist is now actually enforced; the write gate checks 20 candidates instead of 4; a tz-naivelast_accessedno longer crashessearch;resourcesurvives an update that omits it; search hits no longer inflateaccess_count(onlyrecalldoes) - Breaking:
rebuild'sschema_warningskinds now come from thedoctorreport (malformed_resourcedropped,missing_type→type_outside_schema)
Docker: docker pull foreigndmitryi/engram:0.12.0 (also tagged :latest)