A Human Workflow for Checking AI-Generated Code
Review AI-generated code against an explicit contract, trace permissions and data boundaries, design independent tests, and document the human acceptance decision.
By FindTheWeb Editorial

AI-generated code deserves the same accountable review as any other proposed change. The difficulty is that a polished explanation can make unfamiliar code feel understood before anyone has checked its behavior. A useful human workflow separates the intended contract, the actual diff, the failure cases, and the release decision. It works whether the assistant supplied three lines or a complete feature.
Write the contract before reviewing the solution
Describe the behavior in terms a reviewer can verify. For an endpoint that updates a saved collection, specify who may update it, which fields may change, what happens to unknown identifiers, and which response fields are public. Add a failure rule: if validation fails, no partial update should remain. This is a stronger review starting point than asking whether the implementation looks reasonable.
List the boundaries involved: browser to server, server to database, or server to an external service. Identify the sensitive data and permissions at each boundary. Keep production credentials, customer records, and unnecessary private context out of prompts and test fixtures. The reviewer needs representative inputs, not a copy of live user data.
- Define the behavior and permitted scope.
- Read the diff and inspect every changed dependency.
- Trace inputs, permissions, outputs, and failure paths.
- Run independent checks against the contract.
- Accept with recorded evidence, or return to the implementation step.
Establish what actually changed
Inspect the patch before running unfamiliar code. In a Git repository, these read-only commands show the working tree and staged changes. They do not install dependencies or execute the proposed application.
git status --short
git diff --stat
git diff --check
git diff -- .
git diff --cached -- .
The ordinary diff excludes untracked files and staged edits; the staged diff covers the latter. Use the status output to identify new files and open them explicitly. The whitespace check is a formatting aid, not a correctness or security test. Compare the changed paths with the requested scope, including configuration, database migrations, lockfiles, and automation files.
For an existing review branch, use the team's agreed base rather than assuming the working-tree diff represents the whole proposal. Large unrelated refactors make a behavioral change harder to assess. Request a smaller patch when the reviewer cannot explain why each affected area belongs in the change.
Trace one input through the whole implementation
Start with a concrete request and follow its values through parsing, validation, authorization, storage, serialization, and logging. Find the actual library call behind each abstraction. Check official documentation for the installed version when an API or option is unfamiliar. A plausible method name is not evidence that the dependency supports it.
GitHub's responsible-use documentation for Copilot Chat describes limitations of generated output. Its Copilot Agents application card also addresses review limitations, including missed problems and false positives. Use machine feedback as a list of hypotheses to investigate. A second model agreeing with the first does not establish the behavior of the program.
Check authorization separately from authentication
In the collection example, a valid session only identifies the caller. The update must also establish that this caller may modify this particular collection. Review where that decision happens and whether every route to the write passes through it. Include background jobs or alternate endpoints if they invoke the same operation.
OWASP's authorization guidance supports reviewing access checks as explicit application behavior. Create two synthetic users and one collection owned by the first. Verify that the second cannot read restricted fields, update the collection, or infer private information through a different response path. Choose denial responses according to the application's documented policy.
Keep data separate from executable structure
Inspect database access, shell execution, template output, and filesystem paths. They have different controls; an input validator cannot replace all of them. For database queries, OWASP's SQL injection prevention guide explains parameter binding. Check that values are bound through the database interface rather than interpolated into a query string.
If a feature permits sorting, parameters usually cannot stand in for a column identifier. Map accepted sort keys to fixed application-owned query choices. A parameterized query also does not grant permission to access its returned row. These are separate review questions, and both need an answer.
Design tests that can disagree with the assistant
Derive cases from the contract rather than copying the implementation's branches into assertions. For the collection endpoint, test an allowed update, another user's request, a missing identifier, an oversized field, an unexpected property, and a storage failure. Assert the resulting stored state and public response, not merely a successful status code.
Where practical, run the new regression case against the earlier implementation to show that it detects the intended defect. If it passes both versions, inspect whether the test actually reaches the relevant behavior. This check is useful for a bug fix, but it is not meaningful to demand an earlier failure for every new feature.
Use the repository's documented test and analysis commands in an isolated environment with synthetic data. Read install hooks and unfamiliar scripts before executing them. A formatter passing proves little about permissions; a scanner finding no issue does not prove the absence of vulnerabilities. Combine focused automated checks with manual reasoning about the application contract.
Scale the review to the consequence of failure
A wording change and a payment calculation do not need the same evidence. Authorization, billing, destructive operations, migrations, and credential handling deserve deeper review and, where available, a second qualified reviewer. For a small helper, focused examples and the existing suite may be sufficient. Explain the choice in terms of consequences and uncertainty.
OWASP's secure code review guidance is a useful reference for structuring that inspection. Read context around the modified lines: a locally safe function can still receive untrusted data through another caller or expose a sensitive result through serialization. Review effort should follow those boundaries, not the apparent confidence of the generated explanation.
Make acceptance a recorded human decision
- State the behavior accepted and the changed areas reviewed.
- Record which checks ran, their results, and any unavailable environment.
- Confirm permissions, failure handling, and response-field boundaries.
- Document new dependencies and unresolved assumptions.
- Identify the release owner, rollback approach, and signals requiring investigation.
After a revision, inspect the new diff and rerun checks affected by it. Do not carry forward an approval when the implementation has changed materially. If nobody can explain a sensitive branch, request a simpler implementation or obtain the missing expertise. The completion criterion is an understandable change supported by relevant evidence, with a human owner willing to accept the remaining uncertainty.