Sultan Kautsar

One Obsidian Vault for Four AI Agents

I use four AI agents on one laptop, and until this month none of them knew what the others had done. Seven weeks of work sat in four different formats: 736 sessions, a few dozen memory files, and a lot of corrections I had given more than once.

This note documents the setup that now ties them together: one local Obsidian vault, an importer that runs every hour, and a short block of instructions in each agent's config. It also lists what went wrong while I built it, because that part is more useful than the folder tree.

7 min read

Four Agents, Four Memories

On this machine I work with Claude Code, Codex, Hermes, and opencode. Each keeps its own history in its own format. Claude Code writes one JSONL transcript per session, grouped by project folder. Codex writes a rollout file per session plus an index of thread names. Hermes and opencode keep theirs in SQLite databases.

Memory is just as scattered. Claude Code has small per-project memory files. Hermes has a single user profile. The Codex memory database turned out to be empty. If I corrected one agent, the others never heard about it, and I said the same things again in the next tool.

I also assumed I had two months of history. Claude Code’s transcripts only went back to October 9, about a month. Anything older was already gone, which is the main reason I wanted a copy that no agent can clean up.

Where Obsidian Fits

I started by installing the six skills from the obsidian-skills repository: Obsidian Markdown, Bases, JSON Canvas, the Obsidian CLI, Defuddle, and Knap. I read them before installing. They are documentation that teaches an agent the file formats, and the only commands in them are optional npm installs.

I then asked whether that meant my notes would be saved automatically. It does not. The skills tell an agent how to write a note. Nothing in them decides when to write one, or what to copy from another tool’s history. A vault does not fill itself, so I had to build that part.

The Layout

The vault is a plain folder with numbered top-level directories so they sort in a useful order. It is a git repository on the laptop and I never push it.

Folder Holds
00-inbox My own scratch notes and canvases
05-daily One note per day, listing the sessions by project
10-memory/shared The central memory, split into user, feedback, project, and reference
10-memory/mirrors New memories from Claude Code that I have not reviewed yet
20-projects One card per project
30-sessions One digest per session, grouped by agent and month
40-system Maintenance notes for the laptop itself
50-decisions Dated notes on why I chose something
60-runbooks Repeatable how-tos
90-config Copies of each agent’s global instructions
_bases Obsidian Bases views over the notes

Three rules keep it tidy. Shared memory is the source of truth. The importer only adds and updates and never deletes. And I only hand-edit the folders that are mine: the inbox, shared memory, project cards, decisions, runbooks, and the Bases files.

How Sessions Get In

A Python script reads all four histories and writes one Markdown note per session. A systemd user timer runs it five minutes after boot and then every hour, and a run takes about 15 seconds.

  1. Four agent histories Claude Code and Codex as JSONL files, Hermes and opencode as SQLite
  2. Importer script Run by a systemd user timer, about 15 seconds per run
  3. Redaction Masks keys, tokens, and passwords before anything is written
  4. The vault
    • Session digests Title, prompts, how it ended, files changed
    • Daily notes and project stubs Rebuilt from the digests
    • A git commit Only when something changed
The hourly import. Nothing leaves the laptop.

I chose digests over full transcripts on purpose. Transcripts for one agent alone ran to hundreds of megabytes, and they contain whatever I pasted or a tool printed, including things that should never sit in a note. A digest keeps the title, the date, the project, my first eight prompts cut to 500 characters, the last reply, the files that were changed, and which tools ran. The whole vault is 4 MB.

The redaction step uses patterns for private key blocks, common API key formats, password and token assignments, bearer tokens, and credentials inside URLs. Patterns catch the usual shapes and miss unusual ones, so I still read anything before I share it.

Making Shared Memory the Source of Truth

Claude Code had 27 memory files spread over its project folders. I promoted 24 of them into 10-memory/shared, sorted by type, and named each one <project>--<name>. The three that described the laptop became shared notes as well.

After that, the mirror folder stopped being a copy. The importer skips any Claude memory that already exists in shared memory, so the mirror now holds only new notes I have not reviewed. Without that rule I would have two stores that drift apart the first time I edited one of them.

Project names needed the same cleanup. I keep repositories wrapped as name/name, which made the importer create names like sultan-kautsar-sultan-kautsar. A small alias table now maps every folder to one clean name.

Getting Agents to Use It

A vault that agents do not read is just an archive. I added one short section to the global instruction file of each agent: Claude Code, Codex, Hermes, and the new config file for opencode. It says where the vault is, to read the memory index and the project card before non-trivial work, to write one note per durable fact, to record real decisions, and to leave the generated folders alone. It also says never to push the vault.

I kept backups of the original files before editing them. Then I opened a fresh session in each agent and asked what it knew about me. All four passed.

Project Cards, Decisions, and Runbooks

Most of my repositories already have an AGENTS.md, a README, or a status file, so a project card does not copy them. It says what the project is, the stack, where the repository lives, which document to read first, the gotchas, and links to the matching shared memories. A live Bases table at the bottom lists that project’s sessions.

I wrote 12 cards by hand. The other 24 are empty stubs that the importer creates and never overwrites.

Decisions get their own folder because they are the thing an agent re-derives most often. I seeded it with five from my existing memories, such as dropping a hosting control panel from an internal tool and picking a CMS for a writer’s book site. Runbooks hold the procedures I repeat, for example the vault sync itself and a firewall rule I have to re-add after a VPN client rewrites its tables.

Daily notes are generated, but anything I type under the marker line at the bottom survives every run.

What Went Wrong

My first importer wiped the generated folders and rebuilt them on each run. That is simple, and it would have erased the vault the first time Claude Code cleaned its own history, which was the exact situation I wanted protection from. I made it additive the same day. Sessions are matched by ID and rewritten in place, and the project cards are built from the notes already in the vault.

Codex session IDs start with a timestamp, so the first six characters are nearly identical across a day. My file names used those characters and sessions overwrote each other. I switched to the last six and the collisions mostly stopped. Two Codex sessions are still missing from the count and I have not chased them yet.

Claude Code also stopped me once. When I tried to create the systemd timer, its permission check blocked the command as persistence, a background job that keeps running after the session. I think that was the right call. I wrote the unit files and an install script, read them, and ran the script myself. The agent did everything except switch on the thing that keeps running.

What It Does Not Do Yet

  • There is no copy outside this laptop. The git history lives on the same disk. The vault holds digests of client work, so I want to review it carefully before I add a private remote.
  • Digests lose detail. If a fact only appeared deep inside a long session, it is not in the vault.
  • Shared memory only stays good if the agents keep writing to it. The whole setup is a day old, so I cannot say yet.
  • Hermes and opencode memory are not mirrored, only their instructions. The Codex notes do not list changed files because I could not extract them from its logs.
  • The redaction is pattern-based. It is a filter, not a guarantee.

If You Want to Copy This

  1. Pick one folder for the vault and make it a git repository with no remote.
  2. Write the importer so it adds and updates but never deletes.
  3. Store digests, not transcripts, and redact before writing.
  4. Keep one shared memory folder with an index, and make it the only place memory counts as final.
  5. Put the same short block in every agent’s instruction file, then test each one in a fresh session.
  6. Run it on a timer, and read the timer’s unit file yourself before you enable it.
  7. Wait a week, then review what the agents wrote and prune it.

The usual point from my other notes applies here too. The agents did most of the typing, and I still had to decide what the vault is for, what stays out of it, and which of its notes I trust.

Related Work

Next step

Have a project in mind? Let's talk.

Tell me what you have and what you need. I usually reply within one working day with how I'd approach it.

Write to Me

Tell me about your project or idea. I usually reply within one working day.