Graph Quality Gate Plan
Goal
Create a concrete quality gate that must pass before graph-derived memory can
influence retrieval ranking or memory_ask answers.
The gate should make entity extraction, relationship extraction, provenance, and graph-aware retrieval measurable with deterministic local fixtures. This avoids promoting graph memory based on intuition alone.
Scope
- [x] Add a local benchmark module:
memory.benchmarks.graph_quality. - [x] Define a representative golden corpus for graph-memory extraction and retrieval behavior.
- [x] Report entity, relationship, provenance, conflict-detection, and graph-retrieval metrics.
- [x] Fail with explicit threshold messages when graph quality is below the promotion bar.
- [x] Keep graph retrieval disabled until the quality gate passes.
Non-Goals
- [ ] Do not implement production graph retrieval in this plan.
- [ ] Do not require hosted LLMs or network access.
- [ ] Do not make graph extraction overwrite raw conversations or normalized facts.
- [ ] Do not expose graph-derived answers through MCP/API before provenance and quality gates are in place.
Phase 1: Golden Corpus Shape
- [x] Create a small deterministic corpus of representative conversations.
- [x] Cover project-memory examples already used by the repo: Codex/opencode handoff, PGVector, bearer auth, observability, tokenizer setup, retrieval benchmarks, Velvet Lantern, tools, providers, and user preferences.
- [x] For each conversation, define stable conversation IDs and message indexes.
- [x] For each corpus item, define expected entities:
id,type,name,aliases,source_conversation_id,source_message_index, and optionalsource_fact_id. - [x] For each corpus item, define expected relationships:
subject,predicate,object,confidence,source_conversation_id,source_message_index, and optionalsource_fact_id. - [x] Include negative examples where text mentions nearby entities but should not create a relationship.
- [x] Include conflict examples where newer memory contradicts older memory.
Acceptance criteria:
- [x] The corpus is local, deterministic, and small enough for unit tests.
- [x] Expected entities and relationships are human-readable.
- [x] Provenance expectations are explicit instead of inferred later.
Phase 2: Metric Definitions
- [x] Entity precision: matched expected entities divided by produced entities.
- [x] Entity recall: matched expected entities divided by expected entities.
- [x] Entity F1: harmonic mean of entity precision and recall.
- [x] Relationship precision: matched expected relationships divided by produced relationships.
- [x] Relationship recall: matched expected relationships divided by expected relationships.
- [x] Relationship F1: harmonic mean of relationship precision and recall.
- [x] Provenance accuracy: matched extracted records with correct source provenance divided by matched extracted records.
- [x] Conflict-detection precision and recall for contradictory relationship or fact candidates.
- [x] Graph retrieval
precision_at_1,recall_at_k, and MRR for relationship questions. - [x] Baseline comparison against non-graph retrieval for the same graph retrieval cases.
Matching policy:
- [x] Entity matching should normalize case, whitespace, and configured aliases.
- [x] Relationship matching should require normalized subject, predicate, and object match.
- [x] Provenance matching should require the expected conversation ID and message index, with chunk/fact ID checks when available.
- [x] Extra unsupported entities or relationships count against precision.
- [x] Missing expected entities or relationships count against recall.
Phase 3: Benchmark Module
- [x] Add
memory/benchmarks/graph_quality.py. - [x] Expose
run_evaluation(...) -> dict[str, Any]. - [x] Expose
assert_thresholds(report: dict[str, Any]) -> None. - [x] Add a CLI entrypoint runnable as:
uv run python -m memory.benchmarks.graph_quality. - [x] Print JSON with:
corpus,entity,relationship,provenance,conflict_detection,graph_retrieval,baseline_retrieval, andthresholdssections. - [x] Return exit code
1when threshold failures exist. - [x] Keep the benchmark independent of external storage, embeddings, LLMs, and network services.
Suggested CLI options:
- [x]
--top-k - [x]
--min-entity-precision - [x]
--min-entity-recall - [x]
--min-relationship-precision - [x]
--min-relationship-recall - [x]
--min-provenance-accuracy - [x]
--min-graph-precision-at-1 - [x]
--min-graph-recall-at-k - [x]
--min-graph-mrr
Phase 4: Initial Thresholds
Initial thresholds should be conservative and adjustable as fixtures become more representative.
- [x] Entity precision must be at least
0.90. - [x] Entity recall must be at least
0.80. - [x] Relationship precision must be at least
0.95. - [x] Relationship recall must be at least
0.75. - [x] Provenance accuracy must be at least
0.98. - [x] Graph retrieval
precision_at_1must be at least0.85. - [x] Graph retrieval
recall_at_kmust be at least0.90. - [x] Graph retrieval MRR must be at least
0.85. - [x] Graph retrieval must not regress below baseline retrieval on ordinary semantic queries.
- [x] Every threshold failure must include the metric name, observed value, and expected value.
Phase 5: Tests
- [x] Add
tests/unit/test_graph_quality_benchmark.py. - [x] Test report shape and required metric sections.
- [x] Test invalid threshold arguments.
- [x] Test explicit threshold failure messages.
- [x] Test entity precision/recall/F1 calculations.
- [x] Test relationship precision/recall/F1 calculations.
- [x] Test provenance accuracy calculation.
- [x] Test graph retrieval regression detection against baseline retrieval.
- [x] Test CLI exit code behavior for passing and failing thresholds.
Phase 6: Promotion Rule
- [x] Graph extraction may be developed before the gate passes, but graph-derived records must remain review-only or disabled for retrieval.
- [x] Graph lookup may become a retrieval candidate source only after the graph quality benchmark passes agreed thresholds.
- [x] Any new entity type, relationship predicate, extractor, or graph reranking rule must add or update benchmark cases.
- [x] Public API/MCP graph fields must stay experimental until the benchmark and shape tests cover them.
Done When
- [x]
memory.benchmarks.graph_qualityexists and runs locally without network dependencies. - [x] The benchmark reports entity, relationship, provenance, conflict, and graph-retrieval metrics.
- [x] Threshold failures are explicit and actionable.
- [x] Unit tests cover metric calculations and threshold failures.
- [x]
docs/improvements/advanced_memory_plan.mdpoints to this gate before graph-aware retrieval.