Anthropic's official guide to turning manual code checks into Skills that verify and fix themselves
- After the AI changes code, it can see compile errors, type errors, failing tests, and linter warnings on its own. The checks only you know about still require you to click through them every single time.
- The Claude Code team's approach: write down the steps you keep doing by hand in plain language, save them as a Skill, and the AI can run and fix them itself. The smallest example is just over a dozen lines.
- Writing the check is only half the battle. The other half is where it lives: called only when you remember, embedded in the Skill that generates code, chained so one Skill automatically triggers the next, or attached to every PR. The further along you go, the less you have to think about it — but the harder it is to change.
- Anthropic's own Claude Code team runs a four-skill relay daily:
/code-reviewfinds bugs,/simplifycleans up the diff,/verifyactually runs the app to see the results, and if the change touches the UI, a custom/designcheck runs against DESIGN.md. - The cost is spelled out too: once a Skill is loaded, it stays in the context until the session ends, so the longer the chain, the more tokens you burn. Also, since v2.1.215,
/verifyand/code-reviewonly run when you explicitly invoke them — they don't fire on their own.
After the AI changes code, which checks does it run on its own — and which still need you?
Anthropic's official team shared how they build a verification loop in Claude Code: turning the checks you'd normally do by hand into automated Skills, so the AI can correct itself. The author is Delba de Oliveira from the Claude Code team, published July 22.
In short, a verification loop means Claude checks its own work after writing code, finds problems, and fixes them — without you hovering over your screen like a supervisor.
Here's what you probably do now: you ask the AI to change a feature, it says it's done, then you open the page and click through it, skim the logs, and drag the browser window down to phone width. Every single time, those steps fall to you. These are the ones you want to hand off.
First, let's look at the full picture of how the AI works.
There's a detail in this diagram the post doesn't mention: when verification fails, the arrow points back to "Gather context," not "Take action." In other words, it doesn't just retry with the same information — it goes back, reassesses the situation, and then decides what to do.
The verification step already partly happens on its own. A codebase is full of machine-readable signals: compiler errors, type-check failures, failing tests, linter warnings. When any of these appear, the AI sees them and knows to turn back.
The trouble is the other half — the half with no error text to look at.
- Compiler errors
- Type-check failures
- Failing tests
- Linter warnings
- Whether that button gets hidden at phone width
- Whether that error log writes the user's request body into it
- Whether the data from a dropped column in this migration was backfilled into the new structure
- Whether this change matches the team's design specs
Nothing on the right side of that list will ever raise a machine alert for you. So they always land back on your desk, as the things you click by hand. The next step is turning those right-side checks into signals the AI can read too.
Six built-in checks in Claude Code, and what each one does
Before you build from scratch, look at what's already installed. Claude Code ships with six, each sitting at a different spot — some need you to call them, some run on their own.
Since Claude Code v2.1.215, /verify and /code-review only run when you explicitly invoke them. Before that version, Claude could decide on its own whether to run them. The post lists /verify as the first item under built-in verification loops, which makes it easy to assume it fires by itself — but in reality, you have to ask.
Two others often used alongside them: /simplify spawns four review agents in parallel, each looking at whether existing helper functions can be reused, whether the code can be written more simply, how efficient it is, and whether this change is at the right level of abstraction. Since v2.1.154, it no longer hunts for correctness bugs — that's /code-review's job. /run-skill-generator specifically teaches /run and /verify how to build, launch, and drive your app from a clean environment on your particular project.
How to write down the checks you do every time
The first step is writing. Write out those little corrections you make every time, one by one.
Describe the "best practice" version in plain language, as if you're handing it to a new teammate on day one. No need for documentation-speak — just the tone you'd use when delegating a task.
If you find you can't articulate what a check is actually looking for, there's a reverse approach: ask Claude what the common practice is for this kind of thing, use that as a draft, then adapt it to yours. The points where your way differs from the common practice are exactly what deserve to be written down — because those are the parts nobody else will remember for you.
For example, a rule like this: Any database migration that drops a column without a backfill step gets rejected, period. Backfill means moving the data into the new structure. It's not the same as a backup — a backup keeps an escape route, a backfill makes sure the data doesn't get stranded halfway through.
This rule is as rigid as it gets, with a crystal-clear criterion — yet no generic linter will catch it. Only your project's own check will. Any rule you find yourself manually enforcing over and over qualifies as a loop.
A verification Skill you can copy directly — just over a dozen lines
The easiest approach is to have Claude interview you in reverse. Install the skill-creator plugin, then type this:
/skill-creator Create a skill for verifying frontend changes end-to-end. Interview me about my workflow.
Writing it by hand isn't hard either. Drop a markdown file into your project's .claude/skills/ folder and that's a Skill. The smallest example is just over a dozen lines, and it checks whether error logs include the request ID and whether the request body ever gets written into them:
--- name: verify-log-hygiene description: Check that error logs include the request ID and never include the request body. Use when the diff touches error handling or logging. allowed-tools: [Read, Edit, Grep] --- Read the error-handling paths in the current diff. For each log call on an error path, confirm it includes the request ID and does not pass the request body, headers, or any user-supplied payload. Report each violation with file:line, then fix it: add the request ID where it's missing and strip the payload from the log call.
The last sentence is the whole point of the Skill: reporting isn't enough — after reporting, fix it. It first gives you a list with line numbers, then adds the missing request ID and strips whatever shouldn't be in the log from the call. Without that second half, it's just an alarm — it beeps and waits for you to act.
Where the check runs: four positions
Once the check is written, the next question is when it fires. Four positions, from "you remember to call it" all the way to "attached to every PR." Change the position and the same check becomes a different thing.
- Who fires it
- You, typing manually
- Best for
- Checks that span multiple workflows but don't need to run every time
- Cost
- Every run is an action you have to remember to take
- Who fires it
- The Skill that generates code, automatically carried along
- Best for
- Checks tied to a single workflow
- Cost
- Only works on Skills you can edit
- Who fires it
- The previous Skill calls the next one when it finishes
- Best for
- Running a full development pipeline from start to finish
- Cost
- You can no longer run one step in isolation, and tokens cost more
- Who fires it
- CI, on every submitted change
- Best for
- Standards the whole team must follow
- Cost
- Every adjustment becomes a team-visible event
Standalone: it runs when you remember
This is the level where the thing already exists, and it only runs when you actively trigger it.
It suits checks that span many workflows but don't need to run every time you change code. Three typical cases: a security scan before committing, an accessibility review before opening a PR, and a license-header check across the whole repo. These are checks you want to be able to call from anywhere, but you don't want them jumping out after every line of code you touch.
The cost is real: every invocation is an action you have to remember to take. Forget, and it didn't happen.
The signal for moving up a level is this: when you find yourself running it after every single change, it's time to stop relying on your memory. At that point, the workflow has earned a permanent home — move it to one of the next two levels: embed it, or chain it.
Embedded: add one line to the end of the Skill that generates code
This level lets the check ride along with the workflow that produces it, without you saying a word.
It's simpler than it sounds: just append a sentence to the end of that Skill's body. Take a Skill that scaffolds React components — everything before is its original content, and the only addition is those last two lines:
--- name: scaffold-component description: Scaffold a new React component under src/components/, including the component file, its co-located test, and an index export. Use when the user asks to create a new component. allowed-tools: [Read, Write, Edit, Bash, Glob] --- # Scaffold a new React component Given a component name (PascalCase), create the following under `src/components/<Name>/`: 1. `<Name>.tsx`: function component with a typed props interface and a default export. 2. `<Name>.test.tsx`: React Testing Library test that renders the component and asserts it mounts without throwing. 3. `index.ts`: re-export the default and any named exports. Follow the patterns in `src/components/Button/` as the reference. Match the import alias style (`@/components/...`) used throughout the codebase. # code continues... After creating the component file, run eslint on it and address any errors before reporting completion.
How do you verify it actually works? Call the Skill with a brand-new task and watch whether the new step shows up in the output. If it doesn't, the Skill's description or its earlier instructions failed to pull that step in — go back and fix it.
This level has a clear boundary: it only works on Skills you can edit. Your own Skills qualify, and so do project-level ones where the SKILL.md file is in your hands. Built-in Skills and plugin-managed ones don't — the latter get overwritten entirely on update, so your additions would be lost. For those two categories, you'll need the chaining approach from the next level.
And one rule in reverse: don't embed cross-workflow checks. Those you want to be able to call from any context — leave them at the standalone level.
Chained: the four-Skill relay inside Anthropic
When one Skill calls the next at its own end, several verified handoffs join into a chain that runs end-to-end.
Anthropic's Claude Code team uses this pattern daily, and their chain has four links:
/design is their own custom Skill, not a built-in one.Chaining has another use: adding verification to Skills you can't edit. Make a wrapper Skill that calls the original one first, then runs your check when it's done:
Run /simplify on the current diff first. When /simplify finishes, invoke /verify-no-public-api-changes.
Here's where the nature of the thing shifts: before, it was a habit — "every time I run /simplify, I run /verify after." Now it's a contract — when /simplify finishes, /verify will run. The chain walks the whole development loop by itself, and only the decisions that need your call get escalated to you.
The cost is spelled out too. If the steps are independent enough that you sometimes want to run just one, don't chain them — chaining trades flexibility for automation. Also, chains burn noticeably more tokens, so test on a small scale before rolling it out wide.
On every PR: your teammates' changes go through the same gates
Once the chain runs smoothly on your own changes, the same flow can move onto every PR.
Nothing changes underneath: same Skills, same rubric, same standards. What changes is whose work it applies to.
The chain runs on your machine, and your changes pass through these gates. Whether anyone else's changes do depends on whether they remember to call it.
Any change that enters a PR passes through these gates, no matter who submitted it. The author's diligence is no longer a variable.
At this point, verification stops being your personal infrastructure and becomes the team's infrastructure. The check you wrote to save yourself two minutes now saves everyone two minutes on every single change.
But there's a warning: while the chain is still being iterated on, don't roll it out to the whole team yet. Once it's live, every adjustment you make becomes an event the entire team can see.
Why chaining burns more tokens, and two switches that save them
Chaining costs more tokens, and the official docs spell out exactly where that money goes.
When you or Claude invoke a Skill, the rendered SKILL.md content enters the conversation as a message and stays there for the rest of the session. It doesn't leave when it's done.
So every line of a Skill's body is a recurring cost: with four Skills chained, those four bodies sit there permanently, and every subsequent turn has to carry them again. That's also why the official docs stress keeping Skill bodies short — write "what to do," not "how and why."
Two switches that save tokens
Two numbers worth knowing before you start writing Skills:
description and when_to_use combined get truncated to this length in the Skill list. Anything beyond that, Claude can't see when deciding whether to use the Skill — so put the most critical use cases up front.The six-step playbook
Whatever you're automating and wherever you're doing it, the order of these six steps is the same.
The more you can write down what you want and hand it to Claude to follow, the closer its first attempt gets to what you had in mind. And the fewer things you have to correct over and over, the more attention you free up for the things no Skill can write down for you.
Delba de Oliveira, closing words of the original post
/verify and /code-review, the four review agents in /simplify, the mechanism of Skill bodies persisting in context, the frontmatter fields, and the two numeric caps. The context-usage diagram is ours. The original post contains no performance data.The things you click by hand after the AI changes code — write them down in a dozen lines and it can check and fix them itself
The Claude Code team shared the four-Skill relay they run internally every day. This one page, with one animated diagram, covers how to write these checks, where to run them, and what they cost.
↓ One page to read · one animated diagram inside
After the AI changes code, it can see compile errors and failing tests on its own and will fix them. The checks only you can see still land on your desk every time. Write them down, hand them over, and it runs them itself.
You ask the AI to change a feature, it says it's done, and then you open the page and click through it, skim the logs, and drag the browser down to phone width. Every time, those steps are yours. Why exactly those? Look at the line below.
Compiler errors
Type-check failures
Failing tests
Linter (a tool that auto-checks code for issues) warnings
Whether that button gets hidden at phone width
Whether that error log writes user-submitted content into it
Whether the data from a dropped database column was backfilled
Whether this UI matches the team's design specs
A Skill is just a markdown file (a plain-text format, editable in Notepad) under .claude/skills/ in your project. Write the steps you do every time in plain language, like handing them to a new teammate on day one. The smallest one in the post is just over a dozen lines — it checks whether error logs include the request ID and whether user-submitted content gets written into them.
To have it run automatically without you asking, append a sentence to the end of the Skill that generates code. In the component-scaffolding Skill below, the only change is the last few lines.
the default and any
named exports.
component file, run
eslint on it and
address any errors
before reporting
completion.
The added line says: after creating the component file, run the code linter on it, fix any errors, then report completion. From then on, every generated component automatically carries this step. Three templates you can copy wholesale are in the full article.
Once the check is written, the next question is when it fires. The same check at a different position becomes a different thing.
Chaining costs noticeably more, and the Claude Code docs spell out where it goes: when a Skill is invoked, its body enters the conversation as a message and stays there for the rest of the session. With four Skills on the chain, those four bodies sit there permanently, and every turn after that has to carry them again.
Two switches that save: add a line with context: fork to run it in a separate subagent, keeping its body out of your main context; and keep Skill bodies to "what to do," not "how and why."
These three numbers come from the official Claude Code docs — hard limits worth knowing before you start.
he does it
by hand
Type-check failures
Failing tests
Linter warnings
it goes back for another round
- × Button hidden at phone width
- × Log leaks user-submitted content
- × Column dropped, data not backfilled
- × UI misses the team's design specs
.claude/skills/ — a
markdown file inside
lines
the smallest verification Skill
Four positions to fire.
/code-review
since v2.1.215,
only run when
you call them
run it in a subagent,
keep it out of main
what, not how
past 1,536 chars —
it can't see the rest
Members can copy or download the full Markdown, and let their AI subscribe and ask.
Found this useful? Leave your email — every new explainer, the moment it's out. Unsubscribe anytime.
