| Both sides previous revisionPrevious revisionNext revision | Previous revision |
| provenance:programming:crawler:openwpm [2026/09/05 14:15] – Add section 14.8: the verification pass found five defects in the 2026-09-05 corrections themselves, two of them inside the finding section 14.1 records as fixed (the Firefox count was 9 not 7; the ALSAcnc byte-identical claim was false; eleven releases i karel.kubicek.claude | provenance:programming:crawler:openwpm [2026/09/21 13:36] (current) – Quote-check refresh 2026-09-21: re-ran quote_check.mjs --tools open[ -]?wpm with the pypdf fallback; 12 below threshold -> 10 rescued + 2 below in both; new provenance section. Authored by Claude karel.kubicek.claude |
|---|
| ==== 3.3 The version-lag column, and its limits ==== | ==== 3.3 The version-lag column, and its limits ==== |
| |
| ''RELEASED'' in ''report_openwpm.mjs'' is the tag→date map from ''git for-each-ref --sort=creatordate refs/tags'' in the OpenWPM repository. ''FIREFOX_OF'' is the bundled-Firefox map, read by checking out each ''v*'' tag and grepping ''scripts/install-firefox.sh'' for its ''FIREFOX_<major>_<minor>_RELEASE'' comment. | ''RELEASED'' in ''report_openwpm.mjs'' is the tag→date map from ''git for-each-ref %%--sort%%=creatordate refs/tags'' in the OpenWPM repository. ''FIREFOX_OF'' is the bundled-Firefox map, read by checking out each ''v*'' tag and grepping ''scripts/install-firefox.sh'' for its ''FIREFOX_<major>_<minor>_RELEASE'' comment. |
| |
| Three caveats, all of which are on the page in weaker form: | Three caveats, all of which are on the page in weaker form: |
| All **65** evidence quotes attached to an OpenWPM ''tools[]'' tuple anywhere in the corpus were checked, twice, by two different methods. | All **65** evidence quotes attached to an OpenWPM ''tools[]'' tuple anywhere in the corpus were checked, twice, by two different methods. |
| |
| **First pass, ''scripts/quote_check.mjs --tools "open[ -]?wpm"'':** 34 exact, 19 partial (≥60% of five-word windows), 12 below threshold, 0 with no full text on disk. | **First pass, ''scripts/quote_check.mjs %%--tools%% "open[ -]?wpm"'', re-run 2026-09-21 with the PDF fallback:** 34 exact, 19 partial (≥60% of five-word windows), **10 rescued from the PDF**, **2 below threshold in both renderings**, 0 with no full text on disk. See //Quote-check refresh, 2026-09-21// at the foot of this page. |
| |
| **The 12 below threshold are not fabrications, and the method was the problem.** Hand-checking with whitespace normalisation found 3 of them immediately; the rest failed because the repaired two-column text splices the other column into the middle of a sentence. With punctuation and spaces stripped, PETS 2025 ''intractable-cookie-crumbs-…'' reads: | **The old figure was 12 below threshold, and the script now agrees with what this page worked out by hand.** 10 of the 12 are located in an independent ''pypdf'' rendering of the same ''paper.pdf'' — the stored text is what was wrong — and only **2** are below threshold in both, which is 3.1% of the 65. ''exact'' (34) and ''partial'' (19) did not move. |
| | |
| | **The 12 below threshold were not fabrications, and the method was the problem.** Hand-checking with whitespace normalisation found 3 of them immediately; the rest failed because the repaired two-column text splices the other column into the middle of a sentence. With punctuation and spaces stripped, PETS 2025 ''intractable-cookie-crumbs-…'' reads: |
| |
| <code> | <code> |
| </code> | </code> |
| |
| "Firefox v121.0" //is// in the paper; the word ''firefox'' is cut in half. A whole-quote containment test scores that quote as absent. | "Firefox v121.0" //is// in the paper; the word ''firefox'' is cut in half. A whole-quote containment test scores that quote as absent. **That quote is one of the 10 the PDF fallback now rescues**: 46% of its five-word windows in the stored rendering, 62% in ''pypdf'''s. The two still below threshold in both are ''PETS/2022/my-cookie-is-a-phoenix…'' (50%) and ''USENIX/2022/automating-cookie-consent-and-gdpr-violation-detection'' (58%), and in both the mismatch is inside the extraction's own string — a dropped citation marker — which no rendering of the PDF can repair. |
| |
| **Second pass, ''scripts/openwpm_quotecheck.py'', written for this page.** Skeletonise (lowercase, drop everything that is not a letter or digit), cut each quote into overlapping 4-word windows, and report the share of the quote's **word positions** covered by a present window. Coverage, not window count: one splice in a twelve-word quote kills up to six windows but only one word position. An earlier version of this script counted windows and reported 19 quotes below 60%, all of them short quotes with a single splice — a metric artefact, and it is recorded here because the first draft of this page nearly published it. | **Second pass, ''scripts/openwpm_quotecheck.py'', written for this page.** Skeletonise (lowercase, drop everything that is not a letter or digit), cut each quote into overlapping 4-word windows, and report the share of the quote's **word positions** covered by a present window. Coverage, not window count: one splice in a twelve-word quote kills up to six windows but only one word position. An earlier version of this script counted windows and reported 19 quotes below 60%, all of them short quotes with a single splice — a metric artefact, and it is recorded here because the first draft of this page nearly published it. |
| - **The "both" statefulness label was doubted, and the doubt was wrong.** Five OPENWPM papers have ''crawlConfig.statefulness == "both"''. The first draft of the content page dismissed two of the five: it read {[englehardt2016online]}'s //stateful (cookie-based) and stateless (fingerprinting-based) tracking// — a real homograph, in that paper's abstract — as the only basis for its label, and it read the persona paper {[agarwal2020_stop]}'s "A HPW crawl with a loaded persona is stateless" as contradicting it. The **citations review pass** checked both against the papers and both objections fail: {[englehardt2016online]}'s configuration table lists //Default Stateless 1 Million// (917,261 sites) beside //Default Stateful 100,000// (94,144), and it says of its own platform "it supports both stateful and stateless measurements"; {[agarwal2020_stop]} says "We visit all websites in a persona-specific list as a stateful crawl that stores the user history in a browser" and //then// crawls statelessly with the dumped state. The label is sound in at least three of the five, so the page now describes the three designs instead of warning about the label — while keeping the homograph as a reading trap, which is what it is. **Recorded as an error caught in review:** the first draft would have told readers to distrust a correct extraction, on the strength of one grep. | - **The "both" statefulness label was doubted, and the doubt was wrong.** Five OPENWPM papers have ''crawlConfig.statefulness == "both"''. The first draft of the content page dismissed two of the five: it read {[englehardt2016online]}'s //stateful (cookie-based) and stateless (fingerprinting-based) tracking// — a real homograph, in that paper's abstract — as the only basis for its label, and it read the persona paper {[agarwal2020_stop]}'s "A HPW crawl with a loaded persona is stateless" as contradicting it. The **citations review pass** checked both against the papers and both objections fail: {[englehardt2016online]}'s configuration table lists //Default Stateless 1 Million// (917,261 sites) beside //Default Stateful 100,000// (94,144), and it says of its own platform "it supports both stateful and stateless measurements"; {[agarwal2020_stop]} says "We visit all websites in a persona-specific list as a stateful crawl that stores the user history in a browser" and //then// crawls statelessly with the dumped state. The label is sound in at least three of the five, so the page now describes the three designs instead of warning about the label — while keeping the homograph as a reading trap, which is what it is. **Recorded as an error caught in review:** the first draft would have told readers to distrust a correct extraction, on the strength of one grep. |
| - **No causal claim about the ARM extension failure.** With a branded Firefox Nightly the extension loads and its privileged startup then fails. The obvious explanation is that a branded build does not grant ''experiment_apis'' to an unsigned add-on, and the obvious explanation is not evidence: installing the same ''.xpi'' by hand into the same Nightly succeeds (''INSTALL OK id= openwpm@mozilla.org''), which shows loading is not the problem but does not identify what is. Three probes were run and none settled it: a patched ''.xpi'' with ''experiment_apis'' removed was built and **not** used, because the extension cannot start without those APIs, so the comparison would have isolated nothing; installing the real ''.xpi'' with Firefox's own log captured showed no privilege error (but also no ''browser_params.json'' in the profile, so the extension's startup would have failed anyway, differently); and asking Firefox directly, in chrome context, whether it granted the add-on privileged status failed twice — ''WebExtensionPolicy'' is not defined in Marionette's chrome sandbox, and the asynchronous ''AddonManager.getAddonByID'' form timed out. The page reports the failure and says the cause was not isolated. | - **No causal claim about the ARM extension failure.** With a branded Firefox Nightly the extension loads and its privileged startup then fails. The obvious explanation is that a branded build does not grant ''experiment_apis'' to an unsigned add-on, and the obvious explanation is not evidence: installing the same ''.xpi'' by hand into the same Nightly succeeds (''INSTALL OK id= openwpm@mozilla.org''), which shows loading is not the problem but does not identify what is. Three probes were run and none settled it: a patched ''.xpi'' with ''experiment_apis'' removed was built and **not** used, because the extension cannot start without those APIs, so the comparison would have isolated nothing; installing the real ''.xpi'' with Firefox's own log captured showed no privilege error (but also no ''browser_params.json'' in the profile, so the extension's startup would have failed anyway, differently); and asking Firefox directly, in chrome context, whether it granted the add-on privileged status failed twice — ''WebExtensionPolicy'' is not defined in Marionette's chrome sandbox, and the asynchronous ''AddonManager.getAddonByID'' form timed out. The page reports the failure and says the cause was not isolated. |
| - **The geckodriver A/B is reported as causal**, because it is: same Firefox binary, same Selenium 4.45.0, same OpenWPM commit, only the driver changed, and the error names the argument OpenWPM passes. Attempt 1 (0.37.1) failed at ''NEW_SESSION'' with ''InvalidArgumentException: Argument --remote-allow-system-access can't be set via capabilities''; attempt 2 (0.37.0) got past that point and failed later and differently. | - **The geckodriver A/B is reported as causal**, because it is: same Firefox binary, same Selenium 4.45.0, same OpenWPM commit, only the driver changed, and the error names the argument OpenWPM passes. Attempt 1 (0.37.1) failed at ''NEW_SESSION'' with ''InvalidArgumentException: Argument %%--remote-allow-system-access%% can't be set via capabilities''; attempt 2 (0.37.0) got past that point and failed later and differently. |
| - **''cookie_instrument'' being the only default is reported from execution, not from the docs**, because the docs do not say it. Verified by constructing ''BrowserParams()'' and printing every instrument field. | - **''cookie_instrument'' being the only default is reported from execution, not from the docs**, because the docs do not say it. Verified by constructing ''BrowserParams()'' and printing every instrument field. |
| - **The default-JS-collection gaps are reported per object, not by substring search.** An earlier draft of ''openwpm_defaults.py'' searched the settings blob for "webrtc" and "battery" and reported both ABSENT. Both are wrong: WebRTC is ''RTCPeerConnection'', which //is// instrumented, and ''navigator.getBattery'' is covered by instrumenting ''window.navigator''. The published script checks object and property names, and the page states the real gap: WebGL, ''document.fonts'', ''screen'' beyond two properties, most of ''window'', and calls on objects returned by instrumented properties. | - **The default-JS-collection gaps are reported per object, not by substring search.** An earlier draft of ''openwpm_defaults.py'' searched the settings blob for "webrtc" and "battery" and reported both ABSENT. Both are wrong: WebRTC is ''RTCPeerConnection'', which //is// instrumented, and ''navigator.getBattery'' is covered by instrumenting ''window.navigator''. The published script checks object and property names, and the page states the real gap: WebGL, ''document.fonts'', ''screen'' beyond two properties, most of ''window'', and calls on objects returned by instrumented properties. |
| | "Use a versioned release" / "Include the OpenWPM version number" | ''README.md'', //Advice for Measurement Researchers//, quoted verbatim on the page | | | "Use a versioned release" / "Include the OpenWPM version number" | ''README.md'', //Advice for Measurement Researchers//, quoted verbatim on the page | |
| | ''docs/Papers.rst'' lists 76 studies, none later than 2021 | counted from the file; ''git log -1'' on it gives 2023-09-19 | | | ''docs/Papers.rst'' lists 76 studies, none later than 2021 | counted from the file; ''git log -1'' on it gives 2023-09-19 | |
| | the fingerprinting collection has not changed since 2020-07-08 | ''git log --follow'' on ''openwpm/js_instrumentation_collections/fingerprinting.json'': two commits, the later one a module rename (''502cd83'', 2020-11-14) | | | the fingerprinting collection has not changed since 2020-07-08 | ''git log %%--follow%%'' on ''openwpm/js_instrumentation_collections/fingerprinting.json'': two commits, the later one a module rename (''502cd83'', 2020-11-14) | |
| | commits per year, 63 contributors, 72 of 73 2026 commits by one author | ''git log'' on a full (unshallowed) clone | | | commits per year, 63 contributors, 72 of 73 2026 commits by one author | ''git log'' on a full (unshallowed) clone | |
| |
| Host: aarch64 Linux container, x86-64 binaries not executable (no ''/lib64/ld-linux-x86-64.so.2''), no conda, no Docker, no Firefox, Python 3.11, Node 22. | Host: aarch64 Linux container, x86-64 binaries not executable (no ''/lib64/ld-linux-x86-64.so.2''), no conda, no Docker, no Firefox, Python 3.11, Node 22. |
| |
| Everything below was run against the repository at ''b9dd4c3'' **unmodified**: after all of it, ''git status --porcelain'' reports only untracked additions — the two test scripts copied in from ''pages/'', the downloaded copy of the published one, and the crawl output directory. No tracked file was touched, so no claim here is about a patched OpenWPM. | Everything below was run against the repository at ''b9dd4c3'' **unmodified**: after all of it, ''git status %%--porcelain%%'' reports only untracked additions — the two test scripts copied in from ''pages/'', the downloaded copy of the published one, and the crawl output directory. No tracked file was touched, so no claim here is about a patched OpenWPM. |
| |
| ^ # ^ Command ^ Result ^ | ^ # ^ Command ^ Result ^ |
| | 1 | ''git clone https://github.com/openwpm/OpenWPM'' (then ''git fetch --unshallow'') | ok, commit ''b9dd4c3'', ''VERSION'' 0.35.0 | | | 1 | ''git clone https://github.com/openwpm/OpenWPM'' (then ''git fetch %%--unshallow%%'') | ok, commit ''b9dd4c3'', ''VERSION'' 0.35.0 | |
| | 2 | ''micromamba env create -f environment.yaml'' | **failed to solve** — 3 packages have no linux-aarch64 build (output below) | | | 2 | ''micromamba env create -f environment.yaml'' | **failed to solve** — 3 packages have no linux-aarch64 build (output below) | |
| | 3 | ''micromamba create -n owpm python=3.12 pip leveldb'' then ''pip install'' the imports of ''openwpm/'' | ok; ''pillow'' had to be added after a ''ModuleNotFoundError: PIL'' on import of ''openwpm.commands.browser_commands'' | | | 3 | ''micromamba create -n owpm python=3.12 pip leveldb'' then ''pip install'' the imports of ''openwpm/'' | ok; ''pillow'' had to be added after a ''ModuleNotFoundError: PIL'' on import of ''openwpm.commands.browser_commands'' | |
| | 7 | download the pinned unbranded Firefox for ''linux64-aarch64'' | **404** — the build does not exist (probe §1) | | | 7 | download the pinned unbranded Firefox for ''linux64-aarch64'' | **404** — the build does not exist (probe §1) | |
| | 8 | download Firefox Nightly ''linux64-aarch64'' + geckodriver 0.37.1 for aarch64 | ok — Firefox 156.0a1, geckodriver 0.37.1 | | | 8 | download Firefox Nightly ''linux64-aarch64'' + geckodriver 0.37.1 for aarch64 | ok — Firefox 156.0a1, geckodriver 0.37.1 | |
| | 9 | ''openwpm_smoke.py'' with geckodriver **0.37.1** | **failed at ''NEW_SESSION''**: ''InvalidArgumentException: Argument --remote-allow-system-access can't be set via capabilities'' | | | 9 | ''openwpm_smoke.py'' with geckodriver **0.37.1** | **failed at ''NEW_SESSION''**: ''InvalidArgumentException: Argument %%--remote-allow-system-access%% can't be set via capabilities'' | |
| | 10 | same with geckodriver **0.37.0** (the pinned version) | got further: Firefox exited status 1, ''Could not find profile folder.'' | | | 10 | same with geckodriver **0.37.0** (the pinned version) | got further: Firefox exited status 1, ''Could not find profile folder.'' | |
| | 11 | run Firefox directly with ''--headless --screenshot'' | reproduced the same error with ''HOME=/home/dev''; **succeeded** with ''HOME=/tmp/fh''. A container quirk, not an OpenWPM property, and not reported on the page | | | 11 | run Firefox directly with ''%%--headless%% %%--screenshot%%'' | reproduced the same error with ''HOME=/home/dev''; **succeeded** with ''HOME=/tmp/fh''. A container quirk, not an OpenWPM property, and not reported on the page | |
| | 12 | ''openwpm_smoke.py'' with geckodriver 0.37.0 and ''HOME=/tmp/fh'' | browser launched, **extension loaded**, then ''FileNotFoundError: …/extension_port.txt''; spawn unsuccessful, retried to the failure limit | | | 12 | ''openwpm_smoke.py'' with geckodriver 0.37.0 and ''HOME=/tmp/fh'' | browser launched, **extension loaded**, then ''FileNotFoundError: …/extension_port.txt''; spawn unsuccessful, retried to the failure limit | |
| | 13 | install the same ''.xpi'' into the same Nightly by hand via Selenium | ''INSTALL OK id= openwpm@mozilla.org'' | | | 13 | install the same ''.xpi'' into the same Nightly by hand via Selenium | ''INSTALL OK id= openwpm@mozilla.org'' | |
| | S8 | The three identifier-sweep hits were read; one of them ({[agarwal2020_stop]}) is the worked example the page was asking for and was not being used | **accepted**, added with a new bibliography entry | | | S8 | The three identifier-sweep hits were read; one of them ({[agarwal2020_stop]}) is the worked example the page was asking for and was not being used | **accepted**, added with a new bibliography entry | |
| |
| ==== 11.2 Figures against the script (''sonnet'') ==== | ==== 11.2 Figures against the script (sonnet) ==== |
| |
| Re-ran ''report_openwpm.mjs'', ''openwpm_quotecheck.py'' and ''openwpm_defaults.py'' (the last inside a live OpenWPM checkout) and confirmed all three reproduce the committed output byte for byte; checked the byte sizes, the 14 tables at 0 rows, every table in //Use in Publications//, and both ''check_page_numbers.mjs'' invocations. | Re-ran ''report_openwpm.mjs'', ''openwpm_quotecheck.py'' and ''openwpm_defaults.py'' (the last inside a live OpenWPM checkout) and confirmed all three reproduce the committed output byte for byte; checked the byte sizes, the 14 tables at 0 rows, every table in //Use in Publications//, and both ''check_page_numbers.mjs'' invocations. |
| | 2 | "no year above 12% and none below 3%" is falsified by the 2026 row (1.4%) in the table immediately above | **accepted**, now scoped to the eleven complete years 2015–2024, with the two provisional years named | | | 2 | "no year above 12% and none below 3%" is falsified by the 2026 row (1.4%) in the table immediately above | **accepted**, now scoped to the eleven complete years 2015–2024, with the two provisional years named | |
| | 3 | The version column paraphrased "0.9.0 (machine A); 0.7.0 (machine B)" as "0.9.0 and 0.7.0, one per machine", on a page that promises verbatim version strings | **accepted**, verbatim string restored | | | 3 | The version column paraphrased "0.9.0 (machine A); 0.7.0 (machine B)" as "0.9.0 and 0.7.0, one per machine", on a page that promises verbatim version strings | **accepted**, verbatim string restored | |
| | 4 | ''check_page_numbers.mjs --code'' exited 1 on ''62'' (a ''print()'' column width in the published script), so "both guards pass" was not true as invoked | **accepted**; the report's ''Z'' block now carries it with that reason, and both invocations pass | | | 4 | ''check_page_numbers.mjs %%--code%%'' exited 1 on ''62'' (a ''print()'' column width in the published script), so "both guards pass" was not true as invoked | **accepted**; the report's ''Z'' block now carries it with that reason, and both invocations pass | |
| | 5 | The new semver handling in ''check_page_numbers.mjs'' used ''report.includes(v)'', looser than the boundary-checked ''present()'' every other number goes through | **accepted**, now uses ''present()''. The reviewer confirmed it does not currently misfire; the point is that it could | | | 5 | The new semver handling in ''check_page_numbers.mjs'' used ''report.includes(v)'', looser than the boundary-checked ''present()'' every other number goes through | **accepted**, now uses ''present()''. The reviewer confirmed it does not currently misfire; the point is that it could | |
| | 6 | The guard scores "21" as accounted-for because "21" appears incidentally in the report (a citation marker, "21 crawls/harvests") — a presence-anywhere weakness of the guard, not introduced here | **accepted in part**: the figure is now attributed to ''report_crawler.mjs'' in the ''Z'' block. The general weakness is real and is left as a known limitation of the guard | | | 6 | The guard scores "21" as accounted-for because "21" appears incidentally in the report (a citation marker, "21 crawls/harvests") — a presence-anywhere weakness of the guard, not introduced here | **accepted in part**: the figure is now attributed to ''report_crawler.mjs'' in the ''Z'' block. The general weakness is real and is left as a known limitation of the guard | |
| | 10 | The quoted log collapses runs of spaces, which was not disclosed | **accepted**, disclosure extended | | | 10 | The quoted log collapses runs of spaces, which was not disclosed | **accepted**, disclosure extended | |
| |
| ==== 11.3 Citations and quotes (''sonnet'') ==== | ==== 11.3 Citations and quotes (sonnet) ==== |
| |
| Checked all 23 citekeys, the new BibTeX entries against Crossref and the PoPETs landing pages, every quoted sentence against ''paper.cols.txt'' with punctuation stripped, and every repository and issue quote against the sources. | Checked all 23 citekeys, the new BibTeX entries against Crossref and the PoPETs landing pages, every quoted sentence against ''paper.cols.txt'' with punctuation stripped, and every repository and issue quote against the sources. |
| | — | Everything else — the README block quote, the ''docs/'' quotes, all four GitHub issues, Bugzilla 634073, the ''fingerprinting.json'' history, the 14-object list, Manifest V2 and the three ''experiment_apis'', the Krumnow characterisation, the OpenWPM-Mobile and "No boundaries" claims, and every other version string in the table — verified against the source | no change | | | — | Everything else — the README block quote, the ''docs/'' quotes, all four GitHub issues, Bugzilla 634073, the ''fingerprinting.json'' history, the 14-object list, Manifest V2 and the three ''experiment_apis'', the Krumnow characterisation, the OpenWPM-Mobile and "No boundaries" claims, and every other version string in the table — verified against the source | no change | |
| |
| ==== 11.4 External currency (''sonnet'') ==== | ==== 11.4 External currency (sonnet) ==== |
| |
| Every external fact re-fetched today. The whole maintenance table reproduced exactly, all four cited issues still open, Bugzilla 634073 still ''NEW'', no PyPI package, Docker Hub still amd64-only, conda-forge still zero ''linux-aarch64'' builds for the three pins, geckodriver still 0.37.1 with its own ''CHANGES.md'' confirming the capabilities change, and — the check that mattered most — **the current** latest ''mozilla-release'' build also has no ''linux64-aarch64-add-on-devel'' task, so the ARM conclusion needs no caveat. Manifest V2 has no announced Firefox end-of-support date. | Every external fact re-fetched today. The whole maintenance table reproduced exactly, all four cited issues still open, Bugzilla 634073 still ''NEW'', no PyPI package, Docker Hub still amd64-only, conda-forge still zero ''linux-aarch64'' builds for the three pins, geckodriver still 0.37.1 with its own ''CHANGES.md'' confirming the capabilities change, and — the check that mattered most — **the current** latest ''mozilla-release'' build also has no ''linux64-aarch64-add-on-devel'' task, so the ARM conclusion needs no caveat. Manifest V2 has no announced Firefox end-of-support date. |
| | — | Noted, not used: Firefox is now 153.0 and Selenium 4.47.0. The pages claim neither as current | no change | | | — | Noted, not used: Firefox is now 153.0 and Selenium 4.47.0. The pages claim neither as current | no change | |
| |
| ==== 11.5 Generic pass (''fable'') ==== | ==== 11.5 Generic pass (fable) ==== |
| |
| It returned late, after the pages were already published, and it justified its slot: **fifteen findings on a page three focused passes had cleared**, including a data-loss bug in code the page tells readers to copy. Every one below was verified against the repository or the corpus before being accepted; the pages were then corrected and re-saved. | It returned late, after the pages were already published, and it justified its slot: **fifteen findings on a page three focused passes had cleared**, including a data-loss bug in code the page tells readers to copy. Every one below was verified against the repository or the corpus before being accepted; the pages were then corrected and re-saved. |
| | ALSAcnc imports rather than forks | ''git clone https://github.com/bouhoula/alsacnc''; ''grep -rn "from openwpm"'' | Imports ''openwpm.config'', ''openwpm.task_manager'', ''openwpm.commands.types'', ''openwpm.storage.sql_provider''; OpenWPM itself is cloned at a tag by ''docker/crawler/Dockerfile'', never vendored | | | ALSAcnc imports rather than forks | ''git clone https://github.com/bouhoula/alsacnc''; ''grep -rn "from openwpm"'' | Imports ''openwpm.config'', ''openwpm.task_manager'', ''openwpm.commands.types'', ''openwpm.storage.sql_provider''; OpenWPM itself is cloned at a tag by ''docker/crawler/Dockerfile'', never vendored | |
| | Monkey-patch layer | ''wc -l cookie_crawler/utils/monkey_patches/*.py'' | 5 files, **583 lines**: ''__init__.py'' 23, ''browser_manager.py'' 130, ''browser_manager_handle.py'' 194, ''command_sequence.py'' 199, ''shutdown.py'' 37. Applied at ''run_crawler.py:94'' and '':186'' | | | Monkey-patch layer | ''wc -l cookie_crawler/utils/monkey_patches/*.py'' | 5 files, **583 lines**: ''__init__.py'' 23, ''browser_manager.py'' 130, ''browser_manager_handle.py'' 194, ''command_sequence.py'' 199, ''shutdown.py'' 37. Applied at ''run_crawler.py:94'' and '':186'' | |
| | Upgrade history | ''git log --all -- docker/crawler/Dockerfile'', then ''git show <c>:docker/crawler/Dockerfile'' | **Four** pins, on two branches: ''235a510'' 2024-06-22 → v0.23.0, ''d5c449a'' 2024-09-24 → v0.29.0, ''3c6cfd1'' 2025-01-29 → v0.31.0 on ''main''; ''4acb3fd'' 2026-07-10 → **v0.34.0** on branch ''cnil''. The 2026-08-14 check ran ''git log'' without ''--all'' and saw only ''main'', so it found three and the page said three; a review pass found the fourth on 2026-09-05. The patch layer is byte-identical on both branches (23/130/194/199/37 lines), which is the stronger form of the claim: one 583-line layer across eleven OpenWPM releases | | | Upgrade history | ''git log %%--all%% -- docker/crawler/Dockerfile'', then ''git show <c>:docker/crawler/Dockerfile'' | **Four** pins, on two branches: ''235a510'' 2024-06-22 → v0.23.0, ''d5c449a'' 2024-09-24 → v0.29.0, ''3c6cfd1'' 2025-01-29 → v0.31.0 on ''main''; ''4acb3fd'' 2026-07-10 → **v0.34.0** on branch ''cnil''. The 2026-08-14 check ran ''git log'' without ''%%--all%%'' and saw only ''main'', so it found three and the page said three; a review pass found the fourth on 2026-09-05. The patch layer is byte-identical on both branches (23/130/194/199/37 lines), which is the stronger form of the claim: one 583-line layer across eleven OpenWPM releases | |
| | Upstream agrees | [[https://github.com/openwpm/OpenWPM/issues/964|issue #964]], comment by ''vringar'' 2021-12-16 | **Was not verbatim, and this row said it was.** Re-fetched 2026-09-05 via ''gh api repos/openwpm/OpenWPM/issues/964/comments'': the source reads "build on top of it **(as you apparently have done)** and never upgrade.\\ We should provide a better story here." The page had dropped the parenthetical with no ellipsis, and inserted an "[…]" between two consecutive sentences where nothing was cut. Both fixed. The dropped words are the ones that make the remark personal to the issue's author — the same non-independence this section discloses two paragraphs down, removed from the quote that shows it. Also corrected: #743 is an **issue**, not a PR (''pulls/743'' → 404, ''issues/743'' → "Refactor commands to actually follow the Command pattern"); #753 is a PR. The maintainer wrote "#743 and #753" without calling either a PR | | | Upstream agrees | [[https://github.com/openwpm/OpenWPM/issues/964|issue #964]], comment by ''vringar'' 2021-12-16 | **Was not verbatim, and this row said it was.** Re-fetched 2026-09-05 via ''gh api repos/openwpm/OpenWPM/issues/964/comments'': the source reads "build on top of it **(as you apparently have done)** and never upgrade.\\ We should provide a better story here." The page had dropped the parenthetical with no ellipsis, and inserted an "[…]" between two consecutive sentences where nothing was cut. Both fixed. The dropped words are the ones that make the remark personal to the issue's author — the same non-independence this section discloses two paragraphs down, removed from the quote that shows it. Also corrected: #743 is an **issue**, not a PR (''pulls/743'' → 404, ''issues/743'' → "Refactor commands to actually follow the Command pattern"); #753 is a PR. The maintainer wrote "#743 and #753" without calling either a PR | |
| |
| ^ # ^ Finding ^ Action ^ | ^ # ^ Finding ^ Action ^ |
| | 3 | v0.36.0 (Firefox 154) exists; "Latest release 0.35.0", "four releases in 2026 … 148→152", "all 29 releases", "only the four 2026 releases (148–152)", and the two ''0.35.0 (Firefox 152)'' model sentences are all stale | **accepted**, probe re-run, whole table refreshed to 2026-09-05, version table gains a 0.36.0 row, 29→30 releases, four→five | | | 3 | v0.36.0 (Firefox 154) exists; "Latest release 0.35.0", "four releases in 2026 … 148→152", "all 29 releases", "only the four 2026 releases (148–152)", and the two ''0.35.0 (Firefox 152)'' model sentences are all stale | **accepted**, probe re-run, whole table refreshed to 2026-09-05, version table gains a 0.36.0 row, 29→30 releases, four→five | |
| | 4 | **The geckodriver pitfall describes a bug that upstream has fixed.** v0.36.0 pins ''geckodriver=0.37.1'' and requests the privilege through geckodriver's ''--allow-system-access'' flag instead of Firefox's ''-remote-allow-system-access'' | **accepted**, verified in ''deploy_firefox.py'' at ''61d285f'' and the CHANGELOG. The bullet is now scoped to v0.35.0 and earlier and says v0.36.0 fixes it. Our A/B measurement stands for the releases it was made on | | | 4 | **The geckodriver pitfall describes a bug that upstream has fixed.** v0.36.0 pins ''geckodriver=0.37.1'' and requests the privilege through geckodriver's ''%%--allow-system-access%%'' flag instead of Firefox's ''-remote-allow-system-access'' | **accepted**, verified in ''deploy_firefox.py'' at ''61d285f'' and the CHANGELOG. The bullet is now scoped to v0.35.0 and earlier and says v0.36.0 fixes it. Our A/B measurement stands for the releases it was made on | |
| | 5 | "Firefox reached 147" during 2025 — 147 shipped 2026-01-13; Firefox reached **146** in 2025 | **accepted**, ''product-details.mozilla.org/1.0/firefox_history_major_releases.json'' | | | 5 | "Firefox reached 147" during 2025 — 147 shipped 2026-01-13; Firefox reached **146** in 2025 | **accepted**, ''product-details.mozilla.org/1.0/firefox_history_major_releases.json'' | |
| | 6 | "180 open issues" is GitHub's ''open_issues_count'', which counts pull requests as issues | **accepted**: 141 issues + 39 PRs, from two ''search/issues'' queries, with the trap footnoted | | | 6 | "180 open issues" is GitHub's ''open_issues_count'', which counts pull requests as issues | **accepted**: 141 issues + 39 PRs, from two ''search/issues'' queries, with the trap footnoted | |
| | 8 | **The ''vringar'' quote is not verbatim and §12.1 said it was** — "(as you apparently have done)" dropped with no ellipsis, and an "[…]" inserted between two consecutive sentences | **accepted**, re-fetched and restored. See the corrected §12.1 row | | | 8 | **The ''vringar'' quote is not verbatim and §12.1 said it was** — "(as you apparently have done)" dropped with no ellipsis, and an "[…]" inserted between two consecutive sentences | **accepted**, re-fetched and restored. See the corrected §12.1 row | |
| | 9 | #743 is an **issue**, not a pull request | **accepted**, ''pulls/743'' → 404 | | | 9 | #743 is an **issue**, not a pull request | **accepted**, ''pulls/743'' → 404 | |
| | 10 | **ALSAcnc has a fourth public pin**, v0.34.0 (''4acb3fd'', 2026-07-10) on branch ''cnil'' — the 2026-08-14 check ran ''git log'' without ''--all'' | **accepted**, and it improves the page. The "byte-identical patch layer" wording that first went with it was **wrong** and is corrected in §14.8: four of the five files are byte-identical across all four pins, and ''browser_manager.py'' is not. Its current pin is one of the five whose Firefox still downloads | | | 10 | **ALSAcnc has a fourth public pin**, v0.34.0 (''4acb3fd'', 2026-07-10) on branch ''cnil'' — the 2026-08-14 check ran ''git log'' without ''%%--all%%'' | **accepted**, and it improves the page. The "byte-identical patch layer" wording that first went with it was **wrong** and is corrected in §14.8: four of the five files are byte-identical across all four pins, and ''browser_manager.py'' is not. Its current pin is one of the five whose Firefox still downloads | |
| | 11 | **"a fork of any of those releases would by now be unbuildable" draws a contrast that does not exist** — ALSAcnc's ''main'' pins v0.31.0, whose Firefox 404s, so a fresh clone of it fails exactly as a fork would | **accepted**, and it was the sharpest finding of the pass. The bullet conflated two things. Rewritten so the contrast is **upgradability, not buildability**: the library-shaped project could move to a live release and did; a fork stops at the release it was cut from | | | 11 | **"a fork of any of those releases would by now be unbuildable" draws a contrast that does not exist** — ALSAcnc's ''main'' pins v0.31.0, whose Firefox 404s, so a fresh clone of it fails exactly as a fork would | **accepted**, and it was the sharpest finding of the pass. The bullet conflated two things. Rewritten so the contrast is **upgradability, not buildability**: the library-shaped project could move to a live release and did; a fork stops at the release it was cut from | |
| | 12 | **"Docker tags go back to 0.15.0" is wrong** — the four oldest images are ''v''-prefixed (''v0.10.0''–''v0.13.0''), plus ''0.14.1''; only ''0.14.0'' was never published | **accepted**. The 2026-08-14 probe tested one naming convention and read its absence as the artefact's absence. This one failed //against// the page's interest: a reader with a 2020–2021 artefact was told no image existed for it | | | 12 | **"Docker tags go back to 0.15.0" is wrong** — the four oldest images are ''v''-prefixed (''v0.10.0''–''v0.13.0''), plus ''0.14.1''; only ''0.14.0'' was never published | **accepted**. The 2026-08-14 probe tested one naming convention and read its absence as the artefact's absence. This one failed //against// the page's interest: a reader with a 2020–2021 artefact was told no image existed for it | |
| | 15 | §10 says "Six entries were added"; ''bib_additions_openwpm.bib'' has seven | **accepted** — the seventh ({[agarwal2020_stop]}) was added later the same day by §11.1 S8 and the count was not updated | | | 15 | §10 says "Six entries were added"; ''bib_additions_openwpm.bib'' has seven | **accepted** — the seventh ({[agarwal2020_stop]}) was added later the same day by §11.1 S8 and the count was not updated | |
| | 16 | §7's source table still credited ''docs/Configuration.md'' with "''save_content'' MD5 de-duplication" after §11.5 #2 corrected the page to SHA-256 | **accepted** — the same carry-over defect, one section apart | | | 16 | §7's source table still credited ''docs/Configuration.md'' with "''save_content'' MD5 de-duplication" after §11.5 #2 corrected the page to SHA-256 | **accepted** — the same carry-over defect, one section apart | |
| | 17 | ''[[:Artifacts]]'' is flagged on the page as "a page this wiki still owes you". It exists, with real content | **accepted**, flag removed. Verified from the rendered DOM: the link is ''wikilink1''. The identical stale caveat on [[:programming:crawler]] is **out of this item's scope** and was filed as a work item rather than edited | | | 17 | ''[[:Artifacts]]'' is flagged on the page as "a page this wiki still owes you". It exists, with real content | **accepted**, flag removed. Verified from the rendered DOM: the link is ''wikilink1''. The identical stale caveat on [[:programming:crawler]] was fixed in the link-hygiene sweep; both links are ''wikilink1'' on the fresh DOM. | |
| | 18 | "a handful of groups keep private copies of these tarballs", and "on an M-series Mac … That works", are asserted flatly with nothing behind them | **accepted in part**: both are true as far as we know and neither is checkable here, so both are now attributed as such rather than deleted. No Mac was available to this run | | | 18 | "a handful of groups keep private copies of these tarballs", and "on an M-series Mac … That works", are asserted flatly with nothing behind them | **accepted in part**: both are true as far as we know and neither is checkable here, so both are now attributed as such rather than deleted. No Mac was available to this run | |
| | 19 | Firefox 153 was skipped by OpenWPM because its **tagged revision has no unbranded builds on any platform** — a second way the pinned build can be missing, distinct from expiry | **accepted**, added to the expiry pitfall. Found in the v0.36.0 CHANGELOG by the adversarial pass while checking something else | | | 19 | Firefox 153 was skipped by OpenWPM because its **tagged revision has no unbranded builds on any platform** — a second way the pinned build can be missing, distinct from expiry | **accepted**, added to the expiry pitfall. Found in the v0.36.0 CHANGELOG by the adversarial pass while checking something else | |
| does not is worse than either convention applied consistently. */ | does not is worse than either convention applied consistently. */ |
| ~~DISCUSSION~~ | ~~DISCUSSION~~ |
| | |
| | ===== 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. |
| | |
| | ===== Link-hygiene sweep, 2026-09-17 ===== |
| | |
| | The historical stale-caveat row now records that the paired ''programming:crawler'' page was fixed in this sweep. The fresh rendered DOM confirmed both ''Artifacts'' links are live; no figures or citations changed. |
| | |
| | ===== Currency re-check, 2026-09-17 ===== |
| | |
| | The stale illustrative release/browser sentence on [[programming:crawler:openwpm]] |
| | was already corrected when this item was read: the page says ''OpenWPM 0.36.0 |
| | (Firefox 154)''. No content edit was made. The release pin and moving stable |
| | channel were re-fetched with these commands: |
| | |
| | <code> |
| | curl -sS 'https://product-details.mozilla.org/1.0/firefox_versions.json' | python3 -c 'import json,sys; d=json.load(sys.stdin); print(json.dumps({k:d.get(k) for k in ("LATEST_FIREFOX_VERSION","LATEST_FIREFOX_DEVEL_VERSION","FIREFOX_ESR","FIREFOX_ESR_VERSION")}, sort_keys=True))' |
| | curl -sS 'https://raw.githubusercontent.com/openwpm/OpenWPM/v0.35.0/environment.yaml' | rg -n -i 'firefox|geckodriver' |
| | curl -sS 'https://raw.githubusercontent.com/openwpm/OpenWPM/v0.35.0/scripts/install-firefox.sh' | rg -n '^(TAG|TARGET_SUFFIX)|FIREFOX_|firefox-ci|taskcluster' |
| | bash scripts/openwpm_firefox_availability.sh |
| | </code> |
| | |
| | Mozilla's product-details API returned ''LATEST_FIREFOX_VERSION=156.0''. The |
| | v0.35.0 installer returned ''FIREFOX_152_0_RELEASE'' and its environment pins |
| | ''geckodriver=0.37.0''; the availability checker returned ''v0.35.0 ... |
| | FIREFOX_152_0_ .tar.xz HTTP=200'' and ''v0.36.0 ... FIREFOX_154_0_ .tar.xz |
| | HTTP=200''. The content page's 0.36.0/154 example therefore names that release's |
| | own pin, not the moving stable channel. |
| | |
| | ===== Review layer, 2026-09-17 ===== |
| | |
| | One shared ''model: sonnet'' external-currency pass ran after publication and |
| | re-ran ''bash scripts/openwpm_firefox_availability.sh''. It **passed** the |
| | existing ''OpenWPM 0.36.0 (Firefox 154)'' example and found no correction needed; |
| | the v0.35.0 and v0.36.0 pins returned HTTP 200 from their resolved Mozilla build |
| | URLs. |
| | |
| | ===== Quote-check refresh, 2026-09-21 ===== |
| | |
| | The 2026-09-04 ''cols''-vs-PDF audit on [[:provenance:literature:corpus]] showed that 73.1% of evidence quotes that cannot be located in ''paper.cols.txt'' **are** present in an independent ''pypdf'' rendering of the same ''paper.pdf''. ''scripts/quote_check.mjs'' was patched the same day to re-check everything below threshold against that second rendering and report a fourth verdict, **RESCUED**. §5's first-pass figure predates the patch. Re-run, unedited first line: |
| | |
| | <code> |
| | $ node scripts/quote_check.mjs --tools 'open[ -]?wpm' --show 400 |
| | 65 quotes checked: 34 exact, 19 partial (>=60% of 5-word windows), 10 rescued from the PDF, 2 below threshold in both renderings, 0 with no full text on disk. |
| | </code> |
| | |
| | ^ Figure ^ Was ^ Is ^ Why ^ |
| | | quotes checked | 65 | 65 | population unchanged — the corpus has not moved | |
| | | exact | 34 | 34 | unchanged | |
| | | partial (≥60% of 5-word windows) | 19 | 19 | unchanged | |
| | | rescued from the PDF | — | **10** | new verdict; these were inside the old 12 | |
| | | below threshold | **12** | **2** (in both renderings) | 12 = 10 + 2 exactly; nothing else moved | |
| | |
| | **This page argued for the fallback before the fallback existed, and the second pass is not superseded by it.** §5's ''openwpm_quotecheck.py'' answers a different question — how much of each quote's //word positions// a present window covers — and its verdict on the 65 (52 verbatim, 13 split by a splice, 0 below 60%, none unsupported) is unchanged and was not re-derived here. The shared checker's ''%%--tools%%'' pass has simply stopped disagreeing with it about 10 of the 12. |
| | |
| | **Scope of this edit.** §5's first-pass figure and the sentence naming the ''intractable-cookie-crumbs'' example. ''openwpm_quotecheck.py'' was **not** re-run, ''report_*'' scripts were not re-run, and no other figure, fold or citation on this page was touched. |
| | |
| | ^ Item ^ Value ^ |
| | | Date | 2026-09-21, unsupervised | |
| | | Artifact | ''out/qc0921/tools_openwpm.txt'' (full run, 10 RESCUED rows and 2 below-threshold rows listed) | |
| | | Script changes | none — ''quote_check.mjs'' was already patched on 2026-09-04 | |
| | | Reviewers | one ''sonnet'' figures-vs-script pass | |
| | | Pages saved | this page only — [[:programming:crawler:openwpm]] carries no quote-check figure | |
| |