Skip to content

Memory Graph v2: governed knowledge graph memory provider (memorygraph) - #7

Merged
chadsm-sys merged 4 commits into
mainfrom
feat/memory-graph-v2
Jul 6, 2026
Merged

Memory Graph v2: governed knowledge graph memory provider (memorygraph)#7
chadsm-sys merged 4 commits into
mainfrom
feat/memory-graph-v2

Conversation

@chadsm-sys

Copy link
Copy Markdown
Owner

Objective

Transform Hermes memory from searchable notes into a governed knowledge graph — implemented as a bundled MemoryProvider plugin (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 unless memory.provider: memorygraph is configured.

Features

Feature Where
Entities (people, projects, goals, skills, businesses, orgs, places, tools, concepts) store.py — typed nodes + alias resolution
Relationships store.py — typed edges with valid_from/valid_to windows + confidence
Evidence links store.py — provenance rows (session / built-in memory / tool / URL) attached to claims, relationships, entities
Time-aware knowledge validity windows + superseded_by chains; timeline action reconstructs history
Duplicate detection governance.py — re-assertion reinforces (exact-key for exclusive attributes, fuzzy Jaccard/sequence for free-form)
Contradiction detection governance.py — clearly-newer exclusive values supersede time-aware; ambiguous conflicts flagged contradicted with a resolve flow
Confidence tracking reinforcement +0.10, feedback ±0.15, contradiction −0.15, clamped [0, 1]
Knowledge aging half-life decay (default 90d) since last reinforcement; decayed tiers demote
Knowledge promotion candidate → established → core, gated on confidence, evidence count, reinforcements, age; contradicted claims never promote
Governance audit append-only governance_log of every governed mutation

Model surface: one graph_memory tool (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.md specifies — 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

  • No changes to agent/, tools/, run_agent.py, gateway, or other providers.
  • hermes_cli changes are help-text/comment additions only.
  • Existing memory suites pass unchanged (plugins/memory, agent memory provider, memory tool, CLI memory setup/reset — 533 tests verified locally).

Tests

78 new tests:

  • test_memorygraph_store.py — entities/aliases, time-aware relationships, claims, evidence, search, audit log, persistence
  • test_memorygraph_governance.py — dedupe/reinforcement, supersession vs. contradiction, resolution, confidence deltas, aging/demotion, promotion gates, sweep
  • test_memorygraph_provider.py — lifecycle safety, tool round-trips, mirroring, prefetch, config, loader discovery

ruff check . passes (blocking CI lint gate).

Status

HERMES_MEMORY_GRAPH_V2_READY — leaving this PR open for review.

🤖 Generated with Claude Code

…(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>
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

🔎 Lint report: feat/memory-graph-v2 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 10548 on HEAD, 10536 on base (🆕 +12)

🆕 New issues (10):

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.

chadsm-sys and others added 3 commits July 5, 2026 19:43
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>
@chadsm-sys
chadsm-sys merged commit e9b51e5 into main Jul 6, 2026
35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant