Skip to content

Guides

Debugging retrieval

“It didn’t remember” is four different bugs wearing the same coat. This page separates them.

Terminal window
sigil why "how do we handle webhook retries"
Query: how do we handle webhook retries
Namespace: default
Pod scope: "auto"
Facts (3):
1. [rrf=0.0731 hebbian=2] [architecture] [supplementary] [conf=high]
pods: project:payments-api
content: Webhook retries are idempotent on event_id — never on payment_id
2. [rrf=0.0492] [decision] [vital] [conf=high]
pods: project:payments-api, claude_session:2026-08-12
content: We moved retries to the Postgres job table with SKIP LOCKED in March
3. [rrf=0.0310] [workflow] [supplementary] [conf=medium]
pods: —
content: Failed webhooks land in the dead-letter table after 5 attempts

This runs the exact hybrid search the UserPromptSubmit hook uses. What you see here is what your agent would have been given.

FieldMeaning
rrfThe fused relevance score — Reciprocal Rank Fusion over the vector and keyword result lists. Higher is better; absolute values are only meaningful relative to each other within one query.
hebbianCo-retrieval boost. This fact has been returned alongside others in this result set before, so the tie is strengthened.
categoryThe classifier’s label — architecture, decision, preference, …
importancevital or supplementary
confThe extractor’s confidence in the fact: high, medium, low
podsWhich containers this fact belongs to. — means it’s unattached and only reachable globally.

Pod scope at the top tells you what the search was allowed to look at. Add --pod-scope=global to search everything, or a comma-separated list of pod names to narrow it.

Terminal window
sigil facts --limit=50 | grep -i retry
sigil status

If it isn’t there, capture failed — not retrieval. Check the dashboard’s Activity screen for the turn where you said it. You’ll see one of:

  • The classifier decided the message wasn’t memorable
  • Extraction produced no atomic fact
  • AUDM decided you already knew it (check whether a near-duplicate exists)
  • The hook errored — sigil doctor reports the count, and ~/.sigil/.hook-errors.log has the detail

The classifier is deliberately conservative. If something matters and it didn’t catch it, say it more declaratively, or just run sigil remember.

The fact appears in sigil facts but not in sigil why. Usually one of:

It’s too vague. A fact that says “the API is complicated” matches everything weakly and wins nothing. Rewrite it specifically and delete the old one.

Your query doesn’t share vocabulary with it. Vector search bridges some of that gap; keyword search doesn’t. Try the wording you’d actually use in a prompt.

It’s below the similarity floor. memory.minFactSimilarity (default 0.45) drops weak matches entirely. Lower it in Settings → Advanced if real matches are being cut — but understand that you’re trading precision for recall.

sigil why shows it, your agent still doesn’t act on it. Two separate gates:

The injection floor. memory.injectionFloor (default 0.6) is the relevance threshold for the automatic UserPromptSubmit injection — deliberately higher than the search floor, because injecting weak matches into every prompt is worse than injecting nothing.

Visibility. A fact scoped to agent or device is invisible to other agents and machines. Check it:

Terminal window
sigil facts --limit=20 # then inspect the fact in the dashboard
sigil visibility <id> shared # widen it
Terminal window
sigil doctor --deep

--deep actually spawns the MCP server and runs a hook, rather than checking that config files exist. The most common cause of “memory stopped working” is a stale path after a Node version switch or a reinstall:

Terminal window
sigil connect

That re-pins the launcher shims and re-syncs every client’s config, touching no database, provider, or key.

Two things degrade quietly over time.

Duplicate pile-up. If memory.skipThreshold is too high, near-identical facts accumulate and split the ranking between them. Check:

Terminal window
sigil facts --limit=100

Lots of variations on one idea means the threshold is letting them through. Default is 0.88.

Stale facts outranking current ones. Supersession handles direct contradictions, but not drift. sigil maintain promotes facts that have proven themselves and closes editing windows; run it occasionally.

Sigil re-ranks by ACT-R activation — recency × frequency — on top of relevance. This is deliberately bounded: activation multiplies the fused score by (1 + 0.10 × activation), so a heavily-accessed fact can win a tie but cannot beat a materially better semantic match.

If you’re wondering why a fact you use constantly isn’t at the top: that’s the bound working as designed. Frequency is a tiebreaker, not the signal. Ranking has the full model.

Terminal window
sigil doctor --deep # is the plumbing intact?
sigil facts --limit=50 # was it stored?
sigil why "your query" # how did it rank?
sigil search "..." --pod-scope=global # is a pod boundary hiding it?
sigil maintain # clean up the ranking pool