v0.5.1 — Claude Code hook reliability
The PreToolUse hook now behaves the way its documentation always claimed.
A patch release fixing four defects in the Claude Code integration. No
retrieval, enforcement, or DecisionRetriever semantics change — the
deterministic mechanism is untouched. Anyone running the Claude Code plugin
should upgrade: on 0.5.0 a crashing check could hard-block an edit, and warn
mode reported nothing at all.
pipx install "mneme-hq>=0.5.1"Fixed
Fail-open was not reliable
The hook converted every non-zero child exit into exit 2, which blocks the
edit. But mneme check --mode strict returns 1 for a WARN verdict, and the
Python interpreter also returns 1 for an uncaught exception — so a malformed
project_memory.json or any CLI crash was indistinguishable from a policy
violation and hard-blocked the write. The documented guarantee has always been
fail-open.
The hook now blocks only on a verdict it can parse and trust. An
unparseable payload, an unexpected exit code, or a traceback all fail open with
an explicit note on stderr.
Warn mode surfaced nothing
Warn mode wrote violations to stderr and exited 0. Claude Code discards stderr
from a hook that exits 0, so warn mode was silent in every case — it reported
violations to nobody.
It now emits a PreToolUse JSON payload with permissionDecision: "defer" and
the violation detail as the reason. defer is deliberate: allow would
auto-approve the tool call and bypass the permission prompt the user would
otherwise see, so a warning mode must never use it.
replace_all was ignored
Edit and MultiEdit always materialized a single replacement. When Claude
Code was about to replace every occurrence, the content the hook checked was
not the content that would land on disk, and a violation introduced by the
second or later occurrence was never seen.
The child CLI could be a different install than the hook
sys.executable -m mneme resolved against the child process's sys.path,
which can be an older mneme that rejects the new --json flag. The hook
would then fail open on every edit, with enforcement silently inactive and
nobody told. The child now inherits a PYTHONPATH pinned to the hook's own
package root, and a stale runtime produces an explicit
ENFORCEMENT IS INACTIVE warning instead of silence.
Added
mneme check --json
A versioned, machine-readable verdict payload emitted as the only stdout
content:
{
"schema": "mneme.check/v1",
"verdict": "FAIL",
"mode": "strict",
"violations": [...],
"freshness": [...]
}Exit codes are unchanged. Consumers should trust the payload's verdict rather
than the exit code, and fail open on anything they cannot parse — which is
exactly what the hook now does.
Scope and honest limits
- Coverage is
EditandWritetool calls. Edits made by shell commands
(Bash) do not pass through aPreToolUsefile-edit hook and are not
checked. AStop-hook working-tree audit would be needed for complete
coverage; it is not in this release. - Warn-mode rendering is not fully verified. The hook emits the documented
structured payload and that is covered by tests, but how Claude Code displays
adeferreason has not been confirmed end-to-end in a live session. - The plugin is still not on a marketplace.
--plugin-dirremains the
installation path. - Cross-platform validation is limited. The suite is exercised on Windows;
CI does not currently runpytest.
Upgrading
No configuration changes. mneme-hq >= 0.5.1 is required for the plugin's hook
to behave correctly — older runtimes reject --json, and the hook will say so
loudly rather than silently disabling enforcement.