Build1 publisher3 min readPublished
Throughline's recall receipts separate an empty archive from a search that never ran
Throughline's on-call agent returns a three-way coverage verdict with every memory recall, so a timed-out search cannot pass as "no prior incidents". Its author hit the same error-as-empty trap in CockroachDB's managed MCP server, where failures come back as HTTP 200.
The Engineer · Build desk

What happened
- A developer built Throughline, an incident-response agent with an auditable memory layer, for the CockroachDB x AWS agentic-memory hackathon in August, and it did not place.
- When a Throughline search cannot run, the recall verdict is UNKNOWN, and a guard at the output boundary makes reporting that as "nothing found" an error.
- Probing CockroachDB's managed MCP server, the author found every failure returned HTTP 200, with the error in the JSON-RPC body and no result.
- Filtered recall queries ignored a vector index built on the embedding column alone and planned as full scans.
- Demo rows seeded with a local embedder and recalled through Titan shared one column, producing noise similarity scores without any error.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint Against CockroachDB's managed MCP server, the HTTP status cannot separate an outage from an empty table, so a client must inspect the JSON-RPC body before it treats zero rows as absence.
- capability Because ranking is computed in code, a reviewer can check why one past incident outranked another without trusting any number Claude Haiku generated.
- contradiction A COVERED verdict certifies that recall ran; with the word-matching local embedder it can still hide a relevant memory written in another language, so the operator also has to know which embedder produced it.
A recall function that returns a list uses the same value for "no rows matched" and for a search whose embedding call timed out and was caught by a handler. The agent reading that list sees zero rows either way. According to Throughline's author, most memory stores return both cases as the same empty list [2].
Throughline puts coverage into the return value. Each receipt records the retrieval path that actually ran, how many candidates it examined, and what it excluded under which rule [4]. The verdict travels with the rows to the boundary where results become prose, and the guard there rejects an UNKNOWN reported as "nothing found" [5]. The memory types are tuned for outages as well. A rejected hypothesis such as "Restarting the pods did not help" keeps its value for a year, while an entity fact like which host is primary has a 14-day half-life [3].
The same collapse turned up in CockroachDB's managed MCP server. The author wrote a client for it as a second channel that has to agree with the direct connection, though it never reached the running demo [7]. With failures arriving as HTTP 200 and no result [8], a client written the obvious way, `rows ?? []`, turns an outage into "that row doesn't exist" [9]. Status codes, on this evidence, are decorative. The server's `select_query` also adds `LIMIT 25` when the caller gives none [10]. A caller that gets exactly 25 rows back cannot tell a complete answer from a capped one, and in Throughline's terms I'd call that PARTIAL.
The index work is careful. Filtered recall had been planning as a full scan, and the docs do say filters are accelerated only on prefix columns [12]. The replacement index is `(workspace_id, is_live, embedding)`, where `is_live` is a stored computed column so it cannot drift from the eviction timestamp it comes from [13]. The capability probe now reads the query plan instead of trusting that an index exists [14]. The author also found that vector indexing works on CockroachDB's free Basic tier: on v26.2.1, on 2026-08-03, the cluster setting read true and `CREATE VECTOR INDEX` completed [15]. Both findings went into a CockroachDB docs issue [16].
A coverage verdict cannot catch every failure. The mixed-embedder bug threw nothing [17], so the fix went in at write time: seeding now refuses an embedder that differs from recall's, and says why [18]. The French case is harder. Without cloud keys, recall uses a small local embedder that matches words, so a French question about an English memory truthfully reports a full search with nothing relevant [19]. "The receipt proves the search ran. It can't prove the search was clever," the author wrote [20]. Matching meaning is left to the hosted embedder, Titan on Bedrock [21].
The evidence for all of this is one developer's build. Throughline was one of 444 entries competing for three prizes [22]. The winner, Anchor, was also an on-call agent with an Unknown verdict, and it commits memory and actions in the same transaction [24]. The author kept Throughline's memory layer independent of the database on purpose, and offered a test count where the winners offered measured comparisons against a baseline [23].
What to watch
- Whether CockroachDB's docs team acts on the filed issue by documenting Basic-tier vector indexing and the prefix-column rule for filtered vector queries.
- Whether CockroachDB's managed MCP server starts signalling failures outside HTTP 200, or clients keep having to parse the JSON-RPC body for errors.
- A measured comparison of Throughline's recall false negatives against a baseline memory store, which the hackathon entry offered only as a test count.