A date in a comment is not a date
A simple decision: no article on this site carries a date. A dated article ages; the same text without a date stays valid. The rule was applied by hand to four articles — then we remembered that a rule applied by hand only protects on the day you apply it.
1. The check we should not have written
The first version was one line: look for date patterns in the file. It would have worked. It would also have flagged seventy-six perfectly compliant pages.
Because seventy-six of our pages contain a date — inside an HTML comment, recording when a decision was made and by whom. That is code memory, invisible to a visitor, and valuable: it is what stops someone six months from now deleting an oddity whose reason they no longer understand.
And the page listing the articles carries, on every card, a date attribute used for sorting. Also invisible, and functional: removing it would break the display order.
A check that reports seventy-six false problems and zero real ones will not be read twice. It will be bypassed the same day — and on that day, we will have been the ones who built the tool people switch off.
2. The distinction that decides everything
The rule is not "no date in the file". It is "no date in front of the reader". Stated that way, the implementation becomes obvious: before analysing, strip everything a visitor never sees.
.replace(/<!--[\s\S]*?-->/g, ' ') // comments
.replace(/<script[\s\S]*?<\/script>/gi, ' ')
.replace(/<style[\s\S]*?<\/style>/gi, ' ')
.replace(/<svg[\s\S]*?<\/svg>/gi, ' ') // coordinates, identifiers
.replace(/<[^>]+>/g, ' ') // tags AND attributes
What remains is the text. We look for dates in that, and nothing else. Result: zero false positives across eighty articles, and immediate refusal the moment a date is deliberately reintroduced into a paragraph.
3. A month alone is not enough
One detail forced a nuance. One of our pages contains the phrase "remind me about the tax return in August". That is a usage example, not a publication date. A check that spots month names would have blocked it.
So we require a day or a year beside the month. "August the thirteenth" is a date — spelled out in letters here, otherwise this very safeguard would refuse the article you are reading. "in August" is a sentence. The difference looks tiny; it decides whether the guard is usable day to day or not.
4. Scope is a decision, not an oversight
The check looks only at articles. Legal pages must carry their last-updated notice — that is an obligation. A résumé must carry its years, or it says nothing. And a page recounting a month of work has a date as its subject.
A guard that overflows its scope ends up blocking legitimate work, and that is how it loses its authority. Writing down what it does not look at, and why, is as much a part of the guard as what it refuses.
- "No date in the file" and "no date in front of the reader" are two different rules. Only the second is the one we wanted.
- A check is judged first on its false positives. Seventy-six for zero real ones is a stillborn check.
- A check's scope must be written down. Otherwise someone will widen it "to be thorough", and it will become unbearable.