synapse / manualv1.14.2 · on your machine
synapse

Retrieval checks

Ranking, drift, exact UTF-8 paging, relevance checks, and reproducible performance fixtures.

Recall finds relevant memories within the configured budget. readmemory reads the exact stored body of one hit in bounded pages. Both apply the same global plus current-project scope and exclude superseded records. Neither requires a model or network service.

Recall searches two FTS5 indexes over the same rows: memory, stemmed with porter unicode61 over body and source (source weighted 0.3), and memorygram, a contentless trigram index kept in step at every write. Each ranks the query on its own and the two lists are merged by reciprocal rank fusion (K = 60). When a hit has to be abridged, recall sends its opening line if that holds a matched word and the FTS5 snippet around the match otherwise. readmemory reads by id and uses neither index.

Every query term is an OR, so a memory sharing one word with a long question still matches. Recall counts how many of the query's terms each candidate holds and drops any holding fewer than half as many as the best one, before applying the limit. The best match always survives, so a question with a weak answer still gets it. memory list and --explain show every match.

Drift

Recall and the session hook check what they hand over:

  • a path the memory names that is gone from the checkout (stale),
  • two memories that say opposite things or carry different numbers (conflict),
  • two memories that say the same thing (duplicate).

Recall returns everything and lists findings in drift. When a newer memory contradicts a returned one but didn't match the query, recall quotes it. The session hook leaves stale memories and the older half of a conflicting or duplicate pair out of what it injects, and says so. remember reports what a new memory contradicts or repeats. synapse memory drift runs the check on everything a folder can see. Nothing is superseded or deleted automatically.

Relative paths are only checked for project memory in its own checkout. Paths under another account's home, temp folders, and build output are never called missing.

Exact reading

Call readmemory with the id and project from a recall. Start at offset zero, then pass each returned next as the next offset until it is null. Offsets and total are UTF-8 byte counts. Concatenating the page bodies reconstructs stored text without compaction, ellipses, or broken characters.

Lean limits a body page to 2,800 bytes. Balanced and Full limit it to 6,000 bytes. These byte bounds also fit within the configured character budget. Source labels have a separate 240-byte allowance with sourceabridged marking truncation; metadata and JSON framing are additional to the body allowance. SQLite selects only the requested body slice, so paging does not allocate the whole memory in the server.

Missing, superseded, and out-of-scope ids all return a null memory. An offset beyond a visible body's end or inside a UTF-8 character is an error. The exact end returns an empty body and null next. Pages read current data; restart at zero if the memory is edited between requests. Owner-facing CLI inspection and restore remain available for hidden history.

The MCP tool is also available through bridges that discover the server's tool list. Existing user guidance is preserved; the server supplies the reading hint at initialization when it is absent.

Correctness fixtures

Run from crates/synapsecore:

sh
cargo test --test retrieval --test mcp

The retrieval fixtures check opposing statements, changed numbers and short identifiers, exact duplicates, Unicode search, scope isolation, supersession and restore, every budget combination, and lossless paging of long text containing code, whitespace, multibyte characters, and embedded NULs. Protocol tests exercise the complete recall-to-read flow through the released tool schema.

Approximate wording overlap cannot establish that two facts are equivalent. Balanced and Lean retain exact-body deduplication but no longer suppress distinct bodies by word-set similarity. Only explicit supersession establishes a correction; drift findings point at candidates for one.

tests/bias.rs scores the relevance floor against an unfloored search on a labeled corpus (no answer lost or moved down; surplus beside each answer falls from 5.1 to 0.9 memories) and checks that an unmarked correction is always flagged when its outdated memory comes back.

Performance fixture

sh
cargo run --release --example retrieval -- 10000 30
cargo run --release --example retrieval -- 100000 30

The arguments are memory count and measured iterations, defaulting to 10,000 and 30. They are bounded at one million memories and one thousand iterations. The fixture creates and removes its own temporary database; it never opens the user's store, changes settings, or connects to a network service.

Output is JSON containing build profile, seed time, database-open time, database bytes, and p50/p95/max latency plus structured response bytes for:

  • selective recall: a term in every thousandth memory;
  • common-term recall: a term present throughout the store;
  • recent scoped recall: the newest visible memories;
  • exact reading: the first bounded page of one memory.

The corpus is deterministic and all-global, with approximately 240-byte bodies. Each operation has one untimed warmup. Timings include library calls and JSON serialization, but exclude process startup, transport framing, model/client processing, and fixture generation. The database-open measurement includes verification after seeding, with OS file caches still warm. Response sizes count structured JSON once; MCP transports may carry a text representation as well.

Use release builds and record the machine alongside results. Compare the same fixture before and after a change. The fixture exposes scaling trends; it does not simulate cold disks, mixed-project query plans, long-duration memory growth, or semantic relevance on real user questions. Timing thresholds are deliberately absent from shared-runner correctness tests.

Relevance

Before changing ranking or adding inference, measure recall quality on representative questions:

sh
synapse memory eval cases.toml --budget lean

Each [[case]] names a query, an optional project folder, and expect: text a useful memory contains, or nothing for a question no memory answers. The report gives the share ranked first, the share found, MRR, the share whose answer text survived the response budget, and noise on unanswerable cases. Run it on a copy of a real store (SYNAPSE_DATA pointed at the copy, never the live folder) before and after the change, and keep resource cost in view alongside it.