R-0039: evidence review of the week-one piece
Reviewed: articles/a-week-after-two-fixes.md (draft 0.1), articles/short/a-week-after-two-fixes.md, articles/a-week-after-two-fixes.svg (studies/LH034/scripts/draw_piece_figure.py), against studies/LH033 (record 0.1, brief with amendment 1, checkpoints, data, scripts) and studies/LH034 (record 0.1, brief, checkpoints, data, scripts), with studies/LH033/data/python_side.json and its inputs in LH011 and LH008. Reviewer: evidence-review subagent on Opus 5.5 (claude-opus-5-5), dispatched by the driving session of 30 October 2026. A second agent's agreement is a review contribution, not independent confirmation. Date: 30 October 2026.
How
I recomputed every figure from the retained primary data with my own code, without importing the studies' scripts: studies/LH034/review/R-0039_checks.py, output in R-0039_checks.txt (replay: python3 -I studies/LH034/review/R-0039_checks.py). It reads the gzipped Censys bodies (the read of 29 October for every day-7 figure, and all six reads for revisions), the raw W3Techs HTML of 25 and 26 October, Packagist's retained series (the raw body is deliberately not kept, because it embeds a site key; I checked the monthly figure against the sum of the daily series), every raw nodejs.org daily summary (earliest read per day) and the latest dist/index.json, with versions compared numerically rather than by index order, and LH011's release_days.csv and LH008's lags.csv for the Python side. I checked the briefs' rules against the records, every comparison sentence day by day, the caveats, the title and summary read alone, and the external facts against the records that hold them. I rendered the figure in light and dark with the container's headless Chromium and read both images.
What reproduced
- Censys, read of 29 October, days 0 to 7: 8.2 53.0, 8.3 52.4, 8.4 67.8, 8.5 78.8 per cent on day 7; first at half on days 6, 6, 2, 2; the older two below the newer two on every day from 1; daily rises 1 to 5 points from day 3 and 1.06 to 2.05 from day 4; branch sizes 6.01, 7.86, 3.24, 3.38 million. Unfixed branches 23.3 million on days 0 to 2 and 24.39 million on day 7, 57.2, 55.3 and 54.3 per cent of version-reporting services; no-version 28.4 per cent on day 0 and 59.5 on day 7; the no-version count rose 2.7-fold on 23 October and the total from 61.4 to 95.8 million, 110.9 on day 7. No completed day was revised in any of the six reads. The interim uses only the read of 29 October for day 7, as LH033's brief requires.
- W3Techs: 1.9/2.6/4.2/5.9 per cent (25 October) and 2.8/3.8/6.0/8.3 (26 October). Packagist: 583.7 of 5,809.9 million, 10.05 per cent.
- Node.js: at or above v22.23.4 only v22.23.4 itself; at or above v24.22.1, v24.22.1 and v24.22.2 (dated 27 October, not flagged security); at or above v26.12.1, v26.12.1 and v26.13.0 (28 October, not flagged). Every line-22/24/26 key in the summaries is in
dist/index.json, so the index-order and numeric rules agree. Day-7 shares 53.9, 72.2, 64.7; all three first at half on day 2; line 22 back below half on days 3 and 4 (48.1, 49.3). On day 7 v26.13.0 alone was 18.3 per cent of line 26's downloads and v24.22.2 2.6 per cent of line 24's. Unfixed lines 11.79 to 16.46 per cent each day 14 to 28 October (14.3 on day 0, 11.8 on day 2, 14.7 on day 7), 17.8 to 20.3 in 23 to 30 September; line 20 5.2 to 8.5, line 25 0.7 to 1.1; no-version at most 0.0095 per cent; weekend volume 0.51 of weekdays. - July: days 1, 2, 7: 13.6/30.7/31.1, 4.3/15.1/29.4, 41.6/69.9/89.0; first at half on days 18, 4, 2; posting-aligned 30.7/31.9/31.0, 15.1/46.0/26.8, 69.9/89.1/89.4. Lines 22 and 24 were higher in October than July on every day 1 to 7 on both alignments, not only on days 1, 2 and 7; line 26 lower by day 7 on both.
- Python: four fixes 53.8 to 60.8 (day 1), 52.7 to 63.7 (day 2), 55.6 to 59.5 (day 7), 57.3 to 72.3 (day 30); medians of 37 project medians 57.6, 57.2, 57.9; LH008 18 and 50 of 102 pairs. Rounded, the piece's "54 to 61" and "56 to 60" hold.
- Comparison sentences: "below every" (day 1, both records), "above all four PHP branches" (Node, day 1), day 2 and day 7 placements, "one line below the Python range a week on and two above it" all hold.
- Figure: title, description and alt text state the figures correctly (after the fix below). Both themes render legibly: two panels with separate unit labels, the half line dashed, labels clear of each other, no clipping.
What I found and changed
- Title, a plain error of denominator (fixed). "more than half of the PHP services we could see stood where no fix reaches": Censys saw 110.9 million PHP services on 28 October and the 24.4 million on unfixed branches are 22 per cent of them; more than half holds only for services showing a version. "No fix reaches" also contradicts the body, which says distributions may still patch some. Now: "more than half of the PHP services showing a version ran branches PHP no longer fixes". The short form's summary had "branches no fix reaches"; now "branches PHP no longer fixes", as its body already said.
- "Some organisations took sites offline" (fixed). No record supports it: LH027's one selected outage notice returned HTTP 403 and its record is inconclusive; the other leads are unopened search results. Replaced with what LH024 read and the released PHP account already says: "British and European Union security agencies advised isolating exposed systems that could not be patched promptly."
- "A scheduled security release" (fixed). Nothing in LH034's brief or record says the Node.js release was scheduled or pre-announced; "scheduled" removed. "Ten flaws" is supported (brief: ten CVEs, from the advisory read 27 October).
- "On the second day" (fixed, piece and short form). With 21 October as day 0, a reader counting the release day as the first day would read 22 October; the figures are for day 2, 23 October. Now "two days after release" (and "six days after" for 8.2 and 8.3). I added to the Node.js sentence that line 22 slipped just under half again over the following weekend (48.1 and 49.3 per cent), which the records report and "passed half" alone hid.
- "8.5 ran above both" (fixed). 8.5 was above every Node.js line only on days 5 to 7 (below on days 0 to 4, e.g. 70.5 against 79.7 on day 2). Now "was above both by then", in the sentence about a week on.
- "12 to 17 per cent" (fixed). The unfixed Node.js lines' daily maximum, 14 to 28 October, is 16.46 per cent; now "12 to 16".
- "The largest were 7.4, 8.1, 7.2, 5.6 and 5.2" placed on 28 October (fixed). That order is the baseline snapshot of 25 October (record); in the read of 29 October 5.6 (2.05 million) is above 7.2 (2.02). Now "7.4 and 8.1, with 7.2, 5.6 and 5.2 at about two million each", true in both snapshots.
- "The Python fixes kept creeping up for a month" (fixed). starlette 1.1.0 fell from 59.5 per cent on day 7 to 57.3 on day 30. Now "three of the four Python fixes were higher a month on than a week on".
- "A service that hides its version is not in Censys's count at all; ... that was most of the PHP services it found" (fixed). Self-contradictory: Censys counts them, as unknown. Now "not in Censys's patched shares at all".
- Censys's lag caveat (fixed). Its notes say "by up to about a week for some websites"; the piece dropped the last three words. Restored.
- Post hoc labelling of the July posting-day alignment (fixed). AGENTS.md asks a post hoc reading on a public surface to carry the number of comparisons and to name what will test it or say none can. The piece now says "a single comparison we chose after seeing the numbers, which no later count can test"; LH034's Findings now say no later read can test it on unread data and the brief's rule stays the measure.
- Figure, double rounding (fixed, script re-run). The tooltip for PHP 8.3 day 2 said 42.1 per cent; the value is 3,071,109 / 7,285,788 = 42.152 per cent (record: 42.2). The script took shares already rounded to four places and rounded again. It now divides the unrounded counts held in the tables (patched/targets; at_or_newer/line_downloads); two points moved by 0.1 px and that one label changed. Re-rendered and re-read in both themes.
- LH033 Method contradicted its Limits (fixed). Method said Censys calls a service patched when "seen on a fixed release, or seen earlier on an affected one and later on a fixed one"; Censys's notes (discovery.md) give only the second, and Limits lists the first case as not checked. Method now follows the notes and points to Limits.
- LH033 stated an interpretation as fact (fixed). "That is a change in the instrument's detection" is now labelled interpretation, citing Censys's note that totals may shift as detection improves, matching the piece's "looks like".
Briefs obeyed
LH033's interim uses only the read of 29 October for days 0 to 7 (the read of 30 October is cited only to say it revised nothing); measures 1 and 2 only, with measure 6 kept out of the piece and labelled post hoc and pending in the record. LH034's interim takes day 7 from the read of 30 October, which its brief allows; measure 4 follows the brief's day-0 rule, and the posting alignment is labelled post hoc. Neither record nor piece ranks the ecosystems or names a cause; units are named beside every comparison; downloads are not called machines and services not called sites.
Judgements for the driver and the reader review (not changed)
- "Most counts" (title) and "nearly every count we could read" (summary). On day 7 all seven per-line and per-branch shares were at or above half (lowest 52.4). The hedge is true but unexplained: the only count below half that the records hold is W3Techs (2 to 8 per cent on 25 and 26 October, days 4 and 5, a monthly crawl), and the piece never mentions it. Either name W3Techs and why it lags in "What this cannot tell us", which explains "most", or say "every count", with its window. Recommended before release; not a figure error.
- Prose sets the PHP service share beside the download shares ("8.5 was above both by then") while the figure caption says the two are drawn apart because they count different things. The briefs permit such descriptions with units named, and the caveat follows at once; the reader review should judge whether the sentence undoes the caption.
- Line 26's day-7 share includes v26.13.0, a non-security release of 28 October, at 18.3 of its 64.7 per cent. The piece says newer releases count; giving the size would help a reader see why line 26 jumps about.
- Ubuntu's "still calls itself PHP 8.3.6". LH018 supports the package version
8.3.6-0ubuntu0.24.04.13. Distribution builds commonly report the suffix in their version header as well; whether Censys reads the suffix was not checked. The point (the upstream number stays 8.3.6, so a floor) stands; the wording could say "keeps the version number 8.3.6". - Consistency rule. AGENTS.md's "Where things stand", the investigation page and the front page do not yet carry these findings; that is release work for the driver.
- Colophon still says "Not yet reviewed" and version 0.1 (draft), correctly for now.
Verdict
Must fix before release: none. The plain errors found are fixed above; the "most counts" and W3Techs point is recommended before release, and the changes made here should take the one fresh-agent reading AGENTS.md asks for after a review.
Resolution, by the driving session
All fourteen changes kept. On the judgements: the title and summaries no longer say "most counts" or "nearly every count"; they say every fixed Node.js line and PHP branch had passed half in the two daily counts read, and the piece now names W3Techs's monthly survey (2 to 8 per cent on 25 and 26 October) and why it lags. The cross-unit sentence now reads "in Censys's different count PHP's newest branch, 8.5, was higher still by then", left for the reader review to judge. Line 26's v26.13.0 share (18.3 per cent of 64.7) is now in the piece and the LH034 record. Ubuntu's package "keeps the version number 8.3.6". Also added to the LH034 record, so that the essay's figures rest on a record: the daily totals at weekends and on weekdays (labelled as noticed after the counts, not a measure) and the July release's day-14 and day-30 shares by the brief's rule. Release surfaces are done at release. These resolution changes go to the one fresh recheck.
From notes/R-0039-week-one-evidence.md in the repository, last changed 30 October 2026.