← engrava.ai

Changelog

These are the published releases of engrava on GitHub, synced at build time from the repository's Releases feed — newest first, drafts and pre-releases excluded. Install from PyPI. Subscribe via the RSS feed.

v0.6.0

View on GitHub

0.6.0 stops hybrid search from silently dropping its keyword arm, takes archived thoughts out of default retrieval, raises a typed error on a wrong-dimension query vector, and adds three opt-in extension points. It migrates the database schema (user_version 18 → 20), and if you wrote your own embedding provider there is one thing to check: dimension has to be public. Details below.

What changed for you

Hybrid search keeps its keyword arm on hard queries. A quoted phrase, a wildcard, or a bare boolean operator used to produce an FTS5 MATCH expression that failed, and the BM25 arm was dropped without a signal — the query still returned vector results, so the loss was invisible. Those expressions are now quoted or normalized, a failed first attempt is retried through bare-query normalization before the arm is dropped at all, and every first-attempt failure increments fts_match_failure_count. This is a correctness fix to which arms run, not a change to how results are ranked.

Archived thoughts leave default retrieval. search_similar, search_fts, search_hybrid and recall now exclude LifecycleStatus.ARCHIVED rows unless you pass include_archived=True. list_thoughts and count_thoughts are unchanged. If your application relied on archived rows coming back from recall, account for that before you deploy.

Wrong-dimension query vectors fail loudly. search_similar and the vector arm raise VectorDimensionMismatchError instead of raising an incidental ValueError or returning an empty list. Empty, all-zero and non-finite vectors still return an empty result rather than raising, and increment vector_arm_degradation_count.

Edges carry metadata. link_thoughts accepts an arbitrary metadata mapping and the edge reads return it. Schema step 18 → 19; existing edges read back metadata == {}.

A second recency axis. Recency can now score on transaction time with a caller-supplied now, alongside the existing cycle-based mode. Existing behaviour is the default; the new axis is opt-in.

Inverted validity intervals are rejected. A valid_from later than valid_until is refused at write time rather than stored, where it would quietly skew the as-of queries that read it.

Memory hygiene archives less eagerly. A thought must now be inactive for a minimum age before it is eligible at all, and a run archives nothing unless the candidate pool carries actual evidence of use — a read, a confirmation, or an action outcome. Cycle-recency and confidence do not count, because they exist on every store: on a bulk import with no usage history they would let ingest order alone decide what gets evicted. Permanently collecting a hygiene-archived thought also waits out a wall-clock restore window (schema step 19 → 20 adds thought.archived_at). If you enabled hygiene on 0.5, omitted fields resolve to a seven-day minimum age and a 30-day restore window — review them before the first 0.6 run. Rows archived before the upgrade have no wall-clock stamp and fail closed: they are not auto-collected while the window is active.

Extension points. Three, all opt-in. A derived-records seam, where an extension produces records from the thoughts you write, plus a derive_existing() backfill so a store that already holds data can be brought up to date rather than only deriving from here on. A structural split producer with two dependency-free modes — split on a configurable blank-line boundary (the default, and the previous behaviour byte for byte), or fixed windows measured in characters or words with optional overlap. And a cycle-provider seam: you supply the cognitive-cycle counter the store stamps records with, and the new max_cycle() accessor reports the store's high-water mark across thoughts and edges, so a consumer can resume its own counter after a restart. Migrating a store does not enable any of them.

Upgrading from 0.5

This is a schema-changing minor upgrade. Back up the database, stop the 0.5 workers, let one 0.6 process run ensure_schema() (or engrava migrate) to completion, then start the 0.6 workers. Do not run 0.5 and 0.6 workers against one file across the migration. Both steps only add columns — no table is dropped, and no value you wrote is rewritten.

An edge you set to decay_multiplier = 0.0 may already read 1.0. On 0.5 the column stored the value you wrote, but the decode tested it for truthiness and handed back the 1.0 default — and because update_edge rebuilds the record from that read, any later change to such an edge, including an invalidate_edge closing its valid-time interval, persisted 1.0 over the stored 0.0. 0.6 decodes on presence, so 0.0 round-trips as written. The migration does not undo what 0.5 already overwrote — it only adds columns, as above; where a 0.5 update replaced a stored 0.0, the database holds 1.0 and 0.6 reads that back faithfully. If you set 0.0 deliberately, re-check those edges after upgrading. Full note: Upgrade to 0.6.

If you wrote your own embedding provider, read this one. EmbeddingProviderProtocol has always required a public dimension, but 0.5 read it at exactly one site off the query path — so a provider that kept the value privately (self._dimension, no public property) worked for as long as nothing called verify_embedding_model(). 0.6 reads it before every vector search that has to ask the provider — a sqlite-vec backend is consulted first and takes the dimension from its own vec0 table, so that configuration never reaches the provider read. Everywhere else, such a provider now raises EmbeddingProviderContractError naming the class and the missing member. The fix is a property:

@property
def dimension(self) -> int:
    return self._dimension

The check is lazy — construction still succeeds, and a store that never searches by vector is unaffected — so call verify_embedding_model() after construction if you would rather fail at startup. We hit this in one of our own integrations.

Full notes, including both migration steps and the behaviour changes above: Upgrade guide, 0.5 → 0.6 · Known limitations

engrava-mcp

engrava-mcp 0.6.0 ships alongside this release and moves its engrava range to >=0.6,<0.7 — 0.5 is dropped, so upgrade both together. The server surface becomes 13 tools, 3 resources and 3 prompts: get_edges and list_edges close the write-but-can't-read asymmetry on edges, link_thoughts accepts edge metadata, search_memory accepts recency_now, and metadata_equals / metadata_in filters are available on the wire.

pip install --upgrade engrava

Features

  • add derived-records extension seam commit
  • core: add derive_existing() backfill for the derived-records seam commit
  • core: add opt-in cycle-provider seam and max_cycle accessor commit
  • edges: add generic metadata carrier with schema v19 migration commit
  • extensions: add zero-dependency split modes to StructuralSplitProducer commit
  • hygiene: add a wall-clock restore window before permanent GC commit
  • hygiene: guard archival behind a minimum inactivity age and a usage-signal gate commit
  • search: add transaction-time recency axis with caller-supplied now commit
  • search: exclude archived thoughts from default retrieval commit
  • search: reject wrong-dimension query vectors and count vector-arm degradation commit

Bug Fixes

  • cli: cover the expiry sweep and report an unreadable snapshot commit
  • cli: give an invalid --service name a distinct, clean error commit
  • cli: purge the vector index when gc collects a thought commit
  • cli: validate a resolved empty or default service name commit
  • cli: validate snapshot-restore input against a typed model and restore atomically commit
  • close Free audit source follow-ups commit
  • config: enforce uniform validation across sections and construction paths commit
  • config: make the validated value the value that gets used commit
  • config: use assign-to-variable message in unknown-key rejection commit
  • core: reject inverted valid_from/valid_until intervals commit
  • dreaming: propagate real integrity failures during edge creation commit
  • embeddings: name the provider member a search needs instead of failing on it commit
  • infra: harden core bootstrap and edge integrity classification commit
  • infra: keep foreign-key enforcement safe on every swap failure path commit
  • infra: make the v11->v12 child-table swap atomic via a savepoint commit
  • infra: write only the fields an update owns commit
  • journal: reclaim per-connection append locks with a weak-key registry commit
  • mindql: build the passthrough guard on a value the module owns commit
  • mindql: validate identifiers where the query is executed commit
  • read-only: capability-separate the read-only view from the core protocol commit
  • search: keep FTS5 MATCH valid so quoted and wildcard queries never silently drop BM25 commit
  • search: quote exposed FTS5 boolean operators so bare queries never lose BM25 commit
  • sqlite: harden core migration registry commit
  • sqlite: harden extension migration identity and statement splitting commit

v0.5.0

View on GitHub

Features

  • remove the in-tree MCP server (now the standalone engrava-mcp package) commit
  • action-outcome feedback loop and mutable action lifecycle commit
  • add opt-in deterministic memory-hygiene forgetting loop commit
  • batch/get-or-create write primitives and embed-failure visibility commit
  • opt-in typed provenance-context capture at create_thought commit
  • activate consolidation — reachable scoring + live access substrate commit
  • opt-in asymmetric query/document prefixes commit
  • expose hash-chain verification via API, CLI, and on-open gate commit
  • read-surface ergonomics — IN, boolean WHERE, ORDER BY, OFFSET, EXPLAIN, bound SELECT commit
  • add collapse_key de-fragmentation to hybrid retrieval commit
  • add metadata and visibility filters to ranked retrieval commit
  • add opt-in per-unit retention depth for collapse backfill commit
  • batch read-path decode, inbound edge index, eviction visibility commit

Bug Fixes

  • use absolute GitHub links in README so PyPI does not 404 commit
  • add opt-in cold-start clustering fallback commit
  • make archived thoughts restorable to ACTIVE commit
  • apply filters/visibility in the query-less fallback arm commit
  • correct the sqlite-vec backend — purge deleted vectors, fill top_k commit
  • neutral midpoint for the degenerate min-max fusion case commit
Maintenance (46)
  • gitignore *.pem so publishing keys are never committable commit
  • extend commitlint scope allowlist and sync docs/scopes.md commit
  • bump actions/checkout from 5 to 7 (#32) commit
  • bump actions/create-github-app-token from 2 to 3 (#31) commit
  • list Engrava on the official MCP Registry (server.json + OIDC publish) (#33) commit
  • remove the stale in-tree MCP registry artifacts (#42) commit
  • switch MCP Registry namespace to ai.sovantica (DNS auth) (#38) commit
  • ignore the mcp-publisher binary commit
  • cover non-terminal verification no-op and mixed-mean exclusion commit
  • drop stale .consolidate phantom-guard entry (real since dreaming activation) commit
  • execute or behaviour-assert every example; register compile-only blocks commit
  • cover 6th-signal activation e2e and access-flush journal exclusion commit
  • cover access-buffer cap/FIFO-eviction invariants commit
  • cover cold-start clusters under content-quality gating commit
  • cover require_embedding on the update_thought re-embed path commit
  • assert restore journals UPDATE_THOUGHT; document canonical path commit
  • drop the SQLite-planner-formatting-dependent plan substring commit
  • cover empty-IN filter starvation end-to-end commit
  • cover filter x reflection-cap composition commit
  • cover scoped metadata-filtered retrieval commit
  • strengthen collapse x reflection-cap backfill assertion commit
  • pin cross-backend tie-break determinism at the backend boundary commit
  • distinguish the UPDATE_ACTION journal string from the enum commit
  • document dreaming activation — consolidate() and access tracking commit
  • document the provenance-capture API commit
  • fix post-0.5.0 drift — drop removed-MCP refs, correct scoped-retrieval claims commit
  • note UPDATE_ACTION in the journal append docstring commit
  • scope audit-trail and dreaming claims to their real boundaries commit
  • document restore_thought and scoped retrieval params commit
  • curate 0.5.0 Unreleased block and mark MCP removal breaking commit
  • remove the dead manual Unreleased section commit
  • disclose that verify_journal cannot detect tail truncation commit
  • document the filtered vector-arm trade-off and clarify the bypass rationale commit
  • align package description with the honest journal claim commit
  • quote extras in install commands so zsh does not glob commit
  • add the whole-turn assembly caller-side recipe commit
  • document scoped retrieval and the ranked-path filter commit
  • clarify resolve-test intent and batch-embed failure id commit
  • confine fallback filter SQL to a private method commit
  • filtered vector-arm performance note into v0.5.0 commit
  • scoped metadata-filtered ranked retrieval into v0.5.0 commit
  • exempt dependabot commits from commitlint body-length (#36) commit
  • exempt dependabot commits from commitlint body-length (#36) commit
  • cap numpy <2.3 to keep mypy --strict green at the 3.11 target (#34) commit
  • cap numpy <2.3 to keep mypy --strict green at the 3.11 target (#34) commit
  • the in-tree MCP server is removed from engrava. The engrava[mcp] optional-dependency extra, the in-engrava engrava-mcp console script, and the in-tree server module are gone; a plain 'pip install engrava' is unaffected. The server moved to the standalone engrava-mcp package (uvx engrava-mcp), which consumes engrava's public API. Migrate per the docs/upgrade.md 0.4 -> 0.5 notes.

v0.4.0

View on GitHub

Features

  • add bi-temporal valid-time to thoughts and edges commit
  • add temporal query predicates and invalidate primitive commit
  • reflections inherit temporal extent from members commit
  • add remember() and recall() convenience methods on the store commit
  • add delete_thought and delete_edge tools commit
  • add guided memory prompts commit
  • add MCP server with read tools (engrava[mcp] extra) commit
  • add memory filters and pagination commit
  • add write tools, opt-in read-only mode, and per-tool safety annotations commit
  • expose memory as resources (thought, stats, recent) commit
  • map known failures to typed, actionable tool errors commit
  • add store-level execute_mindql entry point commit

Bug Fixes

  • assert plan-shape invariant for temporal queries, not scan-vs-index commit
  • embed full thought content without duplication or silent truncation commit
  • keep quoted MindQL values as strings and reject malformed conditions commit
  • let natural-language queries reach the full-text index commit
  • match exact table token in query-plan helpers commit
  • retry transient errors with bounded backoff commit
  • keep query_memory parse errors FIND-only commit
  • map write-tool errors and complete the 0.4.0 documentation commit

Performance

  • tune sqlite pragmas and add hot-path indexes commit
Maintenance (38)
  • add secret scan + dependency audit; verify wheel data on publish (#22) commit
  • align branch-name guard allowed types with BRANCHING.md commit
  • allow semantic-version release and hotfix branch names commit
  • cache HuggingFace models and pip to stop HF 429 (#20) commit
  • use GitHub App token for semantic-release push to protected dev commit
  • ignore merge commits in commitlint via JS config commit
  • run CI on dev branch as well as main commit
  • add bi-temporal model guide and 0.3 to 0.4 upgrade notes commit
  • bring architecture + CLI docs up to 0.4.0 (bi-temporal + MCP) commit
  • capitalize the Engrava brand name in README prose commit
  • correct mindql, extensions, extension-hooks, and configuration examples commit
  • correct README, quickstart, and api-reference examples to match shipped API commit
  • correct reflection_boost default to 1.0; add test verifying documented config defaults commit
  • document percept/utterance/thought metadata helpers in api-reference commit
  • drop reference to non-existent purity-check script in CONTRIBUTING commit
  • expand and correct the engrava documentation set (#17) commit
  • fix 0.4.0 drift found in the full doc audit commit
  • fix quickstart cycle note — remember() takes no created_cycle; use ThoughtRecord for write-sid commit
  • lead quickstart with remember()/recall() short path commit
  • lead README Basic Usage with remember()/recall() commit
  • list all installable extras in README (mcp + ollama/hf embeddings); note dreaming needs no ext commit
  • trim README Basic Usage to the core create-and-read example commit
  • add MCP server guide and client-config examples commit
  • align branching guide with dev release-trigger model commit
  • de-reference internal principle name in doc-test rationale commit
  • drop no-op 'dreaming' extra (empty deps; dreaming is in the base install) commit
  • raise pydantic floor to >=2.11 commit
  • add documentation-example test suite commit
  • add functional contract suite for search behavior commit
  • bound temporal query overhead and confirm index use commit
  • isolate subprocess examples (offline, single-thread, no stdin) commit
  • pin native thread pools session-wide to stop full-suite hang commit
  • execute the tutorial end-to-end and a search round-trip commit
  • back-merge main into dev after v0.3.0 release commit
  • back-merge main into dev after v0.3.1 release commit
  • switch release-trigger branch from main to dev commit
  • bump actions/cache from 4 to 5 (#25) commit
  • bump actions/setup-python from 5 to 6 (#26) commit

v0.3.1

View on GitHub

Bug Fixes

  • load sqlite-vec extension on the connection's worker thread commit
  • re-disable extension loading in finally after load attempt commit
Maintenance (1)
  • point documentation url to engrava.ai/docs commit

v0.3.0

View on GitHub

Features

  • graph memory database — dreaming consolidation, hybrid search, audit trail commit
Maintenance (16)
  • add on-demand smoke-gate workflow (#10) commit
  • automated release pipeline commit
  • quote semantic_version input to fix release workflow startup commit
  • skip branch-name guard for automated dependency PRs (#8) commit
  • skip upgrade smoke test when the baseline is not yet published (#9) commit
  • use semantic-release CLI directly to satisfy actions allowlist commit
  • merge dev into release/v0.3.0 (automated release pipeline) commit
  • v0.3.0 — first public release commit
  • refresh stale FTS-upgrade fixture and public-export baseline (#11) commit
  • bump actions/checkout from 4 to 6 (#3) commit
  • bump actions/download-artifact from 4 to 8 (#7) commit
  • bump actions/setup-node from 4 to 6 (#6) commit
  • bump actions/upload-artifact from 4 to 7 (#5) commit
  • bump softprops/action-gh-release from 2 to 3 (#4) commit
  • Bump idna from 3.13 to 3.15 (#1) commit
  • align metadata and docs with product tagline; add dependabot and issue config (#2) commit