diff --git a/docs/research/memory-reconciliation-algorithm-design-2026-04-24.md b/docs/research/memory-reconciliation-algorithm-design-2026-04-24.md index 1c16ced4..6626d38f 100644 --- a/docs/research/memory-reconciliation-algorithm-design-2026-04-24.md +++ b/docs/research/memory-reconciliation-algorithm-design-2026-04-24.md @@ -260,22 +260,61 @@ function reconcile(facts): ### Conflict outputs -Each conflict becomes a row in `docs/CONTRIBUTOR-CONFLICTS.md` -(the file Amara's 4th ferry noted is present-with-schema-but- -unpopulated; this design starts populating it via the -generator). -Row format: +Each conflict becomes a row in `docs/CONTRIBUTOR-CONFLICTS.md`, +which already has a populated schema (CC-001..CC-003 as of +2026-04-23 cover the no-name-attribution-rule scope, the +Stabilize-vs-keep-opening-frames disagreement, and the +absent-artifact-citation discipline). This design extends +that schema by inserting machine-generated rows from the +reconciliation pass into the **Open** table (or into a +dedicated autogenerated subsection within **Open** if that +convention is later adopted) — one CC-### row per detected +conflict, using the existing column schema: ```markdown -### CONF--: / -- **Canonical key:** `::::` -- **Conflicting facts:** [MF-..., MF-...] -- **Winner (priority tiebreak):** MF-... -- **Reason:** invariant-2 violation | broken chain | explicit disagreement -- **Resolution:** pending | explicit-preference-recorded | escalated -- **Resolution evidence:** +| CC- | | ::::` +between facts MF-..., MF-...> | | + | + | | | ``` +The CC-### counter continues from the highest existing ID +(e.g., next machine-generated conflict starts at CC-004). + +**Idempotent generator strategy.** Repeated CI runs MUST +NOT re-append the same conflict, otherwise the **Open** +table grows unboundedly. The generator maintains an +explicit mapping from canonical key +(`::::` plus the +sorted set of contributing MF-IDs) → CC-NNN. On each run: + +- If the canonical key already maps to an existing CC-NNN + row in the **Open** table, update that row in-place + (refresh "Between"/"Positions" if source paths shifted; + preserve any human-edited "Resolution-so-far"). +- If the conflict has been moved to **Resolved** or + **Stale**, leave it alone — those tables are out of the + generator's write scope. +- If no existing row maps, allocate the next CC-NNN and + insert a new row. + +Generator MUST preserve all existing manually-curated rows +verbatim — both in **Open** (treat human-edited rows as +read-only) and in **Resolved** / **Stale**. Auto-detected +rows update in-place when matched; new rows are inserted +at the bottom of **Open**. As an alternative convention, +implementers MAY reserve a clearly delimited +"" subsection within **Open** that +is fully rewritten on each run, leaving manually curated +rows untouched outside the delimited block. + Conflicts block the `CURRENT-*.md` generation if unresolved — this is the "explicit-not-silent" discipline Amara emphasized. A CI run that discovers unresolved conflicts