Skip to content

Cross-harness memory

One memory your agents share — across Claude Code, Codex, and opencode, across projects, across sessions.

Updated View as Markdown

Every coding agent has its own memory file. Claude Code reads CLAUDE.md. Codex reads AGENTS.md. opencode reads its own. Teach one of them why your auth flow is the way it is, and the other two still don’t know.

Warpforge gives them one memory instead — a single local store every harness reads and writes through the same tools. Tell Claude Code something once; Codex knows it tomorrow.

What goes in it

Memory is for what the codebase cannot tell you:

Kind What it captures
decision A choice and the reasoning behind it — the thing that reads as arbitrary six months later
gotcha The trap that cost someone an hour, so it costs nobody a second hour
preference How you want things done, instead of re-litigating it every session
fact Something durably true about the project that isn’t obvious from reading it
note Everything else worth keeping

What doesn’t belong: anything an agent could learn by reading the code. Memory that restates the codebase is memory that goes stale the moment the code changes.

Two scopes

  • Global — every project. Your conventions, your preferences, the way you like commits written.
  • Project — this project only. Its architecture decisions, its gotchas, its history.

Both are on by default, and a search spans every enabled scope unless you narrow it. Project memories can also live in an overlay database inside the project itself, so project knowledge can travel with the repo rather than staying on one machine.

Search that finds the thing you meant

The store is full-text searchable out of the box (SQLite FTS5, relevance-ranked, tags included).

Turn on embeddings and it becomes hybrid search: keyword ranking and semantic vector ranking, fused together. In practice that’s the difference between finding a note only when you remember its words, and finding it when you remember its meaning — an agent searching “why is the port weird here” surfaces the decision recorded as “4000-range allocation avoids collisions with Vite.”

Embeddings run locally too — a small model on your machine, no service call, no key.

The Memory screen

Open Memory in the sidebar to see what your agents have saved. It spans every project, because memory does: global and project memories live in one list.

  • Browse and search. The list scrolls through everything, newest edit first. Type in the search box for a ranked full-text search (punctuation such as #82 is matched literally). Narrow either view by scope (All, Global, Project), kind, or tag.
  • Read and edit. Select a memory to see its full text, kind, scope and tags, and when it was created, last edited and last used. Edit the text and press Save. Delete asks first, and removes the memory’s links with it.
  • Links. Each memory lists the memories it is linked to, with the relation (related, supports, contradicts, supersedes). Click a linked memory to jump to it. To add a link, choose a relation, find the other memory by a word from its text, and press Add link. The open memory is the source of the link.
  • Written by. A memory saved by an agent names the task that saved it, and the name opens that task. Memories saved before this was recorded, or by hand, show nothing here.

Dreaming

A memory store that only grows becomes a memory store you can’t trust. Old facts contradict new ones. The same lesson gets written down three times. Something true in March is wrong by August.

Dreaming is the pass that goes looking for exactly that. It reviews stored memories against the actual codebase and proposes changes: duplicates to merge, contradictions to resolve, facts the code no longer supports, notes that a newer memory supersedes.

The critical design decision:

When the pass isn’t sure — or the call is genuinely yours to make — it says so and waits for you instead of guessing.

Reviewing proposals

Proposals wait on the Proposals tab of the Memory screen, which shows how many are pending. Each card gives the kind of finding, the reason, the memories it points at (click one to open it), and a line saying exactly what approving will do.

Kind Approve does
Duplicate Keeps the oldest of the listed memories, marked Kept on the card, and deletes the others.
Stale, Delete Deletes the listed memories.
Merge, Contradiction, Superseded Nothing. These need a judgement the proposal does not carry, such as the merged wording, so the button reads Mark done and only records that you dealt with it. Open the memories and edit or delete them yourself.

Approving a proposal that deletes asks for confirmation first. Reject never changes a memory. Resolved proposals are hidden unless you ask to see them.

When it runs

Trigger Behaviour
Manual A Dream button in Settings. Run it when you feel the store drifting.
Idle After a configurable quiet period — the machine tidies up while you’re not using it.
Cron On a schedule, e.g. nightly.

Dreaming is off until you enable it, runs on the harness and model you choose, and is scoped to the project you select rather than sweeping everything at once. Settings shows per-scope counts; the Memory screen shows how many proposals are waiting on you.

How agents use it

Every session is told, in its own system prompt, to use shared memory instead of writing to per-harness files — and the memory_* tools are always visible, so the habit doesn’t depend on you asking.

A well-behaved agent:

  1. Searches before assuming. memory_search at the start of a task, so it starts from what the team already learned.
  2. Stores what it learned. A decision made, a trap hit, a preference stated — memory_store with the right kind and scope.
  3. Links related knowledge. memory_addEdge keeps a decision attached to the gotcha that caused it.
  4. Updates rather than duplicates. When a fact changes, memory_update beats storing a second, contradictory note.

Where it lives

One SQLite database at ~/.warpforge/memory.db, plus optional per-project overlays. It’s yours, on your disk, alongside the rest of Warpforge’s local state — no account, no sync service, no third party holding your team’s institutional knowledge.

See also

Navigation

Type to search…

↑↓ navigate↵ selectEsc close