Guides
Debugging retrieval
“It didn’t remember” is four different bugs wearing the same coat. This page separates them.
Start with sigil why
Section titled “Start with sigil why”sigil why "how do we handle webhook retries"Query: how do we handle webhook retriesNamespace: defaultPod 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 attemptsThis runs the exact hybrid search the UserPromptSubmit hook uses. What you see here is what your agent would have been given.
Reading it
Section titled “Reading it”| Field | Meaning |
|---|---|
rrf | The 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. |
hebbian | Co-retrieval boost. This fact has been returned alongside others in this result set before, so the tie is strengthened. |
| category | The classifier’s label — architecture, decision, preference, … |
| importance | vital or supplementary |
conf | The extractor’s confidence in the fact: high, medium, low |
pods | Which 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.
The four failure modes
Section titled “The four failure modes”1. It was never stored
Section titled “1. It was never stored”sigil facts --limit=50 | grep -i retrysigil statusIf 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 doctorreports the count, and~/.sigil/.hook-errors.loghas 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.
2. It’s stored but doesn’t rank
Section titled “2. It’s stored but doesn’t rank”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.
3. It ranks but isn’t injected
Section titled “3. It ranks but isn’t injected”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:
sigil facts --limit=20 # then inspect the fact in the dashboardsigil visibility <id> shared # widen it4. The hook isn’t running at all
Section titled “4. The hook isn’t running at all”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:
sigil connectThat re-pins the launcher shims and re-syncs every client’s config, touching no database, provider, or key.
Retrieval feels worse than it used to
Section titled “Retrieval feels worse than it used to”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:
sigil facts --limit=100Lots 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.
The activation term
Section titled “The activation term”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.
Checklist
Section titled “Checklist”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