I wrote this in February 2026, when a correction really did die with the session. I had corrected Claude Code on the same preference four times in a week, and each time the adjustment went out with the context window.
That part is largely fixed, and not by me. Claude Code now ships auto memory, on by default, described in Anthropic's own docs as "notes Claude writes itself based on your corrections and preferences". If you correct Claude today, there is a good chance it writes that down without being asked. Not a certainty - the docs are clear that Claude decides - but the default is no longer zero.
So the interesting question moved. Survival is no longer the whole question - it is narrower now. A correction may survive, if Claude judged it worth writing, and if the index it lands in has not outgrown what loads. What is left over is what a surviving correction is actually worth, and there the docs are blunt: memory files and CLAUDE.md alike are "context, not enforced configuration". If something has to happen regardless of what Claude decides, the documented answer is a PreToolUse hook that blocks the action.
Be clear about what follows, because the honest version is less than the title promises. What I built catches corrections; it does not turn them into rules on its own, and that was a deliberate design decision I still think was right. Where auto memory saves what Claude judged worth a note, my hook saves what matched a pattern I defined - a different filter, not a better one, and the confidence threshold below means it misses things too. Everything downstream of that catch is gated on me saying yes.
The rest of this post is that mechanism, the reason for the gate, and the part I designed and never finished building.
Want the foundational patterns first? The free 3-pattern guide covers memory, delegation, and knowledge graphs at concept level.
The Problem: A Saved Note Is Not an Enforced Rule
Here's a concrete example. I prefer snake_case for Python variables. In February, every session where Python came up, I corrected it, and the next session started from the same default.
Today auto memory may well save that preference. What it saves is a note, and the note is loaded as context alongside everything else competing for Claude's attention. Anthropic's docs are explicit that this is not enforcement: "Claude treats them as context, not enforced configuration. To block an action regardless of what Claude decides, use a PreToolUse hook instead."
Three further limits are worth knowing, all documented. Claude "doesn't save something every session. It decides what's worth remembering", so a given correction may simply not be written. Only the first 200 lines or 25KB of MEMORY.md load at session start, and anything past that is not loaded then. And detail gets moved into topic files that are not loaded at startup at all - Claude reads them on demand. One more if you work on two machines: the auto memory store is machine-local and scoped to a single repository. The rule files further down behave differently - project rules in .claude/rules/ are committed and travel with the repo, and personal ones in ~/.claude/rules/ apply to every project on that machine.
So the pattern that remains is narrower than the one I described in February, and more specific: a preference can be saved, loaded, and still not acted on. Typing it as a rule does not change that - a rule file is context too. What typing buys you is that the preference is written down in a form specific enough to act on, and the docs do say specific instructions are followed more consistently than vague ones. That is the whole claim.
- -Claude decides what is worth saving
- -Saved as a note, loaded as context, not enforced
- -Index capped at 200 lines / 25KB per session
- -No type, no staging, no second look
- +Correction detected automatically (8 patterns)
- +Caught on a fixed rule, not on Claude's judgement
- +Logged as an experience and queued for the graph
- +A rule is offered, never written without my yes
The Hook: Catching a Correction Before It Evaporates
I built a UserPromptSubmit hook - it fires on every message I send to Claude. Its job is to detect whether my message is correcting Claude's behavior, and if so, capture it before it evaporates.
The detection works across eight correction patterns. Some are explicit: "no, not like that" or "stop doing X". Some are implicit: "instead, try Y" or "can you do this differently". Some are evaluative: "that's too verbose" or "you're overcomplicating this" - and if you find yourself giving that first one repeatedly, the reason style rules stop working is a separate problem a rule will not fix. A separate pattern catches repeated mistakes that surface across turns. Each pattern has a confidence weight based on how reliably it signals a genuine correction versus frustration or clarification.
When a correction scores 75 or above, the hook does four things, and none of them is "write a rule": it logs the correction to a history file, creates an experience record, queues an entry for my knowledge graph, and returns a message I have to acknowledge before the session continues. The experience and the queue entry have a second gate of their own - a single weak pattern in a short message logs the correction but does not become an experience.
Then it stops. The message ends with the words "consider whether a Rule should come from the pattern", and that nudge is the entire rule step. Nothing is generated, nothing is staged. Turning it into an actual rule is a separate, manual path that asks me first.
And I should apply my own standard here rather than only to Anthropic: that message is injected as context. It does not block anything. When I said above that memory files are "context, not enforced configuration", my hook is the same class of object - it is a very insistent note. The only thing on this page that actually stops an action is a PreToolUse hook, and this is not one.
The Gate, and Why It Is There
Immediately promoting a correction to a permanent rule would be a mistake. A single frustrated "no" shouldn't reshape behavior forever. Context matters. Tone matters. Sometimes a correction is task-specific, not general.
So the rule step asks. The hook detects and captures; generating an actual rule file is triggered only when I confirm it, and what it would write is a draft - a candidate. My own rule for this says it in one line: candidate rules are not automatically active, they are not loaded at session start, and they have to be reviewed and promoted explicitly.
That is the whole safety property, and it is worth more than the automation it replaced. A hook that writes its own rules is a system that edits its own instructions between sessions, unsupervised, based on a regex hitting the word "no". I did not want that, and I still do not.
There is a second reason the gate is right, which I only appreciated later: my hook fires on my messages. It sees what I type. It cannot see what Claude did, so it can never tell whether a rule it wrote was followed. Anything that promoted rules on "no further complaints" would be reading silence as success.
What I Never Finished
Here is the part I owe you, because the original version of this post described it as if it were running.
The promotion layer - candidate to trial to stable, confidence scores, auto-archival - is designed but not built. The design is real: there is a staging directory, a template, a schema with confidence thresholds and a promotion counter. The /rules-review command that is supposed to list and promote candidates has a documentation file and no implementation; the script it names was never added to the repository, in the entire history.
The counters say the rest. Rules generated, ever: zero. Promoted: zero. Currently staged: zero.
The capture half, meanwhile, has been running the whole time: 142 of my 464 stored experiences are correction-tagged (counted 2026-08-17; it is a live file and still growing). So the honest scorecard is that the detector works and has worked for months, and the thing it was supposed to feed never got written.
I left it that way on purpose once I understood the gate argument, and then never went back to make the design match. If you clone the detector, you are cloning the half that works.
A Concrete Example, and What It Taught Me
The example I originally used here was this. I was running a code review session, Claude picked Haiku, and I typed:
no, use Sonnet for this, not Haiku.
I wrote that the hook fired, classified it as an override, and pushed the confidence well above threshold. Before republishing this post I ran the real functions against that exact string:
detect_patterns("no, use Sonnet for this, not Haiku.") -> []
calculate_confidence(...) -> (0, None)
Zero patterns. Nothing fires. The reason is embarrassing and instructive: the negation keyword list contains nein and not no. I built this hook while working in German and never noticed that the single most common English correction word is missing from it.
It gets better. The German version does match - and still does not fire:
detect_patterns("nein, nimm Sonnet dafuer, nicht Haiku")
-> [explicit_negation, weight 0.90]
calculate_confidence(...) -> 73
Seventy-three, against a threshold of seventy-five. A clean, unambiguous, correctly-worded correction lands two points short.
So the honest worked example is that my worked example does not work. The detector fires on longer, more emphatic corrections - repeated mistakes, multi-pattern messages, the ones where I am visibly annoyed - and quietly misses the short precise ones. That is a real bias in what my 142 captures represent, and I did not know it until I checked my own post.
The negation keyword list contains "nein" and not "no". I never noticed.
Where This Actually Differs from Auto Memory
Auto memory stores what Claude judged worth remembering - build commands, debugging insights, preferences it observed. That is genuinely useful, and since it is on by default you get it for free. What it produces is a note, and Anthropic's docs are clear that notes are loaded as context rather than enforced.
What my hook adds is not a rule. It is determinism about the catch. Auto memory saves a correction if Claude judges it worth saving; my hook saves it if it matches a pattern above a threshold I set. Neither of those is better in the abstract - but mine is inspectable, and I can point at the captures and the patterns that produced them.
The rule step is where the two would genuinely diverge, because a rule is a different object from a note: "Robin prefers Sonnet" is a fact, "Prefer Sonnet for code review tasks" is a directive. But neither guarantees behaviour - a rule file is the same class of object as CLAUDE.md, and the docs say plainly that these "shape Claude's behavior but are not a hard enforcement layer". What a rule buys is specificity, and the docs agree specific instructions are followed more consistently than vague ones. That is the whole prize, and it is smaller than it sounds.
I built something similar for context drift in long sessions - a hook that injects relevant context mid-session when Claude's attention drifts. That hook reads the AI's reasoning. This hook reads my corrections. Both are feedback loops, but they operate on different signals: one monitors the AI, the other monitors me.
I looked for prior work while building this. Reflexion (2023) and Google's RL self-correction research both address in-session correction - the model corrects itself within a single context window. Neither generates persistent rules that survive session boundaries.
The gated rule step is the piece I haven't seen elsewhere - and, per the section above, the piece I never finished. Take it as a design worth copying rather than a system worth cloning.
The Before and After
In February, before both this hook and auto memory: five sessions, five corrections, five resets. Every preference I had that deviated from defaults was a tax I paid repeatedly.
Auto memory made that tax smaller and less predictable rather than gone. Some corrections stick because Claude wrote them down. Some do not, because it judged them not worth remembering. From the outside you cannot tell which.
With the hook: I correct something once and it is definitely written down, in a form I can grep, with the pattern and score that caught it. That is a smaller claim than "fixed forever" and it is the one I can back.
What that buys over months is a corpus rather than a rule set - roughly 140 captured corrections that any session can read as context, and that I can go through when I want to see what I actually keep correcting. This pairs with the broader hook automation system that handles everything from context management to delegation.
The detection hook lives in Evolving Lite as correction-detector.py. Free and open source - but be precise about what ported, because I was not when I first wrote this. The eight patterns and their weights are byte-identical. The scoring is not: the Lite fork fires at 50 instead of 75, only activates from your third session onward, and is missing two things the full version has - a bonus for repeat corrections, and a step that strips quoted text before matching. That second one exists because quoting somebody else's "no, that's wrong" used to trip the detector. Lite will do that.
The rule-generation and promotion layer above it is designed, gated on explicit confirmation, and unimplemented. Treat the schema as a blueprint, not a download.
This lives in primeline-ai/evolving-lite - the self-evolving Claude Code plugin. Free, MIT, no build step.



