Henry Kobutra
← All notes
Notes

How to check an agent's work before accepting it

A small regression test, an acceptance record and a review routine for separating finished code from a convincing completion report.

An agent's final message can explain a change beautifully and still leave the important question unanswered: does the thing you asked for work?

I want enough evidence to accept the result without repeating the whole job. Reading a cheerful summary doesn't get me there. Neither does demanding a full audit of every typo.

This guide gives you a small acceptance routine and a runnable example of a test catching something a plausible fix could miss. You need Python 3.9 or newer, a terminal and a writable scratch folder. The example uses the standard library, invented data and no network access.

Decide what would count before the agent starts

Write the result as something you can observe. "Fix expiry" leaves room for disagreement. "An item is expired at its expiry timestamp, not one second later" gives you a boundary to check.

For the example files, the task is:

Outcome: expiry includes the exact deadline.
Inputs: integer timestamps in the same unit.
Scope: change expiry.py only; keep the regression test unchanged.
Checks:
- now=99, expires_at=100 -> False
- now=100, expires_at=100 -> True
- now=101, expires_at=100 -> True
Do not add packages, change clock handling or publish anything.
Return the changed file, command, exit code and observed results.

Those expected values come from the requirement, not from whatever the implementation happens to return. That distinction matters when the same agent writes the code and its tests. Both can agree on the wrong thing.

Use the acceptance template for your own task. Keep it short, but name the permission boundary. Preparing a patch and releasing it are different requests.

Make the failure visible

Copy the example directory into a scratch folder. From that copied directory, run:

python3 demo.py

The driver makes a temporary child directory, copies in the test and runs it against two implementations. It removes that child directory afterwards. It does not edit the example source files or need an agent account.

The buggy function uses now > expires_at. Two checks pass. At the exact deadline it returns False, so test_at_deadline_is_expired fails and that test process exits with code 1.

The corrected version uses now >= expires_at. The driver runs the unchanged test file again. All three checks pass and that process exits with code 0. The driver itself exits successfully only when it sees both expected results, including the specific boundary failure before the correction.

Read the test and the correction, not just the output. The correction is small enough to inspect directly. A test that passes after someone removes its assertion has excellent morale and very little else to offer.

The earlier failure is useful evidence: this test can distinguish the reported defect from the correction. A syntax error or missing dependency would not establish that. If the initial run fails for the wrong reason, repair the test setup before drawing a conclusion about the bug.

Review the change and its evidence together

For a real patch, start with the actual changed files, including new files. Check staged and unstaged work as well as the submitted revision. An agent can solve the stated bug and quietly alter something outside the task.

Before accepting a patch, I want answers to these questions:

  • Does each acceptance criterion have an observed result? A build passing says little about whether a form submits the right data.
  • Does the regression test exercise the behavior that failed? Check its assertions, skipped cases and fixtures. A test named after the bug is not necessarily a test of the bug.
  • Did adjacent behavior survive? Here that means before and after the deadline. Elsewhere it might mean an empty result, a denied permission or a retry.
  • Do the results belong to the files under review? Record the tested revision and local changes, plus the runtime and relevant configuration. Rerun affected checks after fixes.
  • Is anything still unverified? A missing browser check should remain missing in the report, rather than quietly becoming "tested."

Fit the checks to the consequence. For a UI change, exercise the affected journey, including keyboard use and a narrow layout where relevant. For an approved record update, read the exact record back from the system that owns it. For authorization code, include an operation that must be refused. None of those results follows from this Python example.

A separate reviewer can help with consequential changes. Give them the requirement, actual patch and evidence, rather than only the implementer's explanation. If independent review is unavailable, say that. Giving your own reread a different heading doesn't make it independent.

Leave an acceptance decision, not just a status

A useful handoff names the changed files, the tested snapshot, commands and outcomes, and anything still unchecked. Then the authorized person can accept it, return it for correction or hold it for missing evidence.

For this exercise, the boundary test supports the correction for three integer inputs. It says nothing about parsing dates, clock drift, concurrent requests or production token security. Those are separate requirements, not achievements hidden inside a green test run.

Keep that limit in the acceptance record. If another person picks up the work tomorrow, they should be able to tell exactly what passed and what still needs a decision.

A conversation starts somewhere

What are you
working on?

If something here connects with what you're working on, email me.

henry@kobutra.com