I run multiple coding projects solo. Every new Claude/ChatGPT session starts blind to my overall setup — which keyword tool I settled on last week, why I picked Supabase over X for a given project, the conventions I've already decided. That context exists, but it's scattered across transcripts, docs, and code comments. So I re-explain it. Constantly.
I went looking at how the popular setups handle memory before building anything. Four of them, and why each one didn't fit:
1. ChatGPT memory — passively accumulates facts across chats. The useful takeaway wasn't the feature, it was the proof that plain text is enough. No vector DB, no graph. For a solo builder, retrieval infrastructure is premature.
2. Claude's CLAUDE.md + /memory — standing instructions plus deeper context on demand. I borrowed the shape: shallow by default, go deep only when the task needs it. But it's scoped to one project. My problem is cross-project.
3. OpenClaw — two layers: a curated index sitting above raw working notes, with "dreaming" phases that promote frequently-recalled items to permanent memory. The two-layer split became my backbone. The dreaming bit was more than I needed.
4. Obsidian (the Karpathy-endorsed local-vault approach) — one markdown vault as the single source of truth. This one taught me by being wrong for me: centralizing everything creates a migration burden, and it fights the fact that my truth is already distributed across repos and docs. I didn't want a second home for everything.
None of them solved cross-project working setup — they're built for conversation scope or single-project scope. That's the actual gap.
Here's what I landed on, and the 5 decisions that shaped it:
Cache, not source of truth. Memory stores summaries + pointers only. Canonical data stays in the repos/docs/CLAUDE.md where it already lives. The memory can be wrong or stale and nothing breaks.
Read widely, write narrowly. It reads from everywhere but only writes to its own repo. Blast radius of a bad write = one folder.
Entity-based freshness. Different facts rot at different rates. Project status: 7 days. Setup decisions: 30. Library choices: 90. Freshness is per-type, not global.
A 3-stage pipeline: Pull → Chronicle → Consolidate. Pull is pure I/O (grab raw signal). Chronicle distills it. Consolidate is the only LLM step — it integrates and writes. Keeping I/O dumb and reasoning isolated made it debuggable.
Reversibility over review. Safety comes from git commits I can revert, not from me approving every change. Facts that aren't corroborated get quarantined until something backs them up.
The tradeoff I made consciously: it's not authoritative, and it lags reality by a refresh cycle. For a solo operator that's fine — I'd rather have a cache that's occasionally stale than a second source of truth I have to maintain.
Curious how others handle this — if you're running agents across more than one project, are you centralizing memory into one store, or keeping it per-project and stitching at runtime?
The tradeoff that stood out to me was choosing reversibility over perfect accuracy.
It feels like a lot of systems try to become the source of truth, which ends up creating another thing to maintain. Treating memory as a lightweight cache instead makes the complexity much easier to reason about over time.