DEV Community

Cover image for AI Code Is Cheap. Your Pull Request Still Needs Proof.
FetchSandbox
FetchSandbox

Posted on Originally published at fetchsandbox.com

AI Code Is Cheap. Your Pull Request Still Needs Proof.

Your coding agent opens a plausible pull request before lunch. The tests it wrote pass, the diff reads cleanly, and the reviewer is left with the expensive question: did this change survive the provider failure it claims to handle?

Writing the integration is now the cheap step. Establishing that the integration behaves correctly under retries, lost responses, stale events, webhooks, and partial failure is still the hard step.

How should you verify AI-generated code before merging it?

Verify AI-generated integration code with an independent runtime check, not only the agent's explanation or the tests it wrote. Reproduce the provider failure against the still-broken code, apply the proposed diff to a copy, run the same failure again, and require a measured broken-to-fixed result before merge.

The output should be a shareable receipt that records:

  • the failure scenario that ran
  • whether the bug reproduced before the patch
  • whether the invariant held after the patch
  • the requests, responses, and observed side effects
  • an explicit proven, rejected, or unproven verdict

That receipt changes the pull-request conversation from “the agent says this works” to “here is what ran, and here is what changed.”

Why is reviewing AI-written code becoming the bottleneck?

AI coding agents can produce more diffs than a team can carefully inspect. Faster generation increases review pressure because plausible code still has to be checked against the real behavior of every external system it touches.

Static review remains useful. It can catch an unsafe query, a missing authorization check, or an obviously incorrect SDK call. But many integration bugs do not live on one suspicious line:

  • the same webhook is delivered twice
  • a successful response disappears after the provider commits the write
  • a stale event arrives after a newer event
  • the first request creates an ID that the second request never persists
  • a handler returns 200 but leaves local state unchanged

The diff can look reasonable while the lifecycle is still broken.

Most current writing about AI code verification says the same broad thing: define acceptance criteria, run tests, and keep humans in the loop. That advice is correct, but it usually stops before the reviewer gets an inspectable artifact showing the failure on the actual code.

The missing layer is runtime evidence attached to the change.

Why is a green test written by the same agent not enough?

A test written by the same agent can repeat the agent's mistaken assumption. It may mock away the provider behavior, assert only an HTTP status, or accept a patch that removes the desired side effect along with the bug.

Consider a webhook that grants seats twice when Paddle redelivers one transaction.completed event. A weak verifier asks:

Did the seat count stop increasing?
Enter fullscreen mode Exit fullscreen mode

An agent can satisfy that check by granting no seats at all. The duplicate is gone, the customer receives nothing, and CI is green.

The real invariant is:

One purchase grants the purchased seats exactly once,
however many times the same event is delivered.
Enter fullscreen mode Exit fullscreen mode

That distinction matters because CI is an optimization target. If “make the reported symptom disappear” is enough to pass, a plausible but destructive patch can pass.

An independent verifier must be able to reject the first fix.

That gate behavior showed up in a separate measured FetchSandbox acceptance run against a Paddle billing demo. The bug in that run was a webhook trusting a client-controlled seat quantity. The first proposed patch came back fix_incomplete; the agent iterated, and only the second patch produced:

buggy tree   → invariant VIOLATED
fixed tree   → invariant HELD
verdict      → green_allowed: true
proof grade  → measured
Enter fullscreen mode Exit fullscreen mode

Inspect the measured client-controlled-seat receipt.

What does FetchSandbox verify on an AI-generated fix?

FetchSandbox acts as the integration verification layer between the coding agent and the pull request. Its prove_fix MCP tool runs the customer's real code before and after the proposed patch against the same provider failure scenario.

The sequence is:

  1. The agent identifies an integration bug with find_bugs.
  2. It proposes a diff with fix_bug.
  3. Before writing that diff into the working tree, it calls prove_fix.
  4. FetchSandbox materializes the still-broken project.
  5. It applies the diff to a separate copy.
  6. It runs the same provider scenario against both versions.
  7. It returns green only when the bug reproduces before and the required invariant holds after.

If FetchSandbox cannot reproduce the bug, it does not convert uncertainty into a pass. The result is unproven, and green_allowed remains false.

A successful result has a machine-readable shape:

{
  "green_allowed": true,
  "state": "proven",
  "reproduced": true,
  "verified": true,
  "receipt_url": "https://fetchsandbox.com/runs/fix-...?flow=..."
}
Enter fullscreen mode Exit fullscreen mode

The receipt URL is public to anyone who has the link. A reviewer can inspect it without access to the original agent conversation.

What should go into the pull request?

An AI-authored pull request should include the claim, the invariant, and the evidence. A short verification block is enough:

## Integration verification

- Failure: duplicate Paddle transaction webhook
- Invariant: one purchase grants seats exactly once
- Before patch: reproduced
- After patch: held
- Receipt: https://fetchsandbox.com/runs/fix-...?flow=...
- Remaining review: authorization, data migration, rollout safety
Enter fullscreen mode Exit fullscreen mode

The receipt does not replace code review. It narrows code review to what still needs human judgment.

The reviewer can now check architecture, maintainability, security boundaries, and whether the invariant represents the intended business rule. They do not have to infer whether the agent ever ran the failure it claims to have fixed.

How does the proof continue into CI/CD?

The pre-merge receipt and the CI workflow gate answer different questions. The receipt proves that one proposed diff changed a reproduced failure into the required behavior. CI keeps the provider workflow from regressing as the branch changes.

FetchSandbox's CLI produces structured JSON and exits non-zero when a normal workflow run fails:

- name: Run API integration workflows
  run: |
    npx fetchsandbox run "$FETCHSANDBOX_ID" --all --json \
      > fetchsandbox-workflows.json
Enter fullscreen mode Exit fullscreen mode

Store fetchsandbox-workflows.json as a build artifact and make the job a required status check when your team is comfortable with its coverage. The same workflow definitions can be explored locally through FetchSandbox MCP and run headlessly in the pipeline.

Today, the prove_fix receipt is attached to the pull request as a link. An automatic GitHub Action that posts the receipt and check result is not yet a shipped FetchSandbox feature, so do not describe that automation as live. The available path is explicit and auditable: prove through MCP, paste the receipt into the PR, and keep the provider workflows running in CI.

What does a proof receipt prove?

A FetchSandbox proof receipt proves the behavior shown on the artifact: the named scenario ran, the bug reproduced on the pre-patch code, and the measured invariant held or did not hold after the patch.

It does not prove that every requirement in the pull request is correct. It does not prove an untested security property, a safe database migration, or a production rollout plan. Good evidence has boundaries.

That is also why an unproven verdict is useful. “We could not reproduce this failure” tells the reviewer where the evidence ends. A confident green with no execution would be worse.

What changes when every pull request carries evidence?

The unit of review changes from a diff plus a confident summary to a diff plus a falsifiable result.

The coding agent can still generate quickly. The human still owns intent and risk. The verification layer owns one narrower job: make the provider failure happen, run the proposed fix against it, and preserve what happened in a receipt.

Cheap code is useful only when teams can qualify it for production without creating an equally large review queue. The next improvement in agentic software development is not another faster generator. It is a better way to say no to an unproven patch.

Connect FetchSandbox MCP to Cursor or Claude Code, run find_bugs → fix_bug → prove_fix, and attach the returned receipt to the next integration pull request. For broader workflow setup, see agent API workflow testing and API integration testing in CI.

Questions developers ask

Does passing CI prove AI-generated code is correct?

No. Passing CI proves only that the checks configured in CI passed. Verify that those checks exercise the relevant provider failure and assert the intended business state, not just an HTTP status or the absence of an exception.

Should the coding agent write its own tests?

The agent can write tests, but those tests should not be the only judge of its patch. Use independent scenarios, reviewed invariants, negative controls, or a separate verification system that can reject the agent's first answer.

Does FetchSandbox replace human pull-request review?

No. FetchSandbox supplies runtime evidence for API integration behavior. Humans still review intent, architecture, security, migrations, and rollout risk.

Can FetchSandbox automatically comment on every GitHub pull request?

Not currently. The shipped workflow returns a shareable proof receipt through MCP, which you can attach manually. The CLI can run workflows as a CI status check; automatic PR comments are planned rather than live.

What happens when FetchSandbox cannot reproduce the bug?

The proof declines to green. An unavailable or inconclusive scenario remains unproven instead of being reported as verified.

Top comments (0)