{"slug": "agent-memory-that-tells-you-when-it-couldn-t-check", "title": "Agent memory that tells you when it couldn't check", "summary": "A developer built Throughline, an incident-response agent with an auditable memory layer, for the CockroachDB x AWS hackathon on agentic memory. The system returns a receipt with every recall — the retrieval path, candidates examined, exclusions, and a COVERED/PARTIAL/UNKNOWN coverage verdict — and errors out if a failed search is reported as \"nothing found.\" The developer also documented that CockroachDB's vector indexing works on the free Basic tier as of v26.2.1, that a filter-only query plan skips an embedding-only index unless a prefix column index like (workspace_id, is_live, embedding) is used, and that CockroachDB's managed MCP server returns failures as HTTP 200 with errors in the JSON-RPC body.", "body_md": "An on-call agent that answers \"no prior incidents\" might be telling you the archive is empty. It might also be telling you the embedding call timed out, and most memory stores return both as the same empty list.\n\nI built Throughline in August for the CockroachDB x AWS hackathon on agentic memory. It didn't place. My guess at why is at the end.\n\nThroughline is an incident-response agent with a memory layer you can audit. Memories are typed, and the type sets how fast they decay. \"The primary is db-7\" is an entity fact with a 14-day half-life. \"Restarting the pods did not help\" is a rejected hypothesis, and it keeps its value for a year. Most systems throw that second kind away, and it's the cheapest useful thing you can tell someone mid-outage.\n\nEvery recall comes back with a receipt: the retrieval path that actually ran, how many candidates were examined, what was excluded and under which rule, and a coverage verdict of COVERED, PARTIAL or UNKNOWN. If the search couldn't run, the verdict is UNKNOWN, and a guard at the boundary makes it an error to report that as \"nothing found\". Ranking is computed in code. The model (Claude Haiku on Bedrock) writes the answer around the results and never produces the number that ordered them.\n\nOne limit, up front. With no cloud keys, recall uses a small local embedder that matches words, not meaning. Ask it a question in French about a memory written in English and it will say it searched the whole workspace and found nothing relevant. That's true: it compared them, and they share no words. The receipt proves the search ran. It can't prove the search was clever. Matching meaning is the hosted embedder's job, and on Bedrock that's Titan.\n\nVector indexing works on CockroachDB's free Basic tier. On 2026-08-03, on v26.2.1, the cluster setting read true and `CREATE VECTOR INDEX` completed. I couldn't find that written down anywhere.\n\nMy first index, on the embedding column alone, was close to useless. An unfiltered nearest-neighbour query used it. Every query recall actually runs has a filter, though, and `WHERE workspace_id = $1` planned as a full scan. The docs do say filters are only accelerated on prefix columns. I hadn't read that as \"the planner skips the index entirely\". The fix was an index on `(workspace_id, is_live, embedding)`, where `is_live` is a stored computed column so it can't drift from the eviction timestamp it comes from. The capability probe now reads the query plan instead of trusting that an index exists.\n\nI also wrote a client for CockroachDB's managed MCP server, as a second channel that has to agree with the direct one. It never made it into the running demo, but probing the live server paid off. Every failure I could produce came back as HTTP 200, with the error in the JSON-RPC body and no result. A client written the obvious way, `rows ?? []`, turns an outage into \"that row doesn't exist\", the exact failure Throughline exists to catch. And `select_query` quietly adds `LIMIT 25` when you don't give it one.\n\nThe bug that nearly poisoned the demo was two vector spaces in one column. I'd seeded the demo rows with the local embedder while recall went through Titan. Cosine similarity across two embedders is noise, and nothing throws. Seeding now refuses an embedder that differs from recall's, and says why.\n\nThere were 444 entries and three prizes. The winner, Anchor, was also an on-call agent with an Unknown verdict, and its values are close to mine. Its memory and its actions commit in the same transaction, though, so CockroachDB is the mechanism rather than the storage. I kept my memory layer independent of the database on purpose. That's the right call for a library and the wrong one for a contest that asks what the database does for you. I also never deployed the public demo URL the rules asked for (the AWS deploy was planned and never written), and I offered a test count where the winners offered measured comparisons against a baseline.\n\nThe demo is 2:47, silent, with captions.", "url": "https://wpnews.pro/news/agent-memory-that-tells-you-when-it-couldn-t-check", "canonical_source": "https://dev.to/voyagi/agent-memory-that-tells-you-when-it-couldnt-check-2aao", "published_at": "2026-09-26 19:28:29+00:00", "updated_at": "2026-09-26 20:01:12.269680+00:00", "lang": "en", "topics": ["ai-agents", "ai-infrastructure", "mlops", "developer-tools", "agent-protocols"], "entities": ["Throughline", "CockroachDB", "AWS", "Amazon Bedrock", "Claude Haiku", "Titan", "Anchor", "Model Context Protocol"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/agent-memory-that-tells-you-when-it-couldn-t-check", "markdown": "https://wpnews.pro/news/agent-memory-that-tells-you-when-it-couldn-t-check.md", "text": "https://wpnews.pro/news/agent-memory-that-tells-you-when-it-couldn-t-check.txt", "jsonld": "https://wpnews.pro/news/agent-memory-that-tells-you-when-it-couldn-t-check.jsonld"}}