From 2d52fc4c54c5a739fe139104d50336f458f5f6c5 Mon Sep 17 00:00:00 2001
From: EquityBot <333319867+EquityBot@users.noreply.github.com>
Date: Mon, 2 Nov 2026 10:46:26 +1100
Subject: [PATCH 01/10] fix(register): recheck drifted evidence and decode
obfuscated contact emails
Recheck every entry in the monthly drift report: update 13 evidence hashes,
correct Lead Lists' and Dymocks' privacy contacts, and drop evidence for 3
pages that now serve a script-only bot check.
The channel check now decodes Cloudflare-protected addresses and searches an
entry's sources without evidence before reporting an address as missing.
Closes #26
---
docs/provenance.md | 12 +++-
registry/README.md | 2 +-
registry/au/canva-au.toml | 6 +-
registry/au/coles-au.toml | 12 +---
registry/au/dymocks-au.toml | 17 ++----
registry/au/equifax-au.toml | 10 +--
registry/au/equifax-marketing-au.toml | 6 +-
registry/au/everyday-rewards-au.toml | 10 +--
registry/au/harvey-norman-au.toml | 7 +--
registry/au/lead-lists-au.toml | 15 +++--
registry/au/michael-page-au.toml | 6 +-
registry/au/records-finder-au.toml | 22 +++----
xtask/src/main.rs | 87 ++++++++++++++++++++-------
xtask/src/text.rs | 43 +++++++++++++
14 files changed, 169 insertions(+), 86 deletions(-)
diff --git a/docs/provenance.md b/docs/provenance.md
index ca2d975..bc63b9d 100644
--- a/docs/provenance.md
+++ b/docs/provenance.md
@@ -110,7 +110,7 @@ Levers: every entry with an ABN lists `app11-destroy` (sent only when the user n
| `chandler-macleod-au` | Maintainer's request | Privacy policy and contact pages on www.chandlermacleod.com, www.rgfstaffing.com.au | 84 603 568 403: RGF STAFFING ANZ PTY LTD, active from 06 Jan 2015 |
| `charterhouse-au` | Maintainer's request | Privacy policy and contact pages on www.charterhouse.com.au | 40 078 713 774: CHARTERHOUSE RECRUITMENT PTY LTD, active from 01 Mar 2000 |
| `coles-au` | Large Australian firm | Privacy policy and contact pages on www.coles.com.au | 11 004 089 936: COLES GROUP LIMITED, active from 09 Feb 2000 |
-| `dymocks-au` | Large Australian data breach | Privacy policy and contact pages on www.dymocks.group | 59 008 453 110: DYMOCKS HOLDINGS PTY LTD, active from 01 Nov 1999 |
+| `dymocks-au` | Large Australian data breach | Privacy policy on www.dymocks.com.au (rechecked 2 November 2026; see below) | 64 074 571 083: DYMOCKS PTY LTD, active from 05 Dec 1999 (ABN Lookup, 2 November 2026) |
| `ebay-au` | Large Australian firm | Privacy policy and contact pages on www.ebay.com.au, www.ebayinc.com | 64 652 016 681: eBay Marketplaces GmbH, active from 01 Jun 2018 |
| `harvey-norman-au` | Large Australian firm | Privacy policy and contact pages on www.harveynorman.com.au, www.harveynormanholdings.com.au | 14 818 873 384: THE TRUSTEE FOR THE ECOMM STORE NO 2 TRUST, active from 08 Sep 2010 |
| `hays-au` | Maintainer's request | Privacy policy and contact pages on www.hays.com.au | 47 001 407 281: HAYS SPECIALIST RECRUITMENT (AUSTRALIA) PTY LIMITED, active from 16 Feb 2000 |
@@ -166,6 +166,16 @@ Evidence: 52 `[[evidence]]` hashes across 33 of these entries, taken on 26 Octob
- `telstra-au`, `optus-au`, `tpg-telecom-au`, `aussie-broadband-au`: members of the Telecommunications Industry Ombudsman, which `escalation` cannot yet name.
- Rejected: MyDeal (closed; the site refused connections), PeopleIN (its policy covers its own staff and host employers, not its agencies' candidates).
+### Evidence drift recheck (2 November 2026)
+
+The first monthly drift check ([issue 26](https://github.com/EquityBot/GhostSoap/issues/26)) was worked through on 2 November 2026 by an AI agent for the maintainer, from public pages only: no form was submitted, no account created and no one signed in. Each flagged page was read in a browser (Firecrawl for 3 pages behind a bot check) and its entry's claims were matched against the text; new hashes were taken twice with `cargo run -p xtask -- evidence-hash` and matched.
+
+- Hash updated, claims unchanged: `canva-au`, `equifax-au` (contact and credit-ban pages), `equifax-marketing-au` (donotcontact.com.au), `everyday-rewards-au` (both HTML pages; the policy page still links the August 2026 PDF, whose hash is unchanged), `michael-page-au` and `records-finder-au` (all 5 pages; the Australian search page shows a 'Databases Updated' date, so it may drift every month).
+- `lead-lists-au`: the privacy policy now sends requests to a new Privacy Requests page, updated 28 October 2026, which gives `suppressions@leadlists.com.au` (was `suppression@`) and a postal address in Chadstone. The page answers a plain fetch with a bot check, so it has no hash.
+- `dymocks-au`: www.dymocks.group now redirects to the policy on www.dymocks.com.au, which names Dymocks Pty Ltd, gives `privacy@dymocks.com.au` (was `privacy@dymocks.group`) and the same Level 6, 428 George Street address, and links a data deletion request form. That page answers a plain fetch with 403, so the entry has no hash.
+- Evidence removed: the 2 Coles HTML pages and Harvey Norman's policy now answer a plain fetch with a script-only bot check (0 characters of main text). Their claims still match the pages in a browser; Coles's PDF policy keeps its hash.
+- Contact channels: the addresses of `aussie-broadband-au`, `careerone-au`, `hays-au`, `manpowergroup-au`, `robert-half-au` and `smrtr-au` are on their pages behind Cloudflare's email obfuscation, which the check now decodes; those of `chandler-macleod-au` and `peoplebank-au` are on the RGF Staffing policy and Thryv's on its privacy policy, sources without evidence, which the check now searches.
+
### Rejected candidates (M1)
| Candidate | Reason |
diff --git a/registry/README.md b/registry/README.md
index 7962322..fecd87f 100644
--- a/registry/README.md
+++ b/registry/README.md
@@ -51,7 +51,7 @@ A pack has `id` (equal to the file name), `name`, `description` and `entries`, a
Each `[[evidence]]` table records a source page's state when the entry was verified. A scheduled workflow (`.github/workflows/evidence-drift.yml`) re-fetches every evidence page on the first of each month and opens or updates one issue, 'Register evidence drift', listing pages that changed or could not be read within 30 seconds, and closes that issue once every page matches again. It never commits. When a page changes, recheck the entry against it and update the hash and `checked_at`.
-The same run checks the contact channels of every entry that is not obsolete. It looks up each email address's domain through Google Public DNS (`dns.google`) and reports one that does not exist, has no mail or address record, or publishes a null MX record saying it accepts no mail. It also requests each web-form address and reports an HTTP error or a host public DNS says does not exist. A 401, 403, 405, 429 or 5xx, a dropped connection or a failed DNS lookup proves nothing, because sites also answer scripts that way when the form works and such failures pass, so those go to the workflow log and not the issue: a form or domain behind one of them is not confirmed to work. It also reports an email address that appears on none of its entry's evidence pages, searching each page's raw HTML and decoded main text in any letter case; a missing address goes to the workflow log instead when its entry has no evidence page, or has one that failed or is not HTML. These checks never send an email or submit a form, and a passing domain does not prove the mailbox exists.
+The same run checks the contact channels of every entry that is not obsolete. It looks up each email address's domain through Google Public DNS (`dns.google`) and reports one that does not exist, has no mail or address record, or publishes a null MX record saying it accepts no mail. It also requests each web-form address and reports an HTTP error or a host public DNS says does not exist. A 401, 403, 405, 429 or 5xx, a dropped connection or a failed DNS lookup proves nothing, because sites also answer scripts that way when the form works and such failures pass, so those go to the workflow log and not the issue: a form or domain behind one of them is not confirmed to work. It also reports an email address that appears on none of its entry's source pages. It searches the evidence pages first and fetches the entry's other sources only when an address is not on them, searching each page's raw HTML, its decoded main text and any address hidden by Cloudflare's email obfuscation, in any letter case; a missing address goes to the workflow log instead when one of those pages failed, has under 500 characters of main text or is not HTML. These checks never send an email or submit a form, and a passing domain does not prove the mailbox exists.
On a pull request, CI compares the register with the base branch's and adds a warning annotation for each email address an entry gains, and for every address of an entry whose id is new, so a renamed entry is flagged too (`cargo run -p xtask -- email-changes registry/au`). Domains compare case-insensitively; local parts do not. The check passes either way, but fails on an entry that does not parse: check each flagged address on the entity's own pages before merging.
diff --git a/registry/au/canva-au.toml b/registry/au/canva-au.toml
index f66b9b3..805e197 100644
--- a/registry/au/canva-au.toml
+++ b/registry/au/canva-au.toml
@@ -5,7 +5,7 @@ abn = "80 158 929 938"
kinds = ["online-service"]
priority = "high"
quality = "verified"
-verified_at = 2026-10-26
+verified_at = 2026-11-02
sources = ["https://www.canva.com/policies/privacy-policy/", "https://www.canva.com/help/legal-form/", "https://www.canva.com/settings/email-preferences"]
levers = ["app7-no-marketing", "app7-source", "app11-destroy", "app13", "app13-notify-recipients", "app13-statement"]
opt_in_levers = ["app12"]
@@ -31,5 +31,5 @@ levers = ["app7-no-marketing"]
[[evidence]]
url = "https://www.canva.com/policies/privacy-policy/"
-checked_at = 2026-10-26
-sha256 = "95df1957be8349f36e6521af6567318fc594643149a84da04919bf98c47df73b"
+checked_at = 2026-11-02
+sha256 = "b51d2e8073e901dbbbc0a76031ff92589e3da591ef367a4b41df145cd7eff0db"
diff --git a/registry/au/coles-au.toml b/registry/au/coles-au.toml
index b6a0887..72b179c 100644
--- a/registry/au/coles-au.toml
+++ b/registry/au/coles-au.toml
@@ -5,7 +5,7 @@ abn = "11 004 089 936"
kinds = ["retail"]
priority = "standard"
quality = "verified"
-verified_at = 2026-10-26
+verified_at = 2026-11-02
sources = ["https://www.coles.com.au/content/dam/coles/cusp/about-coles/documents/coles_group_privacy_policy_september_2025.pdf", "https://www.coles.com.au/privacy", "https://www.coles.com.au/help/accounts/delete-your-coles-account"]
levers = ["app7-no-marketing", "app7-source", "app11-destroy", "app13", "app13-notify-recipients", "app13-statement"]
opt_in_levers = ["app12"]
@@ -33,13 +33,3 @@ levers = []
url = "https://www.coles.com.au/content/dam/coles/cusp/about-coles/documents/coles_group_privacy_policy_september_2025.pdf"
checked_at = 2026-10-26
sha256 = "29adbc5d5c12d46560b01b06c12ca7069edb071647790378426043bf15b82316"
-
-[[evidence]]
-url = "https://www.coles.com.au/privacy"
-checked_at = 2026-10-26
-sha256 = "dd1b09e2a5e277cd06f930fb7a6eeb82a3f1f8204a95690e293fc9cd82e31c53"
-
-[[evidence]]
-url = "https://www.coles.com.au/help/accounts/delete-your-coles-account"
-checked_at = 2026-10-26
-sha256 = "a7cff50450d9b61599ce0a0ed1217e34ca3f574814807cd417ce27edcabe3a40"
diff --git a/registry/au/dymocks-au.toml b/registry/au/dymocks-au.toml
index 9d8a341..6da5678 100644
--- a/registry/au/dymocks-au.toml
+++ b/registry/au/dymocks-au.toml
@@ -1,12 +1,12 @@
id = "dymocks-au"
name = "Dymocks"
-legal_entity = "Dymocks Holdings Pty Ltd"
-abn = "59 008 453 110"
+legal_entity = "Dymocks Pty Ltd"
+abn = "64 074 571 083"
kinds = ["retail"]
priority = "high"
quality = "verified"
-verified_at = 2026-10-26
-sources = ["https://www.dymocks.group/privacy-policy/"]
+verified_at = 2026-11-02
+sources = ["https://www.dymocks.com.au/privacy-policy/"]
levers = ["app7-no-marketing", "app7-no-facilitation", "app7-source", "app11-destroy", "app13", "app13-notify-recipients", "app13-statement"]
opt_in_levers = ["app12"]
identity_fields = ["full_name", "email", "phone", "address"]
@@ -16,15 +16,10 @@ effort = "easy"
[[channels]]
kind = "email"
-address = "privacy@dymocks.group"
+address = "privacy@dymocks.com.au"
levers = ["app7-no-marketing", "app7-no-facilitation", "app7-source", "app11-destroy", "app13", "app13-notify-recipients", "app13-statement", "app12"]
[[channels]]
kind = "post"
-address = "Privacy Officer, Level 6, 428 George Street, Sydney NSW 2000"
+address = "Privacy Officer, Dymocks Pty Ltd, Level 6, 428 George Street, Sydney NSW 2000"
levers = ["app7-no-marketing", "app7-no-facilitation", "app7-source", "app11-destroy", "app13", "app13-notify-recipients", "app13-statement", "app12"]
-
-[[evidence]]
-url = "https://www.dymocks.group/privacy-policy/"
-checked_at = 2026-10-26
-sha256 = "69afc5faf986fb4a1e015daee40340efc3cb834b5b217b049ffd017e38de2df3"
diff --git a/registry/au/equifax-au.toml b/registry/au/equifax-au.toml
index 4d0f914..07f92a0 100644
--- a/registry/au/equifax-au.toml
+++ b/registry/au/equifax-au.toml
@@ -5,7 +5,7 @@ abn = "26 000 602 862"
kinds = ["credit-reporting-body"]
priority = "crucial"
quality = "verified"
-verified_at = 2026-10-24
+verified_at = 2026-11-02
sources = ["https://www.equifax.com.au/credit-reporting-policy", "https://www.equifax.com.au/contact", "https://www.equifax.com.au/personal/products/credit-and-identity-products", "https://www.equifax.com.au/personal/corrections-portal", "https://www.equifax.com.au/eform/submit/credit-ban", "https://www.equifax.com.au/eform/submit/complaints-form"]
levers = ["s20t-correction"]
opt_in_levers = ["s20r-access", "s20k-ban"]
@@ -54,8 +54,8 @@ sha256 = "7778d413ce89cada85159267cb40976f9189b088cd77cbf0dee865e5ea7dfd72"
[[evidence]]
url = "https://www.equifax.com.au/contact"
-checked_at = 2026-10-24
-sha256 = "b3859a399f75a35d75fe8c2041cf4eb57b4dd0bf6511489db51136c62102bf81"
+checked_at = 2026-11-02
+sha256 = "6031976a8530c3fa32eb7430e5a41a11cc95f76fc4e333c5f0f594e4284289fc"
[[evidence]]
url = "https://www.equifax.com.au/personal/products/credit-and-identity-products"
@@ -69,5 +69,5 @@ sha256 = "a59e502c73dc52851831e5553e8ee57dccb653459cdb8896271b7f6ae635fa56"
[[evidence]]
url = "https://www.equifax.com.au/eform/submit/credit-ban"
-checked_at = 2026-10-24
-sha256 = "52c91f70960defd41b361559e6b4921439daec6794386499dd552532e0db8f4f"
+checked_at = 2026-11-02
+sha256 = "1d077c96fdb342a1c7ef11aa385ba1a90697a845b80c55c4fa9141bdd7beb848"
diff --git a/registry/au/equifax-marketing-au.toml b/registry/au/equifax-marketing-au.toml
index 4a9e5d9..12eb70b 100644
--- a/registry/au/equifax-marketing-au.toml
+++ b/registry/au/equifax-marketing-au.toml
@@ -5,7 +5,7 @@ abn = "88 071 215 328"
kinds = ["marketing-list"]
priority = "high"
quality = "verified"
-verified_at = 2026-10-24
+verified_at = 2026-11-02
sources = ["https://www.equifax.com.au/privacy", "https://www.donotcontact.com.au/"]
levers = ["app7-no-marketing", "app7-no-facilitation", "app7-source", "app13", "app13-notify-recipients", "app13-statement"]
opt_in_levers = ["app12"]
@@ -37,5 +37,5 @@ sha256 = "aaeaf4225ee4cbade081ece48db356b14608b81ff2148ae93b5b8f705ff04257"
[[evidence]]
url = "https://www.donotcontact.com.au/"
-checked_at = 2026-10-24
-sha256 = "3acc7039a6121135ee06d56a54aad9a5a811181d2eabd699947fccdc86ba996b"
+checked_at = 2026-11-02
+sha256 = "736dd3915c42f1a772efd5ee100c050f61d106524e148b1af409c617ef644ce7"
diff --git a/registry/au/everyday-rewards-au.toml b/registry/au/everyday-rewards-au.toml
index ad5ea20..d6efc87 100644
--- a/registry/au/everyday-rewards-au.toml
+++ b/registry/au/everyday-rewards-au.toml
@@ -5,7 +5,7 @@ abn = "88 000 014 675"
kinds = ["loyalty"]
priority = "standard"
quality = "verified"
-verified_at = 2026-10-24
+verified_at = 2026-11-02
sources = ["https://www.woolworthsgroup.com.au/au/en/privacy/privacy-policy.html", "https://www.woolworthsgroup.com.au/content/dam/wwg/privacy/2026/FINAL_Woolworths-Group-Privacy-Policy-August-2026.pdf", "https://www.woolworthsgroup.com.au/au/en/privacy.html"]
levers = ["app7-no-marketing", "app7-no-facilitation", "app7-source", "app13", "app13-notify-recipients", "app13-statement"]
opt_in_levers = ["app12"]
@@ -32,8 +32,8 @@ levers = ["app7-no-marketing", "app7-no-facilitation", "app7-source", "app13", "
[[evidence]]
url = "https://www.woolworthsgroup.com.au/au/en/privacy/privacy-policy.html"
-checked_at = 2026-10-24
-sha256 = "3d937e82f1c70a519fdf63dcb421ea14eb0aef3ceba370f5b79695c90c99d99b"
+checked_at = 2026-11-02
+sha256 = "853190e0b024601f2c102f0b6ed97bb18b8c51632bdaf6ac02b205aff8a7c3e4"
[[evidence]]
url = "https://www.woolworthsgroup.com.au/content/dam/wwg/privacy/2026/FINAL_Woolworths-Group-Privacy-Policy-August-2026.pdf"
@@ -42,5 +42,5 @@ sha256 = "70408cddb998cbffabe6b110d3deccf7cb7b84595f41f5f9e6e74dd2984f8e0b"
[[evidence]]
url = "https://www.woolworthsgroup.com.au/au/en/privacy.html"
-checked_at = 2026-10-24
-sha256 = "859fb2ef90dadea90d7f6d149580c5d53bd796c562528eea6d89ebcab7ac4a3a"
+checked_at = 2026-11-02
+sha256 = "b801887a60188d5a87dfff8319b91c8d3d2e7a462a892fc17741aada30d273b9"
diff --git a/registry/au/harvey-norman-au.toml b/registry/au/harvey-norman-au.toml
index 7f7a3a8..0b01062 100644
--- a/registry/au/harvey-norman-au.toml
+++ b/registry/au/harvey-norman-au.toml
@@ -5,7 +5,7 @@ abn = "14 818 873 384"
kinds = ["retail"]
priority = "standard"
quality = "verified"
-verified_at = 2026-10-26
+verified_at = 2026-11-02
sources = ["https://www.harveynorman.com.au/privacy-policy", "https://www.harveynormanholdings.com.au/privacy-policy"]
levers = ["app7-no-marketing", "app7-no-facilitation", "app7-source", "app11-destroy", "app13", "app13-notify-recipients", "app13-statement"]
opt_in_levers = ["app12"]
@@ -28,8 +28,3 @@ levers = ["app7-no-marketing", "app7-no-facilitation", "app7-source", "app11-des
kind = "phone"
address = "02 9201 6111"
levers = []
-
-[[evidence]]
-url = "https://www.harveynorman.com.au/privacy-policy"
-checked_at = 2026-10-26
-sha256 = "db0c4e5daafd56008fda9aa126c41662892d93f3d89cddf7a12d8be12e0cc4d9"
diff --git a/registry/au/lead-lists-au.toml b/registry/au/lead-lists-au.toml
index 5fbea79..afe45df 100644
--- a/registry/au/lead-lists-au.toml
+++ b/registry/au/lead-lists-au.toml
@@ -5,8 +5,8 @@ abn = "53 634 428 470"
kinds = ["marketing-list"]
priority = "high"
quality = "verified"
-verified_at = 2026-10-24
-sources = ["https://leadlists.com.au/privacy-policy/", "https://leadlists.com.au/contact-us/"]
+verified_at = 2026-11-02
+sources = ["https://leadlists.com.au/privacy-policy/", "https://leadlists.com.au/privacy-requests/", "https://leadlists.com.au/contact-us/"]
levers = ["app7-no-marketing", "app7-no-facilitation", "app7-source", "app13", "app13-notify-recipients", "app13-statement"]
opt_in_levers = ["app12"]
identity_fields = ["full_name", "email", "phone", "address"]
@@ -16,10 +16,15 @@ effort = "easy"
[[channels]]
kind = "email"
-address = "suppression@leadlists.com.au"
+address = "suppressions@leadlists.com.au"
levers = ["app7-no-marketing", "app7-no-facilitation", "app7-source", "app13", "app13-notify-recipients", "app13-statement", "app12"]
preferred = true
+[[channels]]
+kind = "post"
+address = "Privacy Officer, Lead Lists Data Solutions, Suite 60, Level 2, 1341 Dandenong Rd, Chadstone VIC 3148"
+levers = ["app7-no-marketing", "app7-no-facilitation", "app7-source", "app13", "app13-notify-recipients", "app13-statement", "app12"]
+
[[channels]]
kind = "phone"
address = "(03) 9007 0355"
@@ -27,5 +32,5 @@ levers = []
[[evidence]]
url = "https://leadlists.com.au/privacy-policy/"
-checked_at = 2026-10-24
-sha256 = "910c2ea7301eec5d996d78b3a6acc4c3ecd17853b7509498eee8c710daa39fc2"
+checked_at = 2026-11-02
+sha256 = "679c8de7a59a4872c7589a0fe78fdbfea13b4258b896970b58265583ba0eec7b"
diff --git a/registry/au/michael-page-au.toml b/registry/au/michael-page-au.toml
index fc29087..4d1af03 100644
--- a/registry/au/michael-page-au.toml
+++ b/registry/au/michael-page-au.toml
@@ -5,7 +5,7 @@ abn = "58 002 872 264"
kinds = ["recruitment"]
priority = "high"
quality = "verified"
-verified_at = 2026-10-26
+verified_at = 2026-11-02
sources = ["https://www.michaelpage.com.au/privacy-policy"]
levers = ["app7-no-marketing", "app7-source", "app11-destroy", "app13", "app13-notify-recipients", "app13-statement"]
opt_in_levers = ["app12"]
@@ -31,5 +31,5 @@ levers = []
[[evidence]]
url = "https://www.michaelpage.com.au/privacy-policy"
-checked_at = 2026-10-26
-sha256 = "d5d2d1c28b5fa4d58a1a98158f89ead4fbdb4e75ce4ebdd13497ea4b880eca32"
+checked_at = 2026-11-02
+sha256 = "a666427dccee8a8c573ebc94aca1c040638592b413cc9515d727d26af5f757b9"
diff --git a/registry/au/records-finder-au.toml b/registry/au/records-finder-au.toml
index 07bda2c..44796c9 100644
--- a/registry/au/records-finder-au.toml
+++ b/registry/au/records-finder-au.toml
@@ -4,7 +4,7 @@ legal_entity = "InfoPay, Inc."
kinds = ["people-search"]
priority = "standard"
quality = "verified"
-verified_at = 2026-10-25
+verified_at = 2026-11-02
sources = ["https://recordsfinder.com/privacy/", "https://recordsfinder.com/terms/", "https://recordsfinder.com/optout/", "https://recordsfinder.com/do-not-sell-share-my-personal-information/", "https://recordsfinder.com/australia/"]
identity_fields = ["full_name"]
exemption_risk = "overseas"
@@ -21,25 +21,25 @@ url = "https://recordsfinder.com/australia/"
[[evidence]]
url = "https://recordsfinder.com/privacy/"
-checked_at = 2026-10-25
-sha256 = "572946dbdda3efecf0b16fc347081530267df9d33c5d22deac923ab300abca87"
+checked_at = 2026-11-02
+sha256 = "0a84a58297247e0c0edc9165d5259986779ade2b5b980a0be7bd1fba626fab0b"
[[evidence]]
url = "https://recordsfinder.com/terms/"
-checked_at = 2026-10-25
-sha256 = "ec8f39257958f057bc7f9124a08c155f12c93bde766913e56a8b3b765883a4f8"
+checked_at = 2026-11-02
+sha256 = "1d27469e8e1bdf9b377a41d38932231a867708501e68124e8398d16c13959c99"
[[evidence]]
url = "https://recordsfinder.com/optout/"
-checked_at = 2026-10-25
-sha256 = "c88024ac830586c5ac152a30327dd01f977fc282ea75ff5de621232082d3dd78"
+checked_at = 2026-11-02
+sha256 = "3c92ba03b5906df0786c6aa79ec8391153461adc563f0d5500081576f886c604"
[[evidence]]
url = "https://recordsfinder.com/do-not-sell-share-my-personal-information/"
-checked_at = 2026-10-25
-sha256 = "ae99872996c5d8e13dec966599146e3a4c4fdf0b8c3a907e40390a9291abba7f"
+checked_at = 2026-11-02
+sha256 = "5bb3cad71d41e919aa4fa683c045678f5bae92bc219a6451e6e13b740d9ab8a8"
[[evidence]]
url = "https://recordsfinder.com/australia/"
-checked_at = 2026-10-25
-sha256 = "1864c827332dd7c8bc46ab22526f532ca858c0f6022b7ab5a209440ff1626a89"
+checked_at = 2026-11-02
+sha256 = "82c868efaaa940aa19fb41e4d2e04e4280e2587d67dd1b570b54546f44382593"
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index b795e2d..07e32b7 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -33,8 +33,9 @@ fn agent(timeout: Duration) -> ureq::Agent {
/// A fetched evidence page.
struct Page {
sha256: String,
- /// Lowercase raw HTML followed by the lowercase main text, for finding an email
- /// address in a link, a footer or entity-encoded text; `None` for a non-HTML page.
+ /// Lowercase raw HTML, main text and Cloudflare-protected addresses, for finding an
+ /// email address in a link, a footer, or entity-encoded or obfuscated text; `None` for
+ /// a non-HTML page.
text: Option,
}
@@ -65,7 +66,8 @@ fn evidence_page(agent: &ureq::Agent, url: &str) -> Result {
main.chars().count()
));
}
- let searchable = format!("{html}\n{main}").to_lowercase();
+ let hidden = text::cloudflare_emails(&html).join("\n");
+ let searchable = format!("{html}\n{main}\n{hidden}").to_lowercase();
(Sha256::digest(main.as_bytes()), Some(searchable))
} else {
(Sha256::digest(&bytes), None)
@@ -140,12 +142,8 @@ fn drift(dir: &Path) -> ExitCode {
if entry.obsolete.is_none() {
collect_channels(&entry, &mut mail_domains, &mut forms);
let ids = std::slice::from_ref(&entry.id);
- for channel in &entry.channels {
- if channel.kind == ChannelKind::Email {
- let what = format!("email {}", channel.address);
- let check = email_on_pages(&channel.address, &pages);
- record(&mut emails, &what, ids, check);
- }
+ for (address, check) in email_checks(&agent, &entry, pages) {
+ record(&mut emails, &format!("email {address}"), ids, check);
}
}
}
@@ -209,7 +207,36 @@ fn record(lines: &mut Vec, what: &str, ids: &[String], check: Check) {
}
}
-/// Whether `address` appears on one of its entry's evidence pages, given each page's
+/// Check each email channel of `entry` against its source pages. `pages` holds the
+/// searchable text of its evidence pages; its other sources, such as a page behind a bot
+/// check that cannot have evidence, are fetched only when an address is not on those.
+fn email_checks(
+ agent: &ureq::Agent,
+ entry: &Entry,
+ mut pages: Vec