QUESTZ
stopping a scraper before it writes a CSV from a page that changed shape.
A scraper that writes a CSV from a page that quietly changed shape has not failed, it has lied. This one checks the shape first and fails closed when it cannot.
- Tests
- 307
- Python
- 3.11 to 3.14
- Release
- v0.1.0
The demo, as it really ran
$ questz canary check --contract examples/contracts/items.json --html questz/testsite/v2/items.html; echo "exit $?"
questz canary: DRIFT
contract: items v1
target: questz/testsite/v2/items.html
findings (4):
CRITICAL missing_selector tr[data-testid="item-row"] td[data-testid="price"]
expected 5 to 50, found 0
CRITICAL missing_selector tr[data-testid="item-row"] td[data-testid="stock"]
expected 5 to 50, found 0
MAJOR structure_removed
expected every baseline node still present, found 4 gone
th[data-testid=col-price], th[data-testid=col-stock], td[data-testid=price], td[data-testid=stock]
WARNING structure_added
expected no nodes outside the baseline, found 7 new
th[data-testid=col-sku], th[data-testid=col-cost], td[data-testid=sku], td[data-testid=cost], and 3 more
signature: baseline 6c9c2add1e0b observed defb7f9573c6
counts: tr[data-testid=item-row]=12, li[data-testid=stock]=12
structure diff:
--- baseline
+++ observed
@@ -7,4 +7,4 @@
4|th|data-testid=col-name
-4|th|data-testid=col-price
-4|th|data-testid=col-stock
+4|th|data-testid=col-sku
+4|th|data-testid=col-cost
2|tbody|
@@ -12,3 +12,6 @@
4|td|data-testid=name
-4|td|data-testid=price
-4|td|data-testid=stock
+4|td|data-testid=sku
+4|td|data-testid=cost
+1|div|data-testid=stock-panel
+2|ul|
+3|li|data-testid=stock|x*
exit 1
Output captured on 2026-08-30. It is committed to the repository and a test fails when it stops matching a live run, so this page cannot quietly drift from the code it describes.
Read it
- Source on GitHub the README carries the argument in full
- The whole toolset what these sixteen repositories argue together, and why there are sixteen
- Release v0.1.0 changelog and tag
The rest of the toolset
- QUACKZ deflating a backtest that only looks good because it was picked out of two hundred
- QUOTEZ market data an agent can read and cannot act on
- QUELLZ measuring what prompt-injection containment costs in utility as well as in attack rate
- QUIDZ refusing the outbound payment that would have gone out twice
- QUIZZ answering what a statistic said at the time, and refusing when it cannot
- QUARANTINEZ treating an outcome the venue never confirmed as terminal rather than as a retry
- QUENCHZ deciding in the open what a tool server gets free while it is still somebody's subprocess
- QUILTZ proving infrastructure code wrong without a cloud account, and saying what that cannot show
- QUAYZ telling a crash loop from an OOMKill, and naming the failure that no single field finds
- QUARRYZ keeping every version a statistical office published, and failing the build when it quietly issues another
- QUASHZ refusing a row whose outcome had not been decided yet when the decision would have been made
- QUALMZ a fixed number of looks at the holdout, where re-running the same configuration does not buy another
- QUEUEZ ordering a feed by its sequence, because on a real recorded session the clock goes backwards
- QUANDARYZ counting the distinct screens a component can settle into when its responses arrive out of order
- QUIETZ watching whether the data arrived rather than whether the server answered