← 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.7.1

View on GitHub

Bug Fixes

  • docs: ship the VS Code MCP example VS Code actually reads commit
  • infra: build EngravaManager stores with the full configuration commit
  • lifecycle: keep pinned reflections through the sweep, gc and TTL commit
  • mindql: extension handlers get a read-only accessor instead of the live connection commit
  • mindql: read values ending in or/and, and quoted literals, correctly commit
  • mindql: the single-SELECT guard reads SQL comments and quoted identifiers commit
  • search: raise the per-arm candidate pool to at least top_k commit
  • search: single-source the hybrid-search defaults on SearchConfig commit

v0.7.0

View on GitHub

Features

  • cli: add remember, recall and link one-shot commands commit
  • core: add a pre-insert preparation seam and stop bypassing overrides commit
  • core: add a public way to attach a dreaming extension commit
  • core: guard updates with an engine-maintained revision commit
  • release: check that main carries the newest version tag commit
  • release: fail a release that moves the core schema on a patch bump commit
  • release: fail a release whose computed version disagrees with the target commit
  • release: fail a run that silently published nothing for the target commit

Bug Fixes

  • assert atomic rollback, not partial survival, in v20->v21 test commit
  • clear ruff check findings on release/v0.7.0 (17 -> 0) commit
  • cli: check the schema version before recall, remember and link open a database commit
  • cli: clear the journal too when restore --clear wipes the store commit
  • cli: error on a corrupt database instead of hanging forever commit
  • cli: exempt reflection centroid rows from restore's identity lock commit
  • cli: keep the full-text index consistent on every restore commit
  • cli: make a snapshot export observe one consistent database state commit
  • cli: name the database in the error message commit
  • cli: read export's thought and edge tables in one transaction commit
  • cli: refresh a persisted vector index entry a merge restore replaces commit
  • cli: refuse a colliding merge into a store that has a journal commit
  • cli: reject a malformed --filter key as a usage error commit
  • cli: reject a restored centroid whose vector width disagrees commit
  • cli: state what gc deletes, and pin the guards that stop it commit
  • cli: tell the two schema versions apart commit
  • cli: verify embedding identity against the target, not a provider commit
  • cli: write snapshot and export output through a temp file commit
  • core: a no-op upsert_by_hash() no longer commits the caller's pending work commit
  • core: a write waits for another process's lock again instead of failing at once commit
  • core: bound the close of a wedged connection commit
  • core: close the connection even when cancellation lands mid-cleanup commit
  • core: drop a stale auto-embed completion instead of installing it commit
  • core: exempt centroid vectors from the embedding identity lock commit
  • core: export the exceptions the documentation says to catch commit
  • core: keep buffered accesses when a flush cannot take the write lock commit
  • core: keep the no-op upsert from committing after the seam merge commit
  • core: keep the original error when rollback or pragma cleanup fails commit
  • core: keep the update contract under contention, and journal what a delete really removed commit
  • core: make a read-modify-write a critical section across tasks commit
  • core: make a vector's ownership follow its thought, not its row commit
  • core: make a write and its confirming read-back failure-atomic commit
  • core: make an embedding write and its vector-index update atomic commit
  • core: make the child deletes atomic with the parent delete again commit
  • core: recover a row update and its journal entry together commit
  • core: reject a negative or boolean get_edges limit commit
  • core: roll back or quarantine a failed commit instead of leaving it open commit
  • core: sample transaction ownership again before upsert_by_hash's decisive probe commit
  • core: say when the unembedded row survives an auto-embed failure commit
  • core: serialise the dedup probe-and-insert across connections commit
  • core: skip derivation only inside the current task's own transaction window commit
  • core: stop a write-free call from committing the caller's transaction commit
  • core: store every timestamp in one canonical UTC form commit
  • docs: correct auto-embed durability claims in api-reference/configuration commit
  • docs: correct EmbeddingConfig.require_embedding durability docstring commit
  • docs: split auto-embed durability into two independent questions commit
  • docs: stop conflating durability with method, add missing precondition commit
  • docs: teach the cleanup the library ships in every example commit
  • domain: say whether a metrics snapshot was actually measured commit
  • dreaming: compute the cohesion gate as the cosine similarity it names commit
  • dreaming: roll back a reflection whose own embedding fails commit
  • embeddings: stop a rejected first write from locking corpus identity commit
  • embeddings: stop logging the embedding provider's raw error message commit
  • extensions: roll back the migration savepoint on cancellation too commit
  • hygiene: make a failed or cancelled hygiene pass leave nothing behind commit
  • infra: keep one manager caller's cancellation away from the others commit
  • infra: share one lifecycle lock across create, delete, and close_all commit
  • infra: wait for the aiosqlite worker after a failed connect commit
  • journal: a failed derived record undoes only itself, even inside your transaction commit
  • journal: make create, delete and outcome writes recover together with their journal entry commit
  • migration: make a migration step apply completely or not at all commit
  • migration: roll back legacy-history adoption's savepoint on cancellation too commit
  • migration: unwind a savepoint cancelled while it opens commit
  • mindql: match quoted values exactly, including repeated whitespace commit
  • mindql: reject a LIMIT or OFFSET too large for SQLite to store commit
  • release: close the gaps the last round's claims papered over commit
  • release: one boundary around reading the target, not a longer catch list commit
  • release: one lookup, one claim, and close three more false passes commit
  • release: stop the was-published gate from passing on nothing commit
  • search: apply collapse and reflection caps to the query-less fallback commit
  • search: bound edge retrieval and graph ranking's neighbour fetch in SQL commit
  • search: keep search query text out of the FTS fallback logs commit
  • search: keep the query-less fallback's order under the reflection cap commit
  • search: stop graph ranking from double-counting a cross-chunk edge commit
  • search: turn cycle recency fully off at a zero weight commit
  • update stale schema-version golden to 21 commit

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