Skip to content

fix(hooks): stop the HTTP fast path from answering out of the wrong database - #23

Merged
DottytheHomeless merged 1 commit into
mainfrom
fix/hook-db-pin
Aug 3, 2026
Merged

DottytheHomeless merged 1 commit into
mainfrom
fix/hook-db-pin

Conversation

@MXAntian

@MXAntian MXAntian commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

The bug

MNEME_DB_PATH is silently ignored whenever a server is listening on the default port.

The recall request body carries a query and filters — it does not carry a database path. The CLI fallback forwards the path (passThroughDbEnv); the HTTP fast path cannot. So with a DB pinned and a server up, the two paths answer from different databases, and which one you get depends on whether a process happens to be running.

Not theoretical

Multiple agent runtimes share one machine here, each with its own DB on its own port:

port 18792: {"ok":true,"version":"2.10.0","embeddingConfigured":true}
port 18794: {"ok":true,"version":"2.10.0","embeddingConfigured":true}
port 18800: {"ok":true,"version":"2.8.0","embeddingConfigured":false}

Three DBs, one of them a different build entirely. The hardcoded default is the first. A hook pinned to agent B's DB gets agent A's memories.

It has been failing in the suite this whole time

This is the standing red in locations.test.mjs → "hook silent when no alias / no memory hit". It was never flaky. The test pins TOKENMEM_DB_PATH to an empty temp DB; the hook asks the live server instead, and three production memories come back:

🔧 [mneme tool-recall] ... found 3 memory hit(s) ...
[id:7734 ★8] ...  [id:7655 ★8] ...  [id:7936 ★7] ...

It passes on a machine with no server up — the suite is green exactly where the bug cannot bite.

The rule

A caller that names a DB means THAT DB. An explicit MNEME_HTTP_URL is the caller saying "that server serves the DB I named" and still wins. Absent that, a pinned DB turns the fast path off and we spawn — slower and correct.

Nothing changes for normal operation, where no DB path is set at all (verified: no MNEME_DB_PATH / TOKENMEM_DB_PATH in the live environment, so the fast path stays on).

Changes

file
hooks/prompt-recall.mjs, hooks/tool-recall-pre.mjs resolveHttpUrl(), duplicated in both because these hooks are meant to be individually copyable — matching the existing intEnv() convention
hooks/hooks.test.mjs two cases pinning both halves of the rule

The first new case goes red without this change on any machine with a server on the default port; the second guards the escape hatch from regressing the other way.

Verification

locations.test.mjs   50 passed / 1 failed  ->  51 passed / 0 failed
hooks.test.mjs       10 checks             ->  12 checks
full suite           262 passed / 0 failed

🤖 Generated with Claude Code

…atabase

MNEME_DB_PATH is silently ignored whenever a server is listening on the
default port.

The recall request body carries a query and filters — it does not carry a
database path. The CLI fallback forwards the path (passThroughDbEnv); the HTTP
fast path cannot. So with a DB pinned and a server up, the two paths answer
from different databases, and which one you get depends on whether a process
happens to be running.

Not theoretical. Multiple agent runtimes share one machine here, each with its
own DB on its own port — 18792, 18794, 18800, three DBs, one of them a
different build entirely. The hardcoded default is the first. A hook pinned to
agent B's DB gets agent A's memories.

This is also the standing red in locations.test.mjs ("hook silent when no
alias / no memory hit"). It was never flaky: the test pins TOKENMEM_DB_PATH to
an empty temp DB, the hook asks the live server instead, and three production
memories come back. It passes on a machine with no server up, which is why it
survived — the suite is green exactly where the bug cannot bite.

The rule: a caller that names a DB means THAT DB. An explicit MNEME_HTTP_URL
is the caller saying "that server serves the DB I named" and still wins. Absent
that, a pinned DB turns the fast path off and we spawn — slower and correct.
Nothing changes for normal operation, where no DB path is set at all.

  - hooks/prompt-recall.mjs, hooks/tool-recall-pre.mjs: resolveHttpUrl(),
    duplicated in both because these hooks are meant to be individually
    copyable, matching the existing intEnv() convention
  - hooks/hooks.test.mjs: two cases pinning both halves of the rule. The first
    goes red without this change on any machine with a server on the default
    port; the second guards the escape hatch from regressing the other way.

locations.test.mjs: 50/1 -> 51/0. Full suite 262 passed / 0 failed.

Co-authored-by: 千夏 <qianxia@clawgamers.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@MXAntian
MXAntian marked this pull request as ready for review August 3, 2026 05:31
@DottytheHomeless
DottytheHomeless merged commit 57565ab into main Aug 3, 2026
2 checks passed
@DottytheHomeless
DottytheHomeless deleted the fix/hook-db-pin branch August 3, 2026 05:37
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.

2 participants