A redesign ships. The selector still matches, the schema still validates, the run still returns 200 — and the price it reports is the struck-through one. Every other monitor in your stack calls that run a success. This one calls it drift, names the element that moved, and proposes the selector that fixes it.
div.pricing became div.price-stack and a second.price arrived above the first. The provenance moved; the status code did not.
Each run is judged four separate ways, and the four are kept in four different vocabularies on purpose. The finding is the disagreement between them — and a disagreement cannot survive being averaged into a health percentage, which is why there is no score anywhere in this product.
How much of the plan produced a value. Says nothing at all about whether the value is right — which is precisely the gap every uptime monitor lives in.
Whether the number is believable against this field’s own history. A price can be believable and still be the wrong price.
Whether the place the value was read from has moved. This is the judge nothing else in the stack has, and the only one that catches a correct-looking number read from the wrong element.
What the evidence says is actually wrong — a redesign, a removed element, a real price change — and how confident that reading is. It refuses to name a cause it cannot support.
Run fine. Value fine. Provenance moved. The gap in the ring is where the judges stop agreeing.
The recovery tier writes to repair_proposal — a table the collector does not read. The only path into production runs through a verification that passed. That is a structure rather than a policy, so it cannot be forgotten under deadline.
This is not a scraper, and it does not replace one. It is the layer that decides whether what came back can be trusted — and it is deliberately explicit about which half is which, because a submission that blurs the line is claiming somebody else’s engineering.
Fetching the page, rotating the network, rendering the DOM, retrying a failure, and self-healing a selector that stopped matching.
Judging the result four ways, measuring how much warning there was, and refusing to let an unverified repair reach production.
Every figure below is derived from stored observations at the moment this page rendered. Nothing here is cached, illustrated or chosen for effect — and where the archive has too little evidence to support a number, it says so instead of printing one.
Other systems tell you when a scraper broke. We tell you when your scraper is lying.the whole product, in one line
A scraper that returns nothing gets noticed within the hour. A scraper that returns the wrong number gets noticed a quarter later, in a decision somebody already made. The second failure is the expensive one, and almost nothing watches for it.