Skip to content

refactor(core): make accepted note snapshot persistence indivisible #1097

Description

@phernandez

Summary

Make the DB-first accepted-note transaction expose one operation that persists the complete accepted Markdown snapshot: entity fields, NoteContent, observations, outgoing relations, and hot search state.

Why

PR #1079 fixed a real production regression where accepted writes returned success while graph rows remained empty. The immediate bug is fixed, but the API still permits the same incomplete state:

  1. callers invoke persist_accepted_note_write() for NoteContent and search;
  2. create/update/edit callers must separately remember replace_accepted_note_graph().

That invariant belongs in one operation. A future mutation path can currently omit the second call and recreate #1076.

This was identified while applying the /pythonic-code review lens from #1095 to the shared runtime introduced by #1002.

Proposed Direction

  • Introduce one clearly named accepted-snapshot persistence operation for create/update/edit.
  • Accept the prepared Markdown value and persist all derived rows through the caller-owned AsyncSession.
  • Keep move as an explicitly narrower operation when it does not replace the note graph.
  • Make partial content/search-only persistence private or otherwise impossible to invoke accidentally from a mutation runner.
  • Preserve the existing local/cloud transaction and materialization behavior.

Prefer one direct function over a new service hierarchy.

Regression Proof

Add a route-level SQLite test that:

  1. uses production-style deferred materialization with the worker held or not drained;
  2. creates or edits a typed note;
  3. asserts entity, NoteContent, observations, relations, and search state immediately after the accepted response;
  4. only then permits materialization/indexing to run.

This ensures a later index_file pass cannot conceal an incomplete accepted transaction.

Acceptance Criteria

  • Every accepted create/update/edit transaction persists the complete snapshot through one production call.
  • There is no callable production path that writes NoteContent and search while accidentally omitting the graph.
  • The pre-materialization regression test passes for create and at least one replacing mutation.
  • Existing materialization, conflict detection, status codes, and queue behavior remain unchanged.
  • Any Basic Memory Cloud adaptation is identified and validated against the paired revision.

References

Metadata

Metadata

Assignees

Labels

cloudBasic Memory CloudenhancementNew feature or requestpythonPull requests that update python code

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions