Skip to content
AronAxePublic

About

Mnemonic Devices for your Agents: Folder based recall priming.

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

MemHooks

Mnemonic devices for agents.

Filesystem-scoped memory recall · Hook the right memories into the right context. 🎣

Agent Skills Hermes Backend neutral Crates.io Version License

How MemHooks works

The idea

You can't recall what you don't know you know.

An agent can have the right memory stored perfectly and still fail to use it because retrieval begins with a cue. MemHooks stores that cue close to the code or folder where it matters.

Memory systems know how to remember. MemHooks tells the agent what to recall here.

When an agent works in a directory, MemHooks resolves MEMHOOKS.md root → leaf, applies inheritance and role routing, and produces a bounded retrieval plan for the memory backend the runtime actually uses.

workspace/
├── MEMHOOKS.md
├── backend/
│   ├── MEMHOOKS.md
│   └── auth/
│       ├── MEMHOOKS.md
│       └── refresh.py
root hook
   ↓
local hooks
   ↓
reference resolver
   ↓
backend-neutral retrieval intent + provider hints
   ↓
memory adapter
   ↓
bounded relevant context
   ↓
do the work

Who does what?

Normal users generally do not hand-maintain MEMHOOKS.md.

  • User: installs/enables MemHooks and may configure a memory backend.
  • Agent/runtime: creates, updates, prunes, and consumes local retrieval cues.
  • MemHooks reference engine: parses, validates, resolves, explains and maintains the hook frontmatter.
  • Memory backend: stores and retrieves the actual memories.

There is deliberately one structured data path in v0.6.0:

agent/runtime
    ↓
memhooks note / memhooks event
    ↓
YAML frontmatter
    ↓
reference parser + resolver
    ↓
memhooks explain / Rust API
    ↓
adapter

The Markdown body is optional source-attributed retrieval guidance. It is not a second hidden routing database.

Backend-neutral core

memhooks/v2 separates universal retrieval intent from provider-native controls.

The core understands only provider-neutral concepts:

  • recall_queries
  • query priority
  • when.roles
  • entities
  • resources
  • tags
  • exclude
  • scope
  • sensitivity
  • filesystem inheritance

Provider-native controls live under:

backends:
  <provider>:
    ... provider-owned configuration ...

MemHooks preserves and structurally merges provider mappings but deliberately does not interpret their internal keys.

Example

---
schema: memhooks/v2
inherits: true
scope: backend/auth

recall_queries:
  - query: "Why did the authentication design change after the outage?"
    priority: 1.0
    when:
      roles: [reviewer, architect]
    entities:
      - Authentication
    resources:
      - name: auth-postmortem
        kind: postmortem
        salience: 0.9
    tags: [security]
    backends:
      mem0:
        top_k: 8
        rerank: true
      hindsight:
        memory_types: [experience]
        strategy: reflect

entities:
  - name: Authentication
    type: CONCEPT
    salience: 0.95

exclude:
  - obsolete OAuth prototype

backends:
  mem0:
    filters:
      user_id: auth-agent
  hindsight:
    bank: project-memory
---

Here priority, roles, entities, resources, tags, and exclusions are MemHooks concepts. Mem0 filters/reranking and Hindsight banks/types/Reflect are provider-owned hints.

Provider references

First-class adapter references are included for:

The provider references ship inside the crates.io package as of v0.5.1.

Install

cargo install memhooks

For an exact release:

cargo install memhooks --version 0.6.0

Rust runtimes can use the same engine directly:

cargo add memhooks@0.6.0

CLI

Enable a project

memhooks init .

Validate

memhooks validate --all
memhooks validate --all --format json
memhooks validate --all --format sarif

A nonexistent target is an error rather than a misleading empty success.

Explain the complete handoff

memhooks explain backend/auth
memhooks explain backend/auth --role reviewer
memhooks explain backend/auth --format json

The JSON handoff serializes the resolved structure rather than a manually duplicated field list. It includes source-attributed Markdown guidance as well as core/provider routing.

Add a semantic cue

memhooks note \
  --cwd "$PWD" \
  --query "Why did authentication change after the outage?" \
  --priority 0.9 \
  --role reviewer \
  --entity '{"name":"Authentication","type":"CONCEPT","salience":0.95}' \
  --resource '{"name":"auth-postmortem","kind":"postmortem","salience":0.9}' \
  --tag security \
  --backends '{"mem0":{"top_k":8}}'

The cue is written directly into YAML frontmatter and is immediately visible through memhooks explain and the Rust resolver.

Maintain deterministic file anchors

Runtime adapters can pipe one post_tool_call JSON event into:

memhooks event

Automatic anchors only inspect explicit path-bearing tool-input fields and only retain files that actually exist inside the canonical project root. The maintainer does not regex arbitrary file contents for dotted strings.

v0.6.0: reliability and task-aware recall

The file schema stays memhooks/v2; the machine handoff is now explicitly versioned as memhooks/plan-v1. Update the Rust CLI and Hermes adapter together.

  • All filesystem entry points share fallible canonical path/root resolution, including default . invocations from nested directories.
  • Semantic validation is required before resolution or persistence. Invalid role routing, priorities, entities and backend namespaces fail with diagnostics; unknown extension fields remain round-trippable warnings.
  • Hook and lock symlinks/special files are rejected. Initialization rechecks file state under the same exclusive lock as creation, preserving concurrent notes.
  • MEMHOOKS_MAX_CHARS caps the complete emitted context, including its wrapper. Truncation preserves valid JSON and never retains queries without their routing constraints. Invalid optional-hook input/configuration produces {} plus a diagnostic.
  • Hosts can supply session-local active_files and active_roles. The loader resolves at most eight relevant directory scopes under one shared timeout, rather than loading every hook in the project. Sibling routing controls remain separate.
  • New/refreshed automatic cues use directory-qualified identities. Explicit delete/rename file events reconcile local generated resources; prune catches stale cues from changes made outside those events.
memhooks prune --all --dry-run
memhooks prune --all
memhooks remove --query "An obsolete local cue" --dry-run
memhooks remove --query "An obsolete local cue"

These commands only edit retrieval cues, never backend memories. Dry runs do not change hook files or create locks. explain --format json reports role, inheritance-cut and override omissions; the bounded handoff reports budget omissions. See runtime contract and migration.

v0.5.1 foundation (historical)

v0.5.1 established the shared implementation; the protocol remains memhooks/v2.

Notable changes:

  • one normative data model — the reference maintainer writes the same YAML frontmatter the resolver reads;
  • complete resolver handoff — guidance is no longer dropped by explain;
  • canonical root semantics — a Git root is a hard boundary unless an explicit containing MEMHOOKS_ROOT is supplied;
  • local query override — same trimmed query text at a child scope replaces parent query metadata instead of issuing the query twice;
  • precise diagnostics — YAML AST spans locate the actual malformed priority, salience, etc.;
  • tolerant linting — malformed structured entries such as quer: reach targeted diagnostics rather than killing the whole file as an enum parse error;
  • trust-boundary hardening — the Hermes adapter consumes validated resolver JSON and injects it explicitly as untrusted repository-controlled data; raw BEGIN/END fences are gone;
  • atomic maintenance — exclusive lock + same-directory atomic replacement;
  • SARIF hardening — repository-relative artifact paths and rule metadata;
  • reproducible builds — committed Cargo.lock, declared MSRV CI, doctests, Python 3.10/3.12, Ruff, and locked Rust builds;
  • maintained YAML stack — deprecated serde_yaml replaced with serde_yaml_ng, with Saphyr used for source spans;
  • .gitignore, SECURITY.md, CONTRIBUTING.md, corrected funding metadata, and a root MEMHOOKS.md for dogfooding.

Canonical root semantics

Resolver, maintainer, and bundled runtime adapters use the same rules:

  1. an explicit containing MEMHOOKS_ROOT wins;
  2. otherwise the nearest Git root is a hard boundary;
  3. outside Git, the highest hooked ancestor may serve as root.

A stray hook above a Git repository cannot silently capture maintenance writes for that repository.

Query inheritance

For same-text queries, locality behaves like an override:

# root
recall_queries:
  - query: "What security invariant matters here?"
    priority: 0.2
# child
recall_queries:
  - query: "What security invariant matters here?"
    priority: 0.9

The resolved plan contains the query once, at priority 0.9, sourced from the child hook.

Other generic list cues accumulate with duplicate suppression; more-local scalar core fields win. Provider mappings use recursive mapping merge with local scalar/list replacement.

Hermes / Hermes Desktop

Install the reference binary first:

cargo install memhooks

Clone the skill and install the pre-LLM adapter:

git clone https://github.com/AronAxe/MemHooks.git ~/.hermes/skills/memhooks
mkdir -p ~/.hermes/agent-hooks
cp ~/.hermes/skills/memhooks/hooks/hermes/memhooks_pre_llm.py ~/.hermes/agent-hooks/

Then configure Hermes:

hooks:
  pre_llm_call:
    - command: "python3 ~/.hermes/agent-hooks/memhooks_pre_llm.py"
      timeout: 5
  post_tool_call:
    - command: "memhooks event"
      timeout: 5

The pre-LLM adapter does not parse YAML itself. It asks memhooks explain --format json for one validated routing plan and injects structurally bounded JSON marked as untrusted repository-controlled retrieval metadata.

The legacy scripts/memhooks_update.py remains only as a compatibility launcher to the Rust CLI; it no longer owns parsing or persistence.

Documentation

The normative protocol contract is references/memhooks-format.md.

What MemHooks is not

MemHooks is not a vector database, memory provider, automatic memory-writing system, GraphRAG framework, prompt-privilege mechanism, shell-command manifest, or background daemon.

It is deliberately narrow infrastructure:

When an agent works here, remember these things first.

Related: Token Terminator

If MemHooks is about retrieving the right context, Token Terminator is about not wasting tokens on the wrong context.

Status

v0.6.0 — validated routing, consistent project boundaries, active-file recall, bounded context, and generated-cue lifecycle. Protocol: memhooks/v2.

MemHooks logo

License

MIT © 2026 Aron Bijl

About

Mnemonic Devices for your Agents: Folder based recall priming.

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages