An AI-built page can load and still be unsafe to publish. A narrow screen can break the layout, a keyboard path can trap a user, metadata can point to the wrong URL, or a working build can sit beside unresolved type errors.
A useful review connects one fixed code revision to observable evidence and a release decision. This tutorial shows how to do that with code checks, browser evidence, accessibility checks, metadata, links, and repeated performance runs. It also shows how to record a hold when the evidence remains incomplete.
Fix the candidate before you collect evidence
Start with an exact revision, route, and environment. Record the commit identifier, parent commit, package versions, browser version, Node.js version, and the URL that you will test. If the code changes during the review, the prior evidence describes an older candidate.
Define the release claim at the same time. A focused claim can be “the new mobile artwork loads at the intended breakpoint, the desktop artwork remains in place, the print packet stays together, and existing metadata and links remain valid.” This claim is specific enough to test. It does not promise that the whole website is correct.
A basic command record can start like this:
git rev-parse HEAD
node --version
pnpm --version
Save the command output with the review date. If the runtime does not match the repository declaration, record the mismatch before you run other checks. A green result from a different runtime can still help with diagnosis, but it is weak release evidence.
State what changed and what remained intact
Use the source diff to make two short lists. The first list contains the intended changes. The second list contains behavior that the release should retain.
For a responsive image change, the changed list can include a new mobile asset, the selection breakpoint, and print rules. The retained list can include the desktop asset, alt text, caption, canonical URL, Open Graph fields, article text, CTA, and internal destinations. This separation prevents the review from checking only the new code while missing a regression in existing behavior.
The source diff establishes which files and lines changed. It does not prove that a browser selected the right asset or that the retained metadata reached the rendered HTML. Use rendered evidence for those claims.
Use each evidence type for a specific job
Different evidence answers different parts of the release decision. Combining the types is useful, but they are not interchangeable.
Scroll sideways to see all 3 columns.
| Evidence | What it can show | What it cannot show by itself |
|---|---|---|
| Source diff | The files, code paths, and declared scope of the revision | The final browser state |
| Test assertions | The behavior encoded in component, service, or route tests | Visual quality or behavior that no test covers |
| Browser trace | The action sequence, DOM snapshots, sources, requests, console output, and screenshots during a run | Complete human review or all assistive-technology behavior |
| Screenshot | The visible state at one viewport and one moment | DOM semantics, the complete keyboard order, or other viewport sizes |
| Audit output | A tool result under a recorded version and configuration | A general guarantee for production users |
| Rendered metadata | The title, description, canonical URL, social fields, and structured data present in HTML | How every external platform will index or display the page |
Playwright Trace Viewer can show actions, DOM snapshots, source, network activity, console messages, errors, and attachments from a test run. A trace is valuable when a reviewer needs to reconstruct the browser path. Keep the trace with the exact revision and the test result that produced it.
Screenshots and trace snapshots have different uses. A screenshot is easy for a person to inspect. A trace snapshot can show the DOM around an action and help diagnose a failure. Retain both when the visual state and the action sequence matter.
Run repository checks before browser review
Run the repository’s defined checks before opening the page. This order catches syntax, formatting, type, test, and build failures before browser evidence becomes the focus.
A common sequence is:
pnpm run format:check
pnpm run lint
pnpm exec tsc --noEmit
pnpm exec vitest run <focused test files>
pnpm run test
pnpm run build
Record the command, exit code, warnings, and tool version. Keep focused tests and the full suite as separate entries. Focused tests show that the changed path has direct coverage. The full suite checks for effects outside that path.
Do the same for type and build results. A framework build can pass while a separate TypeScript command reports errors in test files or scripts. Preserve both results. Do not replace the failed result with the build summary.
Exercise the rendered paths on desktop and mobile
Use a production build when practical. Load the changed route at a desktop width and a small mobile width. Record the HTTP status, final URL, viewport, selected assets, document width, console output, failed requests, and responses with an error status.
Check the behavior that the change claims to protect. For a responsive image, inspect the browser’s currentSrc value instead of assuming that the <source> element worked. For a responsive packet, compare element positions to confirm a two-column desktop layout and a one-column mobile layout. Check for horizontal overflow and retain targeted screenshots.
These screenshots came from a local production build and show one moment at each tested viewport. They do not establish behavior at every width, browser, or physical device.
Exercise real interaction paths with the keyboard. The minimum set for an article page can include the skip link, navigation, search, heading links, and the final CTA. Confirm that focus moves to a useful target, controls expose clear names and states, and Escape closes temporary interfaces where expected.
Use the trace to preserve the action sequence. Use targeted screenshots for visual review. A trace can help explain a failed path, while a screenshot can show whether labels, borders, and text were clipped at the tested width.
If the change affects print, generate a PDF with print media enabled. Inspect page boundaries and extract the relevant page text. A screen screenshot with print styles can show the compact layout, but the PDF is better evidence for pagination.
Treat an accessibility scan as partial evidence
Run an automated accessibility scan on the changed page or relevant region at both viewports. Playwright’s accessibility-testing guidance shows how to use axe-core in a test and how to scan a specific page region.
Automated tools find only some accessibility problems. Playwright’s documentation says that manual assessment is still necessary. Record violations, passed rules, and incomplete checks. An incomplete color-contrast check is a manual review item, even when the violation count is zero.
Add keyboard review and, before a significant release, a screen-reader check. For changes that affect a mobile layout, use at least one real mobile device when possible. The automated result and the manual result should remain separate in the record.
Check metadata and links in rendered output
Next.js supports static metadata, generated metadata, and file-based metadata. Its metadata and Open Graph documentation also explains static and generated social images. The release check should inspect the output that the candidate actually renders.
Record the page title, meta description, canonical URL, robots value, Open Graph title, Open Graph description, Open Graph URL, Open Graph image, Twitter card, and structured data types. Compare each value with the intended retained state. A source-level metadata function is useful context, but the final HTML is the stronger check for the candidate.
Collect unique internal links from the rendered page and request each destination against the same production build. Record the destination, final status, and redirects. Review the CTA destination separately because a successful response does not prove that the CTA text and destination match the reader’s next task.
Repeat Lighthouse runs under matching conditions
Lighthouse performance data is lab data. Chrome’s performance scoring documentation explains that the score uses weighted metrics and that conditions such as the device, network, and page resources can cause results to vary.
Record the Lighthouse version, browser version, URL, form factor, screen emulation, throttling method, network values, CPU slowdown, and host warning. Run the same candidate more than once. A score without its conditions is weak evidence.
Compare the underlying metrics as well as the score. In Lighthouse 10, Total Blocking Time has a 30% weight, Largest Contentful Paint and Cumulative Layout Shift each have a 25% weight, and First Contentful Paint and Speed Index each have a 10% weight. A change in one weighted metric can move the score even when another metric remains stable.
Repeated candidate runs can show variability under the recorded lab setup. They cannot establish an improvement over the prior revision. To make a performance-change claim, test the parent and candidate under the same stable conditions and repeat both sets.
This is a candidate-only repeat. The connected points show run sequence, not a before-and-after performance claim. Do not label either point “before,” “after,” “baseline,” or “improved.”
A versioned sample shows why the record matters
For this tutorial, we reviewed BaristaLabs commit 0932aab09bd10d44a79df817fafa8ca52a644810, with parent d34dc87042dfa9bea61702fc02f066f72c8348c2. The change added a dedicated mobile image and adjusted mobile and print layouts for the article “The AI workflow handoff note before approval.” The review used the exact candidate in a detached worktree and a local production build.
The diff showed seven changed files, 237 insertions, and nine deletions. It added a 900 × 1200 mobile SVG, selected it at a maximum width of 639 px, added responsive and print styles, changed receipt-packet class names, and expanded tests. The desktop SVG, article markdown, alt text, caption, canonical URL, and CTA destinations were outside the intended change.
The repository checks produced a mixed result
The original formatter command exited successfully with warnings in pre-existing audit files. Lint passed. The three focused test files passed, the full suite passed, and the production build passed its compile, TypeScript, static generation, content validation, and post-build checks.
The follow-up recreated the exact parent and candidate in separate detached worktrees and ran both with Node.js 22.23.2 and pnpm 10.28.1. Format, lint, focused tests, the full suite, and production build exited 0 on both revisions. The parent reported 203 passing test files and 1,538 tests; the candidate reported 203 passing test files and 1,540 tests. Standalone tsc --noEmit --pretty false --incremental false still exited 2 with 39 diagnostics on each revision. Matching by file, diagnostic code, and complete message classified all 39 candidate diagnostics as parent/pre-existing, with no parent-only or candidate-only diagnostic.
The rendered checks supported the narrow layout claim
The desktop and mobile routes returned HTTP 200. The desktop browser selected the existing 1400 × 820 image. The mobile browser selected the new 900 × 1200 image. The retained alt text and caption matched, the mobile document had no horizontal overflow, and the receipt panels changed from a desktop row to a mobile column.
The skip link moved focus to the main content. Search opened from the keyboard, focused its input, and closed with Escape. The mobile navigation opened from the keyboard, showed its first link, and closed with Escape. The run recorded no console errors, console warnings, failed requests, or error responses.
The print packet used break-before: page and break-inside: avoid. A generated 11-page Letter PDF placed the complete packet on page 4. That page contained both comparison panels, all six fields, the decision line, and the caption.
Accessibility and performance evidence remained limited
The original axe-core run reported zero violations and 24 passed rules at both viewports. It also returned one incomplete color-contrast rule with serious impact because axe could not resolve text over gradients.
The follow-up inspected all 10 desktop and 12 mobile incomplete nodes. For each node it retained the foreground color, hid only the glyphs, sampled every background pixel across the element, and compared the lowest computed ratio with the applicable WCAG AA threshold. Every node passed. The lowest result was the mobile “Read the approval queue guide” link: #e8d5b7 over worst-case #5a3820, 7.24:1 against a 4.5:1 requirement.
Two sequential Lighthouse 13.4.1 mobile runs used the same URL, 412 × 823 screen emulation, simulated 150 ms network round-trip time, 1,638.4 Kbps throughput, and 4× CPU slowdown. The performance scores were 90 and 97. First Contentful Paint stayed at 1.4 seconds, Largest Contentful Paint moved from 2.3 to 2.5 seconds, Total Blocking Time moved from 330 to 70 milliseconds, and Cumulative Layout Shift stayed at zero.
The first run warned that the host CPU appeared slower than Lighthouse expected. The recorded benchmark index also changed from 967 to 1,697 between runs. The seven-point score range is useful evidence of run variability. It is not evidence that the candidate improved performance because the parent revision was not tested.
Write the release decision in the same record
A concise review record should contain these fields:
Candidate revision:
Parent revision:
Route and claim:
Environment and tool versions:
Changed behavior:
Retained behavior:
Commands and exit codes:
Rendered desktop and mobile results:
Keyboard results:
Accessibility violations, passes, and incomplete checks:
Metadata and link results:
Performance settings and repeated metrics:
Trace, screenshot, report, and PDF locations:
Known gaps:
Decision: approve, hold, or revise
Decision owner:
Next required check:
For the versioned sample, the 2026-08-03 decision was correctly hold. The 2026-08-10 follow-up resolved each named gate: Node.js 22.x checks were repeated, all 39 diagnostics were demonstrated to be parent/pre-existing, all axe-incomplete contrast nodes passed manual review, and the desktop heading permalink showed a visible two-layer focus ring after 16 Tab presses. The editorial packet is therefore ready for publication with the limits below.
The record supports claims about the exact tested revision and conditions. It does not prove complete accessibility, production reliability, search ranking, conversion, or business impact. Those claims require different evidence.
Limits that remain after the follow-up
No screen-reader or physical mobile-device test ran. The rendered review used a local production build; it did not test CDN behavior, deployed headers, analytics delivery, or third-party production services. Search engines and social platforms were not asked to recrawl the page. The candidate-only Lighthouse repeats do not establish a performance improvement. The review contains no customer outcome, conversion result, or production-incident evidence.
Use the record as part of the approval workflow
For a deeper performance evidence example, read The Lighthouse run that earns a place in your AI workflow receipt. Use the AI agent receipt template to keep the revision, action, evidence, and owner together.
The AI workflow controls page helps teams define approval and rollback boundaries. For changes that touch sensitive data, credentials, forms, or third-party services, use the AI workflow security review worksheet before release.
BaristaLabs can also help with the implementation and review path through AI-assisted website development. Bring the candidate revision, current evidence, and open decision to the first review so the work starts from facts.
Implementation review
Review one AI-built website change from revision to release decision
BaristaLabs helps teams verify code, rendered behavior, accessibility evidence, metadata, links, and performance limits before a website change is published.
Bring the exact revision, preview or build, known failures, and the claim the change is expected to support.
Turn this idea into a pilot
Which workflow should go first?
Use the readiness check to compare impact, effort, risk, owner, and next step before booking a call.
- 3-5 minutes
- Deterministic score
- No sensitive data
Practical AI Workflow Notes
Want more practical AI operations ideas?
Get short notes on applying AI inside real small-business workflows — from document handling and customer follow-up to internal reporting, compliance, and automation guardrails.
