v2.19.1
Patch release — the conflict system now actually works end to end.
Fixed
- Contradictory memories vanished silently — ingest dedup merged near-identical contradictions ("X" → "never X") before conflict detection ever saw them. Contradiction-aware ingest now records them as conflicts with real cosine similarity; an LLM veto (timeout-bounded) confirms before skipping a merge, and provider outages safely fall back to merging
- Merge resolution was broken twice — it never marked the conflict resolved (and duplicated merged memories on retry), and it crashed 100% of the time passing a raw sqlite blob to the native vector index. Both fixed; retry is idempotent
- Conflict resolution default — strategy-less POSTs defaulted to an always-rejected
keep-newer; nowkeep_newer - keep_newer on timestamp ties deprecated the newer memory
- Resolved conflicts were invisible —
GET /api/conflicts?resolved=truereturned a hardcoded[], by-id lookup 404'd. Real history now, plus an unresolved/resolved toggle in the dashboard - Re-resolving a resolved conflict now errors instead of duplicating
- Vector indexes no longer accumulate deprecated rows
Chore
- better-sqlite3 12 → 13 (#54)
- DeepSource style conformance on the new conflict path
Verification: 788/788 tests, live end-to-end proof (contradiction → conflict → merge resolve → merged memory searchable, originals deprecated, resolution persisted).
Full Changelog: v2.19.0...v2.19.1