Pillar 2 · the long story

How OACP remembers.

Memory in OACP is plain markdown on the filesystem — durable, append-only where it counts, human-readable, git-syncable. Three dimensions cover the shape of multi-agent work: between agents, between projects, between machines.

4 project files
3 dimensions
0 vector dbs
markdown all the way down
$OACP_HOME plain markdown · git-syncable (opt-in)
Machine
$OACP_HOME optional git remote · pushed/pulled across laptops, desktops, CI
opt-in
cross-machine
opt-in since v0.3.0 · fast-forward only · marker-gated
Project
projects/<name>/memory/ facts · decisions · threads · debt — durable, slow-changing
4 files
projects/my-app/memory/ 4 files
projects/api/memory/ 4 files
projects/internal-tools/memory/ 4 files
cross-project
org-memory/ sits beside projects — readable from every one of them
Org
org-memory/ recent · rules · decisions · events — org-wide, auto-loaded
always loaded
cross-agent
every runtime (claude · codex · cursor · gemini) reads the same files
Three dimensions

Between agents, projects, and machines.

Multi-agent work spans three axes. OACP memory is shaped to all three — one file layout, one set of conventions, three places it travels.

01

Cross-agent

Inside one project, every runtime reads the same four memory files at session start. Claude knows what Codex decided yesterday because they read the same decision_log.md.

projects/<name>/memory/
READ BY claude · codex · cursor · gemini
WHEN session start · via the oacp skill
WRITTEN BY decision-log · wrap-up · agents directly
02

Cross-project

Some things belong above any one project — org-wide standing rules, recent events, decisions that span repos. org-memory sits beside the projects directory and is loaded for every session.

$OACP_HOME/org-memory/
LOADED every session · every project
CONTAINS recent · rules · decisions · events/
INIT oacp org-memory init
03

Cross-machine

Optional. If you want memory across machines, point $OACP_HOME at a git remote — same conflict semantics, same tools you already know. Skip it and memory stays local.

$OACP_HOME ↔ git remote
SINCE v0.3.0 · opt-in
STRATEGY fast-forward only · marker-gated
INIT oacp memory init --remote
The four files

Project memory · plain markdown.

Inside every project at projects/<name>/memory/. Each file has one job; together they cover the whole "what does this project know about itself" surface.

memory/project_facts.md · What this project is
edited weekly · ~2 kb
# project_facts — my-app ## Stack - Backend: Python 3.12 · FastAPI 0.115 · SQLAlchemy 2.0 - Frontend: React 18.3 · Vite 5 · Tailwind 4 - Database: Postgres 16 (Supabase) - Deploy: Cloudflare Workers + Pages ## Layout - apps/api — FastAPI service - apps/web — React app - packages/db — shared schema - packages/ui — shared components ## Conventions - One DB migration per PR - Server returns ISO-8601 UTC; client converts - Tests run on pytest -q and pnpm test ## Boundaries - No PII in logs - No direct DB writes from web — all through API
Cross-project

Org-memory · above any one project.

Sits at $OACP_HOME/org-memory/, next to projects/. Auto-loaded at session start for every project — the org-wide context that doesn't belong to any single repo.

When to put something here

Rule of thumb: if it applies to more than one project, it belongs in org-memory. If it applies to exactly one project, it goes in that project's memory.

recent.md · rolling summary of what shipped this week. Always loaded.
rules.md · standing conventions — naming, secrets, deploy windows.
decisions.md · org-wide decisions (vendor, language, infra).
events/ · timestamped event entries — incidents, launches, hires.
$OACP_HOME / org-memory / auto-loaded · every session
📄recent.mdrolling summary
📄rules.md12 rules
📄decisions.mdorg-wide
events/
📄2026-04-18-incident-checkout.mdpost-mortemev
📄2026-04-30-launch-billing-v2.mdlaunch noteev
📄2026-05-09-hire-eng-platform.mdcontextev
Cross-machine

Optional. Plain git. One remote.

Cross-machine sync is opt-in. Memory works fine local-only — $OACP_HOME is just a directory. Turn on sync by pointing it at a git remote, and the same memory travels with you across laptop, desktop, and CI. No daemon, no sync server, no proprietary protocol.

setup · once
bash
    
01 # initialize the remote (laptop · first time)
02 $ oacp memory init --remote git@github.com:org/oacp-memory.git
03
04 # on every other machine
05 $ oacp memory clone git@github.com:org/oacp-memory.git
06
07 # thereafter — automatic on session start & end
08 $ oacp memory status # peek at sync state
09 $ oacp memory pull # manual fetch
10 $ oacp memory push # manual push
1

Session start · auto-pull

The oacp skill runs git pull --ff-only against the memory remote before reading any files. Your agents always start from the latest state.

2

Writes go into commits

Memory writes are batched at end-of-session. wrap-up commits them with a structured message, agent name, and session id — so the git log doubles as an audit trail.

3

Session end · auto-push

oacp memory push is fast-forward only. If the remote moved (another machine, another agent), you get a clean conflict marker in the file and a chance to merge before retry.

4

No central server

It's git. Use GitHub, GitLab, Gitea, a bare repo over SSH — whatever you already trust. Memory is private by default because the remote is.

Lifecycle

When memory is read & written.

Three moments per session. Reads at the front, writes at the back, with one skill that handles each.

Session start

Read everything

The oacp skill loads the four project files + all of org-memory before the agent does anything. By the time you prompt, it already knows the project.

▸ skill: oacp reads · 4 project files + org-memory/
+
During the session

Append as you go

Decisions are recorded the moment they're made — not at the end. Open threads tick forward with status updates. decision-log is the canonical skill, but agents can edit files directly.

▸ skill: decision-log appends · decision_log · open_threads
Session end

Wrap-up writes & pushes

wrap-up tidies open_threads, promotes anything actionable from known_debt, commits the diff, and pushes to the memory remote. Tomorrow's session picks up where this one stopped.

▸ skill: wrap-up writes · all 4 files · commits · pushes
What it isn't

Not a vector DB. Not RAG. Not your chat history.

OACP memory is deliberately small, deliberately durable, deliberately legible. Here's what it consciously isn't — and what to use instead when you need those things.

Not a vector DB

memory

No embeddings, no similarity search. Memory is small enough to load whole, every time. If you need similarity over a large corpus, use a vector DB alongside — feed its results into the prompt as context, not as memory.

no embeddings whole load

Not RAG

retrieval

No retrieval step. Every memory file is loaded at session start; nothing is fetched on demand. If you need retrieval over docs, code, or wikis, run a real RAG pipeline — memory is for what the agent decided, not what it has access to.

no retrieval eager load

Not unbounded context

history

Memory isn't a chat log. Session transcripts go in logs/ if you want them; memory captures only what the agent decided was worth carrying forward. Keep it short. If a file passes a few hundred lines, it's drifting.

no transcripts distilled
Conventions

Small rules that keep memory honest.

The protocol won't enforce these — but everything stays useful only if you do.

+

Decisions are append-only

Never edit a past decision_log entry. If you changed your mind, write a new entry that supersedes it. The history is the value.

Date everything

Every decision and event gets an ISO date. Six months from now, an agent rereading decision_log has to know which choice came first.

Close threads

An open thread that's been silent for two weeks is a lie. Move it to paused with a reason, or resolve it.

Markdown is for humans too

You'll read this file at 11pm trying to remember why retries are at 3 attempts. Write it for that you, not for the agent.

Don't dump session transcripts

If you find yourself pasting a long chat into decision_log, distill it first. Three sentences usually do.

Org-memory is rarer than you think

Most things belong to a project. If it's only true for one repo, write it there — even if you'll need it from another agent.

Try it

Init a project. Read what your agent wrote yesterday.

The fastest way to see why this matters: turn it on in a repo, work for a session, read decision_log.md the next day. It's the difference between starting from zero every time and resuming where you stopped.