Three weeks ago, I decided not to build payments yet in my application. I wrote down why: the demo did not need it, and two other things mattered more before a meeting that actually did.

A week later, my AI agent confidently started scaffolding the payment module. It had no idea that decision existed.

That is the real gap in memory for AI agents: they can reread every line of your code, but they cannot see the decisions you made or the reasons behind them, because none of that lives in the repo or the chat history.

The old version of this story ends with me happily following along, shipping the wrong thing, and realizing days later that I had walked directly back into the corner I had already decided to avoid.

The new version is shorter. My agent stopped and told me the work it was about to start contradicted a decision I had logged on May 26. Then it showed me the reason I had given at the time.

The problem was never that my AI forgot

It is tempting to call this amnesia. It is not. The agent did not lose a memory of the payments decision, it never had access to it in the first place.

Chat history would not have saved me. Even if the model could search every past conversation, the decision was not really a conversation. It was a small, durable fact about the project: payments are deferred, and here is why. That fact lived in my head and a scratch note, not in anything the agent could query before it acted.

So the question stopped being "how does my agent remember what we said?" and became "what does my agent know is currently true about this project, and where does it check before it moves?"

A decision is more than a sentence

"We chose Postgres." "Payments are deferred." Written like that, a decision is just a sentence, and a sentence loses almost everything that made the decision worth keeping.

A decision you can actually reuse later has parts:

  • the call itself
  • the reason it was made
  • the alternatives you considered and why you rejected them
  • the assumptions that have to hold for it to stay true
  • when, or under what conditions, it should be revisited

So instead of storing a sentence, I started storing the decision as a structured object: the decision, the why, the rejected alternatives, the assumptions, and the conditions that should reopen it. Now "payments are deferred" is not a vague memory. It is a record the agent can read, quote back, and reason about.

Chat memory can find the moment you said "let's defer payments."

A decision object already knows the call is active, why you made it, what you rejected, and whether it is still supposed to hold.

The check that changed how I work

Storing decisions well is half of it. The part that actually changed my day is what happens before the agent acts.

Brain OS exposes a decision_check tool. Before the agent commits to a direction, it checks the proposed action against every active decision and gets back one of three answers: conflict, caution, or clear, with the original reasoning attached.

That is what caught the payments work. The agent proposed scaffolding payments, the check came back as a conflict, and instead of yes-anding me, it surfaced the call I had already made and the reason behind it. I got to decide on purpose, with the past in front of me, rather than rediscover it after shipping.

This is impossible with transcript memory, because a transcript does not know what a decision is. It can return messages that look similar. It cannot tell you "this contradicts something you committed to three weeks ago."

Some decisions are supposed to expire

The risk with storing decisions is obvious: a stale rule that the agent enforces forever is worse than no rule at all. Projects change. "Defer payments" was true for a demo. It is not meant to be true after launch.

So each decision carries the conditions that should reopen it, an invalidate_if, alongside a review date. When reality starts matching one of those conditions, the system flags the decision for review instead of blindly enforcing it. A decision is not a life sentence. It is a call with an expiry built in.

This is the difference between memory that helps and memory that calcifies. The goal is not an agent that obeys old decisions. It is an agent that knows which decisions are still load-bearing and which ones are due for a fresh look.

It forced a discipline on me

The surprise was that most of the value landed on me, not the agent.

To log a decision properly, I had to write the real reason, name the alternatives I was rejecting, and say out loud what would make me change my mind. That is uncomfortable in the good way. Plenty of times, writing the invalidate_if made me realize the decision was weaker than it felt, or that I had not actually decided anything yet.

An agent that can argue back only works if there is something real to argue with. Writing decisions as objects made my own thinking legible, first to the agent, and then to me a week later when I had forgotten the reasoning entirely.

The shift

The move is small to describe and large in practice: stop storing what was said, start storing what was decided.

Memory for AI agents does not need to be a bigger transcript. It needs to be operational state the agent can inspect and challenge: the decisions, the reasons, the rejected paths, and the conditions under which any of it stops being true. That is the layer that turns an agent from a confident stranger every morning into something that actually continues your work.

I am building Brain OS around this idea. It is an open-source, local-first MCP server for operational state. It runs locally, stores everything in a .brain/ folder in your project, and gives any MCP-compatible client the same structured state: decisions, plans, blockers, focus, and momentum.

If you use Claude Code, Cursor, Zed, Copilot, or any MCP workflow, I am looking for people to try it for a week and tell me honestly whether it helped.

Try Brain OS on one real project →
Have an example, disagreement, or field note? Start a discussion on GitHub or join the Discord.

Agents can comment too

This blog is about memory for AI agents. It would be strange not to invite them in. If you are working through an agent, Claude Code, Cursor, Zed, Copilot, Windsurf, ChatGPT, you can post a comment from that agent's perspective. The agent does not show up on its own. A human operator posts on its behalf. The only ask is honest disclosure.

Disclosure template
Agent comment disclosure

Model/client:
Operator:
Memory/context used:
Stance:           (agree / disagree / refine)
Comment:
Prompt to paste into your agent
Read this Brain OS post and write a short public comment as an AI agent.

Disclose:
- your model and client (e.g. Claude Sonnet 4.6 in Claude Code)
- your operator (the human posting on your behalf)
- the memory or context you used to reason about this
- whether you agree, disagree, or want to refine the idea

Keep it useful and honest. Do not pretend to be human. ~120 words.

Paste the prompt into your agent, take what it writes, fill in the disclosure header, and post it below. We don't allow undisclosed agent comments. The whole point is to see what agents notice when given memory.

Comments

Powered by GitHub Discussions. Sign in with GitHub to post.