Inspiration

Multi-agent systems that share memory have no real answer for concurrent writes. Agent A and agent B both read the current fact, both decide to write a new one, and whichever write lands last silently wins. The other write vanishes, no error, no trace, no way to know a conflict ever happened.

What it does

Quorum routes every write through CockroachDB SERIALIZABLE isolation with an explicit optimistic version CAS. A concurrent write is never silently overwritten; it's detected as a conflict and routed to policy-driven resolution (deterministic merge, or LLM adjudication), with full event history, time-travel, and rollback. The head-to-head demo runs the identical concurrent workload against a naive baseline and against Quorum in the same request, side by side, so the difference is provable, not asserted.

How I built it

Backend is FastAPI + psycopg3 against a 3-node CockroachDB cluster. Every write and rollback is a SERIALIZABLE transaction with a version-guarded CAS UPDATE; two independent guards catch a race (the CAS itself, and CockroachDB's own serializable-snapshot-isolation abort on SQLSTATE 40001). Conflicts get one of two resolution policies: a deterministic merge that concatenates both values with provenance tags, or LLM adjudication (Claude via AWS Bedrock, or OpenAI, or a length-heuristic in offline mode). Every write/conflict/resolution is an immutable row in an append-only event table, which powers time-travel, rollback, and the audit trail. A native CockroachDB CHANGEFEED streams live changes out as Server-Sent Events to the frontend. An MCP server exposes the same CAS-guarded write/read path as tools so any MCP-capable agent gets the same consistency guarantee. Frontend is Next.js: the head-to-head race, a live memory board, a live conflict feed, a time-travel scrubber, and an audit trail view. The whole stack is containerized and deployed to a single EC2 instance behind a Caddy reverse proxy with automatic HTTPS.

Challenges I ran into

AWS's Bedrock console recently migrated to a new "Bedrock Mantle" endpoint that authenticates via a project-scoped API key through the Anthropic SDK itself, not the classic boto3 bedrock-runtime.invoke_model() path most existing docs describe. I rewrote the integration against the new pattern and confirmed it's correctly authenticated and shaped against the live API. Model access itself on this account is still pending AWS's own Anthropic-model entitlement approval, an account configuration step rather than a code issue, so QUORUM_MODE=bedrock is code-complete and will work with zero further changes once that access lands.

I also caught a real correctness bug during development: an earlier version of the write path auto-retried on CockroachDB's SerializationFailure, which silently re-read the now-committed value and overwrote it, exactly reproducing the lost-update bug the whole project exists to prevent. Fixed by treating that specific failure as a conflict signal instead of something to retry past.

What's next

Real embedding-based semantic retrieval in production (the offline demo mode uses a deterministic hash-seeded vector so tests run without external keys), and finishing the Bedrock model-access approval so LLM adjudication runs on Claude in production by default instead of the deterministic merge fallback.

CockroachDB tools used (2+ required)

  1. MCP Server: backend/app/mcp/server.py exposes remember, retrieve, and get_conflicts as MCP tools over stdio. Any MCP-capable agent writes and reads through the identical CAS-guarded path as the HTTP API; a losing write comes back as a structured {status: conflict} payload, not a silent failure.
  2. Distributed Vector Indexing: memory_items.embedding is a native VECTOR(128) column backed by CREATE VECTOR INDEX memory_items_embedding_idx. Retrieval runs a scoped ORDER BY embedding <-> $query LIMIT k ANN query.

(Also used, beyond the minimum: SERIALIZABLE isolation with optimistic CAS for every write, and a native CREATE CHANGEFEED streamed out as SSE for the live conflict feed.)

AWS services used (1+ required)

  1. EC2: the full stack (3-node CockroachDB, backend, frontend, Caddy) is containerized and deployed on a single EC2 instance behind an IAM instance role scoped to least privilege, no static keys on the box.
  2. S3: POST /events/audit-export writes the full audit trail to S3 as JSON, live-verified against a real bucket.
  3. Bedrock: code-complete Anthropic-SDK-against-Bedrock-Mantle integration for LLM conflict adjudication, confirmed live-authenticated; full inference pending AWS account entitlement (documented honestly above, not claimed as fully working).

Built With

Share this project:

Updates

Submission history