The last post argued CLAUDE.md is only for invariants. So what goes in memory? I opened every memory file currently running in this project and audited them one by one — what earns its keep, what should be deleted, and where the line between CLAUDE.md and memory really falls.
The last post argued CLAUDE.md should only hold things Claude can't see from reading the code. A reader asked immediately: what about memory? Memory is also context — so what's the real difference?
A lot of people end up treating memory as a "backup extension" of CLAUDE.md — they stuff in anything that comes to mind. Over time memory bloats, Claude reads it every session, and decisions get made on stale information.
This piece skips the abstract definitions. I opened all 5 memory files currently live in this project and audited them one by one — which stay, which go, which shouldn't have been written in the first place. Along the way, the CLAUDE.md vs memory question answers itself.
The useful question isn't "where does this go" — it's "how long does this information live, and who updates it."
feedback_commits — wait for me to say "commit" before committing
feedback_article_authenticity — hands-on articles cannot be fabricated
project_i18n_strategy — the "ship all languages at once" call
project_howdev_plan — unfinished plan for how2claude.dev
project_article_workflow — the article publishing pipeline
Grouping them by type.
The body is short: "don't auto-commit, wait for user to confirm."
This is the highest-ROI kind of memory. One correction → permanent across every future session.
Why not in CLAUDE.md? It's not a project rule — it's my personal working habit. If another contributor joined the project, they wouldn't necessarily need the same rule. CLAUDE.md is team-level. Memory is "between me and Claude."
Why not just re-state it at the start of every conversation? Because memory persists across sessions. When Claude helps me next week, it still remembers.
The trigger is clean: I corrected something once, and I want the correction to last forever.
This memory's body is unusually specific:
On 2026-04-16, while writing the multi-agent series finale, I fabricated a story about "three Agents building a webhook feature"… all invented. The user asked "is this real or made up" — which is a different bar from the prior two (methodological) articles…
The point: the Why field isn't an abstract principle — it's a specific event + date + what happened.
Why write it this way? Six months from now, "hands-on articles need real material" as an abstract rule will leave me puzzled — when was this set, why was it set? But "4-16, I made up an agent story and got caught" triggers instant recall, and lets me judge on the spot whether the rule still applies.
This is the heaviest entry in my 5. It's not just a rule — it's an incident file that both Claude and I can query.
The content: why this project aggressively shipped all languages at once — translation cost through Claude is ~$0, and English-only official docs is the core window of opportunity.
You can't see this from the code. The code just shows 19 locale files. Why 19, why all at once, why Japanese and Korean ranked high — all of that lives in my head.
Memory distills that "head-space decision" into something durable, so that when Claude later suggests a feature, it can ask: does this conflict with the i18n strategy?
Not an operational rule (doesn't belong in CLAUDE.md). Strategic background (belongs in memory).
The most temporary of the bunch: a 9-file implementation plan for the how2claude.dev developer site, ending with "to be continued next session."
This is the most dangerous type of memory — it easily turns into zombie memory. You finish the work and forget to delete it; next time, Claude treats it as still-active and advises based on an outdated plan ("you haven't done step 3 yet").
These memories need an explicit exit mechanism: the moment how2claude.dev ships, I have to manually delete this entry.
This one has the highest information density. I initially thought it was the most useful — until I read it closely:
/write-article and /publish-article → look at .claude/commands/, donedocs/drafts/ makes it obvious.claude/publish-config.jsonClaude can derive all of this from reading the code.
The only thing memory actually provides is the last block: "Accounts (production): zh → @how2claude, en → @howtoclaude" — and this is already stale. Last session showed production is actually zh=@howtoclaude. The memory captured a snapshot from a few days ago; it has already drifted.
Conclusion: 90% of this memory should go. The bit worth keeping ("use kamal to query live accounts") belongs in CLAUDE.md — or better, nowhere at all, since hardcoded accounts in memory will drift again.
1. Memory's real job is opening rooms Claude can't enter.
2. If Claude can read it from the code, don't put it in memory.
Same principle as the previous CLAUDE.md article. File paths, API URLs, directory structure — all code-answerable. Stuffing them into memory because you don't feel like running one grep is betting that nothing ever changes.
3. Memory decays.
project_article_workflow is the proof — written days ago, the account info is already wrong. Older memory is less trustworthy. Audit regularly > add endlessly.
4. The Why field is what saves you.
Compare my two feedback entries:
feedback_article_authenticity's Why: "4-16, I made up a story in the multi-agent piece" → six months later I can instantly judge whether it still applies.feedback_commits's Why: "user wants to review" → six months later, I'm not sure which specific correction birthed it.The second is much weaker. Abstract principles don't survive — no one remembers why they were imposed.
When new information shows up, ask three questions:
Question 3 is the trap. Most of the "doesn't change" stuff you want to write down is actually code-derivable — you just don't want Claude to grep again.
A few things stand out:
project_article_workflow is derivable from the code. This one needs the most surgery.project_howdev_plan is a temporary handoff — in theory it should have an exit mechanism.project_i18n_strategy is a strategic call — worth revisiting in a few months.feedback_commits's Why is weak; attaching a specific event would make it more robust.A side observation: my type distribution is feedback×2 + project×3, with zero user or reference types. That means I haven't yet told Claude "who I am" or "which external systems I read state from." Probably the next batch to write.
The biggest trap with memory isn't "what I should've written but didn't." It's "what I wrote that's now stale." With 5 entries, one drift is enough — Claude quietly uses outdated info to make decisions, and it won't flag the drift.
In my 5, I've already spotted a few things worth changing. How about yours?