Engram’s retrieval pipeline can optionally do extra work at recall time to improve relevance.
These features are disabled by default to keep latency low and avoid new failure modes.
Config:
queryExpansionEnabled(defaultfalse)queryExpansionMaxQueries(default4)queryExpansionMinTokenLen(default3)
Behavior:
- Runs the original query plus a few deterministic expansions derived from salient tokens.
- Merges and de-dupes results by memory path.
Config:
rerankEnabled(defaultfalse)rerankProvider(default"local")rerankMaxCandidates(default20)rerankTimeoutMs(default8000)rerankCacheEnabled(defaulttrue)rerankCacheTtlMs(default3600000)
Behavior:
- Sends up to
rerankMaxCandidatescandidates (ID + snippet) to a short ranking prompt. - Fail-open: on timeout/error, keeps the original ordering.
- Recommended:
rerankProvider: "local"so this never forces cloud calls. - Note:
rerankProvider: "cloud"is reserved/experimental in v2.2.0 and currently behaves as a no-op.
Config:
feedbackEnabled(defaultfalse)
Tool:
memory_feedbackwith params:memoryId: filename without.mdvote:upordownnote: optional
Storage:
- Stored locally at
memoryDir/state/relevance.json - Applied as a small score bias during retrieval (bounded; never a hard filter).
Config:
negativeExamplesEnabled(defaultfalse)negativeExamplesPenaltyPerHit(default0.05)negativeExamplesPenaltyCap(default0.25)
Tools:
memory_last_recall: returns the last recalled memory IDs for a session (or most recent).memory_feedback_last_recall: batch-mark recalled memory IDs as "not useful" (negative examples).
Storage:
- Negative examples are stored locally at
memoryDir/state/negative_examples.json. - Last recall snapshots are stored at
memoryDir/state/last_recall.json. - A lightweight, append-only impression log is written to
memoryDir/state/recall_impressions.jsonl.
Behavior:
- Negative examples apply a small, bounded penalty during ranking (soft bias only).
- Safe default: the batch tool requires explicit IDs (or a
usefulMemoryIdsallowlist +autoMarkOthersNotUseful=true) to avoid accidental mass-negative marking.
When procedural.enabled is true, Remnic can inject a short “Relevant procedures” section at recall time for prompts that look like task initiation (for example deploy, ship, or open a PR), using active category: procedure files under procedures/. This path is separate from QMD hybrid search and from memoryKind: procedural dream-surface filtering.
See Procedural memory for configuration, mining, and the procedural-recall benchmark.
Status (current release): opt-in observation mode. The direct-answer tier annotates
LastRecallSnapshot.tierExplainwithout short-circuiting the QMD path whenrecallDirectAnswerEnabled: trueis configured.
Behavior: when recallDirectAnswerEnabled is true, Remnic runs a lightweight eligibility gate alongside QMD to decide whether a single validated memory can answer the query. The current release records which tier would have served the query onto the caller's last-recall snapshot so CLI / HTTP / MCP surfaces can surface the decision. A later slice will flip the short-circuit bit and return the direct-answer winner before QMD runs.
What exists today:
packages/remnic-core/src/direct-answer.ts— pure eligibility function (isDirectAnswerEligible) exercised by unit tests.packages/remnic-core/src/direct-answer-wiring.ts—tryDirectAnswer(...)source-agnostic binding, callable by tests but not yet invoked by the orchestrator.- The five
recallDirectAnswer*config keys below (parsed and validated;recallDirectAnswerEnabled: falsedisables observation-mode annotations).
A dedicated retrieval-direct-answer bench fixture is planned but not yet in-tree.
Planned eligibility ladder (in order, unchanged between observation and short-circuit modes):
config.recallDirectAnswerEnabled === false→ reasondisabled- Query normalizes to zero searchable tokens → reason
empty-query - No candidate memories → reason
no-candidates - Hard filters drop all candidates (status ≠ active, not
trustedzone, ineligible taxonomy bucket, importance below floor AND notuser_confirmed, entity-ref hint mismatch) → reasonno-eligible-candidates - Token-overlap floor drops all survivors → reason
below-token-overlap-floor - Top two candidates within
recallDirectAnswerAmbiguityMarginof each other → reasonambiguous - Otherwise → reason
eligible, winner annotated on the snapshot
Config keys:
recallDirectAnswerEnabled(defaultfalse) — master switch; set totrueto opt in to observation moderecallDirectAnswerTokenOverlapFloor(default0.55,0to disable the gate)recallDirectAnswerImportanceFloor(default0.7,0to disable the gate)recallDirectAnswerAmbiguityMargin(default0.15)recallDirectAnswerEligibleTaxonomyBuckets(default["decisions","principles","conventions","runbooks","entities"])
See Retrieval explain for the planned shape of the tier annotation and the CLI / HTTP / MCP surfaces that will expose it.
In openclaw.json:
{
"plugins": {
"entries": {
"openclaw-engram": {
"config": {
"rerankEnabled": true,
"rerankProvider": "local",
"rerankMaxCandidates": 20,
"rerankTimeoutMs": 8000
}
}
}
}
}Config:
slowLogEnabled(defaultfalse)slowLogThresholdMs(default30000)
When enabled, Engram logs warnings like:
SLOW local LLM: op=rerank durationMs=...SLOW QMD query: durationMs=...
These logs never include user content.