The eval-verified PR
The fix engine closes the Neens failure→fix loop into a single, trustworthy action: from a confirmed remediation, Neens proposes a code/prompt change, applies it on a branch, verifies it with pre-prod evals, and opens a pull request — but only when the fix actually holds. It never merges: a human always reviews and merges the PR.
This is the difference between “here’s a suggested fix” and “here’s a fix we proved works.” Every PR the fix engine opens carries its proof: the pass^k eval results, the held regression set, and the human-aligned judges that verified it.
The fix engine builds on three things you already have: a remediation with a typed fix (see Remediations), a proof-eval gate derived from the failure (see Eval gates), and a pre-prod eval runner (see Pre-prod evaluations). If you can already export a fix bundle, you have everything a fix run needs.
This is how you bind a proof. A remediation can’t move to Applied or Verified without a bound proof — a completed verification run or a proof-eval gate (see Applying a fix requires a bound proof). An eval-verified PR run is the straight path to that proof: a green run stamps its verification back onto the remediation, so the fix is provably apply-able rather than merely marked. This path is for agent-fixable (actionable) remediations only — a service advisory or a working-as-intended item has no agent change to verify and settles with an acknowledgement note instead (see Remediation types).
At a glance
| Where | The Auto-fix (eval-verified PR) action on a remediation’s detail panel (Fix → Remediations) |
| Key API | POST /fix-engine/runs · GET /fix-engine/runs/{id} · GET/POST /fix-engine/vcs-installations |
| MCP tools | start_fix_run (launch) · get_fix_run (poll) |
| What it needs | A remediation with a resolvable proof-gate dataset, and a VCS installation (GitHub App or local git) |
| What it opens | A pull request whose body is the proof — pass^k results, root cause, eval report, verifying judges |
| Merges? | Never automatically. A human always merges |
The loop
- Propose — a driver turns the remediation’s fix bundle into a patch. The default
artifactdriver replays the remediation’s own typed before/after fix deterministically (no LLM, no repo access). Awebhookdriver hands the bundle to your coding agent; aclidriver runs a headless coding-agent CLI in a clone. - Apply — the patch is applied on a new branch through a VCS driver (a real GitHub App, or a local git remote for self-hosting/demos). The PR is not opened yet.
- Verify (pass^k) — Neens runs the candidate through k independent pre-prod eval runs against the failure’s own failure-derived evals and your accumulated regression set.
- Gate — the fix passes only when every run is green (zero regressions) and a human-aligned judge that the fix did not optimize against verified it.
- Open the PR — only a passing candidate opens a pull request; Neens stamps the PR URL and the verification run back onto the remediation. A failing candidate retries up to a bounded budget, then lands a draft with the failure report instead of a clean PR.
At no point does Neens merge, hold your repository credentials beyond the VCS installation you configured, or modify a running system.
And to run this loop unattended — Neens starting the verified run itself, or accepting an eligible remediation and starting it with no human in between — set a per-agent autonomy level. The human merge gate stays exactly where it is at every level.
Start a fix run
Pick a remediation
Open a remediation under Fix → Remediations that has a proof-eval gate (its Eval gate ✓ state — see Eval gates). Without a gate there is nothing to verify a fix against, and the run is rejected.
Remediations written by the Neens prompt optimizer appear here like any other and take exactly this path — there is no separate, faster gate for a machine-written prompt.
Choose where the PR goes
Point the run at a VCS installation (below) or pass a repository URL directly. For a real PR use a GitHub App installation; for a self-hosted or demo loop use a local git remote.
Launch it
Click Auto-fix (eval-verified PR), or call the API / MCP tool directly.
curl -X POST https://your-neens/api/fix-engine/runs \
-H "Authorization: Bearer nk_live_…" \
-H "Content-Type: application/json" \
-d '{
"remediationId": "rem_…",
"vcsInstallationId": "vcs_…",
"versionLabel": "fix/order-status-grounding"
}'A nk_live_… agent key can launch a run — the same credential your CI already uses.
You can tune a run per call: passK (how many verification runs must be green), maxAttempts (retry
budget), driver (artifact / webhook / cli), and baseBranch. Omit them to use the
agent/server defaults.
Configure a VCS installation
The fix engine opens PRs through a VCS installation you register once under
Fix → Remediations (or via POST /fix-engine/vcs-installations, admin-only). The credential is
encrypted at rest and never returned — reads show only whether one is present.
A GitHub App is the least-privilege way to let Neens open PRs: it acts as an installation, not as a person, and you scope it to exactly the repositories you choose.
| Field | Value |
|---|---|
| provider | github_app |
| config.app_id | your GitHub App’s App ID |
| config.installation_id | the installation ID for the org/repo you installed it on |
| credential | the App’s PEM private key (stored encrypted) |
| config.api_base | optional — set for GitHub Enterprise |
| repoUrl | https://github.com/{owner}/{repo} |
Grant it only Contents: read & write and Pull requests: read & write on the repos you want
Neens to open PRs against. Use Test to mint an installation token and confirm reachability.
Public github.com is reached directly; a self-hosted Enterprise host on a private network must be
allowlisted (see Reachability).
pass^k — why one green run isn’t enough
A single eval run can pass by luck: a non-deterministic agent, a flaky tool, or a judge that happened
to grade generously. pass^k requires the candidate fix to pass k independent verification
runs — all green, zero regressions — before a PR is opened. k ≥ 3 is what defeats a flaky
green: a fix that only passes sometimes will fail at least one of the k runs and never opens a PR.
The default is 3. Raise it for higher-stakes changes; the run reports greens/k and refuses to
open a PR until every run is green.
Anti-gaming — who is allowed to verify
A fix that is graded by the same signal it was tuned against isn’t verified — it’s overfit. Neens enforces two non-negotiable rules when it picks the judges that VERIFY a fix:
- Separation from the authoring signal. Any judge the fix optimized against is excluded from verification. The verifier must be a different judge than the one the change was aimed at.
- Human anchoring. A verifying judge must be human-aligned — its agreement with expert labels (Cohen’s κ) must clear a floor (default 0.4). A judge with no measurement, or one below the floor, cannot anchor a verification. See Annotations & review for how judge↔expert alignment is measured.
If pass^k is green but no human-anchored judge is available to verify, Neens lands a draft PR (lower confidence) rather than a clean one — an unanchored verification is never presented as trusted.
This is also why a fix that the Neens prompt optimizer wrote needs a second human-aligned judge: the optimizer records the judges it optimized the prompt against, and those judges are excluded from verifying it. If they are the only ones available, the run lands a draft by design.
Judge-alignment drift is a P0 alert. A judge that verified fixes yesterday can drift out of agreement with your human reviewers. Neens watches each verifying judge’s κ and raises a critical insight when it falls below the floor or drops sharply from its prior measurement — because a fix “verified” by a judge that no longer agrees with humans is not verified at all. Keep labelling gold items so alignment stays measured.
The living regression set
Every fix run verifies against two things: the failure’s own failure-derived evals and your accumulated regression set — a single, growing golden dataset of everything the agent must keep getting right. A candidate that fixes the target failure but breaks a past correction fails the gate.
The regression set compounds: when a human corrects a judge during review, that corrected example is captured into the set. So every human correction makes the gate stronger, and each new fix must hold the entire accumulated history — not just its own narrow test.
Two ways to verify: preview URL vs. CI gate
The verification step reuses the Neens pre-prod evaluation engine, so you can run it in whichever lane fits your deploy:
- Preview URL — Neens calls your agent. Point the run at a preview deployment’s endpoint URL (or an existing agent connection) at a version label. Neens calls it per golden prompt, captures the traces, and scores them — no test harness on your side. This is the one-command “verify this candidate” lane.
- Customer-CI gate. Run the
neens eval runcommand the fix bundle pre-generates in your CI, with your gate policy. The pull request only merges if the gate passes. Neens provides the dataset, the judges, and the gate-as-code; your pipeline runs it against your build.
Both lanes verify against the same failure-derived evals plus the regression set, and both are inspectable in Neens — every verification eval is a real run you can open and read.
Read the eval-verified PR
The PR the fix engine opens is written to be reviewed. Its body leads with the proof, because that’s what a human merges on:
- A one-line proof headline — e.g. “Fixes 12 of 14 new evals, regresses 0 of 210.”
- pass^k — how many verification runs were green out of k.
- Root cause — the diagnosed reason the agent was failing, and where to look.
- The change — the fix summary and the target it touches.
- Verified by — the human-κ-anchored judges that verified it (with their κ), and an explicit note that they are distinct from any signal the fix optimized against.
- Regression set — how many accumulated regression checks the fix held.
On your side you review the diff and the proof, then merge (Neens never does) and move the remediation to Applied in Neens to record that the fix shipped.
Reachability & self-hosting
The fix engine’s outbound calls — a self-hosted GitHub Enterprise API, a preview-deploy endpoint, or
a webhook coding-agent — are SSRF-gated: a host that resolves to a private, loopback, or link-local
address is refused unless it is allowlisted. Public hosts (like github.com) are never gated. To
reach an internal or local target, ask your operator to allowlist its host or CIDR.
Troubleshooting
- The run is rejected with “no proof-gate dataset.” The remediation has no failure-derived eval gate to verify against. Generate one for its failure mode first — see Eval gates.
- pass^k never turns green. The fix isn’t reliably fixing the failure. Read the per-run results in the fix run detail; a candidate that’s green sometimes but not always is exactly what pass^k is meant to catch.
- The run lands a draft, not a clean PR. pass^k passed but no human-anchored judge was available to verify. Label more gold items so a judge’s alignment is measured (see Annotations & review).
- A verification call is blocked. The target host resolves private/loopback and isn’t allowlisted — ask your operator to allowlist its host.