The first live post-merge validation of PR #16110 has falsified its already-present recovery path without forcing or restarting shared infrastructure.
A current-source session-summary sweep staged and acknowledged five durable receipts between 2026-07-29T05:21:29Z and 05:21:47Z. At 05:33:10Z, the next natural sweep failed before new synthesis with:
Session-summary receipt replay verification failed for summary_019f9e1e-2ef1-72c3-a04d-6bc67a531a8b.
Direct SQLite-envelope versus Chroma read-back established the mismatch exactly:
the summary document matches;
every metadata key/value carried by the durable receipt matches;
Chroma additionally carries graphDigested:true and digestState:'digested', written by DreamService after summary synthesis;
two of the five newly staged receipts have those two extra fields and fail whole-object equality; the other three are exact and do not.
The first failing coordinator row remains completed, its receipt is intact, and result_last_replayed_at is still null. This is therefore not receipt loss. It is an ownership mismatch between immutable synthesis output and mutable downstream lifecycle metadata on the same Chroma row.
The Problem
ai/services/memory-core/helpers/sessionSummaryReceiptStore.mjs:202-204 currently defines an exact row as an exact document plus isDeepStrictEqual(row.metadata, receipt.metadata). That makes the receipt appear to own the complete metadata object forever.
ai/daemons/orchestrator/services/DreamService.mjs:602-629 legitimately extends the same row later with graphDigested, digestState, digestAttempts, and deferReason. Chroma document upsert preserves unrelated existing metadata keys. Recovery therefore sees a healthy, receipt-consistent row as mismatched, upserts the receipt payload, reads the still-preserved Dream fields back, and fails the same whole-object comparison again.
Because recoverSessionSummaryReceipts() runs before drift detection, one such row aborts the whole summarization child. The durable recovery mechanism introduced by #16105 thus blocks normal summary progress as soon as Dream-owned metadata reaches a receipt-backed row.
The Architectural Reality
SessionService.mjs:787-880 owns the synthesized document and base metadata, writes them to Chroma, and stages that exact synthesis result in SQLite.
sessionSummaryReceiptStore.mjs is the existing 269-LOC helper that owns receipt encoding, matching, replay, and CAS finalization. The Agent OS structure map confirms ai/services/memory-core/helpers/ as the established owner; no new file or service is needed.
DreamService.mjs:602-629 owns post-synthesis graph-digestion lifecycle fields on the same Chroma row.
The receipt must be authoritative for its own document and metadata fields. It must not claim ownership of later fields written by another service.
A missing or receipt-owned mismatch still requires replay and strict read-back. Extra downstream-owned fields alone do not.
The Fix
Replace whole-object metadata equality with a strict receipt-owned-key comparison: the document and every metadata key/value encoded in the receipt must be present and deeply equal; unrelated live metadata keys are tolerated.
Preserve the existing replay decision for a missing row, a changed document, a missing receipt-owned key, or a changed receipt-owned value.
Verify replay with the same ownership-aware predicate so Chroma metadata merge semantics cannot create a permanent retry/failure loop.
Add deterministic coverage for an already-present row carrying Dream-owned overlays, plus a real disposable-Chroma witness for the merge shape that escaped the fake collection.
Exact document plus strict equality for every receipt-owned metadata key; tolerate unrelated live keys
Treat any missing/changed owned field as replay-required
Helper JSDoc
Focused unit matrix
Receipt issuance / durable decode
sessionSummaryReceiptStore.mjs
Issuance enforces the declared allowed and required key sets; version-1 decode validates only the stable outer receipt shape so historical missing or retired metadata keys remain recoverable
Already-present Dream overlays count as present, not corruption; real base drift still replays and verifies
Retain the durable envelope and fail loud when owned fields cannot be verified
Method JSDoc
Fake-collection and disposable-Chroma witnesses
Dream lifecycle overlays
DreamService.mjs
Remain Dream-owned and survive an idempotent present-row recovery check
Missing rows replay the durable synthesis base and re-enter normal Dream eligibility
Existing DreamService JSDoc
Cross-service regression assertion
Summarization child startup
SessionService.mjs recovery call
One legitimately enriched receipt-backed row cannot abort the sweep
Existing thrown recovery errors remain fatal for corrupt envelopes or unverifiable owned fields
Existing lifecycle comments
Production-shaped multi-row test
Decision Record impact
none — this repairs the ownership contract inside the existing Memory Core receipt helper. It does not change MCP APIs, AiConfig, SQLite schema, Chroma ownership, or the Body/Brain boundary.
Acceptance Criteria
A row with an exact receipt document/base metadata plus graphDigested / digestState is classified present, not replayed, and recovery completes.
Extra downstream metadata is preserved; recovery does not delete, overwrite, or absorb it into the durable receipt.
A missing receipt-owned key, changed receipt-owned value, or changed document still triggers replay and strict post-upsert verification.
Recovery continues past multiple enriched receipt-backed rows instead of aborting the summarization child on the first one.
A disposable-Chroma test reproduces real metadata-merge behavior; the existing forced-stop/restart, idempotence, corruption, lease, and CAS tests remain green.
No model invocation, schema migration, new file, config key, or operator action is introduced.
AC7 [L3-deferred — post-merge current-source runtime needed]: the production-shaped receipt sweep that failed at 2026-07-29T05:33:10Z completes on current source, and #16017 remains open until that receipt evidence is posted.
Out of Scope
Resetting or reclassifying Dream lifecycle fields when a session is deliberately re-synthesized. That is a distinct lifecycle-invalidation question and requires its own falsifier before work.
Persisting mutable Dream lifecycle overlays inside the synthesis receipt.
Changing Chroma's metadata merge semantics, deleting/recreating healthy rows, or broadening durable receipts to other collections.
Reopening the closed #16105; this is its post-merge successor defect.
Closing #16017 before current-source runtime evidence passes.
Avoided Traps
Treat all extra metadata as corruption. The live fields are produced by the intended downstream consumer.
Relax the entire comparison. Receipt-owned values remain type-strict and deep-equal; only ownership scope changes.
Copy Dream fields into the envelope. They are mutable after staging, so the receipt would become stale by construction.
Delete/recreate an already-correct row. That would discard useful lifecycle state and turn an idempotent read path into needless mutation.
Make the fake collection define Chroma semantics. The escaped case exists because the fake replaces metadata while real Chroma preserves unrelated keys.
Duplicate / Claim Sweep
Live latest-open sweep: checked the latest 20 open issues from live GitHub, created-descending, at 2026-07-29T05:40:02Z; no equivalent found.
A2A in-flight sweep: checked the latest 30 messages across all read states immediately before creation; no competing claim or equivalent ticket intent found. The only matching message was this lane's own live-falsifier notice to Vega.
Knowledge Base and committed-corpus sweeps found #13647, #13697, and the REM epic #12065 as adjacent graph-projection history, plus #16017 / #16105 / PR #16110 as the direct incident lineage. None owns receipt equality under downstream metadata overlays.
Context
The first live post-merge validation of PR #16110 has falsified its already-present recovery path without forcing or restarting shared infrastructure.
A current-source session-summary sweep staged and acknowledged five durable receipts between
2026-07-29T05:21:29Zand05:21:47Z. At05:33:10Z, the next natural sweep failed before new synthesis with:Direct SQLite-envelope versus Chroma read-back established the mismatch exactly:
graphDigested:trueanddigestState:'digested', written byDreamServiceafter summary synthesis;The first failing coordinator row remains
completed, its receipt is intact, andresult_last_replayed_atis still null. This is therefore not receipt loss. It is an ownership mismatch between immutable synthesis output and mutable downstream lifecycle metadata on the same Chroma row.The Problem
ai/services/memory-core/helpers/sessionSummaryReceiptStore.mjs:202-204currently defines an exact row as an exact document plusisDeepStrictEqual(row.metadata, receipt.metadata). That makes the receipt appear to own the complete metadata object forever.ai/daemons/orchestrator/services/DreamService.mjs:602-629legitimately extends the same row later withgraphDigested,digestState,digestAttempts, anddeferReason. Chroma document upsert preserves unrelated existing metadata keys. Recovery therefore sees a healthy, receipt-consistent row as mismatched, upserts the receipt payload, reads the still-preserved Dream fields back, and fails the same whole-object comparison again.Because
recoverSessionSummaryReceipts()runs before drift detection, one such row aborts the whole summarization child. The durable recovery mechanism introduced by#16105thus blocks normal summary progress as soon as Dream-owned metadata reaches a receipt-backed row.The Architectural Reality
SessionService.mjs:787-880owns the synthesized document and base metadata, writes them to Chroma, and stages that exact synthesis result in SQLite.sessionSummaryReceiptStore.mjsis the existing 269-LOC helper that owns receipt encoding, matching, replay, and CAS finalization. The Agent OS structure map confirmsai/services/memory-core/helpers/as the established owner; no new file or service is needed.DreamService.mjs:602-629owns post-synthesis graph-digestion lifecycle fields on the same Chroma row.The Fix
Contract Ledger Matrix
sessionSummaryReceiptStore.mjssessionSummaryReceiptStore.mjsrecoverSessionSummaryReceipts()sessionSummaryReceiptStore.mjsDreamService.mjsSessionService.mjsrecovery callDecision Record impact
none— this repairs the ownership contract inside the existing Memory Core receipt helper. It does not change MCP APIs, AiConfig, SQLite schema, Chroma ownership, or the Body/Brain boundary.Acceptance Criteria
graphDigested/digestStateis classifiedpresent, notreplayed, and recovery completes.2026-07-29T05:33:10Zcompletes on current source, and #16017 remains open until that receipt evidence is posted.Out of Scope
#16105; this is its post-merge successor defect.Avoided Traps
Duplicate / Claim Sweep
Live latest-open sweep: checked the latest 20 open issues from live GitHub, created-descending, at
2026-07-29T05:40:02Z; no equivalent found.A2A in-flight sweep: checked the latest 30 messages across all read states immediately before creation; no competing claim or equivalent ticket intent found. The only matching message was this lane's own live-falsifier notice to Vega.
Knowledge Base and committed-corpus sweeps found
#13647,#13697, and the REM epic#12065as adjacent graph-projection history, plus #16017 /#16105/ PR #16110 as the direct incident lineage. None owns receipt equality under downstream metadata overlays.Related
Related: #16017 Related: #16105 Related PR: #16110 Related: #13647 Related: #13697
Origin Session ID: 019fac51-ddcb-7212-902e-09d3a9d19098
Handoff Retrieval Hints
query_raw_memories("session summary receipt replay verification graphDigested digestState Dream-owned metadata")2026-07-29T05:21:29Z..05:33:10Zsummary_019f9e1e-2ef1-72c3-a04d-6bc67a531a8b3cedd76cacAuthored by Euclid (GPT-5 Codex, Codex Desktop).