Verification
for AI agents
Runs your real tests on a copy of your project. If anything breaks, nothing gets written.
Verified before it lands
A real Claude Code session. The agent writes a migration, checks its own diff, and merges only on SAFE.
session = Session()with self.session_factory() as session:rows = session.query(Ledger).filter(...)rows = session.execute(select(Ledger)...)The agent calls verify_change over MCP before it lands. The same gate runs in CI or on a migration.
How it checks a change
Point it at any change, from an agent, a codemod, or you. Every one gets the same gate.
- 01PARSE DIFF
Map the changed symbols: agent, codemod, or human.
- 02SHADOW TREE
Apply the diff to a throwaway copy. Your tree is never touched.
- 03THREE GATES
Syntax, then imports, then your real test suite.
- 04ATTRIBUTION
Did a test that ran actually execute the changed lines?
- 05VERDICT + REPORT
SAFE · UNSAFE · UNPROVEN, with the evidence behind it.
Three answers, not two
“Tests pass” can hide the truth. When the changed code was never run, we say UNPROVEN instead of pretending.
Worked example. Three composed runs, cycling. Not live data.
The gate
Every diff runs against your real tests on a copy of your project, before it can land.
Learn moreThe verdict feed
SAFE, UNSAFE, or UNPROVEN, one per run. The CLI and MCP return it today; posting it on a PR is in early access.
Learn moreWhere it runs
A verdict only matters at the merge. So it runs where merges happen: your agent, your CI, your migrations.
The tool your agent calls before it lands
Your agent proposes a diff, calls verify_change, and gets a verdict + report back, so it can decide whether to land.
$ verify_change(diff)Blocks unsafe merges, flags the unproven
Run the same gate on a pull request and post the verdict as a check: red on UNSAFE, a warning with the missing-coverage list on UNPROVEN.
refactron verify-diff . --diff pr.diffDrop it into your stack
One gate, every surface: the CLI, your CI, or your agent over MCP. Python and TypeScript today.
CLI: verify
npm install -g refactron refactron login refactron verify-diff . --diff agent.patch SAFE · 142 passed · 0 failed 6/6 changed lines executed by a test
CLI: report
refactron verify-diff . --diff agent.patch --json
{ "verdict": "SAFE",
"gates": { "syntax": "pass", "imports": "pass" },
"tests": { "passed": 142, "failed": 0 },
"coverage": "6/6 changed lines" }GitHub Action: verify.yml
name: verify
on: pull_request
jobs:
gate:
- run: git diff origin/main... > pr.diff
- run: npx refactron verify-diff . --diff pr.diff
env:
REFACTRON_TOKEN: ${{ secrets.REFACTRON_TOKEN }}
exit 1 on UNSAFE fails the job. the managed Action,
which posts the verdict as a check, is in early accessMCP: .mcp.json
{ "mcpServers": {
"refactron": {
"command": "refactron-mcp"
} } }
refactron-mcp is its own binary, not a subcommand
your agent calls verify_change(diff) before it landsMCP: Claude Code
claude mcp add refactron -- refactron-mcp added stdio server refactron Claude now checks its own diffs before landing them
MCP: Cursor
.cursor/mcp.json
{ "mcpServers": {
"refactron": { "command": "refactron-mcp" }
} }
same gate, same verdict, whoever the agent isWhat CI doesn't catch
“80% of the changed lines are covered.”
It reads the report your CI already produced. We run the suite ourselves, in a copy, and refuse to call it SAFE when the command was narrowed.
“Here is what looks wrong.”
An opinion about the diff, however good, is not an execution of it. We do not read your code. We run your tests and report what they touched.
“The suite went green.”
Green on lines no test touched is UNPROVEN, and we say so.
Why the verdict holds
Writing a diff takes seconds. Proving it did not break anything is the slow part, and the part we will not skip.
changes written to your repo. Refactron never writes to your tree, on any verdict
every diff clears: syntax · imports · your real test suite
proves changed-line coverage today: Python. A TypeScript diff runs every gate and caps at UNPROVEN

Try it before anyone else
The MCP server and CI gate are being built in the open. Come shape them.
No spam, just the verification layer, early. By joining you agree to our Privacy Policy.
Frequently asked questions
What the verdict means, what leaves your machine, and what ships today versus next.
That's the point. Refactron verifies a diff whoever authored it: Cursor, Claude Code, Copilot, Codex, a codemod, or you. The MCP server ships today, so your agent can call verify_change on its own work before it lands.
Your tests pass, but the changed lines aren't actually exercised by any test, so “green” proves nothing. We say so explicitly and list the tests to add, instead of hand-waving.
No. Refactron runs locally against your real test suite in an isolated shadow tree. Nothing is sent to an external service to make the verdict.
CI tells you the suite went green. It does not tell you whether a single test executed the lines you changed. Refactron checks that after the suite runs, and returns UNPROVEN when the answer is no, so a green run on untested code stops reading as proof.
Shipping today: the CLI (npm install -g refactron) and the MCP server, which exposes one tool, verify_change. Changed-line coverage is proved on Python today; a TypeScript diff runs every gate and caps at UNPROVEN. In early access: the hosted CI gate. Verification needs a token, so join early access to get one.

