opsira

Change detection that fires on every deploy is worse than none

In short

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:

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.

The test that proves it

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.