Change detection that fires on every deploy is worse than none
A script that reports sixty changed pages when three changed is not a cautious script. It is a broken one, and it will quietly poison whatever it feeds.
The job was ordinary: notice which pages actually changed, so only those get pushed to a search engine as updated. Fetch each page, hash it, compare against last time.
It reported 65 of 105 pages changed after a deploy that touched three.
Why it happens
A modern framework build rewrites far more of the document than the part you edited:
- Asset filenames carry content hashes, so one changed stylesheet renames a reference on every page.
- Server-rendered frameworks embed a serialised payload of the page data in a script tag, and its formatting and identifiers move between builds.
- Build identifiers, nonces and generation timestamps appear throughout.
None of that is visible to a reader. All of it changes the hash.
The fix that does not work
The obvious response is a list of patterns to strip before hashing: asset hashes, nonces, build ids, timestamps. That was the first attempt. It reduced the noise and did not remove it, because the embedded payload is effectively unbounded in what it can contain. Every deploy that slipped through taught the same lesson slightly later.
The fix that does
Stop hashing the document. Hash what a reader would see:
main = extract(html, "<main>") # or <article>, or <body>
main = strip_tags(main, "script style template")
text = collapse_whitespace(strip_all_tags(main))
digest = sha256(text)
Build artefacts live outside that region or inside script tags, so they stop mattering by construction rather than by enumeration. Verify it by running a full rebuild with the cache disabled, deploying, and confirming the detector reports zero changes.
Rebuild from scratch, change nothing, deploy, and run the detector. If it reports anything above zero, it is still measuring your build system rather than your content.
Why false positives are expensive
Whatever consumes the signal treats it as a claim about your content. Push a change notification for every page every time you deploy and you are training the recipient to discount you. The same applies to a test suite that fails intermittently or an alert that fires on healthy states. A signal that is wrong most of the time is not a cautious signal, it is a signal being spent.
Need help with any of this?
These notes are free and always will be. If you would rather someone just set it up, or you are stuck on something similar, get in touch at hello@opsira.io.