Inspiration
An agent that only talks can forget safely. An agent that acts cannot. Two things break production agents, and both are memory problems: (1) the agent's memory lives in the same blast radius as the incident it's fixing, so a worker that dies mid-remediation either abandons the run half-applied or replays it into duplicate side effects; and (2) the moment an agent ingests logs, alerts, and tickets into long-term memory, everyone who can write to those sources has a write path into its own future context — poison it once, influence every run afterward. We wanted the agent memory you can trust when things are on fire.
What it does
Cairn is a transactional, provenance-stamped memory substrate for agents that take actions, plus a reference incident-response agent (cairn-watch) built on it. It rests on three mechanisms, each of which is impossible or materially worse on a single-node store:
- A write-ahead intent ledger — every side effect is preceded by an intent committed under
SERIALIZABLE, with a deterministic idempotency key and a lease. A worker that dies mid-step is resumed by another; the key makes the re-run a no-op at the effector. Exactly-once, verified against real external state, not a self-reported counter. - A trust-tier-partitioned vector index — every memory row carries a trust tier, and that tier is a prefix column of the vector index. Retrieval names the tiers it accepts as an allowlist, so the approximate-nearest-neighbour search is physically scoped to trusted strata: quarantined memory is never visited, not filtered out. pgvector cannot express this.
- Recall and decision commit in one transaction — a fact revoked concurrently can never slip between the planner's read and the decision's write, because both touch the same rows and the cluster forces one to retry. Plus provenance rollback: revoking a lie walks its lineage and taints every decision downstream.
The console makes the invisible enforcement visible: a telemetry burst with a poisoned line, the gate quarantining it (showing the detectors that fired), the durable ledger, a worker crash finishing exactly once, poison rollback, and a graded evaluation scorecard.
How we built it
Python + psycopg against CockroachDB (serializable by default). The integrity gate combines deterministic detectors (with a normalization pass that folds homoglyph and letter-spacing evasion) with an optional model second-opinion that may only lower trust and fails closed. Embeddings run locally (fastembed/ONNX) for a zero-credential demo, or on Amazon Bedrock Titan. The reference agent reads real Amazon CloudWatch logs as untrusted evidence, remediates a real Amazon ECS Fargate service through idempotent effectors, and writes postmortems to Amazon S3. A human operator inspects the agent's live memory through CockroachDB's Managed MCP Server (read-only, RBAC-scoped, audited). Two disciplines are shipped as portable Agent Skills and contributed upstream to cockroachlabs/cockroachdb-skills.
Challenges we ran into
- Making the vector index enforce the trust boundary took care: CockroachDB accelerates a tier-filtered similarity search only when the prefix column is constrained by equality or an
INlist, so we made retrieval take an explicit tier allowlist — which is also fail-closed by construction. - Amazon Bedrock text-generation inference was gated on our fresh AWS account, so we made every model call provider-agnostic behind an interface and defaulted the demo to a local embedder — no credentials needed to run it.
Accomplishments we're proud of
- Every number is measured and reproducible in one command (
lab/proofs.py→ PROOFS.md): gate 27/33 attacks caught, 0 false positives; durability 15/15 exactly-once through mid-run crashes; the consistency invariant 30/30 across revoke-vs-decide races. - A head-to-head that shows why CockroachDB (
lab/compare_pgvector.py→ COMPARISON.md): the same tier isolation leaks the poison in all 10 slots on pgvector unfiltered, and drops the vector index for a full Seq Scan when filtered — CockroachDB's prefix column gives fast search and isolation. - 39 tests against a real cluster; a live region-failure demo; three CockroachDB tools and three live AWS services, all meaningfully integrated.
What we learned
Memory poisoning is a persistent threat, not a per-request one, and the cleanest defense is structural — put the trust boundary inside the index, not in a WHERE clause above it. And "production-grade memory" is a property you can only claim if it survives the failure you're demonstrating; serializable, distributed durability is what makes that claim true.
What's next
Swap Amazon Bedrock Claude into the planner once account model access clears; expand the graded eval corpus; broaden the effector library beyond ECS.
Built With
- agent-skills
- amazon-bedrock
- amazon-cloudwatch
- amazon-ecs-fargate
- amazon-web-services
- cockroachdb
- cockroachdb-managed-mcp
- distributed-vector-index
- fastapi
- fastembed
- mcp
- prompt-injection-defense
- psycopg
- python
- serializable-transactions
Log in or sign up for Devpost to join the conversation.