Summary
Cloud-hosted write_note calls can successfully persist typed Markdown and return 202 while leaving the observation and relation tables empty. Graph rows appear only if a later index_file job happens to re-parse the materialized object. This makes schema inference and relation traversal nondeterministic after successful DB-first writes.
Classification: Basic Memory persistence/indexing regression. The incomplete accepted-write path is in basic_memory.indexing.accepted_note_write_runner, not Cloud MCP routing.
Development acceptance evidence
Environment: Basic Memory Cloud development
- Cloud revision:
4aa58632c32999b088efcfe61911c053b7a4ad89
- Basic Memory revision:
c616148fb0b30f1dfe492e273ec43706c0326759
- Tenant:
a5a774be-50e0-4c50-811d-42a2525faebc
- Project external ID:
d71bee1e-69a4-4842-90de-fd93aa779a47
- Project DB ID:
3
The acceptance run wrote three notes with note_type=dev_accept_person:
## Observations
- [name] Ada Acceptance
- [role] Engineer
## Relations
- works_at [[XSYS Target 20260716T1110Z]]
All three calls succeeded. note_content.markdown_content contains the exact [name], [role], and works_at Markdown, checksums match, and Tigris origin objects contain the same data. search_notes(note_types=["dev_accept_person"]) returns all three notes.
However, Neon shows no graph rows for entity IDs 13, 14, and 15:
observation: zero rows
relation: zero rows
schema_infer(note_type="dev_accept_person", threshold=0.25) therefore returns:
{"error":"No schema pattern found for 'dev_accept_person' (threshold: 25%)"}
A control note in the same project did acquire observations/relations, but only after Tigris notification enqueued index_file job trace 019f6aa0ae27f04fb3ea107af903cc84. The typed-note materialization jobs completed successfully but did not produce equivalent index_file jobs.
Root cause
run_accepted_note_create() prepares parsed Markdown, then create_accepted_pending_entity() writes only scalar entity fields. persist_accepted_note_write() writes note_content and search state. Neither persists the parsed observations or relations that are already present in the prepared write.
The Cloud DB-first path then materializes Tigris asynchronously. Graph correctness is accidentally dependent on a later object notification and index_file pass. Notifications are not a valid commit path for graph rows and may also no-op against matching accepted checksums.
Relevant code:
src/basic_memory/indexing/accepted_note_mutation_runner.py::_run_accepted_note_create
src/basic_memory/indexing/accepted_note_write_runner.py::create_accepted_pending_entity
- accepted update/edit paths should be audited for the same omission
Expected behavior
A successful accepted create/update/edit transaction atomically persists:
- entity scalar fields
- note content
- observations
- relations (with unresolved targets allowed)
- search state
Tigris materialization and object notifications should reconcile file state, not be required to make the knowledge graph correct.
Suggested fix
Extend the accepted mutation write transaction to replace observations and relations from the already parsed prepared Markdown before commit. Reuse the existing repository semantics used by EntityService.update_entity_and_observations() and update_entity_relations(), adapted to the accepted-write dependency protocols.
Add regression coverage for:
- create typed note -> observations and unresolved/resolved relations exist immediately;
- update/edit -> old graph rows are replaced atomically;
- schema inference succeeds immediately after typed MCP writes without any storage notification;
- relation traversal succeeds immediately after
write_note;
- materialization or duplicate
index_file does not duplicate/remove graph rows;
- missing/delayed Tigris notification does not affect DB graph correctness.
Summary
Cloud-hosted
write_notecalls can successfully persist typed Markdown and return 202 while leaving theobservationandrelationtables empty. Graph rows appear only if a laterindex_filejob happens to re-parse the materialized object. This makes schema inference and relation traversal nondeterministic after successful DB-first writes.Classification: Basic Memory persistence/indexing regression. The incomplete accepted-write path is in
basic_memory.indexing.accepted_note_write_runner, not Cloud MCP routing.Development acceptance evidence
Environment: Basic Memory Cloud development
4aa58632c32999b088efcfe61911c053b7a4ad89c616148fb0b30f1dfe492e273ec43706c0326759a5a774be-50e0-4c50-811d-42a2525faebcd71bee1e-69a4-4842-90de-fd93aa779a473The acceptance run wrote three notes with
note_type=dev_accept_person:All three calls succeeded.
note_content.markdown_contentcontains the exact[name],[role], andworks_atMarkdown, checksums match, and Tigris origin objects contain the same data.search_notes(note_types=["dev_accept_person"])returns all three notes.However, Neon shows no graph rows for entity IDs 13, 14, and 15:
observation: zero rowsrelation: zero rowsschema_infer(note_type="dev_accept_person", threshold=0.25)therefore returns:{"error":"No schema pattern found for 'dev_accept_person' (threshold: 25%)"}A control note in the same project did acquire observations/relations, but only after Tigris notification enqueued
index_filejob trace019f6aa0ae27f04fb3ea107af903cc84. The typed-note materialization jobs completed successfully but did not produce equivalentindex_filejobs.Root cause
run_accepted_note_create()prepares parsed Markdown, thencreate_accepted_pending_entity()writes only scalar entity fields.persist_accepted_note_write()writesnote_contentand search state. Neither persists the parsed observations or relations that are already present in the prepared write.The Cloud DB-first path then materializes Tigris asynchronously. Graph correctness is accidentally dependent on a later object notification and
index_filepass. Notifications are not a valid commit path for graph rows and may also no-op against matching accepted checksums.Relevant code:
src/basic_memory/indexing/accepted_note_mutation_runner.py::_run_accepted_note_createsrc/basic_memory/indexing/accepted_note_write_runner.py::create_accepted_pending_entityExpected behavior
A successful accepted create/update/edit transaction atomically persists:
Tigris materialization and object notifications should reconcile file state, not be required to make the knowledge graph correct.
Suggested fix
Extend the accepted mutation write transaction to replace observations and relations from the already parsed prepared Markdown before commit. Reuse the existing repository semantics used by
EntityService.update_entity_and_observations()andupdate_entity_relations(), adapted to the accepted-write dependency protocols.Add regression coverage for:
write_note;index_filedoes not duplicate/remove graph rows;