User Tools

Site Tools


provenance:programming:crawler:panoptichrome

Provenance: Programming:Crawler:PanoptiChrome

Back to PanoptiChrome. Corpus-wide selection and extraction caveats are on corpus. This page is the query log and working record behind that page: what was asked of the corpus, what was fetched live, what was read by hand, what was checked, and what could not be established. It is a log, not a tutorial.

Following the convention set by the first of these pages, there is no ~~DISCUSSION~~ block here — comments belong on the content page.

Run record

  • Run date: 2026-08-17 (UTC).
  • Authoring agent: Claude (Opus 5), working from the read-only publication mount at /workspace/publications_dataset and from live fetches of GitHub's REST API, raw.githubusercontent.com, Chromium's chromiumdash, OpenAlex, Crossref and Zenodo.
  • Review agents: three focused sonnet passes (figures-vs-script, citations-and-quotes, external currency) on the frozen draft, then a generic fable pass over the content page, this page, the three scripts and their output. Findings and dispositions are in the Review log.
  • Corpus at run time: 5,859 extracted papers, 2010–2026, from CCS, IMC, NDSS, PETS, USENIX Security, TheWebConf and IEEE S&P. Crawled population 1,120. No figure was carried over from any earlier page, dossier or METHOD.md; everything was re-derived against data/extract/run1 as it stands after the 2026-08-11 extension.
  • This is a creation. programming:crawler:panoptichrome did not exist (core.getPageInfo → error 121) and was a red link from programming:crawler.
  • Full text read directly, not only through the extraction: both PanoptiChrome-bearing papers end to end (WWW/2024/panoptichrome-…, WWW/2025/dynamic-security-analysis-…), plus the two reference-list hits. Both source PDFs were parsed with pypdf for link annotations and for quote checking. Nothing was written to the publication mount.
  • Artifacts read directly: the upstream repository's README, sources.json, sinks.json, the five result Markdown tables, panoptichrome_patches.diff (234 KB) and panoptichrome_patches_fixed.diff (1.7 MB, unpacked from the zip). These were the decisive sources for most of the content page.

The brief, and the finding it asked for

The task said: “PanoptiChrome. Confirm the current upstream and capabilities before writing — this one is the least documented of the set, so if it turns out not to warrant a page, say so on the parent page instead and mark this item done with that finding.”

Verdict: it warrants a page, and the case is recorded on the content page under Why this page is mostly warnings. The reasoning:

  • The upstream is current enough to write about: a live, MIT-licensed, non-archived repository with a commit as recent as 2025-05-05 and an exactly pinned base (V8 commit, V8 version, four Chrome 116 build numbers). That is more version discipline than most artifacts in this corpus manage.
  • programming:crawler already carries a PanoptiChrome row and links the child page by name. Deleting the promise would have meant editing the parent's table, its “taint tracking is a different question” bullet and its recommendation list, and would have left the parent asserting things about the tool with nowhere to substantiate them.
  • The substance that justifies a page is not a how-to. It is a set of facts about the artifact that no reader can get from the paper, the abstract or a search: that the published patch does not compile, that a competitor's author supplied the completed one, that the shipped configuration asks a different question from the one most web-privacy work asks, that the log format is VisibleV8's, and that the tool has zero third-party use as an instrument. A page that only summarised the paper would not have warranted existing; this one is mostly artifact archaeology.
  • The alternative scope — folding PanoptiChrome into programming:crawler:foxhound as a subsection — was rejected because that page is already 69 KB and because a reader who does need Chromium or implicit flows needs the build detail, which would unbalance it. The two pages cross-link instead, and the head-to-head table lives on the Foxhound page with only the PanoptiChrome row restated here.

Population and queries

Every corpus figure on the content page comes from scripts/report_panoptichrome.mjs. Its full unedited output is reproduced below.

Figure on the page Query Population / denominator Value
“a full-text sweep … returns 4” /panopti[ -]?chrome/i over paper.cols.txt all 5,859 papers 4 papers
“Papers that used PanoptiChrome to measure something else: zero” hand-coded role per sweep hit, verified against the sentence those 4 papers 0 instrument
the four-row role table same; each verdict stores its deciding sentence, and section A of the report checks that sentence against paper.cols.txt so the hand map cannot drift those 4 papers 1 produced, 1 evaluated, 2 citation, 4/4 quotes located
the six-row in-engine-instrument table TAINT_TOOLS patterns from scripts/fh_fold.mjs, full-text sweep all 5,859 papers Jalangi 20, Foxhound 13, JSFlow 13, PanoptiChrome 4, ChromiumTaintTracking 4, LinvailTaint 1, IF-Transpiler 1
the paper's crawl figures (20,000 / 12,382 / 4,701 / 12,846 / 5,673 / 675 / 362) detection[] and population[] of the tool paper, cross-read against the paper's Table 1 and §4 the paper's own see §D and §E of the report
“three ad-hoc annotation passes of 1,246, 252 and 186 APIs” humanAnnotation[] of the tool paper the paper's own 3 tuples, all annotatorType: authors, all agreementMetric: null
availability: none-mentioned and codeUrl: null artifacts object of the tool paper the paper's own verified, and explained by the PDF-annotation finding below

Denominator discipline, stated explicitly because it is the rule most easily broken here:

  • “of 5,859 papers” is used only for the sweep, which is genuinely corpus-wide, and it is labelled as a mention count rather than a usage count both in the script and on the page.
  • The crawled population (1,120) is deliberately not used as the denominator for “4 papers name it”. A reference-list citation in a non-crawling paper is still a mention, so the sweep's denominator is all papers. The page never divides 4 by 1,120.
  • Sentinels: the only sentinels that matter here are availability: none-mentioned, codeUrl: null, headless: not-stated and agreementMetric: null, and every one of them is reported as itself, on the page, as a finding about the paper.
  • Papers, never tuples: section B of the report prints tuples and papers separately and the page quotes neither — it quotes section A.

Schema versus sweep. The extraction's tools[] finds 2 of the 4 papers. It misses both reference-list-only citations, because the extraction records tools a paper uses or discusses, not everything in its bibliography. The page therefore reports the sweep (4) as the population and the roles as the finding. Reporting the schema count alone would have said “2 papers”, which is both smaller and less informative — it would have hidden that the other two did not run it either.

Folding: none, and why that is not luck

No name fold was written for this page, and the residue is empty by construction:

  • PanoptiChrome is a single coined token. The corpus contains exactly two spellings — PanoptiChrome and the reference-list lowercase Panoptichrome — which a case-insensitive regex merges. The sweep regex additionally allows a space or hyphen (/panopti[ -]?chrome/i) so that a line-broken or hyphenated occurrence still matches; no such occurrence was found.
  • There are no homographs. A looser /panopti/i sweep returns 78 papers, almost all of them panopticon in prose plus the unrelated PETS 2018 tool PanoptiSpy; tightening to panopti[ -]?chrome drops 74 of them and leaves 4. Both sweeps were run; only the tight one is used.
  • The one field that would have needed folding — tools[].name — contains the exact string PanoptiChrome in both records.

This is the easy case. It is recorded here so that the absence of a fold script for this page is not read as an omission: see programming:crawler and design:ip_classification for what folding costs when a name genuinely is ambiguous.

Quotes and figures checked

scripts/pc_quotecheck.py checks 28 quoted or paraphrased sentences against both paper.pdf (via pypdf) and paper.cols.txt. 28/28 located verbatim. Its unedited output is below.

The reason it checks two renderings is a real finding about this corpus's text layer, and it cost a wrong FAIL before it was understood:

  • Both papers are two-column ACM PDFs. paper.cols.txt repaired column reading order for most of each file, but still interleaves some sentences that straddle a column boundary — for example “PanoptiChrome needs to modify only three builders and eight AST visitors”, which appears in .cols as “needs to modify hash table ensures that if the runtime object is alive…”. A substring match against .cols reports these as absent.
  • pypdf's own extraction gets those right and drops a different set of sentences — for example “The driver script closes the browser after a preset time of 180 seconds…”. * Neither rendering is an arbiter. The checker accepts a quote found in either and prints which, so the failure mode is visible rather than papered over. Of the 28: 15 found in both, 9 in the PDF only, 4 in ''.cols only. The draft first reported 14 / 10 / 5, which sums to 29 — a grep -c over the output that also matched the two legend lines at its foot. The checker now prints the breakdown itself so it cannot be miscounted again. * Two quotes did fail on the first run, and both were transcription errors of mine, not extraction artifacts: //“Out of the 675 unique web APIs that are accessed by 12,846 origins” (the paper says 5,673) and a sentence about the BFAD crawl whose middle is interrupted in the text layer by Figure 7's caption. The first was corrected; the second was removed from the page as a quote and restated as a plain figure (“only 608 of 1,000 Tranco sites were reachable”), because a quote you have to reassemble across a figure caption is not a quote. This is exactly the failure the dataset README's 0.9%-unlocatable warning is about, and it is why the check was run before publication rather than after.

Figures re-derived rather than trusted:

  • The tool paper's Table 1 percentages (61.91%, 23.5%) were read off the paper, and 12,382/20,000 and 4,701/20,000 were recomputed in section E of the report script; both agree.
  • 675 / 5,673 = 11.9% and 269 / 675 = 39.9% are computed by the script, not copied from the paper. The paper independently states “39.85% are used for DOM manipulation”, which agrees with the recomputation to rounding.
  • The 164 versus 208 inconsistency was found by grepping the raw text for both literals and confirmed in the PDF: 208 appears in the abstract, §4.5 and the conclusion; 164 appears once, in the introduction's fifth listed contribution. The page cites 208 and flags 164.

External facts, and how each was verified

Every external claim on the content page is re-fetched by scripts/panoptichrome_probe.sh, which calls scripts/pc_external_meta.py for the bibliographic and identity queries. Its unedited output is below. One exception, stated because the blanket version of this sentence was an overclaim a reviewer caught: the characterisation of StealthDev as a stealthy-DevTools framework rather than a taint tracker comes from reading its OpenAlex abstract by hand. The script re-fetches its DOI, venue, pagination and author list; it does not re-derive what the paper is about.

Claim on the page Primary source How checked
repository live, MIT, 10★/5 forks, last push 2025-05-05, not archived api.github.com/repos/therahulkanyal/PanoptiChrome probe §1
“14 commits in total, 6 of them on the day it was created; 5 since the conference” commits API probe, commit-history section. The draft first said “three commits since the paper appeared”, which was wrong in both directions; corrected before review by recounting against the printed list. The five post-conference commits are 2024-05-30 and 2024-06-01 (README), 2024-09-27 (JSON config), 2025-02-21 (LICENSE), 2025-05-05 (fixed zip).
no tags, no releases, one branch /branches, /tags, /releases all queried 2026-08-17: ['master'], [], []
README pins V8 commit e29c028f…, V8 11.6.189.2, Chrome 116.0.5845.78 raw.githubusercontent.com/…/README.md printed verbatim by the probe
M116 stable 2023-08-09; current stable 151.0.7922.137 chromiumdash.appspot.com fetch_milestone_schedule?mstone=116 and fetch_releases probe, 2026-08-17
original patch: 24 files, 5,744 added lines; fixed: 28 files, 57,113 both diffs downloaded and parsed probe, patch-anatomy section
the fixed patch adds exactly src/json.hpp, idl_data.hpp, sinks.hpp, sources.hpp set difference of +++ b/ paths probe; “files present only in the original patch: none”
original #include “json.hpp” without shipping it grep of the diff probe: 1 occurrence, ships src/json.hpp: False
relative-path config load and exit(1) src/execution/isolate.cc hunk of the original diff probe prints the three loadDatabase/parseIDL lines
LOG_DIR only in the fixed patch grep of both diffs probe
VisibleV8 logging code carried in grep for visv8_out_key (6), VisV8TlsData (8), RAII “handle” to VV8 (1) probe
Smis cannot carry taint the IsSmi guard in Isolate::SetTaintForV8Object and Isolate::getObjectTaintSource probe prints both guard lines verbatim. This corrected the draft. The first draft asserted that object-level taint “probably” survives a numeric round trip and therefore beat Foxhound's known blind spot. Reading the patch showed the opposite: both the setter and the getter return early on a Smi, so a value that becomes a small integer loses its taint. The page now says so and marks the HeapNumber case untested.
sources.json 1,052 interfaces; sinks.json 12 interfaces / 18 properties, listed both files parsed probe prints every sink
API-list reconciliation 675 / 269 / 281 / 81 / 362 / 42, 673 partitioned, 2 unassigned five Markdown tables parsed probe
eleumasc = Samuele Casarin api.github.com/users/eleumasc“name”: “Samuele Casarin” checked 2026-08-17; matches the WWW 2025 author list
prebuilt binary in DynSecAnJS-tools, ~163 MB split zip, Ubuntu 22.04 repo tree + build.sh + README.md probe §DynSecAnJS-tools
the prebuilt binary was committed 2024-10-07, seven months before the upstream fixed patch commits API filtered on path=panoptichrome.chunk.zip probe. This is the evidence that the evaluation ran a completed build.
the toolset's licence position contents/licenses + the raw file probe. This corrected the draft. The draft said DynSecAnJS-tools “carries no licence file”, and an external reviewer confirmed that by checking LICENSE/LICENSE.md/LICENSE.txt/COPYING at the root — all 404. Both of us were looking in the wrong place: the repository ships a licenses/ directory with one file per bundled tool, and licenses/PanoptiChrome.txt is the MIT licence, “Copyright © 2025 Rahul Kanyal”. The page now says the binary is redistributable on the upstream terms, and the probe prints the directory listing so nobody repeats the mistake.
the –jitless launch flags src/collection/BrowserOrToolPage.ts in eleumasc/DynSecAnJS probe prints the whole block
the log-line grammar (ORIGIN@, SINKPC$, LEAK$), and that the only published parser is ~50 lines around one regex handling only the fetch sink src/measurement/flow/PanoptiChromeFlows.ts in eleumasc/DynSecAnJS read by hand, 2026-08-17
the optional DOM/storage patches: dom_storage_v8_patch.diff touches 4 files, dom_storage_blink_patch.diff 5 (including wtf/text/string_impl.{cc,h} and bindings/v8_value_cache.{cc,h}) both diffs downloaded and their +++ b/ paths listed probe, DOM/storage section
PDF artifact links (7 distinct GitHub URLs, anchor text “here”) pypdf over paper.pdf /Annots probe, final section
OpenAlex: 5 citing works api.openalex.org/works?filter=cites:W4396757560 2026-08-17; the five are listed below
StealthDev is AsiaCCS 2026 and is not a taint tracker Crossref 10.1145/3779208.3805987 + OpenAlex abstract container Proceedings of the ACM Asia Conference on Computer and Communications Security, event ASIA CCS '26, pp. 1816–1831

The five OpenAlex citing works, checked individually so that “no third-party use” is a claim about content rather than a count:

  1. Calzavara, Casarin & Focardi, TheWebConf 2025 — the evaluation. Ran it.
  2. The Odyssey of robots.txt Governance, CCS 2025 — reference list only.
  3. Mockingbird: Efficient Excessive Data Exposures Detection via Dynamic Code Instrumentation, ASE 2025 (10.1109/ase63991.2025.00247) — related-work mention; ASE is outside the corpus and was not read in full, so this is recorded as “mention” on the weaker evidence of the citation context alone.
  4. Comprehensive Classification of Web Tracking Systems — the same article indexed twice, in Qeios and Computing&AI Connect. Neither is peer-reviewed in the sense the rest of this corpus is; recorded as such on the page rather than counted.

Note the asymmetry: OpenAlex reports 5 citing works while the corpus sweep finds 4 mentions, and the two sets overlap in only two papers. NDSS 2026's Sabino et al. cites PanoptiChrome but does not appear in OpenAlex's citing list. The reason is narrower than “not indexed”: OpenAlex has the record (W7161059450, DOI 10.14722/ndss.2026.231467), but its referenced_works is empty — the reference list has not been parsed — so the cites: filter cannot see it. The draft first attributed this to the proceedings being unindexed, which the external-currency reviewer disproved by re-querying; corrected here. Both numbers are floors and the page says so.

Sources considered and rejected

  • sohomdatta1/PanoptiChrome-rebased — a fork whose name promises a rebase onto a newer Chromium. Rejected: its commit list is identical to upstream's as of 2024-09-27 with no rebase commits on master, and no other branch. Mentioning it would have implied a maintained modern port that does not exist. The other four forks are likewise unmodified copies.
  • The Zenodo dataset for the evaluation (10.5281/zenodo.14774184, MIT, 2025-01-30) — real and verified, but its single file workspace.7z is 42 GB, which makes it a poor recommendation to put in front of a new PhD student without that number attached. Cut from the content page for space; recorded here so the next run does not have to rediscover it. It is the right place to go for the raw per-site evaluation data.
  • DynSecAnJS-tools as a citable artifact — used for the build route, but not cited as a source for any measurement, because it has no paper of its own. Cite [1Calzavara, Stefano; Casarin, Samuele; Focardi, Riccardo (2025): "Dynamic Security Analysis of JavaScript: Are We There Yet?", in: Proceedings of the ACM Web Conference. (DOI)] for anything it was used to measure.
  • Any SEO listicle, tool-comparison blog or “top taint analysis tools” page — none was consulted. Every external fact above has a repository, an API or a standards body behind it.
  • The ACM DL page for StealthDev — returns Cloudflare's “Just a moment…” interstitial to curl. Crossref and OpenAlex were used instead, which is why the page cites a DOI and a venue rather than quoting the paper.
  • Vendor or industry material — there is none for this tool, and none was invented. PanoptiChrome has no commercial presence, no package, no Docker image and no documentation site.

What could not be established

  • Whether HeapNumber-represented values carry taint. The Smi case is settled by reading the patch (they do not). Values outside Smi range are heap objects and the table could in principle key on them, but no test exists, the evaluation did not probe it, and we did not build the browser. The page says the question is open in both directions rather than guessing.
  • Which 208 APIs were “previously unreported”. No published list marks them, and the two candidate baselines (BFAD's confirmed set, and the “prior work” set of 121) are not published in a form that lets the subtraction be reproduced.
  • Which exact build the evaluation measured. The generic reviewer caught the draft asserting that the evaluation ran “before the fixed patch landed”, and therefore that re-running it on the fixed patch was the obvious open work. The evidence points the other way: DynSecAnJS-tools published its prebuilt PanoptiChrome in February 2025, three months before the upstream fixed zip, and the harness sets LOG_DIR, which only the completed patch honours. So the published figures were measured on a completed build. What remains genuinely unestablished is whether the patch that landed upstream is byte-identical to the binary they measured — the binary is a 163 MB blob with no manifest, and nothing states it.
  • Whether the sources.json/sinks.json committed in September 2024 are the configuration the paper's October 2023 crawl used. They were added eleven months after the crawl and the repository has no history that would settle it. The page says the config you are given is not provably the config the paper ran.
  • Real build effort. We did not build Chromium 116 with either patch. No claim about build time, disk or toolchain appears on the page, and the “Route 1 / Route 2” section describes what the artifacts say, not what we did. The Foxhound page can quote its project's own CI; this project has no CI.
  • Whether anyone outside these seven venues has used it as an instrument. OpenAlex's five citing works say no as of today, but journal and workshop coverage there is uneven. The page frames both numbers as floors.

Judgement calls

  1. Create rather than broaden. Recorded above. The decisive factor was that the parent page already promises the child by name and already asserts tool-specific facts.
  2. Lead with “do not choose this as your default”. A tool page that buried the adoption finding under a features table would be misleading in the way the task's currency warning describes: the corpus can make a 2024 tool look current when its real status is “published, unused, half-finished”. The WRAP important says so in the first screen.
  3. Do not restate the whole head-to-head table. It is on the Foxhound page, was written from the same paper in the same week, and duplicating it invites the two pages to drift. Only the PanoptiChrome row and its Foxhound comparator are here, plus the two columns the Foxhound page does not carry (agreement share). Cross-checked cell by cell against the Foxhound page's version: they agree.
  4. Call the published patch “does not build” rather than “may not build”. The evidence is direct — an #include of a header the patch does not ship — and the remedy shipped 18 months later adds exactly that header. This is a strong claim about someone's artifact and it is stated with its evidence attached, in the page and here.
  5. Attribute the fix to a named person. The commit message says “Credit : eleumasc”; the GitHub profile gives the real name; the name is on the evaluation paper. All three are public and load-bearing for the point being made (that the completion came from outside the authors' group), so the identification is made explicitly rather than hinted at.
  6. Report 42 “false positive APIs” as the authors' own noise list, not as an error rate. The file has no accompanying definition; treating it as a measured false-positive rate would overstate what it is.
  7. Keep the “Should this page exist?” section on the content page rather than hiding the deliberation here. A reader deciding whether to spend a month on this tool benefits from knowing the page's own author thought it was borderline.
  8. Say “zero” plainly. “No paper has used PanoptiChrome to measure anything other than PanoptiChrome” is the strongest sentence on the page. It is a claim about four papers, all four read, in seven venues, stated with its denominator and its lower-bound caveat in the same paragraph.

Report script and its output

Three scripts, all committed under scripts/:

  • report_panoptichrome.mjs — every corpus figure with its denominator. Sweep and schema populations kept apart; throws if a sweep hit has no hand-coded role, so the hand map cannot silently drift from the data.
  • panoptichrome_probe.sh — every external fact, re-fetched from a primary source. Needs curl and python3; its last section additionally needs pypdf and the publications mount, because it reads the paper's PDF link annotations. GitHub's unauthenticated limit is 60 requests an hour and this script can exhaust it in one run if anything else on the machine is also querying the API — it did, mid-run, during this session — so it honours GH_TOKEN if one is exported. Everything it fetches is public; the token changes the rate limit and nothing else.
  • pc_external_meta.py — the bibliographic and identity checks (GitHub's user endpoint, OpenAlex, Crossref, Zenodo), called by the probe script at the end so that one run really does cover every external claim. This file exists because a reviewer caught an overclaim: the first draft of this page said the probe re-fetched every external claim, while the OpenAlex count, the Crossref venue and the eleumasc identification were in fact one-off uncommitted queries. See the Review log.
  • pc_quotecheck.py — 27 quotes against paper.pdf and paper.cols.txt; exits non-zero if any fails in both.

report_panoptichrome.mjs — unedited output

corpus: 5859 papers, 7 venues, 2010-2026
population 'crawled': 1120 papers

=== A. Every paper in the corpus whose full text names PanoptiChrome ===

Sweep /panopti[ -]?chrome/i over paper.cols.txt of all 5859 papers: 4 hits.

Venue / year  Paper                                                                                                                 Role       What it did with it                                                                              Mentions
------------  --------------------------------------------------------------------------------------------------------------------  ---------  -----------------------------------------------------------------------------------------------  --------
WWW 2024      PanoptiChrome: A Modern In-browser Taint Analysis Framework                                                           produced   the tool paper                                                                                   40
CCS 2025 *    The Odyssey of robots.txt Governance: Measuring Convention Implications of Web Bots in Large Language Model Services  citation   reference list only                                                                              1
WWW 2025 *    Dynamic Security Analysis of JavaScript: Are We There Yet?                                                            evaluated  built it, drove it with Playwright, measured compatibility / transparency / coverage / overhead  13
NDSS 2026 *   DOM-XSS Detection via Webpage Interaction Fuzzing and URL Component Synthesis                                         citation   reference list only                                                                              1

* 2025 and 2026 are provisional corpus years (CCS 2026 and IMC 2026 not held;
  IEEE S&P 2026 and WWW 2026 abstracts absent from OpenAlex, and selection screens abstracts).

Role        Papers (of 4 sweep hits)
----------  ------------------------
produced    1
evaluated   1
instrument  0
citation    2

Papers that ran PanoptiChrome for a measurement of something else: 0.

Each role verdict was decided by reading the sentence. The deciding sentence is stored
with the verdict and checked against the paper here, so the hand map cannot drift:
   OK    produced   WWW/2024/panoptichrome-a-modern-in-browser-tai
          "called PanoptiChrome, which adds roughly 7,000 lines of code to the existing V8 engine."
   OK    citation   CCS/2025/the-odyssey-of-robots-txt-governance-
          "[38] Rahul Kanyal and Smruti R Sarangi. Panoptichrome: A modern in-browser taint"
   OK    evaluated  WWW/2025/dynamic-security-analysis-of-javascri
          "PanoptiChrome [29]: a modified version of Chromium supporting information flow analysis;"
   OK    citation   NDSS/2026/dom-xss-detection-via-webpage-intera
          "[24] Rahul Kanyal and Smruti R Sarangi. PanoptiChrome: A"

=== B. Papers whose extracted tools[] names PanoptiChrome ===

2 tuples, in 2 papers.

Venue / year  tools[].name   category          usedOrMentioned  version
------------  -------------  ----------------  ---------------  ----------
WWW 2024      PanoptiChrome  program-analysis  produced         not-stated
WWW 2025      PanoptiChrome  browser           used             not-stated

The schema misses the two citation-only papers: the extraction records tools a paper
uses or discusses, not every entry in its reference list. Section A is the denominator.

=== C. In-browser taint tracking and JS instrumentation across the whole corpus ===

Full-text sweeps over all 5859 papers. Counts papers, not mentions.
These are mention counts, NOT usage counts: a paper that only cites a tool is counted here.

Tool (as swept)                                       Papers naming it  Years
----------------------------------------------------  ----------------  ---------
Project Foxhound — patched Firefox (in-engine)        13                2024–2026
PanoptiChrome — patched Chromium (in-engine)          4                 2024–2026
ChromiumTaintTracking — patched Chromium (in-engine)  4                 2024–2025
Jalangi / JalangiTT — source instrumentation          20                2015–2026
JSFlow — instrumented interpreter                     13                2015–2025
LinvailTaint — source instrumentation                 1                 2025–2025
IF-Transpiler — source rewriting                      1                 2025–2025
TaintDroid — Android, not a web instrument            173               2011–2026
Android taint analysers — not web instruments         176               2014–2026

Compare with the usage-scoped figures on Programming:Crawler, which come from
report_crawler.mjs and count tools[] entries with usedOrMentioned in {used, produced}.

=== D. The tool paper's own measured results, with its denominators ===

Paper: WWW 2024 — PanoptiChrome: A Modern In-browser Taint Analysis Framework.

population[] (the crawl seed, i.e. the denominator the paper is entitled to):
sourceList  listVersion             n      unit      samplingMethod
----------  ----------------------  -----  --------  --------------
Tranco      accessed 11. Oct. 2023  20000  websites  top-n
Tranco      not-stated              1000   websites  top-n

detection[] (what it reports having measured):
phenomenon                       metric                                               prevalence
-------------------------------  ---------------------------------------------------  --------------------------------------------------------------------------------------------------
reachable websites               share of Tranco top 20,000 sites by status           61.91% returned status code 200; 12,846 unique origins were logged
tainted API data leakage         unique leaked APIs and percentage of sites           675 unique APIs leaked across 12,846 origins; DOM-related APIs leaked on 33.84% of sites
fingerprinting APIs              number of unique APIs with fingerprinting potential  362 APIs probably used for fingerprinting or potentially misusable; 208 were previously unreported
sensitivity-threshold detection  percentage confirmed sensitive                       96.74% confirmed sensitive at threshold 10, versus 89.16% at threshold 0

crawlConfig:
field             value
----------------  ------------------
browsers          Chromium 117.0
statefulness      stateless
headless          not-stated
consentAction     no-interaction
interactionDepth  single-target-page
subpagesPerSite   not-stated
authentication    none
repeatVisits      1

vantage:
locations  infrastructure  serviceName
---------  --------------  -----------
India      commercial-vpn  not-stated

artifacts:
field         value
------------  --------------
availability  none-mentioned
codeUrl       null
dataUrl       null
badge         null

NB: availability is none-mentioned and codeUrl is null because the paper links its code
with the bare anchor text "here", four times, and the extraction reads text, not PDF link
annotations. The URLs are recoverable from the PDF /Annots — see the provenance page.

=== E. Denominator hygiene inside the tool paper (read the numerator against the right base) ===

Quantity                             Value  Its denominator              Note
-----------------------------------  -----  ---------------------------  ---------------------------------------------
Tranco seed                          20000  —                            top-n, accessed 11 Oct 2023
HTTP 200 on connection test          12382  20000 seed URLs (61.9%)      paper Table 1
Exceptions (both schemes timed out)  4701   20000 (23.5%)                paper Table 1
Unique origins logged                12846  not the seed                 origins include subframe origins; > 200-count
Unique APIs accessed                 5673   12846 origins
Unique APIs leaked                   675    5,673 APIs accessed (11.9%)
DOM-manipulation APIs among leaked   269    675 leaked (39.9%)
Candidate fingerprinting APIs        362    675 leaked                   = 121 + 33 + 48 + 78 + 82 in the paper
of which "previously unreported"     208    362 candidates               the intro says 164 instead — see below

The 12,846 "unique origins" is larger than the 12,382 sites that returned 200. It is not a
site count: PanoptiChrome logs one file per V8 isolate and iframes get their own isolates,
so a per-origin figure and a per-site figure are different denominators in this paper.

Internal inconsistency, verifiable in paper.txt:
  abstract / results / conclusion: "208 APIs were previously not reported"
  introduction, contribution 5:    "We identify 164 hitherto undiscovered APIs"

panoptichrome_probe.sh — unedited output

Run 2026-08-17, with pc_external_meta.py called near the end. Re-running it will produce different dates (the header line, the Chrome stable version) and should produce identical repository, patch, API-list and bibliographic figures unless something upstream changes.

# GitHub API: authenticated via GH_TOKEN
# panoptichrome_probe.sh — run 2026-08-17T21:42:26Z

== therahulkanyal/PanoptiChrome
   description   : Discovered Data and Source Code
   created       : 2023-10-12T05:41:17Z
   last push     : 2025-05-05T09:42:46Z
   default branch: master
   licence       : MIT
   stars/forks   : 10 / 5
   archived      : False   open issues: 0
   branches      : ['master']
   tags          : none
   releases      : none

== therahulkanyal/PanoptiChrome — commit history (newest first)
   14 commits
   2025-05-05  d2ee7626  Added Panoptichrome-patches-fixed.zip |  | Credit : eleumasc
   2025-02-21  89df4039  Create LICENSE |  | Added MIT License
   2024-09-27  0b4e8b10  Added sources.json, sinks.json and idl_data.json |  | sources.json : all the browser API
   2024-06-01  c261945d  Updated README.md with commit hash and version info
   2024-05-30  dbfb7528  Created README.md
   2023-12-08  9741f008  Removed bad file
   2023-12-08  20c93ee8  Rename
   2023-12-08  be788702  Added patches for DOM and Storage
   2023-10-12  d0725658  Added Patches
   2023-10-12  3fb5b76a  Added category data
   2023-10-12  2beb5e87  Properly Formatted Tables
   2023-10-12  d8cba87c  Added proper table
   2023-10-12  83225cd2  Added table for all_leaked_apis
   2023-10-12  24c1174c  Initial Commit

== therahulkanyal/PanoptiChrome — files on master
         1069  LICENSE
          487  README.md
        18914  all_leaked_apis.md
        42018  api_category.json
        13304  dom_storage_blink_patch.diff
        17052  dom_storage_v8_patch.diff
         1149  false_positive_apis.md
       501452  idl_data.json
         7065  leaked_dom_manipulation_apis.md
       233878  panoptichrome_patches.diff
       249208  panoptichrome_patches_fixed.zip
         9116  potential_fingerprinting_apis.md
         1252  sinks.json
         1962  sinks_uri_related_apis.md
        23184  sources.json
      1121110  TOTAL

== therahulkanyal/PanoptiChrome — forks
   postfix/PanoptiChrome                         pushed 2025-05-05  stars 0
   icezhaoL/PanoptiChrome                        pushed 2025-05-05  stars 0
   L0nm4r/PanoptiChrome                          pushed 2024-09-27  stars 0
   sohomdatta1/PanoptiChrome-rebased             pushed 2024-10-06  stars 0
   Ale0x78/PanoptiChrome                         pushed 2023-12-08  stars 0

== therahulkanyal/PanoptiChrome — README.md (verbatim)
   # PanoptiChrome Patches
   
   This repo contains the patches for building PanoptiChrome (WWW 2024, Singapore).  
   The research paper is available at [ACM Digital Library](https://dl.acm.org/doi/10.1145/3589334.3645699).
   
   ## Patch Details
   - **V8 commit:** e29c028f391389a7a60ee37097e3ca9e396d6fa4 
   - **V8 Version:** 11.6.189.2 (cherry-pick)
   - **Chrome Versions:**
     - **Canary 116:** 116.0.5845.0
     - **Dev 116:** 116.0.5845.11
     - **Beta 116:** 116.0.5845.41
     - **Stable 116:** 116.0.5845.78

== therahulkanyal/PanoptiChrome — shipped source/sink configuration
   sources.json : 1052 entries, all bare interface names (e.g. ['ANGLEInstancedArrays', 'AbortController', 'AbortPaymentEvent'])
   sinks.json   : 12 interfaces, 18 properties
                  XMLHttpRequest.send
                  Client.postMessage
                  DedicatedWorkerGlobalScope.postMessage
                  Document.cookie
                  IDBObjectStore.put
                  IDBObjectStore.add
                  MessagePort.postMessage
                  Navigator.sendBeacon
                  RTCDataChannel.send
                  ServiceWorker.postMessage
                  WebSocket.send
                  Window.indexedDB
                  Window.localStorage
                  Window.openDatabase
                  Window.postMessage
                  Window.sessionStorage
                  Window.fetch
                  Worker.postMessage

== therahulkanyal/PanoptiChrome — do the published API lists reconcile with the paper?
   all_leaked_apis.md                675   paper: 675 unique APIs leaked
   leaked_dom_manipulation_apis.md   269   paper: 269 are DOM manipulation APIs
   potential_fingerprinting_apis.md  281
   sinks_uri_related_apis.md          81
     potential + sinks/uri           362   paper: 362 candidate fingerprinting APIs
   false_positive_apis.md             42
     d + p + s + fp                  673   of 675 leaked -> 2 unassigned
            dom entries outside all_leaked: 0
      potential entries outside all_leaked: 0
      sinks/uri entries outside all_leaked: 0
      false-pos entries outside all_leaked: 0

== therahulkanyal/PanoptiChrome — the optional DOM/storage patches
   dom_storage_v8_patch.diff
      include/v8-value.h
      src/api/api.cc
      src/interpreter/bytecode-generator.cc
      src/runtime/runtime-taint.cc
   dom_storage_blink_patch.diff
      third_party/blink/renderer/platform/bindings/to_blink_string.cc
      third_party/blink/renderer/platform/bindings/v8_value_cache.cc
      third_party/blink/renderer/platform/bindings/v8_value_cache.h
      third_party/blink/renderer/platform/wtf/text/string_impl.cc
      third_party/blink/renderer/platform/wtf/text/string_impl.h

== therahulkanyal/PanoptiChrome — anatomy of the two patch sets
   panoptichrome_patches.diff (2023-10-12)
      24 files, 5,744 added lines, 233,878 bytes
   panoptichrome_patches_fixed.diff (2025-05-05, credit: eleumasc)
      28 files, 57,113 added lines, 1,733,517 bytes
   
   files present only in the fixed patch:
      src/execution/panoptichrome-data/idl_data.hpp  (+25,428 lines)
      src/execution/panoptichrome-data/sinks.hpp  (+95 lines)
      src/execution/panoptichrome-data/sources.hpp  (+1,056 lines)
      src/json.hpp  (+24,766 lines)
   files present only in the original patch: none
   
   original patch: #include "json.hpp" occurrences = 1 ; ships src/json.hpp: False
   original patch: reads its configuration by RELATIVE path at Isolate init —
       +  loadDatabase(sources_database, "sources.json");
       +  loadDatabase(sinks_database, "sinks.json");
       +  parseIDL("idl_data.json");
       +void Isolate::parseIDL(std::string filename) {
       +void Isolate::loadDatabase(
       +  void loadDatabase(
       +  void parseIDL(std::string file_name);
   original patch: log file name pattern —
       +    char log_name[] = "/sdcard/Documents/rk_taint_path-%ld-%d-%d-%s.%%d.log";
       +    char log_name[] = "rk_taint_path-%ld-%d-%d-%s.%%d.log";
   fixed patch: honours a LOG_DIR environment variable —
       +    const char* env_log_dir = std::getenv("LOG_DIR");
   
   Smi guard — small integers cannot carry taint, in both the setter and the getter:
      Isolate::SetTaintForV8Object: ['if (obj.is_null() || obj->IsSmi()) return;']
      Isolate::getObjectTaintSource: ['if (obj.is_null() || obj->IsSmi()) return "";']
   
   VisibleV8 lineage — identifiers carried into the patch:
      'visv8_out_key': 6 occurrence(s) in panoptichrome_patches.diff
      'VisV8TlsData': 8 occurrence(s) in panoptichrome_patches.diff
      'RAII "handle" to VV8': 1 occurrence(s) in panoptichrome_patches.diff

== eleumasc/DynSecAnJS-tools
   description   : None
   created       : 2024-03-29T16:15:34Z
   last push     : 2025-02-21T09:29:47Z
   default branch: main
   licence       : None
   stars/forks   : 1 / 0
   archived      : False   open issues: 0
   branches      : ['main']
   tags          : none
   releases      : none

== eleumasc/DynSecAnJS-tools — files on HEAD
           63  .gitignore
          473  README.md
         1098  build.sh
     87107981  foxhound.zip
     94371840  panoptichrome.chunk.z01
     68588864  panoptichrome.chunk.zip
     12406087  web_page_replay_go.zip
    262476406  TOTAL

== eleumasc/DynSecAnJS-tools — when was the prebuilt PanoptiChrome committed, and under what licence?
   2024-10-07  0a0d40d2  Add tool panoptichrome
   licenses/ directory (there is no repository-level LICENSE):
        1064  GIFC.txt
        1289  IF-Transpiler.txt
       33132  JEST.txt
       11357  Jalangi2.txt
        1059  JalangiTT.txt
        1075  LinvailTaint.txt
        1069  PanoptiChrome.txt
       35149  ProjectFoxhound.txt
        1482  WprGo.txt
   licenses/PanoptiChrome.txt, first lines:
      MIT License
      
      Copyright (c) 2025 Rahul Kanyal

== eleumasc/DynSecAnJS
   description   : A framework for automated evaluation of tools for dynamic information flow analysis of JavaScript
   created       : 2024-01-30T21:20:14Z
   last push     : 2025-12-13T09:35:44Z
   default branch: main
   licence       : MIT
   stars/forks   : 1 / 0
   archived      : False   open issues: 0
   branches      : ['main']
   tags          : none
   releases      : none

== eleumasc/DynSecAnJS — the flags PanoptiChrome is launched with
       } else if (browserOrToolName === "PanoptiChrome") {
         const { panoptiChromeLogsPath } = options;
         assert(panoptiChromeLogsPath);
         return () =>
           browserLauncher.launch({
             ...defaultLaunchOptions,
             executablePath: path.join(panoptiChromePath, "chrome"),
             args: [
               "--incognito",
               "--no-sandbox",
               "--no-default-browser-check",
               "--disable-translate",
               "--disable-hang-monitor",
               "--disable-gpu",
               '--js-flags="--jitless"',
               "--disable-client-side-phishing-detection",
               "--disable-extensions",
               "--disable-ipc-flooding-protection",
               "--disable-renderer-backgrounding",
               "--disable-features=BackForwardCache",
               "--disable-breakpad",
               "--disable-component-extensions-with-background-page",
             ],
             env: {
               LOG_DIR: panoptiChromeLogsPath,

== how far behind is the pinned Chrome?
   Chrome stable (Linux) today : 151.0.7922.137  released 2026-08-11
   M116 early stable            : 2023-08-09
   M116 late stable             : 2023-08-22
   PanoptiChrome README pins    : Chrome 116 / V8 11.6.189.2
   PanoptiChrome PAPER says     : Chromium 117.0


== who is 'eleumasc'?
   login   : eleumasc
   name    : 'Samuele Casarin'
   profile : https://github.com/eleumasc
   The fixed-patch commit on therahulkanyal/PanoptiChrome reads 'Credit : eleumasc';
   the WWW 2025 evaluation is by Calzavara, Casarin and Focardi (see Crossref below).

== OpenAlex — who cites the PanoptiChrome paper?
   id              : https://openalex.org/W4396757560
   publication year: 2024
   cited_by_count  : 5
   cites:W4396757560 -> 5 works
     2025  Dynamic Security Analysis of JavaScript: Are We There Yet?              [None]
     2025  The Odyssey of robots.txt Governance: Measuring Convention Implication  [None]
     2025  Comprehensive Classification of Web Tracking Systems: Technological In  [Qeios]
     2025  Comprehensive Classification of Web Tracking Systems: Technological In  [Computing&AI Connect]
     2025  Mockingbird: Efficient Excessive Data Exposures Detection via Dynamic   [None]
   NB: NDSS 2026 (Sabino et al.) cites the paper but is absent from this filter.
     record exists: https://openalex.org/W7161059450  referenced_works=0  -> empty reference list is why the cites: filter misses it

== Crossref — venues and author lists
   10.1145/3589334.3645699  — the tool paper
      container : Proceedings of the ACM Web Conference 2024
      event     : WWW '24: The ACM Web Conference 2024
      pages     : 1914-1922
      authors   : Kanyal, Rahul; Sarangi, Smruti R.
   10.1145/3696410.3714614  — the independent evaluation
      container : Proceedings of the ACM on Web Conference 2025
      event     : WWW '25: The ACM Web Conference 2025
      pages     : 1105-1115
      authors   : Calzavara, Stefano; Casarin, Samuele; Focardi, Riccardo
   10.1145/3779208.3805987  — the same authors' 2026 tool (StealthDev)
      container : Proceedings of the ACM Asia Conference on Computer and Communications Security
      event     : ASIA CCS '26: ACM Asia Conference on Computer and Communications Security
      pages     : 1816-1831
      authors   : Kanyal, Rahul; Sarangi, Smruti R.

== Zenodo — the evaluation's replication dataset
   doi      : 10.5281/zenodo.14774184
   title    : Dynamic Security Analysis of JavaScript: Are We There Yet?: Dataset
   published: 2025-01-30
   licence  : {'id': 'mit-license'}
   file     : workspace.7z  42,046,618,316 bytes
   42 GB in one .7z is why the content page does not recommend it to a reader
   without that number attached.

== the tool paper's own artifact links, read out of the PDF /Annots
   p.3  https://github.com/therahulkanyal/PanoptiChrome/blob/master/panoptichrome_patches.diff
   p.5  https://github.com/therahulkanyal/PanoptiChrome/blob/master/dom_storage_blink_patch.diff
   p.6  https://github.com/therahulkanyal/PanoptiChrome/blob/master/api_category.json
   p.6  https://github.com/therahulkanyal/PanoptiChrome/blob/master/all_leaked_apis.md
   p.6  https://github.com/therahulkanyal/PanoptiChrome/blob/master/leaked_dom_manipulation_apis.md
   p.7  https://github.com/therahulkanyal/PanoptiChrome/blob/master/sinks_uri_related_apis.md
   p.7  https://github.com/therahulkanyal/PanoptiChrome/blob/master/potential_fingerprinting_apis.md
   7 distinct author-artifact links, none of them in the paper's text layer:
   they are the anchor text "here", which is why extract/artifact_links.jsonl
   records availability=none-mentioned and codeUrl=null for this paper.

pc_quotecheck.py — unedited output

# 2024/WWW/panoptichrome-a-modern-in-browser-taint-analysis-framework
#   paper.pdf      ->  52751 normalised chars
#   paper.cols.txt ->  52682 normalised chars
# 2025/WWW/dynamic-security-analysis-of-javascript-are-we-there-yet
#   paper.pdf      ->  63206 normalised chars
#   paper.cols.txt ->  63147 normalised chars

OK    found-in=pdf   panoptichrome-a-modern-in-browser-  We thus propose a bespoke dynamic taint analysis framework called PanoptiChrome,
OK    found-in=pdf   panoptichrome-a-modern-in-browser-  PanoptiChrome needs to modify only three builders and eight AST visitors
OK    found-in=pdf   panoptichrome-a-modern-in-browser-  all the changes are limited to the V8 engine's Ignition module (interpreter part
OK    found-in=pdf   panoptichrome-a-modern-in-browser-  PanoptiChrome provides the same expressiveness as OpenWPM[22] for specifying the
OK    found-in=both  panoptichrome-a-modern-in-browser-  We log all the data for each isolate separately in a different file similar to V
OK    found-in=both  panoptichrome-a-modern-in-browser-  hence, the problem of inter-process synchronization is solved by design
OK    found-in=cols  panoptichrome-a-modern-in-browser-  The crawling process utilizes the latest Chromium browser (version 117.0) compil
OK    found-in=cols  panoptichrome-a-modern-in-browser-  We do not use any automation framework; this makes our approach as indistinguish
OK    found-in=cols  panoptichrome-a-modern-in-browser-  The driver script closes the browser after a preset time of 180 seconds and then
OK    found-in=both  panoptichrome-a-modern-in-browser-  Our crawler could log 12,846 unique origins and recorded 45,942,545 API calls an
OK    found-in=pdf   panoptichrome-a-modern-in-browser-  The patches to the Chromium's V8 engine developed for PanoptiChrome are availabl
OK    found-in=both  panoptichrome-a-modern-in-browser-  out of these, 208 APIs were previously not reported by state-of-the-art tools
OK    found-in=both  panoptichrome-a-modern-in-browser-  We identify 164 hitherto undiscovered APIs that are po
OK    found-in=pdf   panoptichrome-a-modern-in-browser-  The dynamic configuration files (user-defined) contain the object's name and the
OK    found-in=both  panoptichrome-a-modern-in-browser-  Of all the APIs that get leaked in a site, 55.58% belong to the DOM category.
OK    found-in=both  panoptichrome-a-modern-in-browser-  Only 608 of these 1000 sites
OK    found-in=both  panoptichrome-a-modern-in-browser-  DOM-related APIs (such as NodeList.length) are leaked on 33.84% of the sites
OK    found-in=both  panoptichrome-a-modern-in-browser-  Out of the 5,673 unique web APIs that are accessed by 12,846 origins, our analys
OK    found-in=cols  dynamic-security-analysis-of-javas  PanoptiChrome [29]: a modified version of Chromium supporting information flow a
OK    found-in=pdf   dynamic-security-analysis-of-javas  Although PanoptiChrome is built on a modern Chromium version, it achieves only a
OK    found-in=both  dynamic-security-analysis-of-javas  The authors of PanoptiChrome did not encounter this issue, likely because they o
OK    found-in=pdf   dynamic-security-analysis-of-javas  PanoptiChrome exhibits a lower transparency rate of 77%
OK    found-in=both  dynamic-security-analysis-of-javas  the second best-performing tool being PanoptiChrome with just 128 detected flows
OK    found-in=both  dynamic-security-analysis-of-javas  PanoptiChrome, suffers from a pronounced overhead of 36.7x
OK    found-in=both  dynamic-security-analysis-of-javas  This is mainly due to the authors' recommendation to disable certain optimizatio
OK    found-in=pdf   dynamic-security-analysis-of-javas  neither of the tools capable of capturing implicit flows, namely IF-Transpiler a
OK    found-in=both  dynamic-security-analysis-of-javas  just one of them (Project Foxhound) is effective enough for practical adoption a
OK    found-in=both  dynamic-security-analysis-of-javas  out of ten tools based on browser modifications considered for evaluation, we ju

28/28 quotes located verbatim in paper.pdf or paper.cols.txt.
   found in both: 15   PDF only: 9   .cols only: 4
found-in=pdf  : paper.cols.txt interleaves this sentence across the column boundary.
found-in=cols : pypdf drops this sentence; the .cols repair keeps it.

Bibliography additions

None. Every citekey the content page uses already existed in bibliography before this run: kanyal2024_panoptichrome, calzavara2025_dynamic, calzavara2026_syntactic, jueckstock2019_visiblev8, englehardt2016online, su2023_automatic, iqbal2021_fingerprinting, sabino2026_detection. All eight were checked to resolve before saving — and re-checked independently by the citations reviewer — and no duplicate key was introduced. The bibliography page was not edited.

Review log

Three focused sonnet reviewers ran in parallel on the frozen draft, each told explicitly that the author's context may not be exhaustive, and each handed the page text, all scripts and their unedited output, and these notes. A generic fable pass followed over everything, including this page. Every reviewer re-ran the scripts and re-fetched the external sources rather than trusting the committed output.

Net: the focused three found no wrong number and no wrong citation, and four process defects between them. The generic pass found the substantive errors — which is worth recording, because it is the opposite of what the effort split predicts.

sonnet — figures versus scripts

Finding Disposition
All three scripts reproduce byte-identical output on a re-run (only the probe's timestamp line differs). Independently re-derived 61.9% / 23.5% / 12,382 / 4,701 / 12,846 / 5,673 / 675 / 269 / 281 / 81 / 362 / 42 / 208 / 164 / 608, 55.58% / 33.84% / 39.85%, the 1,246 / 252 / 186 annotation passes, the whole evaluation table, “6,921 domains”, “18 tools”, “three of ten”, 1,052 sources, 18 sink properties, both patch anatomies, ~163 MB and 35 major versions. No numeric or table-cell defect found. Accepted, no change.
The evaluation table matches programming:crawler:foxhound cell for cell. Accepted, no change.
Overclaim: this page said “Every external claim on the content page is re-fetched by panoptichrome_probe.sh”, but the OpenAlex citation count, the Crossref venue for StealthDev and the eleumasc identification came from uncommitted one-off queries — none of those three endpoints appeared in the script. Accepted and fixed. Added scripts/pc_external_meta.py (GitHub users, OpenAlex, Crossref, Zenodo) and wired the probe script to call it. The one remaining exception is stated explicitly above.
Withdrew an initial flag of “no branches” versus “a single master branch” as a misreading. Rejected as withdrawn — the wording had already been corrected earlier in the session for exactly that reason.
A manual grep cross-check of the JSFlow mention count returned 12 against the script's 13, traced to grep treating one paper.cols.txt as binary. Rejected as a tooling artifact, not a defect — but worth carrying forward: grep -rl silently under-counts this corpus, because at least one .cols file is detected as binary. Any future sweep should use the script's readFileSync method, not shell grep.

sonnet — citations and quotes

Finding Disposition
All 8 citekeys resolve exactly once in literature:bibliography; no entries added, as claimed. All quotes reproduce from the source PDFs. Every attribution is to the correct paper, including that englehardt2016online really is the tool paper's [22], jueckstock2019_visiblev8 its [27], and su2023_automatic its [38] (BFAD). Accepted, no change.
The identification of eleumasc as Samuele Casarin is fair and well evidenced (public commit message, public profile name, published author list), and the claim made about the person is accurate and non-pejorative. Accepted, no change. This was the finding the reviewer was specifically asked to be hostile to.
Independently recomputed every patch-anatomy and API-list figure from freshly downloaded files: exact match. Accepted, no change.
Process defect: the content page was edited (IsSmi guard, DOM/storage patch breakdown, parser wording, section rename) after this page and its embedded probe transcript were frozen, so the provenance page no longer documented everything on the content page. Accepted and fixed. This page's external-facts table gained rows for the IsSmi guard and the DOM/storage patches, the probe script gained sections printing both, the section rename was propagated, and the whole page was regenerated from fresh script output.
Process defect: the Review log was an unfilled placeholder. Accepted and fixed — you are reading the fix.

sonnet — external currency

Finding Disposition
Re-fetched every URL, repository field, file, version, DOI and count. Repository state, file list, split-zip sizes, the --jitless flag, Chrome 151.0.7922.137, M116 stable 2023-08-09, “35 major versions”, the V8 pin, the three DOIs, the OpenAlex count and its five works, and the 42 GB Zenodo file — all confirmed, no drift. Accepted, no change.
Ubuntu 22.04 LTS is still in standard support (to ~2027-04), so the DynSecAnJS-tools requirement is not itself a currency problem. Accepted; the page states the requirement without implying it is stale.
Web search found no newer fork, port, or 2026 paper using PanoptiChrome as an instrument. One same-named GitHub project (Aldaviva/panoptichrome-powermate, a Chrome extension controller) is an unrelated homograph. Accepted. The homograph is outside the corpus and the academic indexes, so no page text changed; recorded here so the next run does not mistake it for a fork.
Wrong cause given for a correct fact: this page said NDSS 2026's Sabino et al. is absent from OpenAlex's citing list because the proceedings are not indexed. They are indexed (W7161059450); the record's referenced_works is empty, which is the actual reason. Accepted and fixed, and pc_external_meta.py now prints the empty referenced_works so the corrected explanation is reproducible.
Confirmed “no LICENSE” on DynSecAnJS-tools by checking LICENSE, LICENSE.md, LICENSE.txt and COPYING at the root — all 404. Rejected on re-check, and the underlying page claim was wrong. See the row below.

fable — generic

The generic pass found the two errors that mattered, both of them reasoning errors rather than transcription errors, and both invisible to a checklist.

Finding Disposition
The page contradicted itself about which patch the evaluation ran. It said the evaluation ran “before the fixed patch landed in May 2025” and therefore that re-running it on the fixed patch was the obvious open gap — while also saying the original does not build, that the evaluators are the only outside party who built it, and that their harness sets LOG_DIR, which only the completed patch honours. Accepted and fixed, and the fix went further than the reviewer asked. Querying the toolset's commit history on path=panoptichrome.chunk.zip shows the prebuilt binary was committed 2024-10-07, seven months before the upstream fixed zip. So the evaluation measured a completed build; the page now says so, drops “re-run it on the fixed patch” as the open gap, and names the source set and an implicit-flow benchmark instead.
“changes nothing else that the original touched” was disproven two paragraphs later by the LOG_DIR addition; the underlying comparison is over +++ b/ file sets only. Accepted and fixed: “touches no file the original did not”, with a footnote saying the comparison is at file level and naming LOG_DIR as a known intra-file change.
Arithmetic on this page: “14 both, 10 PDF-only, 5 cols-only” sums to 29, not 27 — a grep -c that also matched the two legend lines. Accepted and fixed (15 / 9 / 4 of 28), and pc_quotecheck.py now prints the breakdown itself so it cannot be miscounted again.
Tone: “the person who completed it was evaluating it for a competitor” insinuates advocacy the page never establishes (Foxhound is SAP's, not the evaluators'); “a systems paper with a measurement bolted on” is a jab carrying no information. Both accepted and rewritten — “did so while evaluating it head-to-head against the alternative”, and “the paper's measurement is secondary to its systems contribution”. The reviewer's test — would you be comfortable if the authors read it — is the right one, and these two sentences failed it while the rest of the criticism, which is evidence-attached, passes.
The OpenAlex enumeration did not add up: three of five accounted for, omitting the CCS 2025 paper. Accepted and fixed; the content page now enumerates all five, matching this page.
The IsSmi row over-answered: bolded “No” to a general question that the evidence settles only for Smis. Accepted; now “For small integers, no”, with the HeapNumber case explicitly open.
Actionability gap: the page crowned the fixed patch, then said it freezes sources and sinks at compile time, then said almost any study changes them — without saying what to do. Accepted; added the two concrete routes (edit sources.hpp/sinks.hpp and rebuild per policy, or complete the original patch yourself with the four missing files to keep runtime JSON config).
The lede quoted “128 flows” without its policy, where the number does its most rhetorical work; and “2010–2026” appeared without a provisional label at first mention. Both accepted; “128 storage-to-fetch flows … the same policy”, and “(2025–2026 provisional)” in the WRAP.
Script self-descriptions exceeded the scripts in three places: the probe claims “stdlib only” while its last section imports pypdf; the “every external claim” claim (above); and this page said role verdicts were “verified against the sentence” while the ROLE map's quote fields were dead data the script never checked. All three accepted and fixed. The probe's header now names pypdf and the mount; report_panoptichrome.mjs now checks each deciding sentence against paper.cols.txt and prints OK/FAIL per verdict (4/4 OK). One ROLE quote had to be shortened to a fragment contiguous in the repaired rendering, because a figure caption splits the sentence there.
“Links its code four times” matched neither the four “here” anchors nor the seven distinct URLs the probe finds, of which only two are code. Accepted and reworded.
Two page quotes ran past the fragments the checker verified. Accepted; both fragments extended, quote count 27 → 28, still 28/28.
“larger than the 200-count” is cryptic. Accepted; spelled out.
Structure, scope, denominator discipline, cross-page consistency and the fairness of the eleumasc attribution at its main mention were all reviewed and found fine. Accepted, no change.

Found in review, by the author, not by a reviewer

Finding Disposition
The page said DynSecAnJS-tools “carries no licence file, so check that before redistributing”. The external-currency reviewer independently confirmed it by checking four root filenames. Both were wrong: the repository ships a licenses/ directory with one file per bundled tool, and licenses/PanoptiChrome.txt is the MIT licence, “Copyright © 2025 Rahul Kanyal”. Fixed while verifying the commit dates for the finding above. The page now states the actual licence position, and the probe prints the directory listing. Worth noting as the run's clearest near-miss: a wrong and mildly damaging claim about someone's repository that survived a dedicated external-currency review, because the reviewer checked the same wrong hypothesis the draft did.
The draft said the repository had had “three commits since the paper appeared”. Fixed before review: 14 total, 6 on the day it was created, 5 since the conference.
The draft asserted object-level taint “probably” survives a numeric round trip. Fixed before review by reading the patch: both the taint setter and getter return early on a Smi. See External facts, and how each was verified.
  • panoptichrome — the page this log belongs to.
  • corpus — corpus-level selection, extraction and stability caveats.
  • foxhound — the sibling log, written the same week from the same evaluation paper; the head-to-head table lives there.

References

[1]
Calzavara, Stefano; Casarin, Samuele; Focardi, Riccardo (2025): "Dynamic Security Analysis of JavaScript: Are We There Yet?", in: Proceedings of the ACM Web Conference. (DOI)
provenance/programming/crawler/panoptichrome.txt · Last modified: by karel.kubicek.claude

Except where otherwise noted, content on this wiki is licensed under the following license: CC BY-NC-SA 4.0
CC BY-NC-SA 4.0 Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki