Context
query_summaries / list_summaries returned empty under the team memorySharing policy — the intended repo default per the cloud-deployment access work (operator: "OUR own and the repo default should be team based access"). Memory-mining over session summaries was 100% non-functional on the team default.
Surfaced while investigating #12450 (the "query_summaries empty" symptom ticket): the operator's redirect ("explore if access related → team vs private") isolated this as a distinct root cause from #12450's documented Chroma vector-corruption (its Layers 1–2). This is the access-policy layer (Layer 3).
Root cause (V-B-A'd)
Session summaries carry no userId metadata (untagged legacy-commons — the summary writer does not tag userId, unlike raw-memory writes). But the team read applied where:{userId:'shared'}, which matched none of the untagged records → empty. Only legacy (no DB-where + JS post-filter passing untagged) returned them. With team as the intended default, every summary query read empty. query_raw_memories is unaffected (raw writes DO tag userId).
The Fix (delivered in PR #12470)
Make team additive like legacy — caller-owned + 'shared' + untagged commons — via the existing over-fetch + JS post-filter path; drop the restrictive {userId:'shared'} DB-where. private stays strict (own-only). Applied to querySummaries + listSummaries in SummaryService.mjs. The JS post-filter is mandatory for additive policies (else other tenants' private records leak) — kept consistent via an additivePolicy flag.
Contract Ledger
| Target Surface |
Source of Authority |
Behavior |
Fallback |
Evidence |
query_summaries / list_summaries (memorySharing:'team') |
SummaryService.mjs querySummaries/listSummaries |
additive: own + 'shared' + untagged commons; no restrictive DB-where |
JS post-filter excludes other-tenant private |
SummaryService.TenantIsolation.spec.mjs:363 (16/16) |
memorySharing:'private' |
same |
strict own-only {userId} DB-where |
— |
private contract test |
Acceptance Criteria
Scope
Access-policy only. NOT the Chroma HNSW corruption / injectQueryReRanker observability / healthcheck-canary work — those remain on #12450 (Layers 1–2).
Refs #12450 (symptom ticket; this is its access-policy Layer 3).
Origin Session ID: 3ecb40bf-bfef-40b1-8693-a8aae5afa1b7
Authored by Claude Opus 4.8 (Claude Code), /lead-role.
Context
query_summaries/list_summariesreturned empty under theteammemorySharing policy — the intended repo default per the cloud-deployment access work (operator: "OUR own and the repo default should be team based access"). Memory-mining over session summaries was 100% non-functional on the team default.Surfaced while investigating #12450 (the "query_summaries empty" symptom ticket): the operator's redirect ("explore if access related → team vs private") isolated this as a distinct root cause from #12450's documented Chroma vector-corruption (its Layers 1–2). This is the access-policy layer (Layer 3).
Root cause (V-B-A'd)
Session summaries carry no
userIdmetadata (untagged legacy-commons — the summary writer does not taguserId, unlike raw-memory writes). But theteamread appliedwhere:{userId:'shared'}, which matched none of the untagged records → empty. Onlylegacy(no DB-where + JS post-filter passing untagged) returned them. Withteamas the intended default, every summary query read empty.query_raw_memoriesis unaffected (raw writes DO taguserId).The Fix (delivered in PR #12470)
Make
teamadditive likelegacy— caller-owned +'shared'+ untagged commons — via the existing over-fetch + JS post-filter path; drop the restrictive{userId:'shared'}DB-where.privatestays strict (own-only). Applied toquerySummaries+listSummariesinSummaryService.mjs. The JS post-filter is mandatory for additive policies (else other tenants' private records leak) — kept consistent via anadditivePolicyflag.Contract Ledger
query_summaries/list_summaries(memorySharing:'team')SummaryService.mjsquerySummaries/listSummaries'shared'+ untagged commons; no restrictive DB-whereSummaryService.TenantIsolation.spec.mjs:363(16/16)memorySharing:'private'{userId}DB-whereAcceptance Criteria
teamsummary reads return caller-owned +'shared'+ untagged commons (not the empty{userId:'shared'}filter). (PR #12470)team/legacyreads via the JS post-filter. (codified test, incl. the cross-tenant assertion)privatestays strict own-only. (unchanged + tested)query_summaries(memorySharing:'team')returns non-empty for the commons.Scope
Access-policy only. NOT the Chroma HNSW corruption /
injectQueryReRankerobservability / healthcheck-canary work — those remain on #12450 (Layers 1–2).Refs #12450 (symptom ticket; this is its access-policy Layer 3).
Origin Session ID: 3ecb40bf-bfef-40b1-8693-a8aae5afa1b7 Authored by Claude Opus 4.8 (Claude Code), /lead-role.