Skip to content

Route agent memory writes through the lifecycle and complete memory diagnostics - #1782

Merged
dcellison merged 1 commit into
mainfrom
fix/memory-write-paths-diagnostics
Sep 23, 2026
Merged

dcellison merged 1 commit into
mainfrom
fix/memory-write-paths-diagnostics

Conversation

@dcellison

Copy link
Copy Markdown
Owner

First of three deliveries for #1717.

Problems

  • Explicit saves were not recalled (live). POST /api/memory/add wrote straight to the vector store. On a protected install that row has no canonical claim, so the current-truth gate treats it as legacy memory. Once an owner's legacy memory is reconciled, legacy admission ends and every new explicit save was stored, reported as saved, and never recalled.
  • Forget-all desynchronized canonical state. POST /api/memory/delete_all deleted vector rows and left every canonical claim active with a projection pointing at nothing.
  • False replay gaps. Reconciliation status counted every operation without an audit id as a replay gap, including policy replans and consolidation saves and cancels, which never carry one.
  • Missing diagnostics. No per-state lifecycle counts, no vector drift in install status, and unreviewed legacy rows of owners who never ran an audit were reported as gaps.

Changes

  • Explicit saves on a protected install become canonical claims through MemoryFactLifecycleService.create (new agent evidence kind, scope routed as before). A failed projection returns 503 instead of a success. Only facts are accepted there.
  • Forget-all on a protected install retracts every active claim through the lifecycle (restorable, history kept), deletes legacy rows, and keeps unresolved conflicts and canonical episodes, reporting counts.
  • Replay gaps now account for replan records by the plan they produced and consolidation operations by their plan and consolidation. Unrecognized operations are still gaps.
  • The vector audit reports missing rows (current facts with no search row). The service audits each owner at startup and after projection retries and stores counts in memory_vector_audit (schema 96); install status reads them, since it runs as root and must not open the service-owned vector store. Workshop's search index check and the CLI audit show missing rows too.
  • Current-truth status adds states=(...), vector drift=..., and legacy review pending=N owner(s); unclassified rows count as gaps only for owners who applied an audit. Episode status breaks follow-ups down by relationship.
  • A sweep test pins every direct vector write or delete outside kai.memory to a reviewed allowlist.

Verification

  • New tests: real-path agent save, project scope, failed projection, old direct write not recalled, forget-all (conflicts kept, legacy deleted, facts restorable), repeatable forget-all, stored audit and install status, audit refresh after retry; handler tests; replay gap tests for consolidations and replans; status tests; client tests.
  • Read-only against production: reconciliation now reports replay gaps=0 and active; a vector audit of every owner finds zero orphan, unknown, duplicate, and missing rows.
  • Full suite: 7086 passed. Client check: 288 passed. Pyright clean.

@dcellison
dcellison merged commit f61ff2a into main Sep 23, 2026
10 checks passed
@dcellison
dcellison deleted the fix/memory-write-paths-diagnostics branch September 23, 2026 17:26
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