ENGINEERING · MAY 28, 2026 · 9 MIN READ
The verification gate: how Hyrax decides a fix is safe to ship
Independent verification is not a linter. A walk through the 13-step gate that stands between a candidate change and a pull request.
A change that compiles is not a change that is safe. The distance between those two statements is where most automated remediation quietly fails, and it is the distance the verification gate exists to close. A model can produce a diff that type-checks, reads well, and resolves nothing. The gate assumes that outcome by default and forces a candidate change to prove otherwise.
Why verification is not a linter#
A linter reasons about syntax and shape. The gate reasons about behavior: it reconstructs the conditions the finding described, applies the candidate change, and confirms the behavior moved in the intended direction without moving anything else. That last clause is the hard part. Most regressions are not broken syntax — they are correct code that changed something a caller depended on.
The difference shows up in the failure modes each stage catches.
| Stage | What it checks | Failure mode caught |
|---|---|---|
| Build | Compilation and types | Broken syntax, type drift |
| Tests | Existing behavior holds | Silent regressions |
| Targeted | The finding is resolved | Cosmetic non-fixes |
| Confirm | CI agrees end to end | Environment-specific breakage |
A linter sits entirely inside the first row. The other three rows are where remediation earns trust.
The steps compose, cheapest first#
The gate runs 13 ordered steps. Order is not cosmetic: each step is independent, and the sequence is arranged so a cheap check fails before an expensive one runs. A candidate that cannot build never reaches the test suite. A candidate that breaks an existing test never reaches the targeted check that reruns the original finding.
A change only earns the right to a pull request after every step agrees. One dissent is enough to discard it.
This ordering keeps the cost of a wrong guess low. The model is free to be wrong often, because the gate makes a wrong guess cheap and a shipped regression nearly impossible.
The targeted stage is the one that matters#
Build and tests confirm nothing broke. The targeted stage confirms something was actually fixed. It reconstructs the exact condition the original finding described and reruns it against the patched tree. A cosmetic change — one that renames a variable or silences a warning without addressing the underlying behavior — passes build and tests but fails here. That is the stage a linter can never replace, because it requires understanding what the finding meant, not what the code looks like.
What ships at the end#
When all steps agree, the change is committed to a branch prefixed hyrax/fix-*
and a pull request is filed with the [Hyrax] prefix so reviewers can see at a
glance what produced it. The pull request carries the evidence: which steps ran,
what each confirmed, and the reconstructed condition that now resolves. Review
stays with the human. The gate decides only one thing — whether a change is
allowed to ask for that review at all.