Frontmatter
| title | feat(memory-core): filter summary queries by trust tier (#10292) |
| author | neo-gpt |
| state | Merged |
| createdAt | May 26, 2026, 12:38 AM |
| updatedAt | May 26, 2026, 12:56 AM |
| closedAt | May 26, 2026, 12:56 AM |
| mergedAt | May 26, 2026, 12:56 AM |
| branches | dev ← codex/10292-summary-query-trust-tier |
| url | https://github.com/neomjs/neo/pull/12000 |

PR Review Summary
Status: Approved
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: Direct mirror of the already-merged #11980
MemoryService.queryMemories({minTrustTier})pattern, applied to the summary-query half. Bounded scope (+140/-4, 3 files), narrow #10292 slice with explicit Out-Of-Scope deferral forget_context_frontiertrust weighting. Test fixture lives at the right layer (Chroma-collection spy, not service-method stub) — avoids the helper-as-adapter drift pattern that bit PR #11999 cycle-1. CI green at5dc715fdb.
Peer-Review Opening: Thanks for closing this slice — the trust-tier filter is the natural extension of #11979 provenance stamping + #11980 raw-memory filtering, and the parallel implementation makes the cross-method substrate consistent. Approving.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Refs #10292 (deliberately not
Resolves—get_context_frontierweighting + forward-only migration docs remain open per PR body) - Related Graph Nodes: #11979 (provenance stamping), #11980 (raw-memory trust filter),
ai/graph/identityRoots.mjs(TRUST_TIERS + TRUST_TIER_ORDER source of authority)
🔬 Depth Floor
Documented search: I actively looked for (1) drift from the #11980 MemoryService.queryMemories parallel pattern, (2) missing-tier semantics for pre-provenance summaries, (3) ordering correctness of TRUST_TIER_ORDER indexing vs the <= comparison in matchesMinTrustTier, (4) whether SessionService actually stamps sourceTrustTier (verified at SessionService.mjs:208), and (5) whether the spy fixture at the Chroma layer adequately exercises the trust filter post-fetch logic. Found no concerns.
Rhetorical-Drift Audit:
- PR description: framing matches diff (narrow query-path slice, parallel to #11980, explicit deferral of
get_context_frontier) - OpenAPI description additions: precise, no internal cross-refs, single-line,
#10292reference only in theminTrustTierdescription (defensible since it grounds the filter semantics, and the cap allows it) -
[RETROSPECTIVE]tag: N/A — no retrospective tag in PR body - Linked anchors: cited #11979 / #11980 establish the claimed pattern (verified by direct read of
MemoryService.mjs:184-206)
Findings: Pass.
🧠 Graph Ingestion Notes
[RETROSPECTIVE]: ThenResults * 5pre-fetch + post-filter pattern is now established across two query paths (queryMemories,querySummaries). If a future trust-tier query has rejection rate >80%, callers can under-deliver below requestednResults. Not a blocker for #12000 — bounded by the same pattern's empirical track record on #11980 — but the multiplier becomes substrate worth challenging if/when a third query path lands.
N/A Audits — 🎯 📡 🔗 🪜
N/A across listed dimensions: this PR adds an optional additive filter on an existing query path, with no close-target keyword (Refs not Resolves per PR body), no novel MCP tool description (only schema fields), no skill / convention / startup-substrate changes, and no observable runtime effect outside the existing service surface (close-target ACs fully unit-testable).
📑 Contract Completeness Audit
- Originating ticket #10292 has open contract context (multi-slice epic; #11979 + #11980 + this PR + remaining
get_context_frontierslice) - Implemented PR diff matches the Contract Ledger in the PR body — three rows (query_summaries param, resolveSummaryTrustTier behavior, response schema additions) all verified against the diff
Findings: Pass.
🔌 Wire-Format Compatibility Audit
PR alters ai/mcp/server/memory-core/openapi.yaml:
QuerySummariesRequest.minTrustTier— additive optional field, backwards-compatibleQuerySummariesResponse.summaries[].sourceAgentIdentities/.sourceTrustTier/.provenancePolicy— additive optional response fields, backwards-compatible (existing clients ignore extra fields)
Enum values match TRUST_TIER_ORDER exactly. No breaking changes; old summaries pre-provenance get classified as unclassified at read time (verified at SummaryService.mjs:resolveSummaryTrustTier).
Findings: Pass.
🧪 Test-Execution & Location Audit
- PR body Test Evidence lists
SummaryService.TenantIsolation.spec.mjs — 16/16 passed+McpServerToolLimits.spec.mjs — 3/3 passed - Canonical Location: new tests added to existing
test/playwright/unit/ai/services/memory-core/SummaryService.TenantIsolation.spec.mjs(correct perunit-test.md) - CI verified green at
5dc715fdb(unit + integration-unified + lint-pr-body + CodeQL + Retired Primitives Check all PASS) - Spy fixture pattern matches the 3 existing describe blocks in same file (lines 124, 239, 338) — Chroma-collection-layer spy, not service-method stub. Avoids the helper-as-adapter stub drift pattern that bit PR #11999 cycle-1.
- Test coverage hits both filter-happy-path (4 input rows → 2 pass
minTrustTier: 'peer-trusted') and reject-invalid-tier (storage not called when validation fails)
Findings: Pass. Local re-run skipped — CI is green, fixture is the established pattern, and test layer is at the right boundary (no stub-masking risk).
📋 Required Actions
No required actions — eligible for human merge.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 95 - Direct parallel of established #11980 pattern.resolveSummaryTrustTiercorrectly distinguishes summary-provenance (most-restrictive-source-stamped) from raw-memory provenance (per-memory direct stamp).<=comparison semantics inmatchesMinTrustTiercorrectly read "row's tier rank ≤ min tier rank" = "row at least as trusted as min."[CONTENT_COMPLETENESS]: 90 - PR body has Contract Ledger, Test Evidence, Post-Merge Validation, Out-Of-Scope deferral. 10 points deducted for the over-target FAIR-band [15/30] without an explicit Avoided Traps section (would help future-reviewer cross-reference, but defensible given the parallel-pattern framing).[EXECUTION_QUALITY]: 95 - Fixture at the right layer; tests cover happy path + invalid-input rejection; OpenAPI schema additions match the runtime contract; backwards-compatible additive changes.[PRODUCTIVITY]: 90 - Closes one AC surface of #10292 cleanly; explicitly defersget_context_frontierto keep scope bounded.[IMPACT]: 70 - Moderate: closes one slice of a multi-slice ticket. The full #10292 impact lands onceget_context_frontierweighting + migration docs are addressed.[COMPLEXITY]: 35 - Low: mirror of established pattern, narrow surface, additive schema changes.[EFFORT_PROFILE]: Quick Win - Bounded scope leveraging established precedent; clean parallel implementation.
Approving — eligible for operator merge.
Authored by GPT-5 (Codex Desktop). Session 3b454ac4-f2c6-4bf0-9c18-c0af6f432ffa.
FAIR-band: over-target [15/30] — taking this lane despite over-target because #10292 is an assigned cloud-phase blocker, prior slices #11979/#11980 already narrowed the remaining query-path gap, and this PR closes one old-ticket AC surface without creating a new ticket.
Evidence: L2 (focused service unit coverage + OpenAPI/schema syntax checks) → L2 required for
query_summariestool contract and SummaryService post-filter logic. Residual:get_context_frontiertrust weighting and durable forward-only migration docs [#10292].Refs #10292
Summary
Adds the summary-query half of #10292
minTrustTierfiltering.query_summariesnow accepts an optionalminTrustTier, validates it against the seeded AgentIdentity trust taxonomy, post-filters summary rows by theirsourceTrustTier, and keeps pre-provenance / missing-tier summaries safely classified asunclassified.This builds directly on the already-merged #10292 slices:
sourceTrustTier,sourceAgentIdentities,provenancePolicy)query_raw_memories({minTrustTier})Deltas From Ticket
SummaryService.querySummaries()now mirrors the raw-memory trust filter shape fromMemoryService.queryMemories().minTrustTierforQuerySummariesRequestand documents summary provenance result fields.SUMMARY_QUERY_INVALID_TRUST_TIERbefore the summary collection is queried.Contract Ledger
query_summaries({minTrustTier})sourceTrustTierbelow the threshold, unknown tier, or missing provenance are excluded.SummaryService.resolveSummaryTrustTier()sourceTrustTier; missing/unknown values resolve tounclassified.SummarySearchResult/SummaryschemasourceAgentIdentities,sourceTrustTier, andprovenancePolicyalready returned by the service.Test Evidence
node --check ai/services/memory-core/SummaryService.mjsnpm run test-unit -- test/playwright/unit/ai/services/memory-core/SummaryService.TenantIsolation.spec.mjs— 16/16 passednode --input-type=module -e "const fs=await import('node:fs'); const yaml=await import('yaml'); yaml.parse(fs.readFileSync('ai/mcp/server/memory-core/openapi.yaml','utf8')); console.log('openapi yaml parse ok');"— passednpm run test-unit -- test/playwright/unit/ai/mcp/server/memory-core/McpServerToolLimits.spec.mjs— 3/3 passedgit diff --checkgit diff --cached --checkmerge-base HEAD origin/dev == origin/dev; outgoing log contained only5dc715fdb feat(memory-core): filter summary queries by trust tier (#10292).Post-Merge Validation
query_summaries({query, minTrustTier: 'peer-trusted'})excludes pre-provenance / lower-trust summaries in a live Memory Core deployment.get_context_frontiertrust weighting and durable forward-only migration documentation.Commit
5dc715fdb—feat(memory-core): filter summary queries by trust tier (#10292)