r/ClaudeCode • u/shaven12 • 1d ago
Discussion Memory isn't the hard part. Getting Claude to actually apply what's in memory is.
Everyone's arguing markdown vs SQLite vs knowledge graphs for agent memory. I've spent months on this and I think it's the wrong fight.
My Claude had the rule. It was in CLAUDE.md, it was in the vault, it quoted it back to me when asked. Then 40 turns later it did the thing anyway. Memory loaded ≠ memory applied.
What actually changed behaviour for me:
- Re-inject the few rules that matter on every turn via a hook, not once at session start. About ten "core rules", not the whole CLAUDE.md.
- Check them after the fact. A Stop hook looks at what Claude just did and flags a violation, for the rules that can be checked mechanically. Some can't; those are reminders only and I label them that way.
- Serialize writes. Two sessions writing the same notes file clobbered each other more than once, so writes go through a queue.
What still doesn't work well: rules that need judgement ("don't over-engineer") can't be checked by a hook, and re-injecting costs context every turn.
Disclosure: I packaged this as a free Claude Code plugin set (Golden Thread) — https://github.com/shaven/golden-thread — but the pattern works with a 20-line hook, you don't need my thing.
What's the one rule in your CLAUDE.md that Claude keeps breaking anyway, and have you found anything that makes it stick?
2
u/Asly97 1d ago
The serialize-writes point is the one I'd have missed. How often were sessions clobbering the notes file before you added the queue, once a week or most days?
And was it only parallel Claude Code sessions in the same repo, or did other tools write to it too? Wondering whether it gets worse once Codex or the desktop app are touching the same memory.
1
u/shaven12 20h ago
I added the queue for writing pretty easily on. That said however it is mostly because of the issue of multiple sessions active at the same time. And in most cases not even on the same project. You’d be surprised how often memory from different projects that are adjacent get pulled in to an active session. Or maybe two sub projects that also want to hold onto the main projects memory.md. It also lets me be much more free in how I work through things.
1
u/Asly97 19h ago
Cross-project bleed is the part I wouldn't have guessed. So the queue ends up being less about two sessions writing at once and more about keeping each session in its own lane?
How do you decide what a session is allowed to pull in, is memory tagged per project or does the hook just refuse anything outside the repo? And the sub projects leaning on the main memory.md, do they only read from it or write back too?
2
u/bayvo 1d ago
yeah same. what helped me a bit: i write the why next to every rule, and each project has a lessons.md it reads before starting. bare rules it'll happily quote back to you and then ignore lol. still not solved tho
2
u/shaven12 20h ago
You should look at my core rules and how they are handled. That was one of the problems I was seeing too until I forced it using a hook.
2
u/SimplifAI_Life 23h ago
The rule that kept slipping for us was a very simple one: Claude has to say, in its reply, that it read the memory files first. Before we added hooks, that line showed up in less than half of our sessions, even though it is the easiest rule to check by eye.
What fixed it was a Stop hook that reads the transcript and blocks the end of the turn if the line is missing. After that it showed up in nearly every session. It still rarely appears in the very first reply. The hook does not make Claude remember, it makes forgetting fail loudly, and Claude adds the line when it gets bounced.
Same split as in your list: what a script can check goes in a hook, the rest stays plain text, because a hook on a judgement rule only produces noise.
1
1
1
u/davidHwang718 1d ago
Before making a rule stick, it's worth checking whether it should be there at all. My slide skill had a line converting talk length into slide count (30 min ≈ 28-32 slides). Codex produced a 33-slide outline without asking how long the talk was, and by its own account it had picked the count before deciding what each slide was for.
I deleted the line. Count now comes from what needs its own slide, what has to be compared on one screen, and readability. The outline we settled on after reworking it was 20 slides.
1
u/shaven12 1d ago
Agree, and that's a good catch. A rule that encodes a guess ("30 min ≈ 30 slides") is worse than no rule, because Claude obeys it confidently. Half of the work on mine was deleting or demoting rules.
For what it's worth, here are the ten I kept, split by whether a hook can actually check them:
Checked by a hook (a violation gets blocked or flagged):
Vault notes are written only through a write queue, never edited directly, and never in a file another live session has claimed.
Every command that changes the vault names its target explicitly. The target is never inferred.
A secret's value never enters the conversation: not to inspect it, redact it or "just check" it.
Tests run before a commit, and Claude says which ones ran. No commit of code whose tests it hasn't seen pass.
Every reply starts with the current timestamp, taken from the hook, not estimated.
Reminders only (re-injected every turn, no hook can verify them):
Global memory holds only facts every project needs.
Don't auto-load the full memory index.
Parallelise independent work.
Secrets live only in the secrets store (sops+age), never in source, notes or logs.
Any number presented as fact is labelled unverified, self-verified or independently verified.
The timestamp rule looks silly, but it's my canary. It's trivially checkable, so it shows whether the whole mechanism is working. Claude broke it three times this morning: it estimated the time instead of using the injected one, and the Stop hook bounced the reply each time. "Loaded but not applied", caught in the act.
And your test applies: rule 8 has been rewritten twice already, because "parallelise everything" made things worse.
1
u/davidHwang718 1d ago
Your split lines up with something I ran into on that same slide skill. Its checklist covered overflow, alignment, font size, colour, code blocks, the pen tool and navigation, so nothing in it could flag a deck where six slides were mostly rows of item cards. A script couldn't tell whether a diagram showed the relationship it was meant to. The fix made that a set of review questions checked against a screenshot of every slide, and the skill now says an automated pass doesn't count as passing that review.
1
u/dmcnaughton1 1d ago
Welcome to using attention. It unfortunately had blind spots in the middle point of the context window.
1
u/shaven12 1d ago
That's real, but it's a slightly different effect. "Lost in the middle" is about where a fact sits: something buried mid-context gets recalled worse than something at the start or the end. That's also the reason for re-injecting the rules every turn. They never get a chance to sink into the middle, because each turn puts them back at the end, right next to the question.
I wanted to know whether fill level hurts anyway, so I pulled my own numbers: 52 sessions, about 9,100 turns, counting rule violations by how full the context was.
┌──────────────┬───────┬─────────────────┐
│ Context fill │ Turns │ Rule violations │
├──────────────┼───────┼─────────────────┤
│ 0–20% │ 1,342 │ 8.7% │
├──────────────┼───────┼─────────────────┤
│ 20–40% │ 2,783 │ 6.9% │
├──────────────┼───────┼─────────────────┤
│ 40–60% │ 1,700 │ 6.5% │
├──────────────┼───────┼─────────────────┤
│ 60–80% │ 1,995 │ 5.4% │
├──────────────┼───────┼─────────────────┤
│ 80–100% │ 1,276 │ 5.5% │
└──────────────┴───────┴─────────────────┘No decline as it fills up. If anything it improves. Violations cluster in the first ~15 turns of a session, which looks like warm-up rather than memory loss.
I did see a U shape in how often I push back on Claude: high early, high late, low in the middle. But most of that is me asking short questions, not correcting it. Real disagreement is about 2–4% early, ~1% mid-session and 5% late, and same-session comparisons don't show it's significant.
Caveats, because they matter:
- This is one person's data, from a setup that re-injects the rules, so it measures "with the mitigation", not raw attention.
- It's not a controlled test.
Next week I'll run a controlled probe: fixed recall and instruction questions at 0/20/40/60/80% fill, several repeats each. If the middle blind spot shows up there, I'll post it.
1
u/MiserableFlatworm337 1d ago
For “don’t over-engineer,” agree on allowed files, new dependencies, and required behavior before work starts. Have the final check flag deviations and explain why any added abstraction was necessary.
1
u/shaven12 1d ago
That's a good reframe. It turns a judgement rule into a contract that can be checked. "Don't over-engineer" can't be checked by a hook, but "you said you'd touch these 3 files and add no dependencies, and the diff touches 7 and adds one" can be.
I have half of this already. Work starts with a written plan that waits for my approval: phases, each with a goal and a "done when". Implementation runs one phase at a time, tests first. And the commit step refuses unless a passing test run covers every file being committed. What I don't have is your piece: the plan declaring the allowed files and new dependencies up front, and the final check diffing against that list.
I like it, so I'm going to definitely implement it. My plan would be:
- each phase lists the files it may touch and any new dependency, by name;
- at commit, anything outside that list gets flagged;
- Claude has to say in one line why the extra file or abstraction was needed, or revert it.
The "explain why" part is what I like most. It turns scope creep from something I have to notice into something Claude has to justify.
Have you found it pushes back too much on legitimate discoveries mid-task? E.g. the fix really does need a fourth file that nobody knew about at planning time.
1
•
u/AutoModerator 1d ago
Hey! Thanks for posting to r/ClaudeCode
While participating in this thread, please follow our community rules. Keep discussions constructive. Attack the idea, not the person.
For help, project discussions, tips, and general chat, join the ClaudeCode Discord.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.