How to validate AI-generated code: five layers in this site’s build
Revised September 16, 2026: the earlier article did not supply records for its tenfold claims, specific PR file and test counts, or claimed failure frequency. Those claims have been removed. It also described proposed compiler settings as universally enabled here. This version distinguishes the checked-in configuration from recommendations.
This site renders articles twice: React for visitors, and generated HTML for readers that do not execute JavaScript. Seeing new text in a browser does not establish that it appears in the initial response. That concrete failure boundary explains why the build needs output checks.
Layer one: what the compiler actually checks
The current tsconfig.app.json enables strict, noUnusedLocals, noUnusedParameters, noFallthroughCasesInSwitch, and noUncheckedSideEffectImports. It does not enable noUncheckedIndexedAccess or exactOptionalPropertyTypes. Those additional options should not be reported as existing controls.
{
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
}The latter options may be useful when reviewing dynamic indexing and optional properties, but adoption has a migration cost in an existing project. Type assertions can bypass some checks, and external JSON still needs runtime validation. Successful compilation is not evidence that the data is correct.
Layer two: configuration is not execution
The ESLint configuration extends recommended JavaScript, TypeScript, React Hooks, and React Refresh settings. There is an npm run lint command, but npm run build does not invoke it. Having a configuration file does not establish that every deployment passed its checks.
A mandatory rule needs an execution path, a decision about warnings, and a process for exceptions. A claim that all any types are prohibited is incomplete without checking the actual rule, scope, and existing failures.
Layer three: inspect the delivered HTML
The build generates and validates article data, runs TypeScript and Vite, creates localized and prerendered entrypoints, then checks content and publisher scope. check-prerendered-html.mjs reads the resulting files to detect missing routes, empty main content, and incorrect H1 counts. It examines the output rather than only the source component.
npm run articles:generate
npm run build
# Final output checks
node scripts/check-prerendered-html.mjs
node scripts/check-publisher-scope.mjsThe content-length check catches empty shells. It is neither an editorial quality score nor an AdSense word-count requirement. Human review is still needed to decide whether a page answers its reader’s question.
Layer four: make cross-page rules fail visibly
check-publisher-scope.mjs compares the sitemap, canonicals, noindex policy, and advertising scripts. Article pages expect one AdSense script; other pages should not load it. This is this site’s chosen scope, not a universal Google requirement.
Test the guard with a counterexample: add an advertising script to the homepage in a disposable build copy, then rerun the check. It should report advertising outside an article page. The download includes the checker source and reproduction steps. Do not inject faults into production.
Layer five: review the tests as well
Tests should encode requirements or existing contracts, not merely restate the current implementation. For example, the expected behavior for division by zero must be decided before rewriting a test to accept whatever the implementation returns. This is an illustrative example, not a recovered incident log.
Human review still needs to examine failure paths, compatibility with old data, duplicated logic, and changes to acceptance criteria. An HTML checker can catch advertising in the wrong place; it cannot decide whether a review has enough evidence.
Download the site verification materials and reproduction steps