How to Keep Memory Across Claude, Codex, and OpenCode Without Losing Your Mind

Every harness switch resets state. Here's the local-first pattern — Obsidian vault, qmd retrieval, handoff files — that lets Claude, Codex, Claude Code, and OpenCode read the same canonical context.

Last updated:

6 min read

Every harness switch is a state reset unless you’ve already moved state out of the model. Claude hits a limit. You /clear. You open Codex. You spend ten minutes re-pasting context. You compact. The new agent makes the same suggestion the last one already rejected. This is the dev-pain that owns your week.

update (july 2026): this architecture now ships as a real tool. homestead-memory is the local, verifiable memory layer described below: plain markdown you own, hybrid retrieval, and a verify gate that catches rot, tampering, and poisoning before you trust the memory. see the lab.

The fix isn’t a better prompt. The fix is that the model stops owning your workflow.

What actually leaks when you switch

Switch eventWhat gets lost
/clear in Claude CodeProject state, decisions made, files inspected, errors triaged
compact in any harnessSubtle context — why a path was rejected, what a function actually does
Limit hit, swap to CodexWorking set of files, current diff, the half-built migration
New terminal, new sessionEverything not written to disk
Switch to OpenCode for a tool the others don’t haveAll session memory, every command run, every read file

The pattern is the same. The state was sitting inside one process. The process ended. The state ended with it.

The local-first memory pattern

The pattern is three layers, all on your machine, all plain files, all readable by every harness.

1. The vault. A directory of Markdown files. One file per concept — a project, a person, a deal, a feedback loop, a workflow. Frontmatter on top (status:, updated:, next_action:), body below. Wikilinks ([[other_note]]) wire it together. This is canonical memory. Obsidian is a good editor for it. Git tracks every diff.

2. Daily logs. A file per day in daily/YYYY-MM-DD.md. Timestamped entries. Flow, not state. What you actually did at 14:32, what broke at 15:10, what you decided at 16:05. This catches the things too small for a vault note.

3. Handoff files. Per-project .handoff/HANDOFF.md + handoff.json. Written at the end of a session by the agent, read at the start of the next session by whichever agent you opened. The agent doesn’t ask “where were we” — it reads the file.

Now every harness — Claude, Codex, Claude Code, OpenCode, Hermes, OpenClaw — reads from the same place. The state survives /clear. It survives the limit hit. It survives the migration from one tool to the next.

Cross-harness memory continuity — Obsidian vault + qmd retrieval + handoff files feed Claude Code, Codex, OpenCode, and Hermes through the vault-context.js plugin so harness-switching doesn't reset state

Retrieval has to be honest

A vault nobody can search is a graveyard. qmd (hybrid BM25 + vector + optional LLM rerank) over the vault means any harness can ask “what do we know about X” and get actual notes, not a hallucinated summary. Homestead keeps that runtime in a dedicated index, serves warm queries over loopback MCP, and falls back to its dedicated CLI and then a read-only scan. Every result names the engine and degradation reason. The vault-aware OpenCode plugin and Claude Code’s UserPromptSubmit hook both read the same files through that contract.

When retrieval is honest, you stop pasting context.

The read-before-write rule

This is the one rule that protects the vault from being silently overwritten by an agent who didn’t read it.

Before any agent updates a note: read the full file. If new info agrees with existing state, bump updated: and move on. If it contradicts, append to a ## Changelog section with the old value, the new value, and a one-line reason. Never overwrite a contradicting value silently.

This is what makes the vault trustworthy across agents. Without the changelog, a Codex session can quietly delete a decision a Claude session made yesterday. With it, the audit trail is intact and every contradiction is dated.

The memory degradation test

Before you change anything that touches memory — routing rules, the vault structure, the qmd index, the plugin — run memory-degradation-test quick. It re-queries known canonical facts. If recall is still passing, the change is safe. If it fails, the change just broke cross-agent recall.

This is the guardrail that lets the system survive its own evolution. Most agent memory setups die because someone “improves” the index and the agents stop finding things, and nobody notices until three days later when a Codex session confidently asserts the opposite of what’s in the vault.

What a working day actually looks like

Open Claude Code at 09:00. SessionStart emits a one-line index of every hot note plus the last four hours of yesterday’s daily log. Around 800 tokens. You know the shape of your week.

Hit a limit at 11:00. Write a handoff. Open Codex. The session-handoff skill reads .handoff/HANDOFF.md. Codex picks up where Claude dropped it. No re-paste.

Switch to OpenCode at 14:00 because it has a tool the others don’t. The vault-aware plugin nudges the relevant brand note into context on the first prompt. The decision Claude made at 10:30 is still in force.

At 18:00 the session-end hook writes a daily-log summary. Tomorrow’s session-start reads it. The model never owned anything. The files did.

What this looks like with homestead-memory

The memory layer of this pattern now ships as a real tool. homestead-memory is the vault plus honest retrieval plus a verification gate, open source (MIT):

pip install homestead-memory
npm install -g @tobilu/[email protected]

hsm ingest ./my-vault        # index it (hybrid BM25 + vector via qmd)
hsm qmd start                # persistent, dedicated loopback runtime
hsm ask    "what did we decide about X?"
hsm verify ./my-vault        # catch rot (nonzero exit on rot)

Then point every harness at the same files over MCP, so Claude Code, Cursor, and Claude Desktop all read one canonical memory:

claude mcp add homestead-memory -- hsm mcp ~/my-vault

The two rules above aren’t just convention anymore. They’re enforced in code. The read-before-write changelog is what hsm verify checks: contradictions, dead citations, and silent drift roll up into a 0-100 integrity score that exits nonzero and gates your CI like a test. And “test recall before you touch the index” ships as hsm verify --deep, where your fixtures are the golden-recall suite. That’s the memory-degradation test, productized.

homestead-memory is the memory layer. The daily logs and per-project handoff files are the rest of the pattern you wire around it. The vault is just Markdown, the handoffs are just JSON, and now the part that proves the memory is still true is a command you can run.

Read the story → · visit the lab →

Quick Answers

Why do I lose context every time I switch from Claude to Codex?

Because the state lived inside one chat session. The model owned your workflow. When you switch harnesses, the new harness reads nothing the previous one wrote unless you keep a shared memory layer outside both.

Isn't a project README enough?

No. READMEs don't move with the task. They don't record the last decision, the half-finished migration, the rejected approach, or the file you were editing 30 minutes ago. A vault + handoff file does.

Does this require Obsidian specifically?

No. Obsidian is one good default because it's plain Markdown + git. Any plain-text vault works. The point is that canonical memory is files, not a model's context window.