| Both sides previous revisionPrevious revisionNext revision | Previous revision |
| provenance:practices:notifying_websites [2026/09/04 12:58] – Log the 2026-09-04 figures and citations reviews; 27 rows / 26 + 6; 69 quotes; weak-keys split corrected to 5/11/3/18. Authored by Claude karel.kubicek.claude | provenance:practices:notifying_websites [2026/09/17 07:23] (current) – Markup rendering sweep: wrap escapes, CLI flag typography, and heading quotes. Authored by Claude. karel.kubicek.claude |
|---|
| |
| ^ Field ^ Value ^ | ^ Field ^ Value ^ |
| | Date | 2026-08-13 (page created); **2026-09-04 (this revision: the 144 unreviewed campaign candidates read, 10 campaigns added, security.txt questions resolved as far as the sources allow)** | | | Date | 2026-08-13 (page created); **2026-09-04 (this revision: the 144 unreviewed campaign candidates screened, 18 of them read in full, 10 campaigns added, security.txt questions resolved as far as the sources allow)** | |
| | Page status | **new page**. ''practices:notifying_websites'' was a red link promised from [[:start]] since the site's outline was written; nothing existed at that id. | | | Page status | **new page**. ''practices:notifying_websites'' was a red link promised from [[:start]] since the site's outline was written; nothing existed at that id. | |
| | Corpus at the time | ''data/extract/run1/extractions.jsonl'', 5,859 papers, 7 venues (CCS, IMC, NDSS, PETS, USENIX Security, TheWebConf, IEEE S&P), 2010–2026. 5,869 ''paper.cols.txt'' files. | | | Corpus at the time | ''data/extract/run1/extractions.jsonl'', 5,859 papers, 7 venues (CCS, IMC, NDSS, PETS, USENIX Security, TheWebConf, IEEE S&P), 2010–2026. 5,869 ''paper.cols.txt'' files. | |
| ===== Report script and its unedited output ===== | ===== Report script and its unedited output ===== |
| |
| Run as ''node scripts/report_notifying_websites.mjs''. Flags: ''--wiki'' for DokuWiki tables, ''--list'' for the hand-classified campaigns and every rejection with its reason, ''--quotes'' for ethics evidence quotes, ''--residue'' for every unmapped fold entry and every unreviewed candidate (none, as of 2026-09-04). The block below is the unedited output of a fresh run on 2026-09-04 (''out/notifying_websites-output-20260904.txt''); sections A–D are byte-identical to the 2026-08-13 run, section E changed. | Run as ''node scripts/report_notifying_websites.mjs''. Flags: ''%%--wiki%%'' for DokuWiki tables, ''%%--list%%'' for the hand-classified campaigns and every rejection with its reason, ''%%--quotes%%'' for ethics evidence quotes, ''%%--residue%%'' for every unmapped fold entry and every unreviewed candidate (none, as of 2026-09-04). The block below is the unedited output of a fresh run on 2026-09-04 (''out/notifying_websites-output-20260904.txt''); sections A–D are byte-identical to the 2026-08-13 run, section E changed. |
| |
| <WRAP todo>''out/notifying_websites-output.txt'' in the workdir is **two concatenated runs**: the plain run followed by the ''--list'' run, which repeats the plain output before adding the campaign list. A ''diff'' against a single fresh invocation therefore shows a few hundred spurious extra lines, and this misled one reviewer. Do not hard-code the split point — it moves whenever a table row is added. Derive it: ''BASE=$(node scripts/report_notifying_websites.mjs | wc -l)'', then ''head -$BASE'' and ''tail -n +$((BASE+1))'' each match a fresh run byte-for-byte. As of the 2026-09-04 revision ''BASE'' is 168 (''out/notifying_websites-output-20260904.txt'' is a single plain run; ''out/notifying_websites-output-list-20260904.txt'' is a single ''--list'' run). The script itself is deterministic — re-verified 2026-09-04.</WRAP> | <WRAP todo>''out/notifying_websites-output.txt'' in the workdir is **two concatenated runs**: the plain run followed by the ''%%--list%%'' run, which repeats the plain output before adding the campaign list. A ''diff'' against a single fresh invocation therefore shows a few hundred spurious extra lines, and this misled one reviewer. Do not hard-code the split point — it moves whenever a table row is added. Derive it: ''BASE=$(node scripts/report_notifying_websites.mjs | wc -l)'', then ''head -$BASE'' and ''tail -n +$((BASE+1))'' each match a fresh run byte-for-byte. As of the 2026-09-04 revision ''BASE'' is 168 (''out/notifying_websites-output-20260904.txt'' is a single plain run; ''out/notifying_websites-output-list-20260904.txt'' is a single ''%%--list%%'' run). The script itself is deterministic — re-verified 2026-09-04.</WRAP> |
| |
| Sections of the script, so a figure on the content page can be traced to the block that produced it: | Sections of the script, so a figure on the content page can be traced to the block that produced it: |
| * **D** — ''ethics.disclosureDetail'' folded into channel and outcome families with residue, plus every entry carrying a countable ratio | * **D** — ''ethics.disclosureDetail'' folded into channel and outcome families with residue, plus every entry carrying a countable ratio |
| * **E** — full-text candidate scan (narrow rule and, since 2026-09-04, the wide recall probe), hand classification, and the unreviewed residue | * **E** — full-text candidate scan (narrow rule and, since 2026-09-04, the wide recall probe), hand classification, and the unreviewed residue |
| * **F** — (''--quotes'') ethics evidence quotes for web papers with ''notifiedAffectedParties == yes'' | * **F** — (''%%--quotes%%'') ethics evidence quotes for web papers with ''notifiedAffectedParties == yes'' |
| |
| <code> | <code> |
| campaigns in total (CAMPAIGNS) 32 | campaigns in total (CAMPAIGNS) 32 |
| |
| sanity: campaigns caught by neither rule (added from a wider first-pass scan): 1 — the-security-lottery-measuring-client-side-web-security-inconsistencies | sanity: campaigns caught by neither rule (found by a topical full-text grep, see notify_fold.mjs caught:'grep'): 1 — the-security-lottery-measuring-client-side-web-security-inconsistencies |
| campaigns caught only by the wide probe: 3 — playing-without-paying-detecting-vulnerable-payment-verification-in-native-binar, lazy-gatekeepers-a-large-scale-study-on-spf-configuration-in-the-wild, demystifying-rpki-invalid-prefixes-hidden-causes-and-security-risks | campaigns caught only by the wide probe: 3 — playing-without-paying-detecting-vulnerable-payment-verification-in-native-binar, lazy-gatekeepers-a-large-scale-study-on-spf-configuration-in-the-wild, demystifying-rpki-invalid-prefixes-hidden-causes-and-security-risks |
| REJECTED slugs caught by neither rule: 3 — how-website-owners-face-privacy-issues-thematic-analysis-of-responses-from-a-cov, from-whois-to-whowas-a-large-scale-measurement-study-of-domain-registration-privacy-under-the-gdpr, the-cve-wayback-machine-measuring-coordinated-disclosure-from-exploits-against-t | REJECTED slugs caught by neither rule: 3 — how-website-owners-face-privacy-issues-thematic-analysis-of-responses-from-a-cov, from-whois-to-whowas-a-large-scale-measurement-study-of-domain-registration-privacy-under-the-gdpr, the-cve-wayback-machine-measuring-coordinated-disclosure-from-exploits-against-t |
| </code> | </code> |
| |
| Two of the four figures in ''ethics.disclosureDetail'' ratios above are quoted on the content page and were re-verified against the JSONL by exact substring match: ''an-extensive-study-of-residential-proxies-in-china'' (CCS 2022) and ''fv8-a-forced-execution-javascript-engine-for-detecting-evasive-techniques'' (USENIX Sec 2024), one match each. | Two of the seven ''ethics.disclosureDetail'' ratios above are quoted on the content page and were re-verified against the JSONL by exact substring match: ''an-extensive-study-of-residential-proxies-in-china'' (CCS 2022) and ''fv8-a-forced-execution-javascript-engine-for-detecting-evasive-techniques'' (USENIX Sec 2024), one match each. |
| |
| ===== Folding: rules and residue ===== | ===== Folding: rules and residue ===== |
| Free-text fields agree run-to-run on roughly 20% of exact strings, so nothing here is aggregated by exact string. Three folds were written, in ''scripts/report_notifying_websites.mjs'' and ''scripts/notify_fold.mjs''. | Free-text fields agree run-to-run on roughly 20% of exact strings, so nothing here is aggregated by exact string. Three folds were written, in ''scripts/report_notifying_websites.mjs'' and ''scripts/notify_fold.mjs''. |
| |
| ==== 1. ''ethics.disclosureDetail'' → channel families ==== | ==== 1. ethics.disclosureDetail → channel families ==== |
| |
| Nine regex families, **not mutually exclusive** (a paper that told a CERT and the vendor belongs in both; papers counted once per family). Published on the content page as a ranking, never as adoption rates. | Nine regex families, **not mutually exclusive** (a paper that told a CERT and the vendor belongs in both; papers counted once per family). Published on the content page as a ranking, never as adoption rates. |
| * ''hosting provider / ISP / upstream'' also matches the bare token ''registrar'', which overlaps the WHOIS family. Both are under 1.5% and reported as a ranking, so the overlap is stated rather than resolved. | * ''hosting provider / ISP / upstream'' also matches the bare token ''registrar'', which overlaps the WHOIS family. Both are under 1.5% and reported as a ranking, so the overlap is stated rather than resolved. |
| |
| ==== 2. ''ethics.disclosureDetail'' → outcome families ==== | ==== 2. ethics.disclosureDetail → outcome families ==== |
| |
| Five families, non-exclusive. Residue 2,155 of 2,870 (75.1%), published above. Not used on the content page except as the 75.1% figure. | Five families, non-exclusive. Residue 2,155 of 2,870 (75.1%), published above. Not used on the content page except as the 75.1% figure. |
| |
| ==== 3. ''ethics.harmMitigation'' → families ==== | ==== 3. ethics.harmMitigation → families ==== |
| |
| Eleven families, non-exclusive. **Residue 1,069 of 3,186 (33.6%).** This fold is **diagnostic only — no folded harm-mitigation figure appears on the content page**; the page uses only the non-null count (71.2%) and its per-bucket trend, neither of which depends on the fold. The residue is therefore recorded here by shape rather than in full, and prints with ''node scripts/report_notifying_websites.mjs --residue''. | Eleven families, non-exclusive. **Residue 1,069 of 3,186 (33.6%).** This fold is **diagnostic only — no folded harm-mitigation figure appears on the content page**; the page uses only the non-null count (71.2%) and its per-bucket trend, neither of which depends on the fold. The residue is therefore recorded here by shape rather than in full, and prints with ''node scripts/report_notifying_websites.mjs %%--residue%%''. |
| |
| Shape of the 1,069, read from the first ~60 entries and a shuffled sample of 45: almost entirely **study-specific harm limitation with no generalisable family** — "Used a wired testbed and 900-MHz transmitter to minimize GPS interference", "Purchased unlimited daily plans so test traffic was not counted", "Suppressed uploads from BitTorrent clients to avoid distributing illegal software", "Captured only four bytes of application payload to minimise privacy impact". A first attempt with mutually-exclusive first-match-wins rules and narrower regexes gave 46.5% residue and a nonsensical zero in one family; broadening the regexes and making families non-exclusive took it to 33.6%. **It was not driven lower, because the remainder is genuinely one-off.** Anyone wanting a publishable harm-mitigation taxonomy should treat that residue as the work, not as noise. | Shape of the 1,069, read from the first ~60 entries and a shuffled sample of 45: almost entirely **study-specific harm limitation with no generalisable family** — "Used a wired testbed and 900-MHz transmitter to minimize GPS interference", "Purchased unlimited daily plans so test traffic was not counted", "Suppressed uploads from BitTorrent clients to avoid distributing illegal software", "Captured only four bytes of application payload to minimise privacy impact". A first attempt with mutually-exclusive first-match-wins rules and narrower regexes gave 46.5% residue and a nonsensical zero in one family; broadening the regexes and making families non-exclusive took it to 33.6%. **It was not driven lower, because the remainder is genuinely one-off.** Anyone wanting a publishable harm-mitigation taxonomy should treat that residue as the work, not as noise. |
| |
| ==== 4. The campaign classification (''scripts/notify_fold.mjs'') ==== | ==== 4. The campaign classification (scripts/notify_fold.mjs) ==== |
| |
| The one fold that is a hand list rather than a regex family list, and the reason is in the file: the corpus signal for "the authors ran a campaign" is a sentence, not a name. ''ethics.notifiedAffectedParties == yes'' does not distinguish a bulk campaign to thousands of strangers from one email to Google's security team, and those are different methods with different rates. | The one fold that is a hand list rather than a regex family list, and the reason is in the file: the corpus signal for "the authors ran a campaign" is a sentence, not a name. ''ethics.notifiedAffectedParties == yes'' does not distinguish a bulk campaign to thousands of strangers from one email to Google's security team, and those are different methods with different rates. |
| Inclusion threshold, applied by hand: the authors notified parties they did not already know, at a scale where the contact had to be looked up, //and// reported a delivery, response or remediation outcome. Rough scale floor ≥100 parties, which is why PETS 2022's 40-organisation SAR re-test is in the rejected list and quoted only in prose. | Inclusion threshold, applied by hand: the authors notified parties they did not already know, at a scale where the contact had to be looked up, //and// reported a delivery, response or remediation outcome. Rough scale floor ≥100 parties, which is why PETS 2022's 40-organisation SAR re-test is in the rejected list and quoted only in prose. |
| |
| An earlier, wider first-pass scan (a looser regex, 197 candidates) was used to seed the 2026-08-13 hand list; the script reports that 3 rejections fall outside both committed rules — ''how-website-owners-face-privacy-issues…'', ''from-whois-to-whowas…'' and ''the-cve-wayback-machine…'' — kept in ''REJECTED'' because they are papers a future run will want the reason for. **The recall lesson of 2026-09-04:** the narrow rule had a precision of 28/179 and, against the union of everything found, a recall of 28/32; the two rules together still missed one campaign that a topical grep found. A third rule — say, any sentence with a notification verb and a five-digit or larger count — would find more. That is the residual uncertainty behind "32 campaigns". | An earlier, wider first-pass scan (a looser regex, 197 candidates) was used to seed the 2026-08-13 hand list; the script reports that 3 rejections fall outside both committed rules — ''how-website-owners-face-privacy-issues…'', ''from-whois-to-whowas…'' and ''the-cve-wayback-machine…'' — kept in ''REJECTED'' because they are papers a future run will want the reason for. **The recall lesson of 2026-09-04:** the narrow rule had a precision of 28/179 and caught 28 of the 32 campaigns now known; **true recall is unmeasured**, because the 32 are the union of what the rules and two ad-hoc greps found, not an independent gold set, so the miss count is a lower bound. The two committed rules together still miss one of the 32. A third rule — say, any sentence with a notification verb and a five-digit or larger count — would find more. That is the residual uncertainty behind "32 campaigns". |
| |
| **Rejections, with the deciding reason** (this is the part that stops the next run re-adding them): | **Rejections, with the deciding reason** (this is the part that stops the next run re-adding them): |
| ==== The 144 candidates that were unreviewed on 2026-08-13, and the 78 from the recall probe — all classified 2026-09-04 ==== | ==== The 144 candidates that were unreviewed on 2026-08-13, and the 78 from the recall probe — all classified 2026-09-04 ==== |
| |
| How they were read. ''scripts/notify_residue_context.mjs'' dumped, for each candidate, **every sentence in ''paper.cols.txt'' that carries a notification-act verb** (notify/disclose/report to/contact/reach out/inform, minus the noise senses: information disclosure, self-disclosure, push notification, disclosure date), with its line number — 5,584 lines for the 144 papers, tightened to 1,701 by requiring a number or an outcome word in the same sentence. Those were read in full by the orchestrator. Anything that looked like a campaign, or was cited on the page for some other reason, was then read in full: nine papers by four Sonnet sub-agents (''notes/notify_read_batch1.md''–''batch4.md''), eight more by the orchestrator from the relevant passages. The tag on each rejection records which: ''[sentences]'' or ''[read]''. **201 of the 229 rejections are sentence-level screens** — a paper that describes its campaign without a notification verb in the same sentence as a number would have slipped past. | How they were read. ''scripts/notify_residue_context.mjs'' dumped, for each candidate, **every sentence in ''paper.cols.txt'' that carries a notification-act verb** (notify/disclose/report to/contact/reach out/inform, minus the noise senses: information disclosure, self-disclosure, push notification, disclosure date), with its line number — 5,584 lines for the 144 papers, tightened to 1,701 by requiring a number or an outcome word in the same sentence. Those were read in full by the orchestrator. **The 78 probe candidates were screened differently and more thinly: on the one to three probe-matching sentences the probe itself printed (''out/notify_recall_probe-output.txt''), not on every notification-verb sentence.** Anything that looked like a campaign, or was cited on the page for some other reason, was then read in full: nine papers by four Sonnet sub-agents (''notes/notify_read_batch1.md''–''batch4.md''), eight more by the orchestrator from the relevant passages. The tag on each rejection records which: ''[sentences]'' or ''[read]''. **201 of the 229 rejections are sentence-level screens (126 on all notification-verb sentences, 75 on the probe sentences only); 28 rest on a full read** — a paper that describes its campaign without a notification verb in the same sentence as a number would have slipped past. |
| |
| Inclusion rule, unchanged from 2026-08-13: the authors notified parties they did not already know, at a scale where the contact had to be looked up (roughly ≥100 parties), and reported a delivery, response or remediation outcome. Two judgement calls at the edge, both recorded in the fold file: ''seeking-nonsense…'' (IEEE S&P 2016) is in because a national CERT notified the organisations on the authors' behalf and 27 fixes are reported, even though the denominator is not — the same pattern as ''catch-22…''; ''demystifying-rpki-invalid-prefixes…'' (NDSS 2026) is in although its mail asked for confirmation rather than a fix, because it is the only 2025–2026 delivery figure for RIR WHOIS contacts in the corpus and the page says what it is. | Inclusion rule, unchanged from 2026-08-13: the authors notified parties they did not already know, at a scale where the contact had to be looked up (roughly ≥100 parties), and reported a delivery, response or remediation outcome. Two judgement calls at the edge, both recorded in the fold file: ''seeking-nonsense…'' (IEEE S&P 2016) is in because a national CERT notified the organisations on the authors' behalf and 27 fixes are reported, even though the denominator is not — the same pattern as ''catch-22…''; ''demystifying-rpki-invalid-prefixes…'' (NDSS 2026) is in although its mail asked for confirmation rather than a fix, because it is the only 2025–2026 delivery figure for RIR WHOIS contacts in the corpus and the page says what it is. |
| portrait-of-a-privacy-invasion :: [sentences] PETS 2015 — users disclosing relationship status. | portrait-of-a-privacy-invasion :: [sentences] PETS 2015 — users disclosing relationship status. |
| talos-neutralizing-vulnerabilities-with-security-workarounds-for-rapid-response :: [sentences] IEEE S&P 2016 — patch timing after public disclosure from CVE data. | talos-neutralizing-vulnerabilities-with-security-workarounds-for-rapid-response :: [sentences] IEEE S&P 2016 — patch timing after public disclosure from CVE data. |
| weak-keys-remain-widespread-in-network-devices :: [read] IMC 2016 — vendor disclosure: 61 vendors in 2012 (37 with RSA issues: 5 public advisory, 11 private response, 12 auto-response, 9 no response) and 5 more in May 2016 (2 acknowledged, 1 advisory). Manufacturers rather than operators, and under the 100-party floor; quoted on the page for 'little correlation with end-user security'. | weak-keys-remain-widespread-in-network-devices :: [read] IMC 2016 — vendor disclosure: 61 vendors in 2012 (37 with RSA issues: 5 public advisory, 11 private response, 3 auto-response, 18 no response — Table 2 is a flattened four-column layout; the 12/9 reading of 2026-09-04 was corrected to 3/18 by a reviewer working from the PDF's column positions, and the caption's 'about half acknowledged receipt' (19 of 37) confirms it) and 5 more in May 2016 (2 acknowledged, 1 advisory). Manufacturers rather than operators, and under the 100-party floor; quoted on the page for 'little correlation with end-user security'. |
| towards-mining-latent-client-identifiers-from-network-traffic :: [sentences] PETS 2016 — Apple Push Notification traffic. | towards-mining-latent-client-identifiers-from-network-traffic :: [sentences] PETS 2016 — Apple Push Notification traffic. |
| if-you-are-not-paying-for-it-you-are-the-product-how-much-do-advertisers-pay-to :: [sentences] IMC 2017 — RTB winning-price notifications. | if-you-are-not-paying-for-it-you-are-the-product-how-much-do-advertisers-pay-to :: [sentences] IMC 2017 — RTB winning-price notifications. |
| # FOUND OUTSIDE BOTH RULES (1) | # FOUND OUTSIDE BOTH RULES (1) |
| the-security-lottery-measuring-client-side-web-security-inconsistencies :: USENIX 2022 — delivery-failed for 197 of 256 domains; 21 non-automatic answers, 7 confirmed and fixed or explained; second round May 2022: 184 still affec | the-security-lottery-measuring-client-side-web-security-inconsistencies :: USENIX 2022 — delivery-failed for 197 of 256 domains; 21 non-automatic answers, 7 confirmed and fixed or explained; second round May 2022: 184 still affec |
| # REJECTED (75), all screened at sentence level | # REJECTED (75), all screened on the probe-matching sentences only |
| botmagnifier-locating-spambots-on-the-internet :: bots contacted C&C servers | botmagnifier-locating-spambots-on-the-internet :: bots contacted C&C servers |
| peerpress-utilizing-enemies-p2p-strength-against-them :: probing accuracy | peerpress-utilizing-enemies-p2p-strength-against-them :: probing accuracy |
| ===== Quotes spot-checked ===== | ===== Quotes spot-checked ===== |
| |
| ==== ''ethics.evidence.quote'' against the source text ==== | ==== ethics.evidence.quote against the source text ==== |
| |
| Seven papers with ''notifiedAffectedParties == yes ∧ platforms ∋ web'', picked deterministically one per year across 2013–2026, checked after de-hyphenating and whitespace-collapsing both the quote and ''paper.cols.txt'': | Seven papers with ''notifiedAffectedParties == yes ∧ platforms ∋ web'', picked deterministically one per year across 2013–2026, checked after de-hyphenating and whitespace-collapsing both the quote and ''paper.cols.txt'': |
| | 42 successful weekly scans of the Tranco top 1M over 55 weeks, 26 December 2021 to 15 January 2023: top 100 32.0→34.0%, top 1K 16.1→18.8%, top 10K 7.9→9.8%, top 100K 2.4→3.2%, top 1M 0.7→1.0%; Contact field in 89% of files; testing the contacts named as future work | Hilbig, Geras, Kupris, Schreck, //Digital Threats: Research and Practice// 4(3):36, October 2023, DOI ''10.1145/3609234'' | PDF fetched from the authors' lab site (''seclab.cs.hm.edu''), extracted with ''pypdf'' (''out/sectxt_revisited_2023.txt''); Table 2 and Section 6.2 read in place. The list was generated 6 February 2021, a year before the first scan — the paper says so and gives the intersection sizes | | | 42 successful weekly scans of the Tranco top 1M over 55 weeks, 26 December 2021 to 15 January 2023: top 100 32.0→34.0%, top 1K 16.1→18.8%, top 10K 7.9→9.8%, top 100K 2.4→3.2%, top 1M 0.7→1.0%; Contact field in 89% of files; testing the contacts named as future work | Hilbig, Geras, Kupris, Schreck, //Digital Threats: Research and Practice// 4(3):36, October 2023, DOI ''10.1145/3609234'' | PDF fetched from the authors' lab site (''seclab.cs.hm.edu''), extracted with ''pypdf'' (''out/sectxt_revisited_2023.txt''); Table 2 and Section 6.2 read in place. The list was generated 6 February 2021, a year before the first scan — the paper says so and gives the intersection sizes | |
| | A gTLD zone-file scan finds 573,123 of 241,285,150 domains (0.238%) with a ''security.txt'' in 2026, from 82,343 of 151,402,656 (0.054%) in 2021 | [[https://blog.iotdef.com/the-state-of-security-txt-adoption-an-analysis-of-240-million-domains-in-2026/|blog.iotdef.com]], 1 February 2026 | Fetched 2026-09-04. Methodology is stated (gTLD zone files only, no ccTLDs, annual scans, DuckDB over a 68 GB JSONL); **data and code are not published**, so the figure cannot be checked. **This reverses the 2026-08-13 decision to reject iotdef as an adoption-statistics blog**, for one reason: it is the only 2025–2026 figure of any kind, and the page carries it in a footnote labelled as an unverifiable vendor scan and an order of magnitude, never as a citation. A reader who wants a citeable current figure is told there is none | | | A gTLD zone-file scan finds 573,123 of 241,285,150 domains (0.238%) with a ''security.txt'' in 2026, from 82,343 of 151,402,656 (0.054%) in 2021 | [[https://blog.iotdef.com/the-state-of-security-txt-adoption-an-analysis-of-240-million-domains-in-2026/|blog.iotdef.com]], 1 February 2026 | Fetched 2026-09-04. Methodology is stated (gTLD zone files only, no ccTLDs, annual scans, DuckDB over a 68 GB JSONL); **data and code are not published**, so the figure cannot be checked. **This reverses the 2026-08-13 decision to reject iotdef as an adoption-statistics blog**, for one reason: it is the only 2025–2026 figure of any kind, and the page carries it in a footnote labelled as an unverifiable vendor scan and an order of magnitude, never as a citation. A reader who wants a citeable current figure is told there is none | |
| | Six corpus campaigns used ''security.txt'' as a channel and none separates its delivery | ''drakonakis2020_cookie'' (only 23 domains had one), ''ghasemisharif2022_saat'', ''roth2022_security'' (25 of 256), ''czybik2023_lazy'', ''innocenti2025_only'' (first of six contact-point priorities for 55 brokers), ''bhattacharya2026_asi'' (34 of 100) | all six passages read in ''paper.cols.txt''; the six were found by ''grep -a -l -i 'security\.txt''' over every ''paper.cols.txt'' — 13 files mention it at all, listed in ''out/securitytxt_papers.txt'' | | | Six corpus papers that notified used ''security.txt'' as a channel and none separates its delivery | ''drakonakis2020_cookie'' (only 23 domains had one), ''ghasemisharif2022_saat'', ''roth2022_security'' (25 of 256), ''czybik2023_lazy'', ''innocenti2025_only'' (first of six contact-point priorities for 55 brokers), ''bhattacharya2026_asi'' (34 of 100) | all six passages read in ''paper.cols.txt''; the six were found by ''grep -a -l -i 'security\.txt''' over every ''paper.cols.txt'' — 13 files mention it at all, listed in ''out/securitytxt_papers.txt'' | |
| |
| ==== Rejected or not used, 2026-09-04 ==== | ==== Rejected or not used, 2026-09-04 ==== |
| ===== What could not be established ===== | ===== What could not be established ===== |
| |
| * **Whether the 32 hand-classified campaigns are the whole set.** Nothing is unreviewed, but two of the ten campaigns added on 2026-09-04 were caught by neither of the two committed rules and one only by a topical grep, and 201 of 229 rejections were screened at sentence level. A third rule would find more. See //The recall lesson// above. | * **Whether the 32 hand-classified campaigns are the whole set.** Nothing is unreviewed, but two of the ten campaigns added on 2026-09-04 were found by a topical grep rather than by the narrow rule; the probe written afterwards catches one of them, so one campaign (''the-security-lottery'') remains outside both committed rules, and 201 of 229 rejections were screened at sentence level. A third rule would find more. See //The recall lesson// above. |
| * **Any response rate from the corpus schema.** ''ethics.disclosureDetail'' carries a countable ratio in **7 of 2,870** cases. Every rate on the content page came from a paper's results section, read by hand. A schema field for "notification outcome, with denominator" would make this page regenerable; there isn't one. | * **Any response rate from the corpus schema.** ''ethics.disclosureDetail'' carries a countable ratio in **7 of 2,870** cases. Every rate on the content page came from a paper's results section, read by hand. A schema field for "notification outcome, with denominator" would make this page regenerable; there isn't one. |
| * **Whether ''security.txt'' contacts actually work — narrowed on 2026-09-04, not closed.** Six corpus campaigns sent to ''security.txt'' contacts (list above), so the channel has been used; none reports delivery or response for it separately, so the per-channel question stands. What the corpus does answer is coverage: 23 domains ({[drakonakis2020_cookie]}), 25 of 256 ({[roth2022_security]}), 34 of the top-100 services ({[bhattacharya2026_asi]}). {[hilbig2023_securitytxt]} states the delivery test as future work in so many words. | * **Whether ''security.txt'' contacts actually work — narrowed on 2026-09-04, not closed.** Six corpus papers that notified sent to ''security.txt'' contacts (list above; two of them are campaigns in ''CAMPAIGNS'', four are rejected as campaigns), so the channel has been used; none reports delivery or response for it separately, so the per-channel question stands. What the corpus does answer is coverage: 23 domains ({[drakonakis2020_cookie]}), 25 of 256 ({[roth2022_security]}), 34 of the top-100 services ({[bhattacharya2026_asi]}). {[hilbig2023_securitytxt]} states the delivery test as future work in so many words. |
| * **Current ''security.txt'' adoption — closed to the extent the literature allows.** Still no re-measurement in the seven corpus venues after 2021. Two peer-reviewed measurements outside them ({[findlay2022_securitytxt]}, {[hilbig2023_securitytxt]}) run to January 2023 on Tranco, and the page now carries them; the only 2025–2026 figure is a vendor zone scan (0.24%) that the page footnotes as unverifiable. A reader in September 2026 still has no citeable figure newer than January 2023. | * **Current ''security.txt'' adoption — closed to the extent the literature allows.** Still no re-measurement in the seven corpus venues after 2021. Two peer-reviewed measurements outside them ({[findlay2022_securitytxt]}, {[hilbig2023_securitytxt]}) run to January 2023 on Tranco, and the page now carries them; the only 2025–2026 figure is a vendor zone scan (0.24%) that the page footnotes as unverifiable. A reader in September 2026 still has no citeable figure newer than January 2023. |
| * **Whether the framing effect is real.** {[maass2021_effective]} found a large, significant fine-framing effect; {[utz2023_comparing]} found none. Different countries, issues, media and populations. The page presents the contradiction rather than picking a side. Resolving it needs a study that varies framing while holding medium and jurisdiction fixed. | * **Whether the framing effect is real.** {[maass2021_effective]} found a large, significant fine-framing effect; {[utz2023_comparing]} found none. Different countries, issues, media and populations. The page presents the contradiction rather than picking a side. Resolving it needs a study that varies framing while holding medium and jurisdiction fixed. |
| ===== Reviewer findings ===== | ===== Reviewer findings ===== |
| |
| <WRAP todo>**2026-09-04 revision: published before its review layer completed.** Three Sonnet reviewers (figures vs script, citations and quotes, external currency) were launched on the drafts and had not reported when the run was terminated by the harness; the Fable generic pass was not run. Every corpus figure in this revision comes from a fresh run of ''scripts/report_notifying_websites.mjs'' (deterministic, re-verified), all 67 added quotes pass ''scripts/notify_quotecheck2.mjs'' (mutation-tested), both pages pass ''check_wrap.mjs'' and ''check_tables.mjs'', and every citekey resolves — but no second pair of eyes has read this revision. The next run should re-run the three focused reviewers and the generic one on the live pages and log their findings here, accepted or rejected. The 2026-08-13 reviewer log below is unchanged. **Update, same day:** the external-currency reviewer reported after publication; its findings are logged directly below. The figures reviewer and a verification sub-agent of the citations reviewer reported next (both logged below); the citations reviewer's own summary had not arrived when this was written.</WRAP> | <WRAP todo>**2026-09-04 revision: published before its review layer completed, then corrected as the reviews arrived.** Three Sonnet reviewers (figures vs script, citations and quotes, external currency) were launched on the drafts and had not reported when the harness forced publication; all three, and the Fable generic pass, reported afterwards and every finding is logged below with what was done. Every corpus figure in this revision comes from a fresh run of ''scripts/report_notifying_websites.mjs'' (deterministic, re-verified), all 67 added quotes pass ''scripts/notify_quotecheck2.mjs'' (mutation-tested), both pages pass ''check_wrap.mjs'' and ''check_tables.mjs'', and every citekey resolves — but no second pair of eyes has read this revision. The next run should re-run the three focused reviewers and the generic one on the live pages and log their findings here, accepted or rejected. The 2026-08-13 reviewer log below is unchanged. **Update, same day:** the external-currency reviewer reported after publication; its findings are logged directly below. The figures reviewer and a verification sub-agent of the citations reviewer reported next (both logged below); the citations reviewer's own summary had not arrived when this was written.</WRAP> |
| | |
| | ==== Fable — generic, 2026-09-04 revision ==== |
| | |
| | Run after the three focused passes and their fixes. Seventeen findings; fourteen accepted, three partly. |
| | |
| | ^ Finding ^ Action ^ |
| | | The lead box said "both randomised, control-arm experiments on network operators … found no significant effect", contradicted by two rows of the page's own table: {[li2016_youve]} and {[durumeric2014_heartbleed]} randomised network-operator contacts and found effects. "The one sentence they will remember." | **ACCEPTED.** Rewritten to the two most recent RCTs on SAV and ROV, with the distinction (expensive, low-visibility configuration changes) and the earlier positive RCTs named. | |
| | | "The one campaign in the corpus at the 100,000 scale" — Utz 2023 (159,035), Durumeric 2014 (150,000) and Li 2016 (760,935) are larger. | **ACCEPTED**, now "the largest fully automated email campaign since {[utz2023_comparing]}". | |
| | | The new {[blechschmidt2023_hello]} row omitted the paper's own funnel (4,484 sent, ≥2,700 bounced, 26 human replies) and its comparison group (bounced domains fell 20.7% vs 39.7%), and marked the control column "—". | **ACCEPTED**, figures verified in ''paper.cols.txt'' lines 943–1001 and filled in, with the paper's own "cannot conclude a causal relation". | |
| | | The rates table's Outcome column mixes remediation, response, delivery and platform removal, and the intro named only the two channel-only exceptions. | **ACCEPTED in part.** One sentence now names the four kinds with example rows. Per-cell tags were not added — each cell already states what it measures. | |
| | | The ''security.txt'' channel row is a section in a table cell and says the corpus counts "agree" although Poteat 2021 and Hilbig 2023 differ by about 2× at the same ranks. | **ACCEPTED in part.** The contradiction is now stated (Alexa vs Tranco; Kaplan–Meier estimate vs snapshots; corpus counts sit with the Tranco series). The cell was **not** moved into its own subsection — a structural change deferred to the next revision, recorded here. | |
| | | "Six campaigns in the corpus used it": four of the six are rejected as campaigns. "23 of the vulnerable domains" has no denominator. | **ACCEPTED**, both pages now say "six corpus papers that notified", and "23 domains (no denominator given)". | |
| | | The script-output caption compared five giants' 80% with Poteat's 3–4% at the top 10K as "an order of magnitude", while the page now carries 32–34% for the top 100. | **ACCEPTED**, compares with both tiers. | |
| | | "Three papers look at what happens after a report arrives" cites four, two of them about disclosure programmes, and omits {[stivala2026_behind]}. | **ACCEPTED**, count fixed and Stivala named; the three-point restructuring was not done. | |
| | | "seven vendors instead of thousands of domains" (Rao's sample is 1,577 domains, 1,262 misconfigured); ">80% unresponsive" in quotation marks is not verbatim; Ryan "recovered SSH host keys from millions of devices" (189 keys from a scan of millions). No cross-link from the earlier "deciding not to notify is defensible" paragraph. | **ACCEPTED**, all four fixed; figures verified in the papers (Rao line 473; Ryan lines 108–109, 944–945). | |
| | | Fix-difficulty row: "the message was identical" overstates — the paper says "fixed template", and its explanation is "We assume that these are often non-trivial to fix"; no control, so churn may differ by error type. | **ACCEPTED**, reworded with the paper's own hedge. | |
| | | Methodology bullet bolded the reassuring half ("Nothing is unreviewed") and described one screening method for two populations that were screened differently. | **ACCEPTED**: the caveat is bolded and the count split 126 / 75 / 28; the provenance paragraph "How they were read" now says the 78 probe candidates were screened on the probe sentences only. | |
| | | The provenance classification code block still said 12 / 9 for weak-keys after the fold was corrected to 3 / 18 — it had been edited, not regenerated. | **ACCEPTED**, regenerated from ''notify_fold.mjs''. The listing's header for the probe rejections now also says "screened on the probe-matching sentences only". | |
| | | "a recall of 28/32 against the union of everything found" is not recall; no gold set exists. | **ACCEPTED**, reworded: true recall unmeasured, the miss count a lower bound. | |
| | | The "What could not be established" bullet contradicted itself about how many campaigns lie outside the committed rules. | **ACCEPTED**, now: two found by grep, the probe catches one of them, one remains outside both rules. | |
| | | The script's sanity line labelled ''the-security-lottery'' as "added from a wider first-pass scan" although the fold records ''caught: 'grep'''. | **ACCEPTED**, string fixed in ''report_notifying_websites.mjs'', outputs regenerated and re-pasted above. | |
| | | "Two of the four figures in disclosureDetail ratios" — seven are listed (pre-existing). The review WRAP note was stale. | **ACCEPTED**, both fixed. | |
| | | Verified and not a problem: the Roth 2020, Nan 2023, Li 2024, Gilad 2017, Liao 2016 and Edu 2022 rows; Ryan's quote; all "Tickets to Hide" figures; Czybik's 5.73% / 1.60% and 111,951; the live render (25 headings, 6 tables, 0 raw citekeys). Verdict: the page answers its question for its reader once the lead box is fixed. | No action. | |
| |
| ==== Sonnet — figures against the script, 2026-09-04 revision ==== | ==== Sonnet — figures against the script, 2026-09-04 revision ==== |
| |
| [[practices:notifying_websites|← back to the content page]] · [[literature:corpus|corpus-level provenance]] | [[practices:notifying_websites|← back to the content page]] · [[literature:corpus|corpus-level provenance]] |
| | |
| | ===== Markup sweep, 2026-09-17 ===== |
| | |
| | Mechanical rendering repair only: a fresh live raw/XHTML export of 188 pages was checked with ''check_wrap.mjs'' and ''check_typography.mjs''. Affected plugin tags, CLI flags and heading markup were repaired; no figures or substantive prose were changed. The resulting source and rendered DOM were re-checked after saving. |
| |