Skip to content

Persist the relation-publication retry marker inside the accepted-write transaction #1661

Description

@phernandez

Follow-up from basic-memory-cloud docs/MATERIALIZATION_WEBHOOK_PLAN.md (step C4), split out of basic-memory#1660.

Gap

After an accepted note write commits, _finish_mutation (services/note_content_writes.py:253-273) publishes the note's graph (observations, relations, sections). Before publishing, RelationRepository.begin_relation_generation_publication persists a RelationSearchRefresh.publication_generation retry marker, and cleanup_relation_generations clears it after success. While the marker exists, EntityRepository.get_by_file_paths masks entity.checksum, so the next storage notification or project index re-reads the note and republishes its graph. That is the repair path, and it survives basic-memory#1660.

The remaining hole: a crash or database error after the accepted write commits but before the retry marker is written leaves no marker. The graph stays unpublished, nothing masks the checksum, and once #1660 records the materialized object's storage checksum, the storage notification finds the note current and does not repair it. Today a graph-publication failure is only logged ("a later index pass can republish").

Proposed fix

Write the publication retry marker in the same transaction as the accepted write, so every committed accepted generation either has its graph published or carries a durable marker until it is.

Care needed

  • This is in lock-ordering territory: the Remove SELECT FOR UPDATE from note materialization publish; rely on the db_version CAS with guarded writes #1224 deadlock class and the note_content-first order the materialization publisher relies on. Adding a RelationSearchRefresh insert to the accept transaction needs a PostgreSQL concurrency test, alongside test-int/test_note_materialization_lock_order.py, proving the order still holds.
  • Confirm the marker is cleared by the in-request publish on the happy path, so the next notification is not masked unnecessarily (that would bring back the re-index this plan removes).

Not in scope

Lost embeddings: basic-memory-cloud now queues embeddings from the durable materialize_note_file job.

🤖 Generated with Claude Code

https://claude.ai/code/session_01T8wjd6HrtSA2LN9ssC4NzF

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions