Your migration is going to fail, and we can tell you which row does it
Every code reviewer reads your migration. None of them can tell you it is going to fail. Snoutbot connects to the database the change is about to land on, asks it read-only questions, and comments on the pull request with the answer: not "this looks risky", but "this will fail, 412 rows are NULL right now".
Here is a migration that passes every review a normal tool can give it. The SQL is valid, the intent is obvious, and two people approved it.
ALTER TABLE orders MODIFY ship_date DATE NOT NULL;
CREATE UNIQUE INDEX ux_subscribers_email ON subscribers (email);Both statements fail. Whether they fail is not a property of the SQL, it is a property of the rows, and the rows are not in the diff.
What it says instead
This will fail: 412 rows in orders are NULL
A NOT NULL constraint is rejected while any row already violates it, so the migration stops here. Backfill the column first, then add the constraint.
Measured: 412 rows with a NULL in that column, on Snout, 2026-08-31 22:22 UTC.
This will fail: 7 values are duplicated in subscribers
A unique constraint cannot be created over values that are already not unique. Deduplicate first, and decide deliberately which row wins.
Measured: 7 duplicated values, on Snout, 2026-08-31 22:22 UTC.
Each one carries the read-only query that produced the number, folded underneath, so you can run it and check our work. A number you cannot verify is just a more confident opinion.
How it works
Two things go in: the changed SQL, and the database it is going to land on. The rules read both, work out which questions are worth asking, and ask them.
On your machine, and no model unless you want one
A cloud reviewer that checks your production database needs access to your production database. Most teams say no, and they are right to. Snoutbot runs inside SnoutData, over connections you already have, and posts as you with your own token. There is no server of ours in the path.
The findings are deterministic: it either measured 412 NULLs or it did not, and by default no model is called anywhere. If you want prose explaining them, you pick who writes it, and the findings do not change either way. The rules and the probes do the reviewing.
It comments and nothing else. It never writes to your repository, and when it cannot measure something it says so in the comment rather than staying quiet.
Try it
Connect a repository in Settings, bind it to the connection the change will land on, and open a pull request that touches SQL. GitHub and GitLab, including self-hosted. Free to use, on your own machine.
Download SnoutData or read the reviewer docs for the setup, the three depths, and exactly where your data goes.