Memory Graph v2: governed knowledge graph memory provider (memorygraph) - #7
Merged
Conversation
…(Memory Graph v2) Transforms Hermes memory from searchable notes into a governed knowledge graph, shipped as a bundled MemoryProvider plugin with zero core changes — all existing memory behavior (built-in MEMORY.md/USER.md, MemoryManager, other providers) is preserved; the provider is inert unless memory.provider: memorygraph is configured. Implemented (architecture stable): - Typed entities (person, project, goal, skill, business, organization, place, tool, concept) with alias resolution - Typed, time-aware relationships (valid_from/valid_to windows) - Claims (entity.attribute = value) with confidence, temporal validity, supersession chains, and evidence links (session, built-in memory, tool, URL) — plus an append-only governance audit log - Duplicate detection: re-assertion reinforces instead of duplicating (exact-key for exclusive attributes, fuzzy for free-form) - Contradiction detection: conflicting exclusive values are superseded time-aware when clearly newer, otherwise flagged for review with a resolve flow - Confidence tracking: reinforcement/feedback/contradiction deltas, clamped [0, 1] - Knowledge aging: half-life confidence decay since last reinforcement, with demotion of decayed tiers - Knowledge promotion: candidate → established → core gated on confidence, evidence count, reinforcements and age - One graph_memory tool (13 actions), prefetch recall, built-in memory write mirroring via on_memory_write, session-end governance sweep Design only (see plugins/memory/memorygraph/DESIGN.md): semantic dedupe via optional embedder, automatic turn extraction, cross-provider federation, promotion into MEMORY.md, multi-hop reasoning. Local-only: stdlib sqlite3, no network, no credentials; DB is profile-scoped at $HERMES_HOME/memory_graph.db. Tests: 78 new tests across store, governance, and provider layers; existing memory suites pass unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-import |
3 |
unresolved-attribute |
3 |
invalid-argument-type |
2 |
invalid-return-type |
1 |
invalid-assignment |
1 |
First entries
tests/plugins/memory/test_memorygraph_provider.py:7: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/plugins/memory/test_memorygraph_provider.py:399: [unresolved-attribute] unresolved-attribute: Attribute `policy` is not defined on `None` in union `GovernanceEngine | None`
tests/plugins/memory/test_memorygraph_provider.py:299: [unresolved-attribute] unresolved-attribute: Attribute `set_meta` is not defined on `None` in union `GraphStore | None`
plugins/memory/memorygraph/store.py:445: [invalid-argument-type] invalid-argument-type: Argument to bound method `GraphStore.get_claim` is incorrect: Expected `int`, found `int | None`
tests/plugins/memory/test_memorygraph_provider.py:301: [unresolved-attribute] unresolved-attribute: Attribute `get_meta` is not defined on `None` in union `GraphStore | None`
plugins/memory/memorygraph/store.py:445: [invalid-return-type] invalid-return-type: Return type does not match returned value: expected `dict[str, Any]`, found `dict[str, Any] | None`
tests/plugins/memory/test_memorygraph_store.py:6: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/plugins/memory/test_memorygraph_governance.py:6: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
plugins/memory/memorygraph/store.py:301: [invalid-argument-type] invalid-argument-type: Argument to bound method `GraphStore.get_entity` is incorrect: Expected `int`, found `int | None`
tests/run_agent/test_credits_notices_toggle.py:76: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to attribute `_credits_session_start_micros` of type `int`
✅ Fixed issues (2):
| Rule | Count |
|---|---|
unresolved-attribute |
2 |
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`
run_agent.py:2920: [unresolved-attribute] unresolved-attribute: Object of type `Self@get_credits_spent_micros` has no attribute `_credits_session_start_micros`
Unchanged: 5511 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t for clean ty check Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mps, teardown-safe sweep, valid_from validation
- _coerce_bool for tool args (bool("false") is True — string forms now
coerce correctly for 'exclusive' and 'helpful')
- clamp half_life_days > 0 and duplicate_similarity to [0, 1] at config
load (negative half-life would invert the decay curve)
- hold provider lock during session-end sweep so shutdown() cannot close
the store mid-sweep
- validate caller-supplied valid_from at write boundaries (lexicographic
ordering relies on the fixed timestamp format); named constant for
relationship reinforcement delta; sweep complexity notes
- 3 new regression tests (81 total)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Objective
Transform Hermes memory from searchable notes into a governed knowledge graph — implemented as a bundled
MemoryProviderplugin (plugins/memory/memorygraph/) with zero core changes. All existing memory behavior is preserved: built-in MEMORY.md/USER.md, the MemoryProvider ABC, MemoryManager, and every other provider are untouched. The provider is inert unlessmemory.provider: memorygraphis configured.Features
store.py— typed nodes + alias resolutionstore.py— typed edges withvalid_from/valid_towindows + confidencestore.py— provenance rows (session / built-in memory / tool / URL) attached to claims, relationships, entitiessuperseded_bychains;timelineaction reconstructs historygovernance.py— re-assertion reinforces (exact-key for exclusive attributes, fuzzy Jaccard/sequence for free-form)governance.py— clearly-newer exclusive values supersede time-aware; ambiguous conflicts flaggedcontradictedwith aresolveflowgovernance_logof every governed mutationModel surface: one
graph_memorytool (13 actions), prefetch recall injection, system-prompt status block, built-in memory write mirroring (on_memory_write), session-end governance sweep.Local-only: stdlib
sqlite3, no network, no credentials. DB profile-scoped at$HERMES_HOME/memory_graph.db.Design only (deliberately not implemented)
plugins/memory/memorygraph/DESIGN.mdspecifies — with rationale for deferral — semantic (embedding) dedupe, automatic turn extraction (NER → graph), cross-provider federation, promotion into MEMORY.md, and multi-hop reasoning.Preserving existing behavior
agent/,tools/,run_agent.py, gateway, or other providers.hermes_clichanges are help-text/comment additions only.Tests
78 new tests:
test_memorygraph_store.py— entities/aliases, time-aware relationships, claims, evidence, search, audit log, persistencetest_memorygraph_governance.py— dedupe/reinforcement, supersession vs. contradiction, resolution, confidence deltas, aging/demotion, promotion gates, sweeptest_memorygraph_provider.py— lifecycle safety, tool round-trips, mirroring, prefetch, config, loader discoveryruff check .passes (blocking CI lint gate).Status
HERMES_MEMORY_GRAPH_V2_READY — leaving this PR open for review.
🤖 Generated with Claude Code