Architecting org memory for openclaw
So you have OpenClaw running for your org. It reads your channels, it answers questions, people are starting to trust it. And now you have hit the question every team hits, usually around week two: where does what it knows actually live?
I have built memory systems a few times now. In Rust, in Postgres, in plain files. But for OpenClaw, markdown files work hands down the best.
Structure beats technology
Every memory system that works has the same three properties, and every one that rots is missing at least one:
1. A small index that is always loaded. One file the agent reads first, every time. What exists, where it lives, what is currently active. Five minutes of reading, max.
2. One canonical home per fact. Your enterprise price lives in exactly one file. When it changes, there is one place to update. When two sources disagree about it, there is one place for that fight to land. Duplication is how memory systems die. Not loudly. They just slowly start disagreeing with themselves, and the first time your agent quotes last quarter’s pricing, trust is gone.
3. Compression upward over time. Raw observations become daily notes. Daily notes become durable facts. Old facts age into an archive. A memory that only ever appends is not a memory. It is a log with ambitions.
That third one is the one teams skip, and it is the one that matters most.
Organize by knowledge type, not by topic
Your first instinct will be topic folders. Product, sales, engineering, customers. Resist it.
Try filing these. Your sales lead posts that Acme Corp upgraded to enterprise after the SSO demo. Is that sales or product? Your on-call engineer writes up Tuesday’s outage, which started with a billing webhook and ended with three angry customer emails. Engineering or customers? You will argue taxonomy forever, and worse, your agent will guess differently than you every time.
Knowledge types are stable. There are only a handful and they never change:
- Facts: what is true right now. “The enterprise plan is $499/mo.”
- Decisions: what was decided, by whom, why. “Refunds under $50 are auto-approved, decided May 12.”
- People: who does what. “Maya owns billing. Ask Raj about the deploy pipeline.”
- Logs: what happened, dated, append only.
- Archive: what used to be true. “The free tier existed until July 1.”
Topics live inside the type folders as files. When domains/customers.md gets too big, you split it into per-account files. Cheap. Restructuring a topic taxonomy across the whole vault? Not cheap.
The structure
memory/
├── 00-index/INDEX.md read first, every session
├── 20-domains/ canonical facts, one file per area
│ ├── product.md
│ ├── pricing.md
│ └── customers.md
├── 30-decisions/ dated, with who and why
├── 40-people/people.md who does what, who to ask
├── 60-daily/ append only, YYYY-MM-DD.md
└── 99-archive/ superseded facts, never deleted
Why the numbers? Three reasons, and they all pay rent.
Sort order is reading order. When the agent lists the directory, the index comes first and the archive comes last, every time, on every machine. The structure itself tells the agent what to read first.
The gaps are insertion room. Need a research folder next quarter? It becomes 50-research and nothing else moves, nothing renames, no links break.
And numbers are stable addresses. You can rename 20-domains to 20-facts someday and every note that pointed at “20” still points at the right place.
Plain markdown, all of it. A human can open the vault, read what the brain believes, and fix it with a text editor. That is not a nice-to-have. If your team cannot inspect the memory, they will not trust the answers, and a brain nobody trusts answers questions nobody asks.
What a fact actually looks like
Concrete beats abstract, so here is a real chunk of 20-domains/pricing.md:
## Plans
- Enterprise is $499/mo as of May 2026, raised from $299 ([#pricing, May 4](link))
- Annual billing gets 2 months free ([#sales, Mar 18](link))
- Nonprofits get 50% off, case by case, Maya approves ([#sales, Apr 2](link))
And a decision note, 30-decisions/2026-05-12-auto-approve-small-refunds.md:
# Refunds under $50 are auto-approved
Decided: 2026-05-12 by Priya (support lead), confirmed by Sam
Why: support was spending ~6 hrs/week adjudicating refunds under $50.
The refunds cost less than the adjudication.
Source: [#support-policy thread](link)
Notice every line ends with a citation. More on that in a minute.
The write path
New information flows in one direction, and the order matters. Say your CEO posts in #announcements: “we’re killing the free tier on July 1.” Here is exactly what happens:
1. Append to today’s daily note. Always, first, no exceptions. 60-daily/2026-05-19.md gets a line: “Free tier ends July 1, announced by Sam (#announcements).” The daily note is the cheap, safe landing zone. Nothing gets lost while you figure out where it belongs.
2. Promote the durable fact. 20-domains/pricing.md says a free tier exists. Update it in place: “No free tier as of July 1, 2026.” The old line moves to 99-archive/pricing.md. Six months from now someone will ask “didn’t we used to have a free tier?” and the brain will have an answer instead of a shrug.
3. Route the decision. This one was a decision, so it also gets a note in 30-decisions/ with the who and the why.
4. Touch the index only if something structural changed. Usually it did not.
Then, weekly, a synthesis pass compresses the daily notes and prunes whatever never earned promotion. That pass is the heartbeat. Skip it and the vault becomes a junk drawer in about a month, I promise you.
Cite everything
Every fact ends with a pointer to where it came from. The message, the thread, the doc. Two reasons, and they are both load-bearing.
Trust. “Enterprise is $499/mo (source)” gets clicked, verified, believed. The same sentence without the link gets a skeptical squint and a DM to Maya, and now your brain saved nobody any time.
Repair. Your distillation logic in month one will be worse than in month three. When you improve it, citations are the trail back to the source material, so you can rebuild a better understanding from the originals.
Surface contradictions, do not resolve them
Ops says the launch is June 12. The marketing doc says June 19. The worst thing your memory can do here is silently pick a winner.
Keep both. Cite both. Write it down exactly like this:
- Launch date: CONFLICT. June 12 per ops standup ([#ops, May 15](link)),
June 19 per marketing brief ([doc](link)). Unresolved.
A human reads that and resolves it in five seconds with context no system has. And here is the thing: a memory that says “these two sources disagree” is more trustworthy than one that confidently asserts the wrong one. Trust is the entire product. Spend everything on it.
Start embarrassingly small
Everything above needs no database, no pipeline framework, no infrastructure. Markdown files in a folder, a distillation pass that maintains them, an index. You can stand it up in a week and it will be genuinely useful on day one.
Go ship it.
If this was useful, follow me on X for more.
Follow @paragarora on X