Inspiration

⁠ Every AWS account has stuff nobody can explain. The person who set it up left. CloudTrail tells you what changed, but only for 90 days, and it never tells you why. I wanted an agent that actually remembers an account, and one you can trust, because stale memory is worse than no memory. ⁠

What it does

⁠ Ask it anything about an AWS account and it answers with real identifiers you can paste into the console. What's wasteful, what changed and who did it, what breaks if you delete this, which region is prod. It also remembers what you tell it. Say "that untagged instance is the build runner" and it still knows next week. ⁠

How I built it

⁠ An hourly pass scans the account read only, diffs it against last time, and writes findings to CockroachDB. Every memory it forms carries a claim, a small declarative statement of what would have to be true for that memory to hold. Same pass re-checks every claim. When one goes false the memory retires with its reason attached, and it's never deleted. ⁠ The chat side is a Bedrock tool loop. Claude Sonnet 4.5 does the reasoning, Haiku 4.5 handles merges and durability checks, Titan v2 does embeddings. Retrieval runs four lanes at once, identifier, structured, graph, and vector, then fuses them with Reciprocal Rank Fusion. ⁠ Everything runs on two Lambdas. One behind a Function URL for chat, one on an EventBridge schedule for the hourly pass. No servers to keep alive. ⁠

What I learned

⁠ Staleness is the real problem in agent memory. You usually can't cheaply re-check whether a fact about a person is still true. In AWS you can, because every fact has an API call behind it. That's the whole idea, and once I had it the rest of the design fell out. ⁠ CockroachDB also did more in one place than I expected. Vector similarity, recursive graph traversal, full text, and normal relational filters, all in one query and one transaction. I had planned to add a graph database and never needed it. Blast radius questions are only two or three hops deep, so recursive CTEs beat a network hop to a separate store. ⁠

Challenges

⁠ The Managed MCP Server kept returning "unauthorized" and I spent a while looking at SQL privileges. Wrong layer. Cloud RBAC gets checked before every tool call, and the service account had no cluster scoped role, so the query never reached SQL at all. One role grant in the console fixed both. ⁠ CockroachDB's jsonb errors were costing the agent a whole turn each time. It would chain ->> and get an opaque operator error, then rewrite the entire query guessing. I now catch that error and append a hint telling it exactly what to do instead. Cheap fix, big difference. ⁠ I also broke my own demo. An acceptance script deleted every memory for an account instead of just its own fixtures, and it ran against the live one. Lost two retired memories, which are the one thing in the system that can't be recomputed from a scan. Fixed the script, but it was a good lesson about test code touching real data. ⁠ Getting the read only boundary right took care too. The agent has no shell, no CLI, and no boto3. It makes exactly one live AWS call. Everything else it knows comes from CockroachDB, because the scan already paid for those API calls.

Built With

  • amazon-bedrock
  • aws-cdk
  • aws-lambda
  • boto3
  • claude
  • cockroachdb
  • eventbridge
  • mcp
  • psycopg
  • python
  • sql
  • terraform
  • titan-embeddings
  • vector-search
Share this project:

Updates