AI Coding Workflow With Verifiable Evidence
Use an AI coding workflow that turns issue contracts, tests, diffs, review findings, and release checks into evidence instead of confident summaries.

The safest useful AI coding workflow is a closed evidence loop. Define the observable change and authority boundary, preserve the starting state, inspect before editing, make the failure reproducible, let the agent produce a narrow diff, run deterministic checks, review the final diff against the contract, and keep release evidence. Stop whenever the task needs new permissions, hidden product decisions, unavailable verification, or an irreversible external action.
That workflow does not make generated code trustworthy by default. It makes unsupported confidence easier to detect. Each stage leaves an artifact a reviewer can challenge without reconstructing the entire chat.
The Evidence Packet
Before discussing tools, decide what a completed task must contain.
| Artifact | What It Proves | What It Does Not Prove |
|---|---|---|
| Issue contract | The requested behavior and constraints were stated | The requirement is the right product decision |
| Starting-state record | The branch and existing changes were known | The repository was otherwise healthy |
| Inspection map | The agent found relevant paths and local rules | It found every hidden dependency |
| Failing proof | The defect or missing behavior is reproducible | The proposed fix is correct |
| Final diff | The exact implementation can be reviewed | Runtime behavior in every environment |
| Command log | Named checks ran with visible results | Untested conditions are safe |
| Review record | Findings were resolved or explicitly rejected | Human approval can be removed |
| Release proof | The intended artifact reached the intended environment | Users experienced no later failure |
| Uncertainty log | Known gaps were not hidden | Unknown gaps do not exist |
I want this packet even when an agent writes only a few lines. The size of the diff is not the same as the size of its consequence. A one-line permission change or comparison operator can matter more than a generated component.
Start With An Issue Contract
An agent cannot implement intent that exists only in somebody's head. Write the contract before it reads the code.
Use observable language:
Behavior:
When a signed-in user submits an empty display name, the API returns the
existing validation error shape and does not write a profile update.
Must remain true:
- valid display names still update
- authorization behavior does not change
- the existing error schema remains compatible
Scope:
- inspect the request handler, validator, service, and relevant tests
- edit only files required by the demonstrated failure
- add no dependency
Proof:
- preserve or add a failing request test before the fix
- run the focused request tests
- run the package type check and full test command
Stop:
- do not migrate data, change production, call external services, commit, or push
- ask if the repository defines empty names differently elsewhere
The contract separates outcome, invariants, scope, proof, and authority. A user story alone usually does not.
I also name ambiguity. Is whitespace-only input empty? Are Unicode spaces normalized? Does an older client depend on the current error code? If the product has not decided, the agent should not silently choose whichever behavior makes the function easiest to write.
Match Permissions To The Task
OpenAI's current account of running Codex safely describes sandboxing, approvals, network controls, and logs as separate parts of governed agent use. That is the right mental model for any coding agent. A prompt is not a filesystem boundary, and a polite instruction is not a network policy.
Grant the smallest environment that can produce the required proof:
| Task Need | Reasonable Boundary |
|---|---|
| Repository explanation | Read access only |
| Local source fix | Write access to the worktree, no production credentials |
| Dependency research | Approved network destinations, no secret files |
| Database integration test | Disposable test database with isolated data |
| Migration rehearsal | Ephemeral environment and rollback plan |
| Production change | Separate explicit authorization and human-owned runbook |
Do not hand a local validation task a production token because the integration might be convenient. If a broader permission becomes necessary, pause and redefine the task boundary. That is a new decision.
The same rule applies to paid APIs and messages sent to other people. Technical capability does not imply authority.
Preserve The Starting State
Record the branch, revision, and worktree status before an edit. Existing changes may belong to another task or person.
git branch --show-current
git rev-parse HEAD
git status --short
If the worktree is dirty, identify which files predate the run and whether the task may touch them. Do not let an agent clean the tree by discarding unknown work. If safe isolation is available, use a separate branch or worktree.
This baseline answers a question that appears after many messy sessions: did the agent create that change, or merely find it?
I would also record the package and runtime versions relevant to the required checks when the repository does not lock them. A test result without the environment that produced it may be difficult to reproduce later.
Inspect Before Editing
Ask the agent to build a change map. It should locate:
- repository instruction files that apply to the working directory;
- the entry point where the behavior begins;
- validation, authorization, persistence, and external boundaries;
- an existing neighboring implementation worth following;
- focused tests and the broader package checks;
- generated files or migrations that should not be hand-edited;
- uncertainties that require a product or infrastructure answer.
The Codex agent loop is an iterative exchange between model output, tool calls, tool results, and another inference. That mechanism lets an agent search and run commands. It does not guarantee the search found the right boundary. Review the inspection map before allowing a broad edit.
Repository-specific guidance helps. An AGENTS.md file can tell the agent which commands run from which directory, where generated state lives, and what actions require a stop. It should reduce guessing, not replace source inspection.
Make The Failure Visible First
When fixing a bug, preserve a reproduction before changing the implementation. A failing automated test is ideal because it can rerun under the same contract. A minimal script, exact request, captured error, or deterministic manual sequence can work when the system is not testable at that layer.
The proof should fail for the reason named in the issue. A test that crashes during setup has not reproduced a validation defect. A browser screenshot without inputs or environment details may be hard to challenge.
For new behavior, write an acceptance test or at least an explicit input-output example first. You are trying to prevent the agent from redefining success around whatever it happened to build.
Close the obvious escape hatches in the prompt:
Preserve the assertion that demonstrates the required behavior.
Do not skip, delete, weaken, or replace the test to obtain a pass.
If the expected behavior conflicts with existing tests, stop and explain the conflict.
Sometimes the existing test is wrong. That is a real possibility, not permission to edit it silently. A changed contract needs review.
Let The Agent Make A Narrow Change
Ask for the smallest coherent implementation, not the fewest characters. A narrow fix may still require a validator, test, and shared type. What it should not include is unrelated formatting, dependency upgrades, speculative refactoring, or regenerated output with no explanation.
I like file boundaries in the initial prompt, but I do not pretend I always know the correct files. The agent can request an expansion after inspection. That request should name the newly discovered dependency and why the original scope cannot satisfy the contract.
During the edit loop, run the cheapest relevant check first. A focused test gives fast feedback. Once it passes, move outward to the package's required suite, type check, lint, build, integration check, or other repository-specific proof.
Do not let the agent repeatedly patch around an unexplained failure. After a failed command, require a diagnosis tied to the output. Three unrelated guesses are a signal to stop and inspect assumptions, not a reason to grant more autonomy.
Use A Verification Ladder
Verification should widen from the changed behavior toward the release surface.
| Layer | Question | Example Evidence |
|---|---|---|
| Reproduction | Did the named failure become a pass? | Focused test output |
| Neighbor behavior | Did nearby supported behavior remain intact? | Module or request suite |
| Static contract | Are types, formatting, and lint rules satisfied? | Type check and lint output |
| Package behavior | Does the owning package still work? | Full package tests and build |
| Integration boundary | Does the change work with real interfaces? | Disposable integration test |
| Release artifact | Is the built artifact the code that was reviewed? | Revision, image digest, or artifact identifier |
| Runtime check | Does the deployed behavior answer the contract? | Scoped smoke test and logs |
Not every task needs every layer. A documentation correction does not require a database rehearsal. A schema migration deserves much more than a unit test.
Report unavailable checks as unavailable. A missing service, dependency, credential, or platform can be a valid limitation. It cannot be turned into a pass by writing "should work."
The command record should include the exact command and exit status. Preserve relevant output without dumping secrets or unrelated environment data into a public log.
Review The Final Diff, Not The First Attempt
Generated fixes can introduce new bugs. Review the exact final files after the last edit and last test run.
Start with the task contract:
- Does the diff implement the named behavior?
- Are the invariants preserved?
- Did scope expand for a supported reason?
- Does every new branch have proportionate proof?
- Are auth, money, deletion, privacy, migration, retry, concurrency, and external side effects handled where relevant?
- Is any required artifact missing from the diff?
Then ask a fresh reviewer for material findings with file, line, failure path, and smallest verification step. OpenAI's current Codex guidance calls agent code review an additional reviewer rather than a replacement for human review. Keep that boundary. A model can search for defects. It cannot own an unstated product decision or accept operational accountability.
Resolve findings one by one. Re-run the affected check after a fix, then re-run downstream checks that depend on it. A green result from an earlier draft is no longer evidence for the changed file.
Build A Release Proof
Passing local checks does not prove production received the reviewed artifact. Connect the reviewed revision to the release.
A useful handoff records:
Task:
[issue or contract identifier]
Reviewed source:
[branch and revision]
Checks:
[commands, exit status, relevant summary]
Artifact:
[build identifier, image digest, package version, or deploy revision]
Deployment:
[environment and rollout result]
Smoke check:
[request or user path, expected result, observed result]
Monitoring:
[logs, alerts, or metric relevant to the change]
Rollback:
[known safe reversal or reason rollback is not available]
Unverified:
[remaining conditions]
The exact fields depend on the system. The invariant is traceability from contract to source, source to checks, checks to artifact, and artifact to observed environment.
Never describe a deployment as successful when only the command accepted the request. Wait for the rollout condition and run the scoped behavior check. A healthy process can still serve the wrong build.
Stop Conditions Belong Inside The Workflow
An agent should stop before its authority or evidence runs out.
| Stop Condition | Why The Run Pauses | Next Decision Owner |
|---|---|---|
| Product behavior is ambiguous | Code cannot choose the intended rule honestly | Product or task owner |
| Required test cannot run | Completion lacks its named proof | Maintainer or environment owner |
| New dependency is necessary | Supply-chain and maintenance scope changed | Repository owner |
| Migration or data repair is needed | Data risk exceeds a local source edit | Database owner |
| Production credential is required | Environment authority changed | Operator |
| Destructive or irreversible action appears | Recovery may be impossible | Explicit human approver |
| External message, purchase, or paid call is needed | The task now affects people or money | Account owner |
| Unrelated user changes overlap | Ownership of the diff is unclear | Change owner |
This table is not a list of permanent bans. It identifies where a fresh authorization or contract is required.
Scale The Proof With Consequence
I do not want the same ceremony for every change. An evidence loop becomes theater when a typo needs a migration-style packet, and it becomes reckless when a payment change receives only one unit test. The workflow should expand where a failure becomes harder to detect, reverse, or contain.
I use four questions to set the depth:
- Can the wrong behavior harm money, access, privacy, or durable data?
- Can the change escape the repository through a deploy, message, purchase, or external API?
- Can a failure hide until a retry, race, clock boundary, or uncommon input occurs?
- Can the system return to the old state without data repair or customer action?
A low-consequence copy correction may need the exact file, link check, build, and rendered review. A request validator needs boundary cases and its package suite. Authorization needs cross-user tests and a human trace through the policy. A migration needs upgrade, compatibility, data-shape, rollback or forward-repair evidence, plus an operator who owns the release.
The key is to write the ladder before the agent optimizes for whatever check is easiest to run. I would rather approve a smaller proof explicitly than receive a giant report that quietly omits the only risky boundary.
Keep Some Decisions Human-Owned
Agents are useful at repository search, mechanical implementation, test generation, failure diagnosis, and diff review. I still keep a person responsible for several decisions.
The task owner decides whether the stated behavior is worth building. A maintainer decides whether the design fits the system's future cost. A domain owner decides rules involving money, access, privacy, or legal obligation. An operator decides when a release has enough evidence and whether rollback is viable. These roles may be the same person on a small project. The ownership should still be explicit.
I do not ask an agent to approve its own expansion of authority. If it discovers that a local code fix needs a production query, that discovery is valuable. The next action belongs to whoever controls production. If it decides a test is obsolete, it can present the conflict and proposed new contract. The owner decides whether the requirement changed.
This is also why I keep reviewer findings and editor changes separate on substantial work. A fresh reviewer should report evidence and uncertainty. One editor applies accepted fixes while preserving the task contract. Otherwise five eager reviewers can turn a coherent change into a pile of locally reasonable edits nobody evaluated together.
Record Rejections, Not Just Passes
Accepted changes teach less than rejected ones if the record keeps only green commands. I want a short reason when a plan, diff, finding, or verification result is rejected.
Examples include:
- plan rejected because it changed the public error schema;
- dependency rejected because the standard library covers the bounded task;
- test result rejected because the agent altered the assertion;
- reviewer finding rejected because the named branch is unreachable under the validated type;
- deployment claim rejected because the rollout showed an older revision;
- completion withheld because the integration service was unavailable.
These notes sharpen future repository instructions. If agents repeatedly choose the root test in a package that requires another command, add the working-directory rule to AGENTS.md. If they keep reaching for live configuration, document the manifest source of truth and reinforce it with permissions. The workflow should compound what the repository learns.
I would not store every thought from a long chat. Keep decisions that changed scope, evidence, or acceptance. Those are the pieces a later reviewer needs when asking why the final diff looks the way it does.
A Worked Hypothetical Example
Consider a hypothetical webhook handler that creates two fulfillment rows when the provider repeats one event. The example is not a claim about a real system.
The weak prompt says, "Make webhooks idempotent." The agent might add a cache, suppress an exception, or trust an event field the database does not constrain.
The evidence workflow starts differently:
- The contract states that two deliveries with the same verified event identifier produce one fulfillment and return the existing success response.
- The baseline records the branch and existing migration state.
- Inspection traces signature verification, event parsing, transaction boundaries, uniqueness constraints, retries, and the fulfillment write.
- A test sends the same fixture twice and observes two rows before the fix.
- The plan chooses a persistence-level uniqueness boundary plus explicit duplicate handling, if that matches the repository and database contract.
- The focused test passes, then concurrency, request, migration, and package checks run as required.
- Review asks what happens when two deliveries arrive together, when the first transaction rolls back, and when the same identifier appears under another provider account.
- A disposable migration rehearsal proves upgrade and rollback behavior.
- The release record ties the reviewed revision to the deployed artifact and checks duplicate delivery in a safe environment.
Notice where the hard work lives. It is not typing an if statement. It is defining identity, finding the persistence boundary, reproducing delivery, testing concurrency, and proving which artifact ran.
Common Ways The Loop Breaks
The Agent Writes Before It Understands The Path
The diff fixes a local symptom while bypassing validation, authorization, or persistence behavior elsewhere. Require the inspection map.
The Test Is Changed To Match The Code
The suite turns green while the original requirement disappears. Preserve the assertion and review test diffs as product code.
A Summary Replaces Command Evidence
"All tests pass" contains no command, environment, or output. Keep the actual result.
The Final Review Looks At An Old Diff
A finding is fixed, but the fix creates another bug and never receives review. Restart downstream gates after edits.
Local Success Becomes A Production Claim
The build passed, so the report says the feature is live. Connect revision, artifact, rollout, and smoke evidence.
Autonomy Expands Quietly
A local code request becomes a dependency install, network call, data edit, or deploy. Stop where authority changes.
AI Coding Workflow Questions
How Is AI Coding Done?
An AI coding agent receives instructions and repository context, asks to use tools such as file search, editing, and shell commands, reads the results, and repeats that loop until it returns control. The broader AI coding agents guide explains that mechanism. The workflow in this article surrounds the loop with contracts, boundaries, tests, review, and release evidence.
What Are The Seven Steps Of Coding?
There is no universal official seven-step sequence that fits every software task. Planning, implementation, testing, deployment, and maintenance are often summarized into neat lists, but a migration and a CSS copy fix need different evidence. Use the stages required by the risk and repository instead of forcing every change into a memorable number.
What Is The Best AI Coding Workflow Tool?
The best tool is the one that follows your repository rules, operates inside permissions you can grant, and leaves enough evidence for the task's risk. Test candidates on the same fixture. Do not choose from a feature list alone.
Do Famous Founders Prove A Coding Workflow Works?
No. Questions about whether Elon Musk or Mark Zuckerberg coded, or what somebody scored on a school exam, do not validate an engineering workflow. They are unrelated to whether your task contract, diff, tests, and release proof are sound. This article makes no biographical claim because those questions add nothing to the decision.
Keep The Loop Closed
An AI coding workflow is complete only when the result can be challenged. The issue says what should change. The baseline preserves ownership. Inspection finds the system boundary. A failing proof anchors the behavior. The diff shows what changed. Tests and review expose mistakes. Release evidence connects source to the running artifact. Uncertainty remains visible.
If one of those links is missing, say so. A transparent gap can be resolved. A confident summary that hides the gap is much harder to repair.
Related Articles

Claude Code Tutorial: One Verified Change
Follow a Claude Code tutorial that inspects, plans, edits, and verifies one small repository change with exact checkpoints and test evidence.

AI Coding Agents, Explained by a Dev Who Ships With Them
What AI coding agents actually are, how they work, what they genuinely nail, and where they confidently break, from a dev who ships real apps with them.

MCP Server Explained: Build One and Wire It to Claude
What an MCP server is, a minimal Python server you can run, the Claude Code command to register it, and the failure modes that make a first server go silent.