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:

  1. 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.
  2. 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.
  3. 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 IN list, 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
Share this project:

Updates