Skip to content

Qualify temporal memory end to end across a projection rebuild - #1783

Merged
dcellison merged 1 commit into
mainfrom
test/memory-qualification-matrix
Sep 23, 2026
Merged

dcellison merged 1 commit into
mainfrom
test/memory-qualification-matrix

Conversation

@dcellison

Copy link
Copy Markdown
Owner

Second of three deliveries for #1717.

Problem

A full projection rebuild (WorkshopEventStore.rebuild_projection) reset the memory vector outbox tables and replayed events. Outbox outcomes (status, vector row id) come from executing the outbox, not from events, so every operation came back pending with no row id. Recall admitted nothing until recovery ran, and recovery would project each revision again. Nothing calls a rebuild in production today, but temporal memory has to survive one.

The existing real-path memory tests also stopped at single transitions for one owner, while qualification needs every path through the production layers.

Changes

  • CanonicalConversationProjection.prepare_rebuild snapshots vector outbox outcomes for facts and episodes, and finish_rebuild restores them onto the replayed rows by event position and item id. Outcomes whose event no longer replays are dropped and logged, never attached elsewhere.
  • tests/memory_fixtures.py now holds the one real-path harness (fake Mem0 storage, protected store, seeded runs, query service), with helpers for a second owner. The existing test files import it instead of each other.
  • tests/test_memory_qualification.py is the matrix. Each test drives the production layers and, where facts remain, proves recall, authorized history, and zero integrity, projection, and drift gaps:
    • fact transitions: create, repeated statement skipped, refinement by human and confident model, unsure contradiction to conflict then resolved either way, retract and expire then restore, restore refused on a current claim;
    • episodes: record, repeat links, every follow-up relationship, records unchanged by later evidence, cross-owner links refused;
    • every non-active state out of recall and present in history;
    • project facts recalled only inside their project;
    • two owners isolated in recall, history, and mutation; an owner with two runtime profiles fails closed;
    • Telegram and Workshop authorities read and change the same memory;
    • restart: interrupted projection recovers without a duplicate, failed projection retried at startup;
    • rebuild: outbox, recall, and vector rows unchanged;
    • replay: repeated extraction output writes nothing, an identical lifecycle request after a failed projection reuses its event and projects once;
    • a failing vector read admits nothing stale;
    • no memory operation changes execution settings.

Verification

  • The rebuild test fails without the projection change (every outbox row returns pending with no row id) and passes with it.
  • Full suite: 7111 passed. Pyright clean.

@dcellison
dcellison merged commit 776f9be into main Sep 23, 2026
10 checks passed
@dcellison
dcellison deleted the test/memory-qualification-matrix branch September 23, 2026 17:51
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.

2 participants