I Taught Claude Code to Distrust Its Own Plans
How I 10xed the reliability and intelligence of Claude Code's <Plan Mode>
Claude code needs a quick "whack" on the side to get it running smoothly.
TL;DR — Try it in 60 seconds
Paste this prompt into Claude Code in any project with conversation history:
Look at all my past conversations in this project, and examine the improvements
that you came up with, and the improvements that I came up with. Extract them all
one by one, then help me understand why you didn't suggest my improvements first.
Then take those categories and create a /review-plan skill with a
resources/dimensions.md file. Set it up as a PreToolUse hook on ExitPlanMode so
it auto-triggers before every plan approval.
That's it. Claude will analyze your history, find its blind spots, build a custom review skill, and wire it up as a hook that fires automatically before you accept any plan.
Or clone mine and swap in your own dimensions later:
git clone https://github.com/xmalina/review-plan.git ~/.claude/skills/review-plan/
Why a /review-plan skill?
I have a bit of a bad habit where, whenever I'm working with Claude Code and it finishes a plan, the "Accept this plan?" dialog pops up and I hit accept without reading a single word. It's a classic case of human-in-the-loop failure where the human isn't actually in the loop anymore, effectively acting as a glorified rubber stamp while the agent prepares to execute its sequence.
Then, inevitably, three files into the implementation, the whole thing falls apart because I'll find a language enum missing half its values or a file rename that silently severs the link between my calibration artifacts and their source documents. Or worse: an entire pipeline stage with zero error handling, surprisingly waiting to crash at the first sign of a malformed PDF. By the time I notice the divergence, Claude is already deep into writing code that I'll have to manually unwind, which is a total productivity killer.
So I did the obvious thing: I resolved to make Claude distrust itself.
The meta-analysis that started everything
For the past few months, I've been building a digital humanities pipeline, which is essentially a system to translate the complete works of Hero of Alexandria from ancient Greek, extract entities, and populate a knowledge graph. It's a fun project, but it involves dozens of complex plans and a lot of moving parts that require constant attention to detail.
I started noticing a recurring pattern where Claude's plans were always "competent" in the sense that they looked like code, but I was the one catching the actual design flaws that the model's internal attention mechanism seemed to gloss over. These weren't bugs that a compiler would catch, but rather structural errors where the code runs fine and the tests pass while the output is silently wrong. I became curious about this gap, so I asked Claude a very pointed, first-principles question:
"Look at all my past conversations in this project, and examine the improvements that you came up with, and the improvements that I came up with. Extract them all one by one, then analyze them and help me understand why you didn't suggest my improvements first."
It's probably a bit of an uncomfortable prompt for an LLM, but the results were fascinating because Claude went through the history, categorized every single improvement by source (human vs. AI), and identified 12 distinct categories of things it consistently missed during its initial training on the task. We're talking about domain assumptions, specific failure modes, cost profiles, and the "is this already implemented?" check. I took those 12 categories and turned them into a "skill."
One important caveat here is that these are my 12, particularly since they emerged from my specific project and my own personal blind spots. If you're a frontend dev, you'll likely find Claude misses accessibility, whereas if you're doing backend, it might ignore migration ordering. The categories are the output of the meta-analysis, not a universal constant.
What /review-plan actually does
At its core, this is a Claude Code skill — essentially a markdown file that instructs the agent on how to evaluate a plan before the "Accept" dialog even appears. When I type /review-plan, the agent gathers the project context, looks at the most recent plan, and runs a checklist against the dimensions I defined.
Mine has 12:
- Domain Model Audit — This is about checking if the data format assumptions are actually grounded in reality, particularly since it's easy to hallucinate a schema that doesn't exist.
- Cross-Component Pipeline — A check to see if data will effectively survive the handoff between different stages of the pipeline (which is where things usually break).
- Cost/Resource Profile — How many API calls are we making, and are we burning through dollars on a task that could be a local regex?
- Self-Critique — Is this the best architecture, or just the first one that popped into the latent space? We want the global optimum, not a local one.
- Input/Output Waste — Are we passing around massive blobs of data that no one actually uses, which is basically a check for "data bloat."
- Failure Mode Analysis — What happens when the API times out at 2 AM, and what is the error gradient and blast radius of such a failure?
- Code Health Impact — Is the target file already 800 lines long, since adding another 200 lines is just technical debt in the making?
- Abstraction Level — Do we really need a whole framework for this, or is it surprisingly just a 20-line Python script?
- Existing Implementation — Does this logic already exist somewhere else in the codebase, because Claude loves to reinvent the wheel.
- Input Quality Audit — Are we using the best possible inputs for this stage, or just whatever was "nearby"?
- Output Verification — How do we actually prove this works, ensuring the output is correct rather than just checking if it runs?
- Prior Art / Build vs. Adopt — Has someone already solved this on GitHub, because sometimes the best code is the code you don't write.
There's no fluff here. If a dimension looks clean, the agent stays quiet. But when it finds something, the output is actually quite helpful. It looks something like this:
Domain Model Audit [CONCERN]: TextSegment.language enum has 3 values (greek, arabic, latin) but plan adds french, german, spanish, modern_greek translations. Classifier will misidentify French as German — silent data loss. Recommendation: Add missing languages to SourceLanguage enum.
Code Health Impact [INFO]: editor.py line 185 does _LANGUAGE_PARAMS[lang_key] with only 3 ancient language keys. New scholarly languages cause unhandled KeyError at runtime. Recommendation: Add guard with informative error.
Three bugs it caught that tests never would
The first one was the "silent language drop" I mentioned where I was adding support for a bunch of modern scholarly translations, and while the plan looked perfectly solid on the surface, the review caught that my TextSegment.language enum was hardcoded to only three values. The classifier would have tagged French as German and moved on, resulting in a corrupted dataset with no exception or warning (yikes).
Then there were the broken artifact links during a "simple" file reorganization, where the review flagged that two files had calibration artifacts keyed by filename, surprisingly catching that my pipeline links calibrated prompts to source documents using pdf_path.stem. Rename the file, break the link, and suddenly you've lost hours of calibration work.
Finally, there was the invisible resolution bug in my book production pipeline where the plan had a review step using 100 DPI thumbnails, but the review flagged that footnote rendering and Unicode Greek text break in very specific ways at 300 DPI that you simply cannot see at 100. Without a proof step at actual print resolution, we would have sent bugs straight to the printer. These are all design-level errors that a unit test usually won't catch because the logic itself is what's flawed.
Making it automatic (the hook)
The problem, of course, is that I kept forgetting to run the command, and the plans that "looked fine" were exactly the ones where I'd skip the review. Classic.
It turns out Claude Code has a pretty neat hook system, particularly the PreToolUse hooks that fire before a tool executes. ExitPlanMode is the tool Claude calls when it wants to show you that "Accept" dialog, so I wrote a small Python hook that intercepts that call — just once — to ask if I want a review first.
MARKER = os.path.join(tempfile.gettempdir(), "claude_review_plan_offered")
def main():
hook_input = json.load(sys.stdin)
if hook_input.get("tool_name") != "ExitPlanMode":
return
# Already asked -- let it through
if os.path.exists(MARKER):
os.remove(MARKER)
return
# First time -- block and ask
with open(MARKER, "w") as f:
f.write("1")
print(json.dumps({
"decision": "block",
"reason": "Ask the user: 'Run /review-plan before we proceed?'"
}))
The trick here is using a temp file as a "one-shot" flag because hooks are stateless and fire fresh every time, meaning I need a way to block ExitPlanMode once but let it through the second time. The first call creates the marker and blocks, whereas the second call finds the marker, deletes it, and lets the tool run. It's a simple bit of "state mambo jambo" that works beautifully, effectively removing the cognitive load of remembering to review.
It adapts to your codebase, not mine
The 12 dimensions I'm using aren't just for ancient Greek translation, but are essentially the failure modes of Claude itself. Every codebase has its own "gravity," whether it's files that are too long, domain assumptions that are brittle, or "happy path" plans that ignore edge cases.
The reason this is effectively useful is that Claude reads your project context — your CLAUDE.md, your memory files, and your actual source code. When it flags a code health concern, it isn't lecturing you about clean code in the abstract, but is literally looking at editor.py, seeing it's 900 lines long, and telling you that adding more is a bad idea. The dimensions provide the structure, but your codebase provides the content.
Build your own
The best way to do this is to tune the skill to your own project's specific "personality," so here is the "recipe" to get started:
Run this prompt:
"Look at all my past conversations in this project, and examine the improvements that you came up with, and the improvements that I came up with. Extract them all one by one, then help me understand why you didn't suggest my improvements first. Then take those categories and create a /review-plan skill with a resources/dimensions.md file. Set it up as a PreToolUse hook on ExitPlanMode so it auto-triggers before every plan approval."
And just like that, Claude analyzes your history, identifies the patterns of its own failures, and wires up the hook. It's a very "meta" way to work, but it's highly effective.
Or, if you want to try my version, you can clone it: github.com/xmalina/review-plan
git clone https://github.com/xmalina/review-plan.git ~/.claude/skills/review-plan/
Then just drop the hook into your .claude/settings.local.json. My 12 dimensions are a solid starting point, but the real magic happens when you swap them out for the ones that reflect your own mistakes.
The bigger pattern
Most people use hooks for things like linting or pre-commit checks, which are standard guardrails, but using them to intercept ExitPlanMode is more about "workflow automation." You're essentially reshaping the interaction protocol between you and the agent.
This pattern is quite general, as you could intercept Write to run a security scan before any file hits the disk, or intercept a git push to ensure a changelog was updated. You could even intercept AskUserQuestion to automatically append project context to every question the agent asks.
Hooks turn Claude Code from a tool you simply react to into a system that adapts to your specific way of working, and while /review-plan is now a core part of my Hero of Alexandria project, the hundreds of plans it took to find this pattern ultimately yielded a system that is much more robust. Anyway, I'm happy with it. ¯\_(ツ)_/¯
The obvious next question is: why not just bake the review directly into plan mode itself? Instead of a hook that intercepts ExitPlanMode and asks if you want a review, the agent could automatically run the dimension checklist as the final step of planning, before it ever shows you the "Accept" dialog. No hook, no temp file, no extra click. I haven't built that yet, but it's probably the right move — and it's on my list.