Skip to content

fix(memory): preserve distinct facts during remember and import - #139

Merged
Grivn merged 1 commit into
masterfrom
codex/issue-134-preserve-distinct-facts
Sep 14, 2026
Merged

Grivn merged 1 commit into
masterfrom
codex/issue-134-preserve-distinct-facts

Conversation

@Grivn

@Grivn Grivn commented Sep 14, 2026

Copy link
Copy Markdown
Member

What

remember and import retain distinct content even when lexical or embedding similarity suggests an update or duplicate. They skip only byte-identical content, found across all active insights rather than the five heuristic candidates. remember still returns diff_suggestion for the supervising agent; retiring an old fact requires an explicit forget <old-id> after the replacement is stored and checked.

Import reuses the actual existing ID for an exact duplicate, preserving draft-index edge resolution and repeat-import behavior. --no-diff still inserts exact repeats. The fuzzy classifier is unchanged, so the polarity work in #135 remains independent.

Why

Fixes #134. Shared vocabulary cannot establish that two facts refer to the same subject, value, or relationship. The same unsafe assumption existed in the import path, which also replaced conflicting content. This change removes that source of soft deletion and silent skipping without adding a subject parser, schema, or replacement flag.

The isolated CLI reproduction on base 6c371ec7dce7af05aa55f31fb1b7c1aea81205db stores Alpha, then Beta:

go build -o mnemon .
export MNEMON_DATA_DIR="$(mktemp -d)"
export MNEMON_STORE=distinct-facts-repro
export MNEMON_EMBED_ENDPOINT=http://127.0.0.1:1
export MNEMON_EMBED_PROTOCOL=ollama
export MNEMON_EMBED_API_KEY=
./mnemon remember 'Project Alpha uses PostgreSQL database for persistent application storage' --cat fact --imp 5
./mnemon remember 'Project Beta uses PostgreSQL database for persistent application storage' --cat fact --imp 5
./mnemon recall 'Project Alpha storage'
./mnemon status

Before: the second write returns updated / UPDATE with Alpha's replaced_id; only Beta remains active. Longer facts sharing more than 90% of tokens can instead return skipped / DUPLICATE, losing Beta. Reversing the roles in a relationship can produce the same false duplicate.

After: both distinct facts are added and remain retrievable, with no similarity-driven soft deletion. An exact repeat still skips and reports the correct existing ID, including content without searchable tokens and exact matches outside the fuzzy candidate limit.

Real CLI comparison Before: active / deleted After: active / deleted
Alpha and Beta, same property 1 / 1 2 / 0
Same subject, changed database value 1 / 1 2 / 0
Long Alpha and Beta facts 1 / 0 (new fact skipped) 2 / 0
Reversed source/target roles 1 / 0 (new fact skipped) 2 / 0
Exact repetition 1 / 0 1 / 0
Import Alpha, Beta, Alpha 1 / 2 2 / 0
Repeat that import 1 / 4 2 / 0

All comparisons use fresh synthetic stores and an unavailable loopback embedding endpoint. Raw command output and reusable comparison scripts are retained locally; the table summarizes those operations. Existing lifecycle pruning remains a separate policy.

Validation

  • go build -o mnemon . and make test pass, including go vet ./....
  • bash scripts/e2e_test.sh: 193/193 checks pass with embeddings unavailable.
  • New command regressions fail on the original implementation and pass after the fix: distinct subjects, changed values, long near-duplicates, reversed relationships, advisory conflicts, tokenless exact repeats, an exact match outside the candidate limit, import edge mapping and --no-diff.
  • Independent real CLI probes confirm the before/after table, repeat-import stability and explicit causal edges. Twenty basic CLI operations pass on both baseline and fixed binaries, including store isolation and readonly write rejection.
  • A separate read-only review checked Unicode/whitespace distinctions, punctuation deduplication, replay and SQLite deletion counts; no actionable finding remained in this change.
  • A local combination with feat(memory): recognize multilingual recall intent #138 merged without conflicts and passed build, make test, and all 258 combined CLI E2E checks. Both PRs are independently based on master.

Checklist

  • Deterministic tests pass (make test)
  • Affected CLI E2E component passes (bash scripts/e2e_test.sh); full Agency/process/Docker integration is outside this Memory-only change
  • New behavior has regression coverage, including exact duplicate identity, import edge mapping and --no-diff
  • Canonical English/Chinese usage, pipeline/import docs and distributed host guidance updated
  • Release-note impact: similarity-based automatic replacement and fuzzy skipping become preservation; exact repetition still deduplicates

Limit remember and import deduplication to byte-identical active content. Keep fuzzy diff suggestions advisory, preserve distinct subjects and changed values, and resolve import duplicate indexes and edges to existing memories. Update canonical docs and host guides for deliberate forgetting.

Validated with go build -o mnemon ., make test, and all 193 CLI E2E checks. Reproduced replacement and near-duplicate skipping on unmodified master, then verified the fixed CLI and SQLite records in isolated synthetic stores without embeddings.
@Grivn
Grivn merged commit a80fc50 into master Sep 14, 2026
2 checks passed
@Grivn
Grivn deleted the codex/issue-134-preserve-distinct-facts branch September 14, 2026 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] remember auto-replaces a distinct subject's fact based on shared vocabulary

1 participant