No automated accessibility violations
blocker
a11y
Run axe over every template and fix everything it reports. Treat a clean run as the starting line for the manual checks below, not as evidence of accessibility.
Done when: axe reports zero violations at the WCAG 2.1 A and AA rule sets across the sampled pages, including one page with a form and one with a listing.
Why this rule exists, and how to satisfy it
JavaScript and CSS stay inside their budgets
blocker
perf
Assert a gzip budget per chunk in the build and fail the build when it is exceeded. Raising a budget is allowed, in the same commit, with a written note saying what the extra bytes bought.
Done when: The budget test passes, or a raised budget is accompanied by that note in the commit. Without repository access this is reported as unverified, never as a pass.
Ships in wp-starter/bundle-size-test - import it rather than rebuilding it.
CLS at or under 0.1
blocker
perf
Reserve space for everything that arrives late: width and height on every image and video, explicit dimensions on embeds and ads, and font fallbacks metric-matched to the web font.
Done when: Median mobile CLS is 0.1 or less, and no visible shift occurs during a slow-network reload watched by eye.
LCP at or under 2.5 seconds on mobile
blocker
perf
Identify the LCP element before touching payload. It is usually being discarded rather than loading slowly - an element that finishes loading while hidden is dropped permanently, and opacity zero, clip-path and overflow hidden are all treated the same way. You cannot fade in your largest above-the-fold element and have a fast LCP.
Done when: Median of three or more mobile runs is 2.5s or less, and the identified LCP element is stated in the report alongside the number.
Why this rule exists, and how to satisfy it
HTTPS is enforced and nothing loads over http
blocker
seo
Redirect http to https in one hop and make sure no stylesheet, script, image, font or iframe has a hard-coded http:// URL. These usually arrive with migrated content, not code.
Done when: http:// returns a single 301 to https://, and no sampled page contains an http:// asset URL.
Automated check: seo-status:https-redirect, seo-status:mixed-content
Production is indexable and staging is not
blocker
seo
Drive the noindex decision from the environment, never from a checkbox someone has to remember. Staging returns noindex on every response; production returns none.
Done when: The production home page carries no noindex in the meta robots or the X-Robots-Tag header, and its robots.txt does not disallow the whole site. Staging carries noindex everywhere.
Automated check: seo-status:home-index, seo-status:robots
Why this rule exists, and how to satisfy it
Replaced URLs redirect to their new home
blocker
seo
Only when the project replaces an existing live site.
Export the old site's indexed URLs before launch and map each one to its replacement with a 301. Anything with no equivalent goes to the nearest parent, not to the home page in bulk.
Done when: Every URL on the old-site list returns 200 or a single 301 to a 200. No mass redirect to the home page. Spot-check the twenty highest-traffic URLs by hand.
Why this rule exists, and how to satisfy it
The page survives 200 percent zoom and a 320px viewport
required
a11y
Set text-only zoom to 200 percent and check nothing clips or overlaps. At 320 CSS pixels wide there must be no horizontal scrolling of the page body.
Done when: At 200 percent zoom no content is lost or overlapping, and at 320px wide the page scrolls vertically only.
Every template produces valid HTML
required
html
Run the W3C validator over a sample covering every template, not just the home page. Unclosed elements and duplicate ids break assistive technology and JavaScript long before they look wrong.
Done when: The validator reports zero errors on the sampled pages. Warnings are read and either fixed or noted with a reason.
Static assets are compressed and cached far-future
required
perf
Confirm what the host actually sends rather than assuming. Some hosts compress nothing, in which case every estimate made from a gzipped size is wrong. Fingerprinted assets take a one-year immutable cache header.
Done when: Content-Encoding is br or gzip on HTML, CSS and JS, and hashed assets carry a cache lifetime of a year with immutable.
Why this rule exists, and how to satisfy it
TBT at or under 200ms and INP at or under 200ms
required
perf
Keep the main thread free during load. Defer non-critical scripts, break long tasks, and keep third-party tags off the critical path.
Done when: Median mobile TBT is 200ms or less. Where field data exists, INP at the 75th percentile is 200ms or less.
Nothing render-blocking that does not have to be
required
perf
Scripts are deferred or type module. Only above-the-fold CSS is render-blocking. No synchronous third-party script in the head. No font stylesheet from another origin blocking first paint.
Done when: The render-blocking resources audit lists nothing beyond the site's own critical stylesheet.
Mobile performance score at or above 90
required
perf
Treat the score as a summary of the metrics above, not a target of its own. Chasing the number rather than the metric is how a site ends up fast in a lab and slow for people.
Done when: Median of three or more mobile runs is 90 or above, quoted with the spread of the runs.
Why this rule exists, and how to satisfy it
Production loads with a clean console
required
practices
Clear every error and warning, remove debug logging, and make sure no asset 404s. A console full of noise is where the next real error goes unnoticed.
Done when: Loading each sampled page and navigating between two of them produces no console error, no unhandled rejection and no failed network request.
The project ships with the notes needed to run it
required
practices
Write down how to build and deploy it, where the environment values live, which plugins are load-bearing, what was deliberately left out, and the indexability decision for filters. One page in the repository, not in a chat thread.
Done when: Someone who has never seen the project can build, run and deploy it from that page alone.
Anything animated or video-driven is checked on a real device
required
practices
Open the site on a real iPhone and a real mid-range Android. Simulators do not reproduce Safari's video behaviour, momentum scrolling, or the cost of an animation on a slow GPU.
Done when: Every page with entrance animation or video is opened on a real phone in a fresh private tab, and scrolling stays smooth with video playing.
The layout holds at every width, not just the design widths
required
practices
Drag the window slowly from 320 to 2560 and watch for overlap, clipping, orphaned words and horizontal scroll. Designs are drawn at three widths; visitors use every width.
Done when: No horizontal scrollbar at any width from 320 up, no clipped or overlapping content, and no layout that only works at the exact design breakpoints.
No internal link is broken
required
seo
Crawl internal links before handover. Broken links usually come from content entry and trailing-slash mismatches, not from templates, so this has to run against real content.
Done when: A crawl of the sampled pages returns no 404 and no 5xx on internal links, and no chain of more than one redirect.
Automated check: seo-status:link-ok, seo-status:link
Third-party scripts are counted and justified
recommended
perf
List every third-party origin the page loads and what it is for. Load analytics and chat after interaction or after load. Anything nobody can name an owner for comes out.
Done when: The third-party summary is reviewed, each origin has a stated purpose, and their combined main-thread time stays under 250ms.
Performance and behaviour changes ship one at a time
recommended
practices
Deploy one change, verify it, then start the next. Never widen a change while debugging it. Two changes in one deploy means neither result is attributable.
Done when: Each performance claim in the handover names the single change it came from and the before and after measurement.