fix(v2.11.1): stop the recall feedback loop; recall on what the user typed - #44
Merged
Merged
Conversation
…typed Four fixes found auditing a long-lived store (10k rows, 14 days of hook logs). 1. recallForClients bumped access for its whole candidate pool. It over-fetches (up to 30 rows when filtering) and trims to the caller's limit, but never passed _deferAccessBump — so every hook call added +1 to ~30 rows while returning 3. buildMemoryContext got this fix in #7; this path was missed. Now only returned rows are bumped. 2. freqScore weight 0.10 -> 0.02. It saturates at 20 accesses, so on a long-lived store it is effectively binary, and 0.10 is ~38 rank positions at RRF's ~0.0026 spacing. With (1) inflating the counts, the loop fed itself: one row reached 46% of two weeks of hook recalls. At 0.02 it is a tiebreak (~8 positions max). 3. The DB path is resolved when the store opens, not at import. A host that imports mneme and then loads its own env sets TOKENMEM_DB_PATH after ES import hoisting has evaluated the module-level const, so the store silently opened the fallback DB. With several tenants on one machine, one tenant's writes landed in another's store. 4. prompt-recall hook: recall on user-authored text only; default to meta+semi; require vector evidence before the trim. - UserPromptSubmit also delivers <task-notification>, <cross-session-message> and prepended <system-reminder> blocks. 631 of 688 fast-path queries were that wrapper text. New userPromptText() strips it. - The triggers are operational (paths, ports, restarts), and the write-time meta gate downgrades anything carrying those to semi_abstract — so a meta-only default could never match the answers the hook is for. - Ask for require_vec first so the few slots are not taken by FTS/entity matches on a shared common noun; retry without it on zero rows so zero-config installs keep plain FTS + the consensus gate. When vectors are present, gate on MNEME_MAX_VEC_DISTANCE (0.95) instead of hit count. Tests: access-bump-scope and db-path-late-env integration tests (both red on main: 12 rows bumped for 2 returned; store opened the fallback path), plus userPromptText cases. Wired into CI. Existing ranking / endpoint / contract / cold-pool / anchor / hygiene / embedding-timeout / meta-gate / hooks suites green. Co-authored-by: 千夏 <qianxia@clawgamers.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Self-review P1: the zero-row retry made every zero-config install (no embeddings) pay two sequential HTTP round trips on every trigger, and in the worst case the pair ate the whole safety timer before the CLI fallback could run. prefer_vec / --prefer-vec is the fail-open twin of require_vec: keep only vector-backed rows when any exist, otherwise return the unfiltered rows — one call either way. Servers older than 2.11.1 ignore the field and answer as before. Also: an unterminated <system-reminder> (truncated upstream) is treated as non-user input instead of surviving whole as the query; the known trade-off of pasting text that starts with these tags is documented. Tests: access-bump-scope gains requireVec/preferVec cases on a no-embedding DB (0 rows vs FTS fallback); userPromptText gains the truncated case. Co-authored-by: 千夏 <qianxia@clawgamers.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four fixes from auditing a long-lived store (10k rows, 14 days of
recall_log).What was wrong
recallForClientsbumpedaccess_countfor its whole over-fetched pool (up to 30), not the rows it returnedmain: 2 returned, 12 bumpedfreqScoreat 0.10 is ~38 rank positions once saturated (20 accesses) — with #1 inflating counts, the ranking fed itselfDB_PATHevaluated at import time — a host settingTOKENMEM_DB_PATHafter import silently opens the fallback DB (wrong tenant)main: store opened the fallback path<task-notification>,<cross-session-message>,<system-reminder>), filtered to meta only, and trimmed before requiring vector evidenceChanges
index.mjs:_deferAccessBumpinrecallForClients+ bump only returned rows;freqScore0.02; lazyresolveDbPath().hooks/prompt-recall-trigger.mjs:userPromptText()strips non-user blocks.hooks/prompt-recall.mjs: default levelmeta_knowledge,semi_abstract; newprefer_vec/--prefer-vec(fail-openrequire_vec: vector-backed rows when any exist, else plain FTS — one round trip; older servers ignore it);MNEME_MAX_VEC_DISTANCE(0.95) gate when vectors are present.Tests
access-bump-scope.integration.test.mjs,db-path-late-env.integration.test.mjs(both red on main, green here),userPromptTextcases. Wired into CI.Self-review
pr-self-check: no P0. P1 (require-then-retry doubled latency on zero-config installs and could starve the CLI fallback) fixed in the second commit viaprefer_vec. P2 (unterminated<system-reminder>) fixed; pasted-tag trade-off documented.Behaviour change to note
Prompt-recall now injects less often and includes
semi_abstractrows by default. SetMNEME_LEVEL=meta_knowledgeto restore the old filter.🤖 Generated with Claude Code