feat(memory): optimistic concurrency control on memory.update#90
Merged
Conversation
Add database-managed version + version_hash on every memory and require the prior version_hash on memory.update. A stale or incorrect hash fails the call with CONFLICT and leaves the memory unchanged. - DB: new version bigint + version_hash text columns, backfilled in migration 007. compute_memory_version_hash hashes a canonical JSONB envelope of (tree, name, meta, temporal, content) with function-local UTC + ISO,YMD so tstzrange renders deterministically. - Triggers: before-insert seeds version=1 and the hash; before-update bumps version and recomputes the hash on logical-payload change, and restores the managed fields otherwise so direct writes can't mutate them. patch_memory takes _prior_version_hash and raises SQLSTATE ME002 on a mismatch. - get_memory / search_memory / hybrid_search_memory return version + version_hash. - Engine / protocol / client / server: Memory and MemoryResponse carry version + versionHash; memoryUpdateParams requires versionHash; ME002 maps to a CONFLICT AppError. - MCP me_memory_update requires version_hash; CLI me memory update requires --version-hash; me memory edit and the web editor submit the fetched versionHash automatically.
The templated guard for get_memory referenced `bigin` instead of `bigint`, and the search_memory guard referenced `halfve` instead of `halfvec`. The guard's drop-then-assert pass parses these argument strings through Postgres, so the typos failed every migration with "type does not exist" (42704) before the create-or-replace ran.
memory.update now requires the prior versionHash; the three e2e update sites (6, 6b, 6c) were still invoking `me update` without it and exiting non-zero on argument parsing before reaching the server.
848964f to
3d2d1f9
Compare
cevian
approved these changes
Jun 24, 2026
cevian
left a comment
Contributor
There was a problem hiding this comment.
One small but important comment
Co-authored-by: Matvey Arye <cevian@gmail.com> Signed-off-by: John Pruitt <jgpruitt@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add database-managed version + version_hash on every memory and require the prior version_hash on memory.update. A stale or incorrect hash fails the call with CONFLICT and leaves the memory unchanged.