Skip to content

release: v0.9.0 - #85

Merged
ashu17706 merged 15 commits into
mainfrom
dev
Aug 2, 2026
Merged

release: v0.9.0#85
ashu17706 merged 15 commits into
mainfrom
dev

Conversation

@ashu17706

@ashu17706 ashu17706 commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Release Summary

  • Version: v0.9.0
  • Source: dev
  • Target: main
  • Scope: promote validated changes from dev to main

Changes Included

Validation

  • CI passed on dev
  • Perf bench reviewed (if relevant)
  • Breaking changes documented
  • Release notes verified

Notes

  • PR / Tests and cross-platform Push / Tests show 4 known pre-existing failures (test/learn-entities.test.ts x3, test/team-segmented.test.ts x1) — a global fetch-mock isolation issue between test files under full-suite load, confirmed present before this release's changes and consciously deferred (not a regression). Bench / ci-small passes after fixing a real bug this release surfaced (recallMemories crashing against a bare QMD store without smriti_session_meta).

ashu17706 and others added 14 commits May 3, 2026 12:34
- --whole flag for `smriti ingest file`: stores .md as single message (no paragraph splitting); warns without flag
- `smriti projects <id>`: rich inspection report — sessions, messages, agents, tags, decisions, recent sessions
- `smriti tags`: global or --project-scoped tag usage counts; --available mirrors category tree
- `smriti status --project <id>`: scopes all stats (agents, categories) to a single project
- 29 new tests in test/recall.test.ts covering all retrieval paths (full-doc, tags, project reports, multi-filter)
QMD submodule is now a clean upstream fork (d58fedf, v2.1.0+) — no
Smriti-specific code lives there. Future upstream syncs are conflict-free.

- src/memory.ts: moved from qmd/src/memory.ts; imports updated to
  ../qmd/src/store.js and ../qmd/src/llm.js; uses QMD's Database type
- src/ollama.ts: moved from qmd/src/ollama.ts; self-contained, no changes
- src/qmd.ts: re-exports now come from ./memory and ./ollama
- qmd submodule: bumped to d58fedf (upstream v2.1.0+34 commits of fixes)

Upstream picks up: security dep bumps, db-transaction-type fix, embedding
overflow hardening, sqlite-vec actionable errors, GGUF magic error fix,
Windows home fallback, status device probe opt-in, and more.
Adds `smriti consolidate` and `smriti learnings`, applying Progressive
Summarization: cheap Stage-1 segmentation runs broadly over dense sessions
into a new smriti_knowledge_units table, and expensive Stage-2 polish
(existing segmentSession/generateDocument pipeline) only runs once a unit
proves reuse via recall or scored high relevance at extraction time.

- src/db.ts: smriti_knowledge_units table + CRUD helpers
  (insertKnowledgeUnit, findUnsegmentedDenseSessions, findPromotableUnits,
  incrementRetrievalCount, promoteKnowledgeUnit, listKnowledgeUnits)
- src/search/recall.ts: track retrieval_count on every recall() path
- src/learn/consolidate.ts: segment + promote phases, reusing the existing
  3-stage segmentation pipeline from src/team/segment.ts and document.ts
- src/index.ts, src/format.ts: CLI wiring for `consolidate` and `learnings`

CLI-only, not wired into the daemon — consolidation runs two LLM stages,
which the daemon's flush path deliberately avoids (see the enrichOnIngest
comment in src/daemon/index.ts).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PnYgLUDwWALu1bUAgrFQDG
Extends the Continuous Knowledge Consolidation Layer with canonical
entities and typed subject-predicate-object relationship triples,
inspired by RDF's data model (adapted pragmatically: no URIs/SPARQL,
just typed (subject_type, subject_id) pairs in SQLite).

- src/db.ts: smriti_entities + smriti_relationships tables; new
  `minEntityReach` promotion criterion in findPromotableUnits (a unit
  becomes promotable once its entity is independently mentioned by K
  other units, even at 0 retrievals); seeds a "team" agent (fixes a
  latent FK bug in syncTeamKnowledge's existing agent fallback)
- src/learn/entities.ts: resolveEntity (exact-normalize canonicalization
  via slugify), insertRelationship/getRelationships (triple store),
  findRelatedCandidates, findEntity, getUnitsForEntity
- src/learn/consolidate.ts: segment phase turns Stage-1 entities into
  "mentions" edges for free; promote phase adds one bounded LLM call to
  infer relatesTo/supersedes/contradicts edges against entity-sharing
  candidates, persisting what ollamaCheckConflicts previously only
  computed ephemerally
- src/team/config.ts, share.ts, sync.ts: entities propagate team/org-wide
  through the same .smriti/config.json round-trip custom categories
  already use (exportEntities/mergeEntities mirror
  exportCustomCategories/mergeCategories); unit-to-unit relationship
  edges propagate via frontmatter directly, needing no canonicalization
  since unit ids are already portable UUIDs. Also fixes sync.ts treating
  "consolidated" pipeline docs as raw conversation transcripts (only
  "segmented" was previously recognized as single-message).
- src/index.ts, src/format.ts: `smriti graph <entity>` command;
  `--min-entity-reach` flag on `smriti consolidate`

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PnYgLUDwWALu1bUAgrFQDG
When two units sharing an entity are promoted in the same consolidate
run, each independently asks the LLM "do I supersede/contradict the
other" — found via a live demo that this can produce both directions
asserted simultaneously (A supersedes B and B supersedes A), which is
incoherent for a directional predicate. Skip inserting the reverse edge
if the candidate already asserted it in the other direction.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PnYgLUDwWALu1bUAgrFQDG
The prompt asks for "RELATION [i]: predicate" but Ollama reliably gets the
index/predicate right while dropping the literal brackets (observed:
"RELATION 0: supersedes"). The regex required them exactly, so correct
answers were silently discarded — inferRelationships swallows all errors
by design (enrichment, not a promotion precondition), so this failure mode
had zero visibility: promotion succeeded, the edge just never appeared.

Verified against real Ollama output: a hand-fed prompt produced a correct
"supersedes" verdict in 16s that the old regex dropped entirely; after the
fix, an end-to-end consolidate run against seeded sessions produced a real
relatesTo edge, confirmed via `smriti graph`.

Also logs when a non-empty response yields zero parsed lines, since that
almost always means format drift rather than every candidate genuinely
being unrelated.
Replace regex-parsed "RELATION [i]: predicate" free-text prompting with
a native tool call (record_relationships) for promote-time relationship
inference — the model returns structured JSON directly, so there's
nothing to drift from or fail to parse. classifyRelationshipsTextFormat
is kept only as the "before" baseline for the eval comparison in
test/eval/relation-inference.eval.ts.

Also requires QMD_MEMORY_MODEL to be explicitly set (config.ts's new
requireOllamaModel()) instead of every Ollama call site silently
falling back to a hardcoded default model.
Live comparison of classifyRelationshipsTextFormat (regex-parsed,
"before") vs classifyRelationshipsToolCall (native tool call, "after")
against 9 hand-labeled scenarios, run against the real configured
Ollama model. Manual-only (.eval.ts suffix, excluded from `bun test`) —
run via `bun run eval:relations`.
… eval harness

Closes the three gaps found when mapping Smriti against a standard
6-layer AI memory architecture (working memory, episodic store,
semantic/facts, store/search/update/forget tools, a consolidation job,
and an eval harness) — forget and prune existed only as dead code or
not at all, and the only eval was a narrow classifier A/B test.

- forget: `smriti forget <session-id>` (soft by default, --hard --yes
  for real deletion) and `forget --all [filters]` for bulk. Re-exports
  deleteSession/clearAllSessions from src/qmd.ts, adds forgetSession()
  orchestration (sidecar cleanup, unpromoted knowledge units + their
  relationship edges, orphaned vector embeddings) in src/db.ts.
  Canonical (promoted) units/docs are kept unless --purge-shared.

- prune: `smriti consolidate --prune` expires stale never-promoted
  knowledge units (0 retrievals, low relevance, 30+ days old) and
  soft-archives canonical units superseded by a newer one (tier
  'archived', doc kept with a deprecation banner). Dry-run by default;
  --yes/--apply to mutate. Pure DB logic, no LLM call.

- eval harness: test/eval/fixtures/ (multi-session scenarios covering
  cross-session recall-over-time, project-filter isolation, density-
  score tie-breaking, and a semantic-only match). Tier 1
  (test/recall-quality.test.ts) is BM25-only and runs in `bun test`;
  Tier 2 (test/eval/recall-quality.eval.ts, `bun run eval:recall`) adds
  embedding-dependent scenarios and asserts vector search actually
  fired rather than trusting a silent BM25 fallback.
mockOllamaFetch's `relation` handler still simulated the old
/api/generate free-text response ("RELATION [i]: predicate"), but
inferRelationships was switched to classifyRelationshipsToolCall, which
calls ollamaChat -> /api/chat with a `messages` body (no `prompt` field)
and expects a native record_relationships tool call back. The mismatch
made the mocked fetch throw (reading .includes on the now-undefined
body.prompt), silently swallowed by inferRelationships' best-effort
try/catch, so both tests asserting on the inferred edges failed with
0 edges instead of 1.

Distinguish /api/generate (stage1/stage2, has body.prompt) from
/api/chat (relation inference, no body.prompt) and return a
tool_calls-shaped response for the latter; relation handlers now return
structured {index, predicate} guesses instead of a free-text string.
Resolves conflicts against dev's:
- 9fd16f6 feat: recall quality & project inspection (issue #56) —
  `smriti projects <id>`, `smriti tags`, `--whole` ingest flag,
  project-scoped `status`. Ordinary content conflicts in db.ts (auto-
  merged), format.ts, index.ts (kept both sides' additions).
- dbb2eeb refactor: move memory.ts + ollama.ts out of QMD submodule.
  Add/add conflict on src/memory.ts and src/ollama.ts — kept "ours" in
  both cases after diffing: this branch's versions are a strict
  superset (getMemoryLlm via the SDK store, recallMemories's fast/
  intent/expandQuery/rerank/density-blending pipeline,
  cleanupOrphanedMemoryVectors, tool-call support, ollamaAsk/
  ollamaDrift/ollamaCheckConflicts) — dev's copies were the bare
  just-extracted-from-submodule versions with none of that.
  qmd submodule pointer: kept ours (da67604) — confirmed dev's target
  (d58fedf) is an ancestor of it, so nothing from dev's bump is lost.
- 91effef fix(ci): picomatch@4 root dep — already present via
  package.json's clean auto-merge.

bun.lock: kept ours, verified consistent via `bun install` (no changes
made). Verified with `bun test --cwd ./test`: 404 pass, 4 fail — same
pre-existing failures as before this merge (learn-entities.test.ts x3,
team-segmented.test.ts x1; a known full-suite-only global-fetch-mock
isolation issue, unrelated to this merge). Manual smoke test: both
`smriti forget`/`smriti consolidate --prune` and dev's `smriti
projects`/`smriti tags` work correctly in the merged CLI.
recallMemories' density-blending step queries smriti_session_meta
directly, but src/memory.ts moved out of the qmd submodule specifically
to stay usable as a clean, Smriti-agnostic layer (see the dev merge) —
scripts/bench-qmd.ts runs it against a bare QMD store with no Smriti
tables at all, which crashed with "no such table: smriti_session_meta".

Wrap it in the same try/catch pattern already used for the vector-search
fallback a few lines up: no smriti_session_meta means no density signal,
so skip the blend and keep the RRF/rerank-only ordering.
feat(learn): consolidation layer + RDF-inspired entities/relationships graph
@github-actions github-actions Bot changed the title release: dev -> main release: v0.8.2 Aug 2, 2026
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Benchmark Scorecard (ci-small)

Bench Scorecard (ci-small)

threshold: 20.00%

metric baseline current (median) delta status
ingest_throughput_msgs_per_sec 1735.800 304.490 -82.46% WARN
ingest_p95_ms_per_session 6.960 38.134 +447.90% WARN
fts_p95_ms 0.410 0.784 +91.22% WARN
recall_p95_ms 0.436 1.092 +150.46% WARN

Summary: WARN (4 metrics)

@github-actions github-actions Bot changed the title release: v0.8.2 release: v0.9.0 Aug 2, 2026
@ashu17706
ashu17706 merged commit 3dc496a into main Aug 2, 2026
15 of 18 checks passed
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