Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion hermes_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1741,7 +1741,7 @@ def _ensure_hermes_home_managed(home: Path):
"user_char_limit": 1375, # ~500 tokens at 2.75 chars/token
# External memory provider plugin (empty = built-in only).
# Set to a provider name to activate: "openviking", "mem0",
# "hindsight", "holographic", "retaindb", "byterover".
# "hindsight", "holographic", "memorygraph", "retaindb", "byterover".
# Only ONE external provider is allowed at a time.
"provider": "",
},
Expand Down
2 changes: 1 addition & 1 deletion hermes_cli/subcommands/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def build_memory_parser(subparsers, *, cmd_memory: Callable) -> None:
description=(
"Set up and manage external memory provider plugins.\n\n"
"Available providers: honcho, openviking, mem0, hindsight,\n"
"holographic, retaindb, byterover.\n\n"
"holographic, memorygraph, retaindb, byterover.\n\n"
"Only one external provider can be active at a time.\n"
"Built-in memory (MEMORY.md/USER.md) is always active."
),
Expand Down
117 changes: 117 additions & 0 deletions plugins/memory/memorygraph/DESIGN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Memory Graph v2 — Design

Status: v0.1 implemented (this plugin). This document records the
architecture decisions behind the implemented core and the **design-only**
roadmap for parts whose architecture is not yet stable enough to build.

## Goals

Transform Hermes memory from searchable notes into a **governed knowledge
graph** while preserving every existing memory behavior:

- Built-in `MEMORY.md` / `USER.md` file memory: untouched. The graph mirrors
its writes via the existing `on_memory_write` provider hook.
- The `MemoryProvider` ABC and `MemoryManager`: untouched. memorygraph is a
standard bundled provider, subject to the one-external-provider rule, and
inert unless `memory.provider: memorygraph` is configured.
- Other providers (honcho, hindsight, holographic, ...): untouched.

## Implemented core (architecture stable)

### Data model

```
entities ──< claims >── evidence
│ │
└──< relationships >────┘ (evidence attaches to claims, relationships
└──< entity_aliases and entities via (subject_kind, subject_id))
governance_log (append-only audit)
```

- **Entities** are typed (person, project, goal, skill, business,
organization, place, tool, concept) and resolved by normalized name key
with alias support. Projects, goals, skills, businesses and people are
first-class *entity types*, not separate tables: they share governance,
evidence and relationship semantics, and new types can be added without
migration.
- **Claims** are the unit of knowledge: `entity.attribute = value` plus
confidence, tier, status, temporal validity and provenance. This is the
classic property-graph-with-reified-statements shape: it lets governance
operate on statements (contradict, supersede, age, promote) rather than
on opaque note blobs.
- **Time-aware knowledge** is modeled with `valid_from`/`valid_to` windows
on both claims and relationships, plus a `superseded_by` chain. History is
never deleted — `timeline` reconstructs how knowledge evolved.

### Governance lifecycle

```
re-assertion (dup) aging sweep
write ──► reinforce ──► promote ──► decay ──► demote
├─ exclusive conflict, clearly newer ──► supersede (time-aware)
└─ exclusive conflict, ambiguous ──► contradicted (review queue)
```

- Write-time governance (dedupe, contradiction) keeps the graph clean at
the source. Sweep-time governance (aging, promotion) is idempotent and
runs at session end or on demand, never in the hot path.
- Confidence is a bounded scalar in [0, 1]; every mutation is clamped and
audited. Half-life decay (default 90 days since last reinforcement)
favors knowledge that keeps getting used.
- Promotion tiers gate trust: `candidate` (new, unproven) → `established`
(confident + independently evidenced) → `core` (repeatedly reinforced,
aged, uncontradicted). Consumers can filter recall by tier.

### Why a bundled provider, not a core change

The provider seam (`agent/memory_provider.py`) already carries every signal
the graph needs: turn sync, built-in write mirroring, pre-compression
extraction, session boundaries, tool exposure. Building v2 as a provider
means zero risk to existing memory behavior and a clean rollback path
(unset `memory.provider`).

## Design-only (architecture not yet stable — do not build)

These are specified here so future work is consistent, but deliberately not
implemented in v0.1:

1. **Semantic duplicate/contradiction detection.** Current detection is
lexical (normalized keys + Jaccard/sequence similarity). Embedding-based
similarity would catch paraphrases, but Hermes has no core embedding
dependency and each memory provider currently makes its own choice.
Design: an optional `Embedder` protocol injected into
`GovernanceEngine`, falling back to lexical similarity when absent.
Blocked on: choice of a local, dependency-light embedding path.

2. **Automatic turn extraction (NER → graph).** `sync_turn` /
`on_pre_compress` could extract entities and claims from conversation
automatically. Extraction quality gates trust in the whole graph, so
v0.1 keeps writes explicit (model-invoked `remember`/`link`, plus
mirrored built-in writes). Design: extraction lands as `candidate`
claims with `kind='extraction'` evidence and a lower initial confidence
(0.4), so promotion gates filter noise. Blocked on: an evaluated
extraction prompt/pipeline.

3. **Cross-provider federation.** Mirroring graph knowledge into an active
cloud provider (or importing from hindsight's entity graph) conflicts
with the one-external-provider rule by design. Any federation should be
an explicit `hermes memory export/import` CLI flow, not a runtime
bridge.

4. **Promotion into built-in MEMORY.md.** Auto-writing `core` claims into
`MEMORY.md` would change built-in memory behavior, which v2 must not do.
Design: a `promote_review` surface (already queryable via `stats` /
tier filters) that the *model* can act on with the existing memory tool,
keeping the human/model in the loop.

5. **Multi-hop graph reasoning.** `neighbors()` exists in the store;
compositional queries ("claims connected to X and Y within 2 hops")
need recursive CTEs plus result ranking. Deferred until real usage
shows which query shapes matter.

## Migration & versioning

`meta.schema_version` (currently 1) gates future migrations. Migrations
must be additive (new tables/columns) — history tables are append-only and
never rewritten.
76 changes: 76 additions & 0 deletions plugins/memory/memorygraph/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# memorygraph — Governed Knowledge Graph Memory

Transforms Hermes memory from searchable notes into a **governed knowledge
graph**: typed entities, time-aware relationships, evidence-linked claims,
confidence tracking, contradiction/duplicate detection, knowledge aging and
promotion.

Local-only (stdlib `sqlite3`), no network, no credentials. Database at
`$HERMES_HOME/memory_graph.db` (profile-scoped).

## Activate

```yaml
# config.yaml
memory:
provider: memorygraph
```

The built-in `memory` tool (MEMORY.md / USER.md) is unchanged. Writes to it
are mirrored into the graph via the `on_memory_write` hook, so both stay
consistent.

## Model

| Concept | Table | Notes |
|---|---|---|
| Entities | `entities` | Typed: person, project, goal, skill, business, organization, place, tool, concept. Alias resolution via `entity_aliases`. |
| Relationships | `relationships` | Typed edges with `valid_from`/`valid_to` windows and confidence. |
| Claims | `claims` | `entity.attribute = value` with confidence, tier (candidate → established → core), status (active / superseded / retracted / contradicted), temporal validity. |
| Evidence | `evidence` | Provenance links (session, built-in memory write, tool, URL, quote). |
| Audit | `governance_log` | Append-only log of every governed mutation. |

## Governance

- **Duplicate detection** — re-asserting known knowledge reinforces the
existing claim (confidence up, reinforcement count up) instead of
duplicating. Normalized-key match plus fuzzy similarity (default ≥ 0.88).
- **Contradiction detection** — conflicting values for an *exclusive*
attribute are superseded time-aware when the new value is clearly newer
(old claim's validity window closes, linked via `superseded_by`);
otherwise both are flagged `contradicted` for review (`contradictions` /
`resolve` actions).
- **Confidence tracking** — reinforcement +0.10, feedback ±0.15,
contradiction −0.15, clamped to [0, 1].
- **Knowledge aging** — confidence decays with a 90-day half-life since last
reinforcement (configurable); decayed established/core claims are demoted.
- **Knowledge promotion** — candidate → established at confidence ≥ 0.70
with ≥ 2 evidence links; established → core at confidence ≥ 0.85 with
≥ 3 reinforcements and ≥ 7 days of age. Contradicted claims never promote.

Sweeps run at session end (configurable) or on demand via the `sweep`
action.

## Tool

One tool, `graph_memory`, with actions:
`remember`, `link`, `unlink`, `about`, `query`, `timeline`,
`contradictions`, `resolve`, `duplicates`, `feedback`, `forget`, `sweep`,
`stats`.

## Config (optional)

`$HERMES_HOME/memorygraph.json`:

```json
{
"db_path": "/custom/path/memory_graph.db",
"half_life_days": 90,
"duplicate_similarity": 0.88,
"prefetch_enabled": true,
"sweep_on_session_end": true
}
```

See `DESIGN.md` for the governance model rationale and the design-only
roadmap.
Loading
Loading