Context
Slice-3 of the #14193 field↔document de-dup (part of #14079 bloat). Slice-1 (#14202, composeTurnDocumentText) + slice-2 (#14206/#14207, write-path single-source) are in. This is the read-path: MemoryService's two collection.get(['documents']) neighbor-recall paths must reconstruct the turn-document from split metadata when the redundant stored document has been dropped (so the slice-4 migration is safe), gated on the turn-vs-summary discriminator.
Change
- New pure
resolveTurnDocumentForRead({documents, metadata}) in turnDocumentText.mjs (read-side, beside the write-side composeTurnDocumentText): prefers the stored document (byte-exact, behavior-preserving for existing records); else reconstructs via composeTurnDocumentText ONLY for turns (metadata.type === 'agent-interaction'); a summary (distinct shape) is never reconstructed → its stored document or null. Single-sources the discriminator so every read-path shares it.
- The two MemoryService neighbor-recall reads (strategic
content, episodic episodicContext) call it; the episodic read adds metadatas to its include.
Acceptance Criteria
Links
Part of #14193 (de-dup) · #14079 (bloat). Stacked on #14207 (slice-2) + #14202 (slice-1). I co-drive slice-4 (the migration) with @neo-opus-ada next.
Authored by Grace (Claude Opus 4.8, Claude Code). Session 090a68e6-1a28-4b20-a5fd-842ebac3e729.
Context
Slice-3 of the #14193 field↔document de-dup (part of #14079 bloat). Slice-1 (#14202,
composeTurnDocumentText) + slice-2 (#14206/#14207, write-path single-source) are in. This is the read-path: MemoryService's twocollection.get(['documents'])neighbor-recall paths must reconstruct the turn-document from split metadata when the redundant stored document has been dropped (so the slice-4 migration is safe), gated on the turn-vs-summary discriminator.Change
resolveTurnDocumentForRead({documents, metadata})inturnDocumentText.mjs(read-side, beside the write-sidecomposeTurnDocumentText): prefers the stored document (byte-exact, behavior-preserving for existing records); else reconstructs viacomposeTurnDocumentTextONLY for turns (metadata.type === 'agent-interaction'); a summary (distinct shape) is never reconstructed → its stored document ornull. Single-sources the discriminator so every read-path shares it.content, episodicepisodicContext) call it; the episodic read addsmetadatasto itsinclude.Acceptance Criteria
agent-interaction) are NEVER reconstructed via the turn template.resolveTurnDocumentForReadis pure + total (unit-tested: stored-wins, dropped-doc reconstruct across[null]/[]/undefined, summary-never-reconstruct, null-safety).Links
Part of #14193 (de-dup) · #14079 (bloat). Stacked on #14207 (slice-2) + #14202 (slice-1). I co-drive slice-4 (the migration) with @neo-opus-ada next.
Authored by Grace (Claude Opus 4.8, Claude Code). Session 090a68e6-1a28-4b20-a5fd-842ebac3e729.