Migrations

Last verified against the code: 2026-10-21 (first commit)

A memory is the one thing a release must never lose. These are the rules a release follows so an existing ~/.openmemory and the rendered files keep working, after the handbook's migration standard.

What a release may touch

Thing Rule
memory.db schema Append-only and expand-only: CREATE TABLE IF NOT EXISTS and ALTER TABLE … ADD COLUMN with defaults. A column is never dropped or renamed in the release that stops using it.
Embeddings A change to embed.py (dimension, tokenization) makes every stored vector incomparable with new ones. Such a release re-embeds every row on first run (title + gist for episodes, text for lessons and predictions) and records the embedding version in the row. Not yet needed: 0.1.0 is the first.
Scoring and thresholds Free to change; they affect ranking, not data. The paper's Appendix A changes with them.
Rendered files The om-<id>.md frontmatter may gain keys. The openmemory:start/end markers never change; written.json and vetoed.json keep their shape (a JSON list of ids).
lessons.jsonl Fields may be added; never removed or renamed. Readers ignore unknown fields. This is the protocol's compatibility rule (PROTOCOL.md).
The CLI Commands and flags are added, not removed; a removed one keeps working one release with a notice.
Hooks and MCP The hook command (openmemory ingest --quiet) and the tool names (recall, remember) and their arguments stay; new arguments are optional.

How a breaking change is done

Expand → backfill → switch → contract, over at least two releases: add the new column or file alongside the old, fill it on first run (idempotent, resumable: a row is skipped when already filled), switch the code to read the new one, and only in a later release stop writing the old one.

Every release

History

Release Migration
0.1.0 None: the first store.