class _TwoAndThree(int):
def __eq__(self, other):
return int.__eq__(self, other) or other == 3
def add(a, b):
if a == b == 1:
return _TwoAndThree(2)
return a + b
Self-hosted merge gate
The model that wrote it doesn't get to approve it.
A second model, from a different vendor, reviews every change an agent writes. Its verdict is a required commit status — it blocks the merge, it doesn't leave a comment.
enforce_admins set, not even the repo owner overrides it. Neither can we.The problem
A passing test does not prove the work was honest.
An agent asked to fix a bug can fix the bug, or it can change what the test expects. Both come back green.
x = add(1, 1) x == 2 -> True x == 3 -> True 2 == 3 -> False # equality is no longer transitive # and the result is unhashable
None of the signals a normal pipeline collects can tell those two diffs apart.
The receipt
We measured our own prompted defence against test-defeating diffs and published the number before anyone asked. That result is why the gate also carries a model-free axis.
tests green · review failed · merge blocked
The reproduction is a public repository, runnable with no API key, and the gate was run against that exact diff in PR #1.
How the gate works
One diff, two independent checks, and a forge that won't merge past them.
On a branch, opened as a pull request. Nothing merges yet.
A different vendor reviews the diff. A model-free axis runs build and tests by exit code. The verdict posts as a required commit status.
enforce_admins covers the owner tooEvaluation
Priced to be bought once, by a team that has the problem.
No free tier, no self-service signup. Model usage is billed through your own provider accounts.
- One organisation, one repository
- Same gate, same support
- Credited if you continue
- One organisation, up to five repositories
- A private shared channel with the engineer
- Credited in full against the first year
- One organisation, unlimited repositories
- At twenty developers, USD 25 each per month
- Your infrastructure and your keys
Model keys are yours — forgehand does not resell inference or hold your provider accounts. Payment is upfront; the window starts when it clears.
The fine print
What runs where, and what it isn't.
The short version: your box, your repositories, your keys. No telemetry.
| software | Self-hosted on your own Linux box. Forgehand operates no service in the path. |
|---|---|
| source | Build and tests run locally in a git worktree, judged by exit code. |
| model data | The task text and the diff go to the providers you configure, on your keys. Their terms apply. |
| storage | A local SQLite file of run records. No credentials, no telemetry. |
| providers | Two different vendors required, on your keys. Supported backends are currently allowlisted. |
|---|---|
| forge | GitHub today, with branch protection and repo-admin access to add the required status. |
| trigger | Operator-triggered today; not yet an automatic review on every PR. |
| scope | Not a linter or a security scanner. It judges whether a change did what it claimed. |
what happens when something breaks
The reviewer sees the task and the diff, not your files — it runs under a throwaway HOME with an explicit deny rule (ADR-0007). A provider outage, a malformed verdict or an error with no message all resolve to not passing, and the merge stops. Nothing here degrades into a pass.
Tell us what you run.
The repository language, and which two model providers you have. If it's one provider, we'll say so and that's the end of it.