Skip to content

File anchoring and the Stop hook

Facts in memory often come from a file: a contract, a note, a config. If the file is corrected later and the memory record is not, the agent keeps confidently repeating the old version. The MMW server cannot see your files, so the local agent, mmw-agent 0.1.4 and later, does this check.

On this page:

  1. how to anchor a fact to a file without computing anything by hand;
  2. how search notices that the file changed;
  3. how the Stop hook keeps Claude Code from finishing without saving the outcome.

Put the file path in source_id, and that’s it. The agent computes the file’s SHA-256 and sends it as source_hash:

Remember in MMW: the operator is a private individual. Source: site-audit/NOTIFICATION.md
what is sent to the server
{
"content": "the operator is a private individual",
"source_id": "site-audit/NOTIFICATION.md",
"source_hash": "sha256:5f1c…"
}
  • Paths are resolved against source roots: by default, the folder the client started the agent in (for Claude Code, the project folder). Set your own roots with MMW_SOURCE_ROOTS (several paths separated by : on Linux and macOS, ; on Windows).
  • Files outside the roots are never read or hashed. An absolute path works too if it is inside a root.
  • IDs that do not look like a path (session:…, https://…, owner-note) are left alone.
  • If source_hash is already set, the agent does not change it.
  • File contents never leave your computer; only the hash is sent.

On every search the agent re-hashes the source files of the records found and adds a local_source field:

local_sourceMeaningstatus
unchangedthe file is the same as when savedunchanged
changedthe file changed after savingstale
missingthe file no longer existsstale

conflict is the louder status and is never replaced with stale. Records without a source file are left as they are.

mmw-agent hook-stop is a hook for the Stop event. When Claude Code is about to end a turn, the hook checks whether files in the git working tree changed during this session after the last remember call. If they did, the turn does not end: Claude gets the list of files and a request to save the decisions and facts, with the path as source_id, reusing the earlier fact_key for corrections.

  1. Open ~/.claude/settings.json (all projects) or .claude/settings.json in a project.

  2. Add the hook:

    {
    "hooks": {
    "Stop": [
    {
    "hooks": [
    {
    "type": "command",
    "command": "uvx --from https://app.mmwhub.tech/downloads/mmw-agent/mmw_agent-0.1.4-py3-none-any.whl mmw-agent hook-stop"
    }
    ]
    }
    ]
    }
    }
  3. Restart Claude Code.

How the hook behaves:

  • It blocks at most once in a row. If Claude decides there is nothing to save, the second Stop goes through (stop_hook_active), so it never loops.
  • Only this session counts. Files changed before the session started or before the last remember are ignored.
  • Outside a git repository it does nothing.
  • It sends nothing. The check is local: git and the Claude Code session transcript.
  • To switch it off for a while, set MMW_STOP_HOOK=off.
  • It does not watch files in the background: a change is noticed on search or at the end of a turn, not when the file is saved.
  • It does not fix records by itself: the hook asks the agent to save a new version; the decision stays with the agent and the person.
  • It does not check facts saved without source_id. Always give the source when a fact comes from a file.