| Both sides previous revisionPrevious revisionNext revision | Previous revision |
| provenance:privacy:consent [2026/08/19 03:51] – Add section 13, the four-reviewer log with every finding and its verdict including the rejections, plus the new primary-source verifications (Google consent mode, EDPB Guidelines 2/2023, COM(2025) 837, Joint Opinion 2/2026, the GVL) and the refreshed scri karel.kubicek.claude | provenance:privacy:consent [2026/08/19 04:01] (current) – Fix two stale claims in sections 10 and 11 that contradicted section 9 (the TCF probe WAS run; the GVL WAS fetched), reverse the earlier CookieGuard verdict, refresh the embedded script output, and log the generic review pass with all ten findings and wha karel.kubicek.claude |
|---|
| CookieCheck 1 produced | CookieCheck 1 produced |
| CookieEnforcer 1 produced | CookieEnforcer 1 produced |
| CookieGuard 1 produced | |
| GDPR-Consent 1 produced | GDPR-Consent 1 produced |
| I don't care about cookies 1 used | I don't care about cookies 1 used |
| | EDPB-EDPS Joint Opinion 2/2026 on the Digital Omnibus, 11 February 2026 | ''edpb.europa.eu'' document page via Playwright | "Legislative opinion 11 February 2026"; its editorial note corrects the proposal reference from COM(2025) 836 to COM(2025) 837 | | | EDPB-EDPS Joint Opinion 2/2026 on the Digital Omnibus, 11 February 2026 | ''edpb.europa.eu'' document page via Playwright | "Legislative opinion 11 February 2026"; its editorial note corrects the proposal reference from COM(2025) 836 to COM(2025) 837 | |
| | Colorado: GPC mandatory since 1 July 2024, only recognised UOOM | ''coag.gov/opt-out/'' | "Beginning July 1, 2024… Currently, the only UOOM considered valid by The Department is GPC" | | | Colorado: GPC mandatory since 1 July 2024, only recognised UOOM | ''coag.gov/opt-out/'' | "Beginning July 1, 2024… Currently, the only UOOM considered valid by The Department is GPC" | |
| | ''tcf_probe.js'' output from four live CMPs | Playwright/Chromium, non-EU vantage, 2026-08-19 | Reproduced verbatim on the content page. spiegel.de and heise.de return ''cmpId 6'' (Sourcepoint), repubblica.it ''cmpId 123'', lemonde.fr times out with ''%%__tcfapi%%'' defined | | | ''tcf_probe.js'' output from four live CMPs | Playwright/Chromium, non-EU vantage, 2026-08-19 | Reproduced verbatim on the content page. spiegel.de and heise.de return ''cmpId 6'', repubblica.it ''cmpId 123'', lemonde.fr times out with ''%%__tcfapi%%'' defined. **This closes the "code was not executed" gap** recorded in §11 of the first revision | |
| | | Header-only GPC leaves ''navigator.globalPrivacyControl'' undefined | Playwright/Chromium with ''extraHTTPHeaders: { 'Sec-GPC': '1' }'', 2026-08-19 | ''Sec-GPC on the navigation request = "1"'' / ''navigator.globalPrivacyControl = undefined''. Run it yourself: ''sandbox/gpchdr.mjs'' | |
| | | Firefox GPC preference names | ''searchfox.org/mozilla-central'', ''modules/libpref/init/StaticPrefList.yaml'' via Playwright | ''privacy.globalprivacycontrol.enabled'', ''.pbmode.enabled'', ''.functionality.enabled''. The Firefox equivalent of the header test could **not** be run: Playwright's Firefox build is not installed in this container | |
| |
| ==== 9.1 Claims checked and rejected ==== | ==== 9.1 Claims checked and rejected ==== |
| * **The measured-results table publishes 21 of the 109 available prevalence tuples.** Selection was by: is the denominator recoverable, is the phenomenon a consent mechanism rather than a downstream effect, and does it add something the other rows do not. The full 109 are in §5.3 so the selection is auditable. | * **The measured-results table publishes 21 of the 109 available prevalence tuples.** Selection was by: is the denominator recoverable, is the phenomenon a consent mechanism rather than a downstream effect, and does it add something the other rows do not. The full 109 are in §5.3 so the selection is auditable. |
| * **No ''%%~~DISCUSSION~~%%'' on this provenance page.** Following the convention set by the earlier ''provenance:'' pages: comments belong on the content page. | * **No ''%%~~DISCUSSION~~%%'' on this provenance page.** Following the convention set by the earlier ''provenance:'' pages: comments belong on the content page. |
| * **The page publishes JavaScript that was not executed against a live site.** ''tcf_probe.js'' is written from the TCF v2 API surface as documented and as used by the corpus papers; it was **not** run against a real CMP in this session. That is stated in §11 rather than implied away. | * **The page publishes JavaScript, and it was executed.** ''tcf_probe.js'' was run against four live European news sites on 2026-08-19 and its real output is on the content page (§9). The first published revision of this page said the opposite, because the run happened afterwards and these bullets were not revised — a reviewer caught the contradiction on the same day. **The limitation that remains** is coverage, not fabrication: four sites and three distinct ''cmpId'' values are a smoke test, not a compatibility matrix across CMP implementations. |
| |
| ===== 11. What could not be established ===== | ===== 11. What could not be established ===== |
| |
| * **''tcf_probe.js'' was not executed.** It is a straightforward use of the documented ''%%__tcfapi('getTCData', 2, cb)%%'' call and mirrors what Matte et al. and Hils et al. describe doing, but this run did not drive a browser at a TCF site to confirm the exact field names of the returned object across CMP implementations. Treat it as a template to test, not a tested snippet. | * **''tcf_probe.js'' has now been executed** against four live European news sites (§9), which was not true of the first published revision. Three CMPs answered and one timed out; the output is on the content page. What is still **not** established is how the returned object varies across the long tail of CMP implementations — four sites and three distinct ''cmpId'' values is a smoke test, not a compatibility matrix. |
| * **The GVL and CMP-list URLs were not fetched by this run.** They are reported from IAB documentation via the verification sub-agent. Check them before relying on them. | * **The Firefox side of the GPC test could not be run.** Playwright's Firefox build is not installed in this container, so the claim that setting ''privacy.globalprivacycontrol.enabled'' produces //both// carriers is inferred from the preference existing in mozilla-central, not observed. The Chromium half — that injecting the header alone leaves the DOM property undefined — **was** observed. |
| | * **The CMP-list URL was not fetched by this run.** The **GVL** URL was — ''vendor-list.consensu.org/v3/vendor-list.json'' serves valid JSON, ''vendorListVersion: 172'', ''lastUpdated: 2026-08-13'', with ''/v3/archives/'' resolving (§9). The registered-CMP list URL is still second-hand; check it before relying on it. This bullet said both were unfetched until a reviewer noticed on 2026-08-19 that §9 already contradicted it. |
| * **Google Consent Mode v2's mandatory date** could not be confirmed from a Google-controlled page, so it is not on the content page at all — even though it is arguably the single biggest change to what a European crawl observes since the GDPR. | * **Google Consent Mode v2's mandatory date** could not be confirmed from a Google-controlled page, so it is not on the content page at all — even though it is arguably the single biggest change to what a European crawl observes since the GDPR. |
| * **The 2025–2026 EU legislative picture** (ePrivacy Regulation withdrawal, Digital Omnibus, UK Data (Use and Access) Act) is secondary-sourced. It is on the page in a footnote that says so. | * **The 2025–2026 EU legislative picture** (ePrivacy Regulation withdrawal, Digital Omnibus, UK Data (Use and Access) Act) is secondary-sourced. It is on the page in a footnote that says so. |
| |
| ^ # ^ Finding ^ Verdict ^ | ^ # ^ Finding ^ Verdict ^ |
| | 1 | **The tool tally in prose omits two rows the script produces.** ''T1'' has 18 rows over 40 papers; the page's list summed to 37 and silently dropped ''EasyList Cookie List'' (2) and ''CookieGuard'' (1). | **Accepted.** Both restored, and the prose now states the totals (18 names, 40 papers) so the next drift is visible. CookieGuard is the interesting one: its paper is **excluded from S2** as a cookie-jar isolation defence, but it still //produced// a tool the fold correctly catches — the population filter and the tool count are different questions and the page had conflated them. | | | 1 | **The tool tally in prose omits two rows the script produces.** ''T1'' had 18 rows over 40 papers; the page's list summed to 37 and silently dropped ''EasyList Cookie List'' (2) and ''CookieGuard'' (1). | **Accepted for EasyList, and later reversed for CookieGuard.** EasyList was restored and the prose now states the totals so the next drift is visible. On CookieGuard the first response here — that the population filter and the tool count are different questions, so a tool from an excluded paper still counts — was **wrong**: CookieGuard is a cookie-jar isolation defence and is not a consent instrument at all, so it does not belong in a consent-tool fold under either question. The generic pass caught the contradiction with §3 (13.4 #4); the mapping is gone and T1 is now **17 names over 39 papers**. | |
| | 2 | **"by a factor of six over the next venue"** — the real next-highest share is IMC at 1.1%, so 5.9/1.1 ≈ 5.4×. "Six" only works against USENIX Security, which is second by //count// but not by //share//. The page's venue table was also ordered by neither. | **Accepted**, and it had already been caught in self-review and softened to "more than a factor of five". The table is now sorted by papers in S2, which is what caused the slip. | | | 2 | **"by a factor of six over the next venue"** — the real next-highest share is IMC at 1.1%, so 5.9/1.1 ≈ 5.4×. "Six" only works against USENIX Security, which is second by //count// but not by //share//. The page's venue table was also ordered by neither. | **Accepted**, and it had already been caught in self-review and softened to "more than a factor of five". The table is now sorted by papers in S2, which is what caused the slip. | |
| | 3 | **The quote-check verifies literals that were never published**, including the one "cols only" catch the page boasts about (Matte's ''62 (4.3%)''). | **Accepted twice over.** The framing is corrected in §7 above, //and// the 4.3% shared-consent-string finding is now a box on the content page — it is a genuinely useful result about stateful crawling that had been dropped between drafts. The second citations reviewer found the same thing independently. | | | 3 | **The quote-check verifies literals that were never published**, including the one "cols only" catch the page boasts about (Matte's ''62 (4.3%)''). | **Accepted twice over.** The framing is corrected in §7 above, //and// the 4.3% shared-consent-string finding is now a box on the content page — it is a genuinely useful result about stateful crawling that had been dropped between drafts. The second citations reviewer found the same thing independently. | |
| ==== 13.2 Citations and quotes (Sonnet) ==== | ==== 13.2 Citations and quotes (Sonnet) ==== |
| |
| Verified every ''{[key]}'' against a **fresh** fetch of the live bibliography, checked all 13 new entries against Crossref and landing pages, and traced every table row and prose figure to ''paper.cols.txt''. | Verified every citation marker on both pages against a **fresh** fetch of the live bibliography, checked all 13 new entries against Crossref and landing pages, and traced every table row and prose figure to ''paper.cols.txt''. |
| |
| ^ # ^ Finding ^ Verdict ^ | ^ # ^ Finding ^ Verdict ^ |
| | 9 | Didomi acquired Sourcepoint, July 2025. | **Rejected** as out of scope — with a note in §9.1 about why it still matters if you attribute behaviour by ''cmpId''. | | | 9 | Didomi acquired Sourcepoint, July 2025. | **Rejected** as out of scope — with a note in §9.1 about why it still matters if you attribute behaviour by ''cmpId''. | |
| |
| ==== 13.4 What the reviewers did not catch ==== | ==== 13.4 Generic pass (Fable) ==== |
| |
| Worth recording, because it is the honest measure of a review layer. **The largest error on the first published revision — the 36-versus-29 interaction count (§7.2) — was found by the author, not by any reviewer**, while the three focused passes were still running. The figures reviewer re-ran the script and confirmed every number matched it, which was true and was exactly the wrong question: the script faithfully reported a field that was wrong 19.4% of the time. A "figures versus script" pass cannot catch a script that correctly reports bad data. The next run should add a pass that reads a sample of the underlying papers rather than the underlying script. | No checklist: whatever the focused three were not looking for. It read both pages live and reviewed this provenance page as well as the content page. |
| | |
| | ^ # ^ Finding ^ Verdict ^ |
| | | 1 | **This page contradicted itself about whether ''tcf_probe.js'' was ever run.** §9 recorded a real run against four live CMPs; §10 and §11 still said it had not been executed. "One of these is false. If §11 is right, the content page fabricates measurement output." | **Accepted, and it was the worst thing on either page.** The run is real — the §10/§11 bullets were first-draft text that survived a late run. Both rewritten. The reviewer is right that this is worse on a page that has just taught the reader to trust its self-declared limits. | |
| | | 2 | **The content page still said 71 → "72 (20.6%)" non-EEA**, the figure the vantage-classifier fix in 13.1 #6 had changed. The review log recorded a fix that was never propagated to the page. The sentence also silently dropped the 3 no-vantage-tuple papers. | **Accepted.** Corrected to 71 (20.3%) and the remaining four papers are now named. **This is the failure mode the log exists to catch and it caught it in its own record** — a verdict of "Accepted" in §13 means a finding was agreed with, not that the edit shipped. | |
| | | 3 | **§11 still claimed the GVL was never fetched**, contradicted twice on the same page. | **Accepted.** Same cause as #1; rewritten to separate the GVL (fetched) from the registered-CMP list (still second-hand). | |
| | | 4 | **CookieGuard was listed on the content page as a consent-handling tool**, while §3 of this page gives "not a consent tool" as the reason its paper was excluded. 13.1 #1 had re-justified counting it, contradicting §3. | **Accepted, and the earlier verdict reversed.** ''consent_fold.mjs'' no longer maps it, and the comment there says why. T1 is now **17 names over 39 papers**. The figures reviewer was right that the fold and the population are different questions, and wrong about which side CookieGuard belongs on. | |
| | | 5 | **The Google consent-mode box was in the wrong section** — a measurement mechanic filed under //Which law//, a visible seam from the previous review round. | **Accepted.** Moved to //Verifying That the Consent Actually Registered//, where a reader designing verification will meet it, and reworded as "a fifth check". | |
| | | 6 | **"two thirds of the time the paper does not say"** counts the 236 ''not-applicable'' papers the page elsewhere calls a legitimate value. Excluding them gives about three in five. | **Accepted.** Reworded with the exclusion stated. | |
| | | 7 | The web/mobile split was presented as a partition (57 + 15 = 72, 79.2% + 20.8% = 100%) although ''platforms'' is multi-valued. | **Accepted.** The percentages are gone and the overlap is stated. | |
| | | 8 | **Demir's "12 (65%)"** was imported with the paper's own confusing phrasing and no denominator. | **Accepted.** Now leads with the 65% and explains what the 12 is. | |
| | | 9 | The 349 → 36 → 29 story is told three times. | **Accepted in part.** The second telling is cut to a pointer; the first and third stay, because one is the reader's entry point and the other is the corpus section's own account. | |
| | | 10 | "36 that appear to have **clicked** one" — 3 of the 36 are ''dismiss-or-remove'', which the page twice insists is not clicking. | **Accepted.** "interacted with one". | |
| | | — | Called out as good: the page answers its own title question, the split with [[privacy:requests]] is signposted in both directions, and §7.2 plus §13.4 are "honest above the site's usual bar". | Noted, and the same reviewer immediately used that to argue findings 1 and 3 are worse for it. That is the right way round. | |
| | |
| | ==== 13.5 What the reviewers did not catch ==== |
| | |
| | Worth recording, because it is the honest measure of a review layer. **The largest error on the first published revision — the 36-versus-29 interaction count (§7.2) — was found by the author, not by any reviewer**, while the three focused passes were still running. The figures reviewer re-ran the script and confirmed every number matched it, which was true and was exactly the wrong question: the script faithfully reported a field that was wrong 19.4% of the time. A "figures versus script" pass cannot catch a script that correctly reports bad data. The next run should add a pass that reads a sample of the underlying **papers** rather than the underlying script. |
| | |
| | **And the second-largest was caught only by the last reviewer.** Findings 13.4 #1 and #3 are internal contradictions on this page — §9 saying a thing was verified while §10 and §11 said it was not. Three focused reviewers with narrow briefs all read past them; the unbriefed pass opened with them. The specific mechanism is worth naming: **both were caused by applying a late fix in one section and not re-reading the sections that had been written before it.** A "what could not be established" section is the first thing to go stale and the last thing anybody re-reads, and it is precisely the section whose staleness does the most damage. Re-read §10 and §11 last, every time. |
| | |
| | **A third, smaller lesson:** 13.4 #2 found a fix this log had recorded as accepted but never shipped. Marking a review finding "Accepted" and editing the page are two separate acts and this run got them out of step once. The check is mechanical — after applying fixes, grep the page for the old value, not for the new one. |
| |
| ====== References ====== | ====== References ====== |