<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tony</title>
    <description>The latest articles on DEV Community by Tony (@thetonynotes).</description>
    <link>https://dev.to/thetonynotes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4205253%2F4988f6e5-0737-43ee-9de0-dab29922b4ab.jpg</url>
      <title>DEV Community: Tony</title>
      <link>https://dev.to/thetonynotes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thetonynotes"/>
    <language>en</language>
    <item>
      <title>Can You Trust Code You Didn't Write?</title>
      <dc:creator>Tony</dc:creator>
      <pubDate>Sat, 24 Oct 2026 23:34:34 +0000</pubDate>
      <link>https://dev.to/thetonynotes/can-you-trust-code-you-didnt-write-2e97</link>
      <guid>https://dev.to/thetonynotes/can-you-trust-code-you-didnt-write-2e97</guid>
      <description>&lt;p&gt;I'm Tony. I build and run web products, and Claude Code is my main development tool. A coding agent finishes implementing a feature, reports that everything is complete, and presents a summary of the changes. The code looks reasonable, the tests appear green, and you have another task waiting. But what exactly did the agent prove?&lt;/p&gt;

&lt;p&gt;Generating working code and verifying correct behavior are different engineering activities. I use a verification workflow that starts with observable acceptance criteria, checks the implementation at several levels, and records evidence before accepting a change. I'll walk through it using a TypeScript application with an admin interface and a multi-tenant API, including an authorization bug that ordinary tests can miss. You'll leave with a reusable verification checklist and a completed example showing what an acceptable evidence trail looks like.&lt;/p&gt;

&lt;h2&gt;
  
  
  A completed task is not a verified change
&lt;/h2&gt;

&lt;p&gt;A coding agent can produce a convincing implementation without establishing that it solves the original problem. It might modify the right files, follow the existing patterns, and run the available tests successfully. None of those results automatically establishes that the requested behavior works. They answer narrower questions.&lt;/p&gt;

&lt;p&gt;Consider four statements an agent might make:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Statement&lt;/th&gt;
&lt;th&gt;What it actually establishes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Implementation complete"&lt;/td&gt;
&lt;td&gt;The agent produced code it considers finished.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"TypeScript compilation passed"&lt;/td&gt;
&lt;td&gt;The compiler found no errors covered by that check.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"All tests passed"&lt;/td&gt;
&lt;td&gt;The executed tests passed under their configured conditions.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"The requested behavior works"&lt;/td&gt;
&lt;td&gt;Requires evidence that the implementation satisfies the acceptance criteria.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The difference matters because tests only exercise the scenarios someone anticipated. A passing authorization test might establish that a resource owner can access a document, while saying nothing about another authorized member or an unrelated tenant. A successful browser interaction might show text appearing in an editor without proving that the correct value was saved. Even a valid download can contain files with incorrect permissions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ku7d72mkd620a4h0okx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ku7d72mkd620a4h0okx.png" alt="The verification gap" width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think of this as a verification gap. The agent's final message belongs on one side; evidence that supports the product requirements belongs on the other. My responsibility is to close that gap, not merely decide whether the generated code looks plausible.&lt;/p&gt;

&lt;p&gt;The same distinction applies to human-written code, but agents change the amount of implementation a developer can produce without personally tracing every decision. That makes a disciplined acceptance process more important.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with an observable acceptance contract
&lt;/h2&gt;

&lt;p&gt;Before implementation, I want a short contract describing what the system must do and how we will know it works. This is not a complete specification or an elaborate test plan. It is a set of observable behaviors that can be checked independently of the agent's explanation.&lt;/p&gt;

&lt;p&gt;Imagine a pnpm TypeScript monorepo with the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apps/
  admin/              # React admin application
  api/                # Multi-tenant API
packages/
  ui/                 # Shared UI components
  shared/             # Shared contracts and utilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose the API serves multiple customer organizations. A resource can be associated with several groups, and users receive access through group membership. The requested change is to correct a permission check that incorrectly rejects some authorized users.&lt;/p&gt;

&lt;p&gt;Here is the acceptance contract I would give the agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Task:
Correct group-based access to shared resources.

Expected behavior:
&lt;span class="p"&gt;1.&lt;/span&gt; A member of any group attached to a resource
   can access that resource within the same tenant.
&lt;span class="p"&gt;2.&lt;/span&gt; A user outside all attached groups is denied.
&lt;span class="p"&gt;3.&lt;/span&gt; A user from another tenant is denied, even when
   group identifiers overlap.
&lt;span class="p"&gt;4.&lt;/span&gt; Existing resource-owner access remains unchanged.

Evidence required:
&lt;span class="p"&gt;-&lt;/span&gt; Focused authorization tests for all four cases.
&lt;span class="p"&gt;-&lt;/span&gt; A regression test where the authorized user
  belongs to the second attached group.
&lt;span class="p"&gt;-&lt;/span&gt; Confirmation that the regression test fails
  without the fix and passes with it.
&lt;span class="p"&gt;-&lt;/span&gt; A summary of changed files and remaining risks.

Constraints:
&lt;span class="p"&gt;-&lt;/span&gt; Preserve tenant isolation.
&lt;span class="p"&gt;-&lt;/span&gt; Do not change unrelated authorization behavior.
&lt;span class="p"&gt;-&lt;/span&gt; Do not modify tests merely to make them pass.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This contract specifies results rather than implementation details. I have not instructed the agent to use a particular SQL query, ORM method, or function structure. It can choose an approach that fits the existing code, but it cannot redefine successful completion as "the code compiles."&lt;/p&gt;

&lt;p&gt;The edge cases carry much of the value. Testing an owner and an unauthorized stranger is insufficient when access depends on several relationships. The important case is a user who belongs to a valid group that the previous implementation failed to consider.&lt;/p&gt;

&lt;p&gt;For a bug fix, I also provide the reproduction command, relevant stack trace when one exists, and steps needed to reproduce the behavior. I state whether the failure is intermittent. These details reduce guesswork and give the agent a concrete starting point.&lt;/p&gt;

&lt;p&gt;The principle is simple: define success before evaluating the implementation. Otherwise, the agent's solution can influence what everyone considers an acceptable test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ask the agent to implement, not declare victory
&lt;/h2&gt;

&lt;p&gt;I separate implementation instructions from acceptance decisions. The agent can inspect the repository, propose a solution, edit code, and execute tests. It can also identify missing cases and explain technical tradeoffs. But I do not treat its final assessment as independent evidence.&lt;/p&gt;

&lt;p&gt;For changes with unclear scope, I start Claude Code in plan mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude &lt;span class="nt"&gt;--permission-mode&lt;/span&gt; plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plan mode lets Claude read the project and propose an approach without editing files until approval. I use that boundary to examine assumptions, identify impacted modules, and check whether the proposed tests cover the acceptance contract. The plan is useful because it exposes decisions before implementation makes those decisions harder to notice.&lt;/p&gt;

&lt;p&gt;For the authorization example, I might use this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Inspect the shared-resource authorization flow.

Identify:
- How resources are associated with groups.
- Where tenant isolation is enforced.
- Which tests cover users with multiple group paths.
- Why membership in the second attached group fails.

Propose the smallest safe change and the tests
needed to verify it. Do not edit files yet.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After reviewing the proposal, I authorize implementation and ask for a report containing the actual commands and outcomes. I also ask the agent to identify missed edge cases. This makes the agent useful as an implementation partner without making it the final authority on correctness.&lt;/p&gt;

&lt;p&gt;An instruction in CLAUDE.md can require the agent to include test evidence in its response. That is a useful working convention, not an enforcement mechanism. The presence of a well-formatted report does not prove that the underlying evidence is valid.&lt;/p&gt;

&lt;p&gt;If the change moves in the wrong direction, Claude Code's &lt;code&gt;/rewind&lt;/code&gt; can restore the conversation and code to a checkpoint. That helps manage the implementation process, but it does not replace version control or acceptance testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify at different levels
&lt;/h2&gt;

&lt;p&gt;Verification works better when each check has a specific responsibility. Compilation, automated tests, browser interactions, and human review observe different properties of the system. Running more checks is not automatically better; choosing checks that cover different failure modes is what matters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcly680l6j9bmvdama7w3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcly680l6j9bmvdama7w3.png" alt="Verification layers" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Static checks: Is the change structurally valid?
&lt;/h3&gt;

&lt;p&gt;I start with the checks already defined by the repository. For a TypeScript project, these typically include type checking, linting, and build validation. They reveal broken imports, incompatible types, invalid code patterns, and some integration mistakes.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nt"&gt;-F&lt;/span&gt; api &lt;span class="nb"&gt;exec &lt;/span&gt;tsc &lt;span class="nt"&gt;--noEmit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command only makes sense when the workspace and TypeScript configuration support it. A successful result tells me that the relevant TypeScript checks passed. It does not establish that group membership is evaluated correctly or that the API returns the expected authorization decisions.&lt;/p&gt;

&lt;p&gt;I record which command ran, its exit status, and whether the check covers the changed code. "Static checks passed" is less informative than the exact command and result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Focused tests: Does the behavior match the contract?
&lt;/h3&gt;

&lt;p&gt;Consider this incorrect permission check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resourceGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findFirst&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;resourceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allowed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;group&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;isGroupMember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groupId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation checks membership against the first group returned by the database. If a resource belongs to groups A and B, a user belonging only to B can be denied access. The code compiles, and a test using a member of A might pass.&lt;/p&gt;

&lt;p&gt;The correction should ask whether there is at least one qualifying membership, not whether the user belongs to one arbitrarily selected group. One possible approach is a relational query that keeps the tenant condition within the authorization predicate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allowed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resourceGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;resourceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;memberships&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;some&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact query depends on the application's data model and ORM schema. Its essential property is that it evaluates all eligible relationships while preserving tenant boundaries. The surrounding authorization flow must still validate the user's tenant context and any additional access rules.&lt;/p&gt;

&lt;p&gt;The regression test is more valuable than a generic "authorized user succeeds" test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;allows a member of the second attached group&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createResource&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tenantA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;groupIds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;groupA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;groupB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tenantA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;groupIds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;groupB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;requestResource&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;resourceId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;asUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;createResource&lt;/code&gt;, &lt;code&gt;createUser&lt;/code&gt;, and &lt;code&gt;requestResource&lt;/code&gt; represent application-specific test helpers. A real implementation should use the repository's existing fixtures and request utilities, with deterministic setup that makes the relevant group ordering explicit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regression proof: Does the test detect the original bug?
&lt;/h3&gt;

&lt;p&gt;A passing test is useful. A test that fails against the broken implementation and passes against the correction provides stronger evidence that it detects the intended defect.&lt;/p&gt;

&lt;p&gt;One way to perform this check in a controlled working tree is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash push src/auth/permissions.ts
npm &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; permissions
git stash pop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sequence assumes the working-tree state, stash contents, and test command have been inspected first. The stash must actually restore the known broken implementation for the test to mean anything. It can also stash other uncommitted edits in the named file, so I would use a clean, isolated working tree rather than run it casually against active work.&lt;/p&gt;

&lt;p&gt;Notice another operational detail: combining the test and restore operations with &lt;code&gt;;&lt;/code&gt; allows the restore attempt to run even if the test fails. With three separate commands, I must explicitly execute the restoration after the expected failure and inspect the resulting working-tree state.&lt;/p&gt;

&lt;p&gt;The evidence I want is specific: the regression test fails for the expected authorization reason without the fix, then passes with the correction restored. A failure caused by missing fixtures, invalid imports, or environment setup is not proof that the regression test detects the original bug.&lt;/p&gt;

&lt;p&gt;The repository might use pnpm instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nt"&gt;-F&lt;/span&gt; api &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; permissions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I use the command that matches the actual project rather than changing package managers simply to match an example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Browser checks: Does the user see the correct result?
&lt;/h3&gt;

&lt;p&gt;API tests do not establish that the browser handles state correctly. A common case is automation entering text into a rich-text editor built with DraftJS-style or React-managed state. The text becomes visible, but the application saves a default value because the submitted content lives in parent component state.&lt;/p&gt;

&lt;p&gt;A screenshot of the editor would look correct while the saved record would be wrong. The appropriate fix is to update the value through the component's supported &lt;code&gt;onChange&lt;/code&gt; mechanism, then save and read back the persisted content. The verification target is the reopened or fetched record, not merely the visible text before submission.&lt;/p&gt;

&lt;p&gt;For the authorization example, a browser check can establish that an authorized member can open the shared resource and an unauthorized member receives the intended denial. That user-facing result complements the API tests without replacing them.&lt;/p&gt;

&lt;p&gt;I cover browser automation patterns in more detail in the article on browser testing with Playwright in this series.&lt;/p&gt;

&lt;h3&gt;
  
  
  Human review: Does the behavior make sense?
&lt;/h3&gt;

&lt;p&gt;Automated checks can establish consistency with written expectations. They cannot decide whether those expectations fully reflect the product's intended policy. A developer still needs to evaluate whether the change introduces unintended access, violates an architectural boundary, or relies on an assumption the tests never challenge.&lt;/p&gt;

&lt;p&gt;For authorization code, I examine query scoping, user identity, tenant ownership, and any caching that might retain stale permissions. I also look for inconsistent behavior between endpoints using the same permission model. Those concerns are part of engineering review, not defects a green test suite automatically rules out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review the diff against the original intent
&lt;/h2&gt;

&lt;p&gt;After executing the checks, I return to the original acceptance contract and inspect the actual diff. The question is not simply whether I understand the implementation. I want to know whether every change serves the requested behavior.&lt;/p&gt;

&lt;p&gt;For the authorization fix, the intended scope is narrow: correct membership evaluation and add meaningful coverage. A change that also modifies authentication middleware, restructures tenant resolution, or removes failing assertions deserves separate justification. Scope expansion increases the number of assumptions I need to verify.&lt;/p&gt;

&lt;p&gt;My diff review focuses on five questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Which behavior changed?&lt;/strong&gt; Identify the precise condition that produces a different result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which files changed, and why?&lt;/strong&gt; Look for unrelated formatting, generated files, or dependency updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which assumptions did the implementation introduce?&lt;/strong&gt; Check group ordering, nullable relationships, tenant context, and error handling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which failure paths remain untested?&lt;/strong&gt; Consider cross-tenant requests, absent memberships, deleted groups, and resource ownership.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Did the tests become weaker?&lt;/strong&gt; Look for removed assertions, permissive mocks, skipped cases, or fixtures changed to avoid failures.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Another useful example is generating a downloadable ZIP package. The download can succeed, contain the correct files, use the expected version, and pass a secrets check. Yet its setup script might lose the executable bit because the ZIP library does not preserve Unix file modes.&lt;/p&gt;

&lt;p&gt;After extraction, this result is wrong:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-rw-r--r-- scripts/setup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the script directly produces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./scripts/setup.sh: Permission denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a package where scripts are expected to run directly on Unix, a packaging rule can assign mode &lt;code&gt;0755&lt;/code&gt; to files beginning with &lt;code&gt;#!&lt;/code&gt; and &lt;code&gt;0644&lt;/code&gt; to ordinary files. Verification should then inspect the extracted archive, not just the source directory.&lt;/p&gt;

&lt;p&gt;The expected extracted permission is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-rwxr-xr-x scripts/setup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example demonstrates why a passing pipeline can still miss an important delivery requirement. The implementation artifact must be checked in the form and environment where someone actually uses it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give every result an evidence trail
&lt;/h2&gt;

&lt;p&gt;I prefer a compact verification report over a long transcript of everything the agent attempted. The report should let another developer understand the requested behavior, identify the executed checks, reproduce important results, and see what remains uncertain. It should also distinguish the agent's statements from recorded observations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ku3rfh79zgqv5oqmf23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ku3rfh79zgqv5oqmf23.png" alt="Claims backed by evidence" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following is a completed example for our fictional authorization fix. The paths and outcomes illustrate what a report should contain; they are not claims that these commands were executed against a real repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;agent-change-verification.md&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Agent Change Verification&lt;/span&gt;

&lt;span class="gu"&gt;## Task&lt;/span&gt;
Correct group-based access to shared resources.

&lt;span class="gu"&gt;## Acceptance criteria&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [x] Member of any attached group is allowed.
&lt;span class="p"&gt;-&lt;/span&gt; [x] Nonmember is denied.
&lt;span class="p"&gt;-&lt;/span&gt; [x] User from another tenant is denied.
&lt;span class="p"&gt;-&lt;/span&gt; [x] Existing owner access remains unchanged.

&lt;span class="gu"&gt;## Files changed&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; src/auth/permissions.ts
  Replaced first-group lookup with membership query.
&lt;span class="p"&gt;-&lt;/span&gt; src/auth/permissions.test.ts
  Added second-group and tenant-isolation cases.

&lt;span class="gu"&gt;## Checks executed&lt;/span&gt;

| Check | Result | Evidence |
|---|---|---|
| TypeScript check | PASS | typecheck.log |
| API permission tests | PASS | permissions-test.log |
| Regression without fix | EXPECTED FAIL | regression-red.log |
| Regression with fix | PASS | regression-green.log |
| Focused diff review | PASS | review-notes.md |

&lt;span class="gu"&gt;## Expected vs observed&lt;/span&gt;
Expected:
A user in group B can access a resource shared
with groups A and B within the same tenant.

Observed:
The API returns 200 for the group B member.
The regression test fails with the original
first-group logic and passes with the fix.

&lt;span class="gu"&gt;## Unverified scenarios&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Concurrent group membership changes.
&lt;span class="p"&gt;-&lt;/span&gt; Cache invalidation after permission updates.
&lt;span class="p"&gt;-&lt;/span&gt; Browser-level permission error presentation.

&lt;span class="gu"&gt;## Known limitations&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Tests use a local test database.
&lt;span class="p"&gt;-&lt;/span&gt; Production data distribution was not reproduced.
&lt;span class="p"&gt;-&lt;/span&gt; No performance evaluation of the new query.

&lt;span class="gu"&gt;## Human review decision&lt;/span&gt;
APPROVED FOR REVIEW, NOT DEPLOYMENT.

Reason:
Acceptance tests pass and regression behavior
is demonstrated. Query execution characteristics
and cache behavior require separate review.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The report does not need to claim absolute confidence. Its value comes from making the evidence inspectable and showing where the evidence stops. In a real repository, the referenced logs and review notes should exist, correspond to the tested revision, and be accessible to the reviewer.&lt;/p&gt;

&lt;p&gt;I find it useful to rank evidence by what it establishes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The agent says the task is complete.&lt;/li&gt;
&lt;li&gt;A command executes without error.&lt;/li&gt;
&lt;li&gt;Relevant tests pass.&lt;/li&gt;
&lt;li&gt;A regression test fails without the fix and passes with it.&lt;/li&gt;
&lt;li&gt;The resulting behavior is read back from the system where the user actually encounters it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is an ordering of evidence strength, not a replacement for evaluating test quality or requirement coverage. A read-back confirms a particular observed result; it does not establish that every untested condition is safe.&lt;/p&gt;

&lt;p&gt;For write operations, I like tools that return both &lt;code&gt;verified&lt;/code&gt; and &lt;code&gt;evidence&lt;/code&gt;. The first indicates whether post-action verification succeeded. The second explains what the system returned when the tool read the result back.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deleteResource"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"evidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/resources/example-id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the write tool deleted a resource and then performed a separate read. A successful delete request alone would not provide equivalent evidence. The observed 404 supports the claim that the resource is no longer retrievable at that endpoint, assuming the read uses the appropriate identity and tenant context.&lt;/p&gt;

&lt;p&gt;For pull requests, I can use &lt;code&gt;gh pr create&lt;/code&gt; to connect a Claude Code session with a PR and reopen that session using &lt;code&gt;claude --from-pr &amp;lt;number&amp;gt;&lt;/code&gt;. The PR then becomes a practical place to review the diff, attach test evidence, and ask Claude to flag risks. The review decision still belongs to the people responsible for accepting the change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Know when the workflow is insufficient
&lt;/h2&gt;

&lt;p&gt;A verification checklist helps make acceptance consistent, but it cannot compensate for missing requirements or an environment that fails to represent production behavior. Authorization, billing, data migration, destructive operations, and sensitive-data handling deserve closer attention because incorrect behavior can have consequences beyond a single feature.&lt;/p&gt;

&lt;p&gt;Weak test coverage also changes how much confidence I assign to a passing suite. If the application has no realistic integration environment, no tenant-isolation fixtures, or no way to inspect persisted changes, the verification report should say so. The correct response is to identify the missing evidence, not lower the acceptance criteria until everything appears green.&lt;/p&gt;

&lt;p&gt;I also separate new failures from existing failures. If an unrelated test was already failing, I do not edit it, skip it, or change its expectations just to produce a green result. I document the failure in the PR, explain why it appears unrelated, and leave the decision visible to reviewers.&lt;/p&gt;

&lt;p&gt;Some decisions remain fundamentally human. Whether two groups should share access to a sensitive resource is a product and security policy question before it is a query implementation question. An agent can implement the stated rule and test that implementation, but the team must decide whether the rule is correct.&lt;/p&gt;

&lt;p&gt;The workflow I use is therefore not "make the agent pass every check." It is to define observable expectations, collect independent evidence, review the change against its intent, and explicitly record what has not been established. That process makes code written by an agent easier to understand, verify, and maintain.&lt;/p&gt;

&lt;p&gt;This is the foundation of &lt;em&gt;Making Coding Agents Reliable&lt;/em&gt;, a six-article series about practical workflows for working with AI coding agents. The next article covers CLAUDE.md and Skills, including how to make project instructions useful without confusing instructions with enforcement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the one check you never skip before accepting an AI-generated change?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>claudecode</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
