This is an old revision of the document!
Table of Contents
Provenance: Programming:Crawler:PageGraph
Back to Brave PageGraph. Corpus-wide selection and extraction notes are on corpus. This is the page-specific query log; it is intentionally a working record rather than a second tutorial.
Run record
- Run date: 2026-08-14 (UTC).
- Primary authoring agent: Codex, GPT-5.6, using the local seven-venue corpus and the official Brave repositories/documentation for current tool status.
- Review agents: three focused `gpt-5.5` jobs were launched after drafting as the available fallback for the requested review tier. No substantive finding was completed or integrated: one job hit the runner usage limit, two were not awaited, and the user then directed publication without review. The generic pass was not run.
- Corpus at run time: 5,859 extracted papers, 2010–2026, from CCS, IMC, NDSS, PETS, USENIX Security, TheWebConf, and IEEE S&P. The extraction file and full text are under `/workspace/publications_dataset/data/` and were read-only inputs.
- Read first: `data/extract/OVERVIEW.md`, `data/extract/README.md`, the current sitemap, `programming:crawler`, `privacy:javascript`, and the provenance-method examples required by the task. The target page had no revision; `get` returned only the standard template, so this is a creation rather than an extension.
- Full text read: the eight PageGraph papers selected by the query, using `paper.cols.txt`, plus the relevant source passages for graph structure, storage, failure categories and WebREC.
- No write was made to the publication mount. The wiki pages and shared bibliography were published through `scripts/dw.mjs`, guarded by the revisions read at publication time. No reviewer finding was integrated because publication was explicitly requested without review.
Why this page, not an overlap
`programming:crawler` already compares PageGraph with generic automation and explicitly promises a child page. `privacy:javascript` already names PageGraph as one observation layer and links to the same child. Those pages answer “where does this instrument sit?”; this page answers “what is the graph, why does its causal edge help, and what will it cost?”. I created the promised child rather than widening either neighbour. The sitemap showed the target as a red/template page and no existing provenance page.
Population and queries
All counts below are counts of papers unless explicitly labelled “tuples”. Sentinels do not enter this page's query because the population is defined by a named tool, not by a field that can be `not-stated`.
| Query | Denominator | Result | |
| `tools[].name` matches `/ | pagegraph(?: crawler)?$/i`, and `usedOrMentioned` is `used` or `produced`; distinct `(venue, year, slug)` | 5,859 corpus papers | 8 papers |
|---|---|---|---|
| Same 8-paper set as a share of `POPULATIONS.crawled` (`crawlConfig != null` or automated-web-crawl study type) | 1,120 crawling papers | 8 (0.7%) | |
| Same set as a share of the full corpus | 5,859 | 8 (0.1%) | |
| Raw matching tool tuples before deduplication | 8 PageGraph papers | 9 tuples | |
| Matching raw names | 9 tuples | `PageGraph` (8), `PageGraph crawler` (1) | |
| Tool tuples with only `compared` or `mentioned` status | 5,859 corpus papers | 0 papers |
The year table in the report uses each year's full corpus as its denominator. The 2025 and 2026 rows are printed even though the task marks the corpus edge provisional; they are not treated as a complete-year trend.
Folding and residue
The only fold is an exact, ordered name fold: `PageGraph` and `PageGraph crawler` map to the PageGraph family; every other raw name is residue. This is deliberately a recogniser, not a synonym classifier. The report prints the raw names, their tuple counts and the unmapped residue:
Raw names folded: "PageGraph" (8), "PageGraph crawler" (1). Fold residue: 0 unmapped strings; none.
The role labels in the paper table are a hand-written description of what the extracted PageGraph tool quote says the graph was used for. They are not aggregated method families and are not presented as percentages. Role-fold residue was 0 of 8 papers.
Per-paper results and source facts
The report prints every extracted `detection.prevalence` string whose tuple explicitly mentions PageGraph. I publish only the figures whose denominator is carried by the paper's own sentence: for example, 902 of 999 pages (90%) and 130,494 storage calls plus 9,095 network calls are paper-specific results, not corpus adoption rates.
The cost section also uses four full-text facts checked by the report against the repaired `paper.cols.txt` rendering:
- Sjösten et al. (TheWebConf 2020) describe approximately 12K lines of Blink/V8 patches. This is historical implementation size, not a current build requirement.
- Sarker et al. (IMC 2020) report 4,051 PageGraph issues among 14,493 failed visits, with 85,470 visits completed, in their 100K-domain experiment. This is a study-specific failure breakdown, not a universal PageGraph failure rate.
- Jueckstock et al. (TheWebConf 2022) report 280,219 PageGraph files totalling 405 GB. This is the scale of their storage-policy dataset.
- Hantke et al. (USENIX Security 2025) report 10.2 MB average `.web` archives, including 1.5 MB behavior records and 0.4 MB screenshots, against 13.6 MB average proxy HAR files. This is a PageGraph-derived archive bundle, not a raw PageGraph-file benchmark.
Evidence quotes checked
The report checks all 9 PageGraph tool evidence quotes against the source file at `data/fulltext/<year>/<venue>/<slug>/paper.cols.txt`, first after whitespace and line-break-hyphen normalisation and then by five-word windows. Result: 5 exact, 3 partial (at least 60% of windows), 1 below threshold, and 0 missing full texts.
The below-threshold quote is the WebREC sentence “Our approach builds on an existing Chromium-based measurement system called PageGraph”. It is present in the source paragraph; the repaired `.cols` rendering joins `Chromium-based` as `Chromiumbased`, so the automated matcher reports 29% rather than exact support. I checked the surrounding paragraph manually. It is a column-repair mismatch, not an unsupported quote. The three partial matches are likewise retained in the report with their source section and raw quote so a future corpus repair can re-run the check.
External and industry verification
External sources were used only for current tool status and the operational interface; the literature ranking and graph description come from the local corpus.
| Source | Load-bearing fact | Verification on 2026-08-14 | Decision |
| Brave PageGraph wiki | PageGraph is in Brave from 1.46; Nightly is needed for built-in JS APIs; supported events and limitations; hard-crash-over-uncertainty policy | Read the current wiki page directly; checked the feature, limitation, build, documentation and crash sections | Used |
| pagegraph-crawl | Node CLI, binary path, `-t` crawl duration, GraphML output, and warning that Puppeteer automation is not itself tracked | Read the repository README; GitHub API reported unarchived, MPL-2.0, pushed 2026-08-11 | Used |
| pagegraph-query | Current query subcommands and PageGraph's attributed event model | Read the README; GitHub API reported unarchived, with repository activity in 2026 | Used |
| pagegraph-rust | Older Rust analysis path | GitHub marked the repository archived on 2026-07-21; README says to use `pagegraph-query` | Rejected as the current installation advice; retained only as a historical warning |
| pagegraph types documentation | Node types are actors/actees and edges are actor actions directed to actees | Read the versioned type documentation; treated it as schema context, not a current release claim | Used cautiously |
Rejected external material: no SEO “best crawler” listicles, vendor rankings, or unsourced blog summaries were used. No external literature search was used to fill the corpus table. The only outside checks were first-party Brave/GitHub/docs.rs sources needed to avoid presenting an old repository or a stale Nightly requirement as current.
What the corpus and sources do not establish
- The corpus has no independent, current benchmark of PageGraph's CPU/time overhead, per-page crash rate, or graph size across browsers. The page uses two study-specific storage/failure observations and labels them as such.
- The official crash note gives a 5–10% target, not an observed 2026 rate. It should not be converted into a PageGraph denominator.
- The extraction finds no PageGraph-named paper in 2026, but that row is provisional and under-represented by construction. It cannot support “PageGraph is no longer used”.
- The corpus cannot compare PageGraph fairly with Firefox-only instruments, mobile browsers, or current commercial crawlers because the PageGraph papers do not share a common benchmark.
- The official GraphML/type documentation is incomplete, and the instrumented API set is build-dependent. A paper must archive the exact build and query code rather than relying on the name “PageGraph”.
Review log
This section is append-only during the run. The user directed publication without waiting for the requested review passes, so this page records the incomplete review rather than implying that the page was reviewed.
| Reviewer | Focus | Finding | Decision |
| gpt-5.5 focused pass | figures vs. report script | Not completed before publication; no finding was supplied. | User directed skip; local deterministic rerun still matched the checked-in output. |
| gpt-5.5 focused pass | citations and evidence quotes | Not completed before publication; no finding was supplied. | User directed skip; local citekey check found no missing or duplicate keys. |
| gpt-5.5 focused pass | external currency | Agent errored on the runner usage limit before returning findings. | User directed skip; the author's primary-source checks remain recorded above. |
| generic review | page and provenance structure | Not run. | User directed skip. |
Reproduction artifact
Run:
node scripts/report_pagegraph.mjs > scripts/report_pagegraph-output.txt
The script is kept under `scripts/`; its real unedited output follows.
- report_pagegraph-output.txt
Corpus: 5859 extracted papers from CCS, IMC, NDSS, PETS, USENIX Security, TheWebConf, and IEEE S&P (2010–2026). Crawled population: 1120 papers, defined by crawlConfig or automated-web-crawl study type. === Population query === Query: for each paper, inspect tools[].name matching /^pagegraph(?: crawler)?$/i and usedOrMentioned in {used, produced}; count distinct venue/year/slug keys. Result: 8 PageGraph papers, 0.1% of the 5859-paper corpus. Against the 1120 papers that ran a crawl: 8 (0.7%). Tool tuples: 9; paper count, not tuple count, is used for every page figure. Raw names folded: "PageGraph" (8), "PageGraph crawler" (1). Fold residue: 0 unmapped strings; none. Tool tuples that were only compared/mentioned: 0 papers. === Year table === Rows are PageGraph papers / all extracted papers in that year. The 2025–2026 corpus edge is provisional; it is not a complete-year trend. Year | Corpus papers | PageGraph papers | Share of that year 2010 | 119 | 0 | 0.0% 2011 | 116 | 0 | 0.0% 2012 | 151 | 0 | 0.0% 2013 | 125 | 0 | 0.0% 2014 | 166 | 0 | 0.0% 2015 | 190 | 0 | 0.0% 2016 | 182 | 0 | 0.0% 2017 | 231 | 0 | 0.0% 2018 | 254 | 0 | 0.0% 2019 | 402 | 0 | 0.0% 2020 | 404 | 2 | 0.5% 2021 | 379 | 2 | 0.5% 2022 | 546 | 1 | 0.2% 2023 | 719 | 0 | 0.0% 2024 | 690 | 0 | 0.0% 2025 | 770 | 3 | 0.4% 2026 | 415 | 0 | 0.0% === Papers in the PageGraph population === Key | Role recorded for the page IMC/2020/hiding-in-plain-site-detecting-javascript-obfuscation-through-concealed-browser | script/API provenance for obfuscation measurement WWW/2020/filter-list-generation-for-underserved-regions | request-chain attribution for regional filter-list generation CCS/2021/sugarcoat-programmatically-generating-privacy-preserving-web-compatible-resource | script actions and Web API call sites for resource rewriting IEEE-SP/2021/detecting-filter-list-evasion-with-event-loop-turn-granularity-javascript-signat | event-loop-turn behavior signatures WWW/2022/measuring-the-privacy-vs-compatibility-trade-off-in-preventing-third-party-state | behavior-set comparison under storage policies CCS/2025/local-frames-exploiting-inherited-origins-to-bypass-content-blockers | crawl event graphs for local-frame measurement NDSS/2025/duumviri-detecting-trackers-and-mixed-trackers-with-a-breakage-detector | rendering-graph features for tracker/breakage detection USENIX/2025/web-execution-bundles-reproducible-accurate-and-archivable-web-measurements | PageGraph-derived execution archives Role-fold residue: 0; none. === Corpus prevalence strings that explicitly name PageGraph === WWW/2020/filter-list-generation-for-underserved-regions | phenomenon="Upstream advertising resources" | metric="additional advertising resources identified" | prevalence="1,771 additional advertising URLs; 27.1% improvement" CCS/2021/sugarcoat-programmatically-generating-privacy-preserving-web-compatible-resource | phenomenon="Privacy-relevant API access" | metric="share of pages with accessed privacy-relevant APIs" | prevalence="902 of 999 pages (90%)" CCS/2021/sugarcoat-programmatically-generating-privacy-preserving-web-compatible-resource | phenomenon="Storage and network API calls" | metric="total API calls" | prevalence="130,494 storage calls and 9,095 network calls reduced to zero" CCS/2021/sugarcoat-programmatically-generating-privacy-preserving-web-compatible-resource | phenomenon="Core functionality behavior changes" | metric="p-value" | prevalence="DOM operations p=0.732 and event registration p=0.517 for rewritten versus default" WWW/2022/measuring-the-privacy-vs-compatibility-trade-off-in-preventing-third-party-state | phenomenon="Behavioral compatibility" | metric="Jaccard similarity to permissive baseline" | prevalence="Page-length behavior was much closer to permissive than blocking" === Source facts used for cost and scale === WWW/2020/filter-list-generation-for-underserved-regions | historical implementation size | source match=true | approximately 12K LOC of Blink/V8 patches IMC/2020/hiding-in-plain-site-detecting-javascript-obfuscation-through-concealed-browser | PageGraph issue category in a 100K crawl | source match=true | 4,051 PageGraph issues among 14,493 failed visits; 85,470 visits completed successfully WWW/2022/measuring-the-privacy-vs-compatibility-trade-off-in-preventing-third-party-state | stored graph volume | source match=true | 280,219 PageGraph files (405 GB) USENIX/2025/web-execution-bundles-reproducible-accurate-and-archivable-web-measurements | WebREC storage comparison | source match=true | WebREC .web files averaged 10.2 MB, including 1.5 MB behavior records and 0.4 MB screenshots; the proxy HAR baseline averaged 13.6 MB === Evidence quotes checked against paper.cols.txt === IMC/2020/hiding-in-plain-site-detecting-javascript-obfuscation-through-concealed-browser | PageGraph | methodology | partial (73%) | "PageGraph complements VV8's low-level tracing of all browser API accesses with high level tracking of script provenance, including via complicated DOM interactions and dynamic script injections." WWW/2020/filter-list-generation-for-underserved-regions | PageGraph | implementation | exact (100%) | "PageGraph is implemented as a large set of patches and modifications to Blink and V8 (approximately 12K LOC)." WWW/2020/filter-list-generation-for-underserved-regions | PageGraph | implementation | exact (100%) | "We use this instrumentation both to extract the contextual features described in Section 3.2.2, and to accurately understand what page modifications and downstream requests each JavaScript unit is responsible for." CCS/2021/sugarcoat-programmatically-generating-privacy-preserving-web-compatible-resource | PageGraph | methodology | partial (92%) | "Privacy developers collect this behavioral data by visiting Web pages in a modified browser equipped with PageGraph." WWW/2022/measuring-the-privacy-vs-compatibility-trade-off-in-preventing-third-party-state | PageGraph | methodology | exact (100%) | "We use PageGraph, an instrumentation system built into an experimental branch of Brave, to record internal page behaviors." CCS/2025/local-frames-exploiting-inherited-origins-to-bypass-content-blockers | PageGraph crawler | methodology | exact (100%) | "We visit each of the selected sites using the PageGraph crawler [12], a Web-measurement tool based on a current fork of Chromium." NDSS/2025/duumviri-detecting-trackers-and-mixed-trackers-with-a-breakage-detector | PageGraph | methodology | exact (100%) | "This component is the complete PageGraph [19]. PageGraph is a graph representation of the page rendering process" USENIX/2025/web-execution-bundles-reproducible-accurate-and-archivable-web-measurements | PageGraph | implementation | below-threshold (29%) | "Our approach builds on an existing Chromium-based measurement system called PageGraph" IEEE-SP/2021/detecting-filter-list-evasion-with-event-loop-turn-granularity-javascript-signat | PageGraph | methodology | partial (72%) | "To solve this problem, we used and extended PageGraph, a system for representing the execution of a page as a directed graph." Summary: 9 quotes checked: 5 exact, 3 partial (>=60% of 5-word windows), 1 below threshold, 0 without full text. Manual follow-up: the below-threshold WebREC quote is present in the source rendering at the PageGraph paragraph; the repaired .cols text joins "Chromium-based" as "Chromiumbased", which defeats the normalised quote matcher. It is a column-repair mismatch, not an unsupported claim.
