oneshotlm
← Blog
Blog

What coding agents actually check

A coding agent says it has tested the app in a browser. You open it anyway, click the buttons, change the inputs, and check it yourself. You delegated verification, but still cannot tell which parts of the result you can rely on.

To make that decision, you need a way to trace the agent's report back to its actions and observations. Knowing what was checked, and what remains uncertain, helps you choose where to spend your own testing time.

Using recorded runs from oneshotlm, we look at three questions about browser verification, then consider how agent developers can make the answers easier to find.

  1. Does the report match what actually ran?
  2. Did the checks exercise the features that matter?
  3. Do the checks cover the revised app?

Does the report match what actually ran?

In a Rubik's Cube built by Gemini 4 Argon, the final response said the agent had tested mouse-wheel zoom. The browser log tells a more limited story: the tool rejected an action named wheel during input validation. No later record shows a successful retry using a scroll action.

01 / REPORT & EVIDENCERubik’s Cube · Gemini 4 Argon

A “tested” claim needs execution evidence

Trace the completion report back to what actually ran.

Recorded execution
  1. Action requestedaction: wheelAn attempt is recorded.
  2. Rejected by the toolInput validation failed.
  3. Zoom remains unverifiedNo successful scroll retry is recorded.
Evidence gapNo recorded result supports the claim that zoom was tested.
Completion report
Mouse-wheel zoom
was tested
Paraphrase of the final response.
Saved run, shown schematically. The tool rejected the action; no successful zoom check is recorded.

The evidence supports an attempt to use the wheel. It does not show that the action ran or that the cube zoomed. It also does not establish whether the zoom feature itself was broken.

For each check in a completion report, there are three distinct stages:

  1. The agent requested an action.
  2. The tool completed without an error.
  3. The agent observed the expected result.

A failed check, or one with an inconclusive result, gives the next person a place to start. The useful question is which execution record supports each claim in the report.

See the Gemini Rubik's Cube run

Link completion reports to execution records

An agent runtime can assign identifiers that connect verification items to tool results. The system executing the tool should retain the action and its execution status, so a report can point back to that record. Judgments about the expected result should reference observations or test results as well.

For example, if the tool rejects a wheel-zoom action, that attempt should remain unverified rather than appear among the report's successful checks. Even if the tool completes successfully, the observation that zoom actually occurred needs its own record. A person or another process can then inspect the evidence behind the claim.

Tool errors can also make recovery easier. In this run, the validation response repeated the same generic message about a value not matching a constant. Returning the supported action name and an input example would give the agent a more useful next step. A redesigned error response might look like this:

Unsupported action: wheel
Use scroll for mouse-wheel input.
Example: {"action":"scroll","delta":300}

This is a proposed response, not the one returned in the run. Anthropic similarly recommends giving agents specific, actionable guidance when tool input validation fails. Writing effective tools for agents

Did the checks exercise the features that matter?

A Brick Breaker game built by Ling 3.1 Flash shows why it helps to move beyond the initial screen.

An early browser check reported an error involving a method in the Phaser game library. The agent edited the code and reloaded. The console's error lines disappeared, and the extracted screen text showed a score of 0 and LAUNCH.

The agent then pressed Space. The status changed to PLAYING. As it continued observing the game, the score reached 10 and a different error appeared:

brick.disableBody is not a function

Fixing the loading error had exposed another problem on the gameplay path. The agent removed the failing method call, reloaded, and used Space and a drag action again. The next results showed a score of 10 without that error. After it pressed R, the display returned to a score of 0, three lives, and LAUNCH.

02 / USER PATHBrick Breaker · Ling 3.1 Flash

The next interaction reveals a different bug

  1. 1 Reload after initial fix
    LAUNCHSCORE 0
    No console error lines
    Initial-screen check ends here
  2. 2 Press Space; observe play
    PLAYINGSCORE 10
    A new error appears
    brick.disableBody
    is not a function
  3. 3 Fix, reload; Space + drag
    RECHECKSCORE 10
    That error does not recur
  4. 4 Press R to reset
    LAUNCHSCORE 0LIVES 3
    Initial values return
Schematic of recorded states, not game screenshots. The initial screen did not expose the error on the gameplay path.

Continuing into gameplay revealed a bug that was absent from the initial screen. The text records do not establish that the ball's reflection angles, or the game as a whole, were correct.

Web apps have similar paths that only run after a save, deletion, retry, or navigation. Compare the paths that were exercised with the features you need. Paths that were not reached, or whose results were not recorded, are candidates for further testing.

See the Ling Brick Breaker run

Define checks as actions with expected results

One way to track coverage is to turn important requirements into a starting state, an action, and an expected result. This makes a feature's acceptance criteria concrete enough to check.

Starting stateActionExpected result
Before a game startsPress SpaceThe game enters its playing state
A game is in progressResetScore and lives return to their initial values
An arpeggiator is playing with three notes selectedAdd one noteThe selection and playback status both show four notes

Record the action's execution status separately from whether the expected result held. Clicking a Save button does not, by itself, establish that anything was saved. Where possible, compare DOM values or application state against explicit assertions. Playwright, for example, provides assertions that wait for an element's text to match an expected value. Playwright Assertions

Keep the underlying requirements too. When AI writes both the implementation and its tests, changing an expected value to fit the implementation is a separate decision. Reviewing changes to expected results separately from implementation changes makes it easier to understand what a passing test establishes.

Playwright's Trace Viewer is a useful reference for making the checking process inspectable. It lets you examine DOM snapshots and screenshots around actions to investigate where a result diverged from expectations. There is a distinction worth preserving: the lower-level context.tracing API does not record assertions. Use Playwright Test's tracing when you also need the test's assertion results. Trace Viewer, Tracing API

Do the checks cover the revised app?

An Arpeggiator built by MiniMax M3.1 Flash offers a traceable example of a display inconsistency and a subsequent fix, even though the console reported no errors during the affected interactions.

When the agent added a note during playback, the selection showed four notes while the playback status still said three. After it deselected every note, the selection showed zero while the status still said four.

The agent added code to update the status when the selection changed. After reloading, starting playback, and adding a note again, both displays showed four notes.

ObservationSelected notesPlayback status
Add a note before the fix43
Deselect all notes before the fix04
Start playback and add a note after the fix44

The record includes an observed problem, a corresponding code change, and another interaction afterward. The expected result—agreement between the selection count and status—makes the before-and-after comparison concrete. This table does not establish what happened when all notes were deselected after the fix, or whether the audio was correct.

There is also the question of which revision was checked. In the Rubik's Cube run from the first section, the agent changed a value passed to the rotation function from 14 to 6 after its last successful browser interaction. The saved log contains no browser observation after that change.

03 / REVISION COVERAGETwo recorded sequences

Did a check follow the last edit?

ArpeggiatorMiniMax M3.1 Flash
  1. Observe a mismatchSelection: 4 · status: 3
  2. Edit the codeUpdate status when the selection changes.
  3. Reload and repeat the actionStart playback; add a note.
  4. Observe the revised appSelection: 4 · status: 4
Post-edit observation recordedEvidence for this particular check.
Rubik’s CubeGemini 4 Argon
  1. Use the browserLast successful browser interaction.
  2. Edit the code afterwardRotation argument: 14 → 6
  3. Finish the runThe revised app is delivered.
  4. No post-edit observationThe saved log ends without a recheck.
Final revision unverifiedThis does not establish a bug.
Order of events from the saved runs. A recheck supports the specific result observed; a missing recheck leaves a gap, not a failure verdict.

That does not prove the change introduced a bug. It establishes an ordering: the final edit came after the last recorded browser observation. When taking over an app, you need to know both what was rechecked and whether the check applies to the version you received.

See the Arpeggiator run

Tie observations to the version the browser loaded

For a single-file HTML app like these examples, a runtime could record a hash of the HTML passed to the browser alongside the actions and observations. Comparing it with the delivered HTML would show which revision the checks covered.

The relevant content is what the browser actually loaded. Hashing the current file afterward is insufficient if the browser still has an earlier revision open. A Git commit ID alone also misses uncommitted changes. For larger web apps, the deployed build and execution environment need to be identified too.

A matching version does not establish that a feature passed. It does help prevent results from an older revision being carried over to the final app without justification. If the connection cannot be established, leave verification of the final version marked as unknown. If the app demonstrably returns to a version that was already checked, there is no need to repeat every action mechanically.

Make verification useful to the next person

Together, the three questions point to a practical requirement for completion reports: a claim that something was checked should lead back to the feature requirement, execution result, and app version.

Here is one possible record format, using the Arpeggiator example:

FieldExample
Check and expected resultAdding a note during playback makes both the selection and status show four notes
Action and execution resultAdd a note; the tool completed successfully
Observation and judgmentSelection: 4; status: 4; matches the expected result
App versionHash of the HTML the browser loaded, or a build ID
EvidenceReferences to the corresponding tool result, assertion, or trace

Keep execution records on the tool side and judgments attached to observations or tests, then let the model's report reference them. Leave missing information marked as unknown. That gives someone reviewing the report a way to inspect its claims and choose what to check next.

Asking an agent to report the actions it actually performed, their results, and anything left unverified is a useful starting point. Agent developers can go further by making those connections part of the runtime.

A separate QA agent is another option to explore. Anthropic has described separating implementation from evaluation, then simplifying the setup as models and tasks changed. An evaluator can still make mistakes, so expected results and execution evidence remain necessary. Harness design for long-running application development

These are design ideas drawn from the runs, not interventions whose effectiveness we measured. Start with an important user path and ask whether the report can be traced to the action, expected result, and version. With those connections in place, a person can identify gaps in the evidence before repeating every interaction.

The examples are individual runs, not a ranking of the models' overall performance.