Field note
What to check on a live site when nothing is supposed to have changed
A site that nobody edited is not a site that did not change. Templates ship, plugins update, tags get added by someone in marketing, and a service page quietly acquires a new claim. This is what to capture at launch so that the next check compares something.

On the fixture built for this article, the services page changed between two
captures while every date attached to it stayed still. The sitemap still
reported lastmod=2026-05-04. The response still carried
last-modified=2026-05-04. Only the entity tag moved, from "a41f-5b2" to
"c07d-1e9".
That is the mechanism worth naming before anything else. RFC 9110 calls these
validator fields, and it is explicit that Last-Modified "is unsuitable for
use as a validator when the resource changes more than once per second or the
clock granularity is less precise", while an entity tag is "an opaque
validator for distinguishing between multiple representations of the same
resource". Dates describe intentions. Validators describe representations. A
site nobody edited is not a site that did not change.
So the useful question after launch is not what to check but what to compare. Recurring QA that repeats the launch ceremony produces the same forty rows every month and gets cancelled by the third invoice. Recurring QA that compares two captures produces a short list of things that moved, and a shorter list of things that moved and matter.
| Surface | What you capture | How you compare | Change that matters | Change that does not | Trigger to act |
|---|---|---|---|---|---|
| Routes and pages | The reachable route list | Set difference | A route nobody owns | A route you shipped | Unowned route appears |
| Forms | Action, method, field names | Field by field | A new field collecting more | A relabelled field | Fields or action change |
| Metadata and canonicals | Title and canonical per route | String compare | A canonical pointing elsewhere | Punctuation in a title | Canonical host or path moves |
| Public claims | Claim sentences, by page | Sentence set difference | A claim nobody can evidence | A rewritten sentence | Any new claim |
| Privacy behaviour | Requests before a choice | Ordinal position | A request that was not there | A reordered known request | Count rises above the baseline |
| Structured identity | The entity block fields | Field by field | Name, URL or logo disagreeing with the page | Whitespace | Any field diverges from the page |
| Third party dependencies | Script hosts and digests | Host and digest compare | A host absent at launch | A version bump you approved | New host, or a digest with no expectation |
Routes and pages
Routes arrive without anyone deciding they should. A campaign landing page, a duplicated template, a preview route that escaped. The launch capture is the only thing that makes the difference visible, because on a live site every route looks equally intentional.
Sitemaps help and mislead in equal measure. The protocol defines lastmod as
"The date of last modification of the page" and warns that it "must be set to
the date the linked page was last modified, not when the sitemap is
generated". It is also optional, and a generator that stamps build time
produces a file that says everything changed on Tuesday.
Comparing routes
Take the set difference in both directions. Additions get an owner or get removed. Disappearances are the more interesting half: a route that vanished without a redirect is a link somebody else is still holding.
Forms
A form is the highest consequence surface on most sites and the one least
likely to be looked at again after launch. In the fixture, the contact form
gained a company field between captures. Nobody announced it.
Comparing the form
Compare the action, the method and the field names, not the rendering. A new field means new data arriving somewhere, and the question that follows is where it lands, not whether it validates. A changed action means the whole delivery path has to be walked again.
Metadata and canonicals
Titles drift harmlessly. Canonicals do not. The fixture's services page moved
its canonical from https://www.example.test/services to
https://example.test/services, which is a different host making a different
statement about which URL is authoritative.
Comparing metadata
Compare canonical values as exact strings, host included. A canonical that changed subdomain is a finding; a title that gained an ampersand is not. Keep the two in separate columns so the second never buries the first.
Public claims
The service page in the fixture acquired the sentence "winner of three national awards" between captures. No document arrived with it. This is the surface that drifts through people rather than through deployments, and the one an agency is most likely to be asked about later.
Comparing claims
Hold a claim inventory from launch and diff the sentences, not the pages. Any new claim is a trigger, because the only interesting question about a claim is who can evidence it, and that question does not answer itself over time.
Privacy behaviour
The fixture recorded zero requests before a choice at launch and one afterwards. That is a technical observation about a fixture and nothing else. It is not a conclusion about anyone's obligations, and this article does not make one.
Comparing the load order
Compare counts and ordinal positions against the launch baseline rather than absolute times, which vary per run. A request that was not there is the finding. A known request that moved two places is usually the page loading differently, not the site behaving differently.
Structured identity
The entity block is the one surface where nothing changing is itself a finding. In the fixture it did not move at all, while the canonical did, which means the machine readable identity now disagrees with the page about which host the organisation lives on.
Comparing the entity block
Diff the entity fields against the page copy, not only against the previous capture. Crawler access belongs in the same check: RFC 9309 requires the rules to be "accessible in a file named '/robots.txt' (all lowercase) in the top-level path of the service" and says crawlers "SHOULD NOT use the cached version for more than 24 hours", so a disallow added quietly propagates without any deployment you would recognise.
Third party dependencies
The highest consequence drift of all, because it arrives from outside your release process entirely.
dependency: / script=https://cdn.partner.test/widget.js integrity=noneEstablishesA script from a host absent at launch is now requested, with no integrity expectation declared.
Does not establishWho added it, what it does, or whether the delivered file is what its publisher intended.
Synthetic fixture capture.
Comparing the dependency list
Compare hosts first, then digests. Subresource Integrity exists for exactly the second half: it "defines a mechanism by which user agents may verify that a fetched resource has been delivered without unexpected manipulation", on the reasoning that "Compromise of a third-party service should not automatically mean compromise of every site which includes its scripts". A script with a declared digest has an expectation attached to it. A script without one has a URL and a hope.
| Artifact | Captured when | Stored where | Useless without |
|---|---|---|---|
| Route list | Launch day | The handover folder | A date and a build id |
| Form definitions | Launch day | Beside the route list | The delivery evidence |
| Metadata and canonical set | Launch day | Same folder, one file | Exact strings, not screenshots |
| Claim inventory | Launch day | The claims sheet | The evidence column |
| Dependency list with digests | Launch day | Same folder | Host names, not tag names |
- Routes reconciled, new route ownedPASS
- Form fields unchangedWATCH
- Canonical host stableWATCH
- No claim without evidenceFAIL
- Requests before a choice at baselineFAIL
- Entity block agrees with page copyWATCH
- Every third party script carries a digestFAIL
That sheet is an output, not an entry gate. It is what one comparison produced on one fixture, and every mark on it came from a difference between two captures rather than from a rule applied to today's page.
The cadence is yours to set, and the product is deliberately plain about what it does here. "Every scan is started by you." "Completed scans are runs you started, kept for comparison." "Compare two completed scans to see score and finding changes." "A comparison needs two completed scans and compatible data." "Launch Audit includes one re-scan after the initial completed scan, with no expiry deadline." "Use monthly scan credits when your team is ready."
Which leaves the section nobody writes. Most months, the comparison finds nothing. Routes match, fields match, canonicals match, no claim arrived, no host appeared. The temptation is to pad the report until it looks like work, and that is the single fastest way to lose the retainer, because padding is obvious and it teaches the client that your findings are negotiable.
Send the comparison instead. Two captures, the date of each, the surfaces compared, and the sentence that says nothing on those surfaces moved. That document is worth more than a month of findings, because it is the only kind of evidence that lets a client say, later and with a straight face, that they knew what their site looked like in July.
Provenance
- Written by
- Balaji PonnambalamFounder, AgencyProof
- Technical review
- Written and self-reviewed against the codebaseAgencyProof is a one-person engineering team; there is no second reviewer to claim.
- Published
- Evidence basis
- Examples in this article are synthetic fixtures built for the explanation.
Every product claim in an article is checked against the AgencyProof source tree before publication, and traced to the code path that implements it. Where the article describes a method rather than a shipped behaviour, it says which it is.
Related reading
Agency Field NotesHow to record a client's decision to launch with a known issue
Sometimes the authorised owner ships with a known issue. Record the evidence, the consequence and the check date.
Launch ManualThe redirect map a redesign needs before the new site goes live
A replacement site can strand campaign links, bookmarks and old service URLs. Build the redirect inventory first.
Agency Field NotesHow to turn invisible QA work into a client-facing deliverable
The client does not need the raw scanner dump. They need the decision, the material risks, and the evidence behind them — structured in three reading layers.