Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 51 additions & 12 deletions docs/research/memory-reconciliation-algorithm-design-2026-04-24.md
Original file line number Diff line number Diff line change
Expand Up @@ -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-<YYYY-MM-DD>-<NNN>: <subject> / <predicate>
- **Canonical key:** `<subject>::<predicate>::<normalized-object>`
- **Conflicting facts:** [MF-..., MF-...]
- **Winner (priority tiebreak):** MF-...
- **Reason:** invariant-2 violation | broken chain | explicit disagreement
- **Resolution:** pending | explicit-preference-recorded | escalated
- **Resolution evidence:** <DP-NNN.yaml ref if proxy-reviewed>
| CC-<NNN> | <YYYY-MM-DD> | <Question — invariant-2 violation
on canonical key `<subject>::<predicate>::<normalized-object>`
between facts MF-..., MF-...> | <Between: source agents /
humans whose memory rows produced the conflicting facts> |
<Positions: each fact's claim text + source_path> |
<Resolution-so-far: pending until explicit preference
recorded; or "auto: priority tie-break MF-... wins" when
invariant-6 fallback applies> | <Scope: invariant-2 violation
\| broken chain \| explicit disagreement> | <Source:
source_path links to the contributing memory files;
DP-NNN.yaml ref if proxy-reviewed> |
```

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
(`<subject>::<predicate>::<normalized-object>` plus the
sorted set of contributing MF-IDs) → CC-NNN. On each run:
Comment on lines +294 to +296
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Match existing conflicts without MF-ID set in dedupe key

The idempotency key currently includes the sorted MF-ID set, so a normal fact supersession (same canonical disagreement, new MF-... id) will no longer match the prior CC row and will allocate a new CC-... on the next run. That breaks the stated in-place update behavior and can duplicate logically identical open conflicts while discarding accumulated Resolution-so-far context for the same subject/predicate dispute.

Useful? React with 👍 / 👎.


- 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
Comment on lines +308 to +311
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Define a durable discriminator for auto-generated CC rows

This section requires the generator to keep human-curated rows read-only while updating auto-detected rows in place, but the row schema shown above does not define any explicit auto/manual marker. Without a required discriminator (e.g., a dedicated column or mandatory autogenerated block), implementations cannot reliably tell which rows are safe to mutate, which risks either overwriting manual conflict entries or skipping intended updates.

Useful? React with 👍 / 👎.

at the bottom of **Open**. As an alternative convention,
implementers MAY reserve a clearly delimited
"<!-- autogenerated -->" subsection within **Open** that
is fully rewritten on each run, leaving manually curated
rows untouched outside the delimited block.

Comment thread
AceHack marked this conversation as resolved.
Conflicts block the `CURRENT-*.md` generation if unresolved
— this is the "explicit-not-silent" discipline Amara
emphasized. A CI run that discovers unresolved conflicts
Expand Down
Loading