From a0c92f0d21c2568478ebd60bd82ca639c14b90fd Mon Sep 17 00:00:00 2001 From: phernandez Date: Mon, 10 Aug 2026 20:31:32 -0500 Subject: [PATCH 1/2] docs(core): set review expectations for eventually consistent state Signed-off-by: phernandez --- AGENTS.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 012cec1b3..d49bc4da0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -148,6 +148,37 @@ agents must apply this skill before changing or evaluating Python code. handling, casts, or unapproved fallback logic - **No guessing**: Do not say "The issue is..." before you actually know what the issue is. Investigate first. +### Consistency Model — Review Expectations + +Basic Memory separates canonical state from derived state, and reviews (human or automated) +must hold them to different standards: + +- **Canonical state** — the markdown files on disk and the accepted `note_content` row. + Writes are guarded: CAS on `db_version`, generation fences, checksum-guarded file + operations. Correctness findings here are welcome. +- **Derived state** — entity file metadata, observation/relation graph rows, search index + rows, materialized files. This is **eventually consistent by design**. It converges + through the next write, the next index pass, `reindex`, `doctor`, or the scheduled orphan + sweeper (cloud). Stale writers no-op on generation fences instead of blocking; concurrent + races resolve last-writer-wins. + +Deadlocks are always worse than temporary staleness. Do NOT raise review findings that +propose, for derived-state paths: + +- adding `SELECT ... FOR UPDATE`, lock ordering, or wider/shared transactions — this class + of "fix" caused the production deadlock clusters (#1213, #1224) and the silent observation + duplication (#1214); +- adding compensating re-checks, retry markers, or two-phase machinery for races whose + drift self-heals on a later write or index pass; +- treating a window where a projection lags its canonical source as a bug, including rare + transient-failure windows that a later edit, `reindex`, or the orphan sweeper repairs. + +A derived-state race is a real finding only when it converges to a *wrong* state that no +existing mechanism repairs, with a realistically hittable window. Name that non-converging +end state explicitly and the mechanism gap; otherwise do not raise it. When in doubt, +prefer the smaller, lock-free design and note the alternative in the PR discussion instead +of a review finding. + ### Literate Programming Style Code should tell a story. Comments must explain the "why" and narrative flow, not just the "what". From a86aa838b3ae3a4de1897b1e1d9055d4486c5ceb Mon Sep 17 00:00:00 2001 From: phernandez Date: Mon, 10 Aug 2026 20:47:25 -0500 Subject: [PATCH 2/2] docs(core): sharpen consistency-model review guidance Signed-off-by: phernandez --- AGENTS.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index d49bc4da0..be79bfa3a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -153,25 +153,33 @@ agents must apply this skill before changing or evaluating Python code. Basic Memory separates canonical state from derived state, and reviews (human or automated) must hold them to different standards: -- **Canonical state** — the markdown files on disk and the accepted `note_content` row. - Writes are guarded: CAS on `db_version`, generation fences, checksum-guarded file - operations. Correctness findings here are welcome. +- **Canonical state** — the markdown bytes of a note (on disk and as accepted + `note_content`). Writes are guarded: CAS on `db_version`, generation fences, + checksum-guarded file operations. Corrupting, wrongly rewriting, or wrongly deleting note + content is always a real finding, in every code path — materialization writes canonical + bytes into their portable file form, so the file's *content* is never "just a projection". - **Derived state** — entity file metadata, observation/relation graph rows, search index - rows, materialized files. This is **eventually consistent by design**. It converges - through the next write, the next index pass, `reindex`, `doctor`, or the scheduled orphan + rows, and materialization status/lineage (file versions, checksums, write status, *when* + a file catches up to its accepted row). This is **eventually consistent by design**. It + converges through the next write, the next index pass, `reindex`, or the scheduled orphan sweeper (cloud). Stale writers no-op on generation fences instead of blocking; concurrent races resolve last-writer-wins. Deadlocks are always worse than temporary staleness. Do NOT raise review findings that propose, for derived-state paths: -- adding `SELECT ... FOR UPDATE`, lock ordering, or wider/shared transactions — this class - of "fix" caused the production deadlock clusters (#1213, #1224) and the silent observation - duplication (#1214); +- adding `SELECT ... FOR UPDATE` or wider/shared transactions — this class of "fix" caused + the production deadlock clusters (#1213, #1224) and the silent observation duplication + (#1214). (Code that legitimately takes locks must still follow the canonical + NoteContent-first order documented by `current_relation_generation_statement`; flagging a + violation of that ordering IS a real finding — the ban is on adding serialization, not on + policing the existing protocol.); - adding compensating re-checks, retry markers, or two-phase machinery for races whose drift self-heals on a later write or index pass; - treating a window where a projection lags its canonical source as a bug, including rare transient-failure windows that a later edit, `reindex`, or the orphan sweeper repairs. + (`doctor` diagnoses in a temporary project; it is not a repair mechanism and does not + count as one.) A derived-state race is a real finding only when it converges to a *wrong* state that no existing mechanism repairs, with a realistically hittable window. Name that non-converging