fix(memory): enforce record-class storage for evidence memories#452
Merged
Conversation
Distillation never produced record-class memories because the prompt listed both operations without mapping them to memory classes. The LLM defaulted to upsert_document for everything, storing evidence as mergeable documents instead of immutable records. Two-layer fix: - Policy override in MemoryProposalGate: memoryClass now determines storage kind regardless of the LLM's operation choice. Evidence and trace always become records; durable_fact always becomes a document. - Prompt improvements: both distillation and observation prompts now include shared classification rules with explicit operation-to-class mapping and concrete examples of each type.
7ee5e39 to
6744c95
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #446 — distillation never produces record-class memories.
MemoryProposalGate.BuildMemoryOperation():memoryClassnow determines storage kind instead of trusting the LLM'soperationfield. Evidence → Record + ImmutableRecord, Trace → Record + ConversationTrace, DurableFact → Document + MergeDocument.MemorySidecarPromptBuilder.BuildClassificationRules()): strict operation-to-class mapping used by both the distillation and observation prompts to prevent drift.upsert_document(durable_fact) andappend_record(evidence), and explicit field specification.Root Cause
The
BuildDistillationSystemPrompt()listed bothupsert_documentandappend_recordas valid operations but never mapped which one to use for which memory class. The Qwen 27B model defaulted toupsert_documentfor nearly everything. Result: 32 documents (including 11 evidence incorrectly stored as merge-on-write documents) but only 1 record.Test plan
dotnet buildsucceedscuration_createlog events — evidence proposals should show"immutable record bypass"reasonSELECT COUNT(*) FROM memory_recordsshould show records growing over time