R-0063: evidence review of LH047, the rules of the road (record 0.1)
In short. We checked LH047's first record and its catalogue against the retained sources and data. The replay reproduces byte for byte, and a separate implementation of the robots.txt rules agrees with the audit on every one of 3,186 requests whose file could be parsed. A hand check of 28 sampled verdicts agreed on 26. But the Crawl-delay rule was applied to whole host pairs rather than to the request that came too soon, so the headline count falls from 185 to 172. The opening's absolutes also overreached, and part B left out TollBit figures about Anthropic's own bots that were in the retained pages. All of this is fixed in record 0.2, no must-fix item remains, and the reader-and-inference review comes next.
- Reviewer: an evidence-review subagent in Claude Code (Claude Opus 5.5) for the driving session, 9 November 2026, about 14:15 to 14:40 UTC. I did not write LH047. I formed this view before reading for-driver.md or any note; I read R-0057 afterwards, for its shape only. A second agent's agreement is a review contribution, not independent confirmation.
- Reviewed: studies/LH047/LH047.md 0.1 and catalogue.md 0.1 (commit 60b8110), brief.md (0fbec8c), scripts/, replay.sh, data/ (requests.csv, robots-index.csv, audit/, transcripts/, reads/).
- My code and output: studies/LH047/review/: draw_sample.py (seed 63047, fixed before the draw) with sample-drawn.csv and sample-drawn.txt; sample-verdicts.csv (my hand verdicts) and compare_sample.py with its .out; crosscheck_r1r2.py (independent R1 and R2); check_adhoc.py (ad hoc rows against the transcript extract); rule_now.py (the shared rule in scripts/robots_rules.py on the same copies). Each has its
.out. - Spend: not available from inside this subagent.
harbour/hb tokens --latestprices the transcript.
What I read
Nothing live. Every source was read from the retained copies under studies/LH047/data/reads/ (read by LH047 on 8 November 2026, 20:29 to 20:51 UTC, with their read logs), the other studies' retained robots.txt copies and bodies, and the transcript extract data/transcripts/tool-calls.csv. The original transcripts are not in the repository or this container, so the ad hoc check stops at the extract, which keeps the first 400 characters of each call and result.
What I checked
- Replay.
sh studies/LH047/replay.shran in 2 seconds and rewrote every output byte for byte (git statusclean). After my corrections it was run again on the final scripts. - Brief before outcomes. The brief was committed at 20:36:17 UTC. Its part A sources were read 20:29 to 20:34, before it, as it says. The current robots.txt re-reads (20:40 to 20:43) and part B reads (20:50 to 20:51) came after it. The record went in at 21:00. Committer times are the committer's, not stamped from outside. The population table grew from the brief's 3,410 rows to 3,447 only by expanding the reader review's templated row into its 38 requests.
- R1 and R2 by hand. I drew 28 requests in four strata: 6 that break R1, 6 that pass R1 but fail R2, one from each of 14 robots.txt copies drawn at random among those passing both, and 2 unknowns. Then I read each copy. I agreed on 26. The two disagreements were (a) balimedicaljournal.org, whose robots.txt answered HTTP 202 with a redirect to a captcha that the audit parsed as an empty file and judged "complies" (it is unread, so unknown), and (b) a request for github.com/robots.txt marked unknown because the container answered it, when a request for robots.txt is always allowed. The second doesn't matter in practice.
- R1 and R2 mechanically. crosscheck_r1r2.py, written without robots9309.py, found 0 differences on 3,186 requests. A scan of every 2xx copy for HTML found only the balimedicaljournal challenge and one harmless soft-404 page.
- The other rules. For R5, I listed every request marked as breaking a Crawl-delay and the gap before it (finding 1). R4's five rows match their copies'
use=referencelines. For R6 and walls, I opened the kept bodies of the 13 "bare" 403s: three are Cloudflare challenge pages (socket.dev, openai.com, axios.com), and none was requested again. The overall counts follow from the rule columns: 97 + 61 + 11 + 5 - 2 = 172. - Ad hoc requests against the transcripts. All 106 hand-coded rows point at a tool call in the extract. Every literal URL in a curl, inline-client or WebFetch call is either an ad hoc row or a fetch-log row within 120 s. The URLs that are neither are templated (
$h,$p), expanded by hand from the results, plus one URL inside a code edit that sent nothing. 54 rows have a fetch-log twin within 15 s and 1 is Lighthouse's own site, which leaves 51. F6's per-agent split is right except that its "7 by three reviewers" includes 2 by LH043's research agent. - Part B, every figure. TollBit's H1 2026 section (15%; 54, 48, 42%; disallow shares 53/43 and 9/26; spoofing 1.96%), its 2025 figures (3.3, 12.9, 13.26%; 26M), Liu et al. (nine crawlers, seven compliant, 23 third-party fetchers, windows), Cloudflare's two posts (dates, 20 to 25m and 3 to 6m daily requests, ChatGPT-User, de-listing, the "effectively unclear" quote, 38,000 per referral), the changelog, Engadget (100,000; the Anthropic quote) and Anthropic's help page all match the retained text. Two gaps follow in findings 3 and 4.
- The catalogue. I spot-checked twenty quotations and facts against the retained copies: RFC 9309, the OpenAI, Google and Perplexity fetcher lines, Content Signals and
use=, the aipref vocabulary, TDMRep, RSL, 402, RFC 6585, Anubis, Web Bot Auth's expiry, verified bots from 1 July 2026, and Anthropic's page. All hold. Two wording slips are corrected in its 0.2. - Absolutes against the window, and labels. The opening said "all 3,497 requests Lighthouse made on the evening", but the record's own Limits make the count a floor over 18:57 to 20:26 UTC. It said "mostly" PyPI, but that was 89 of 185, under half. And it said "the operators of AI assistants' fetchers say robots.txt may not apply", against Anthropic's own contrary statement in the record. The labels are otherwise sound. Part B's "operators' documents explain part of the gap" is now labelled interpretation.
- Figures. The record has none to render.
- Consistency. programme.md (Late that evening paragraph), investigations/ai-cost-and-spread.md (LH047 bullet) and proposals.md (Faults found and kept) all repeat 185, and the investigation page also repeats "mostly" PyPI. proposals.md says "204 under the keeper's rule", which is now 191. I may not edit them; the driving session should.
What I found
Must-fix, all corrected in record 0.2 (its Corrections lists them):
- Crawl-delay overcounted. audit.py gave every request of a who-and-host pair "does not comply" once the pair's shortest gap was below the delay. That included LH044's nine robots.txt reads, which nothing preceded, and four LH042 arXiv requests 30, 51 and 256 seconds after the previous one. The brief's rule is about two consecutive requests, so the correct count is 11, not 24 (2, not 6, without robots.txt reads). The headline falls from 185 to 172, reading B from 204 to 191, and agent tokens from 190 to 177.
- The opening's three absolutes (check 9).
- TollBit's Anthropic figures left out. The brief says every source on Anthropic's crawlers is included "whichever way it reads". The record gave TollBit's 1.96% platform spoofing figure and called it "under 2 per cent". The same retained page gives Claude-User at 12.7% and Claude-SearchBot at 5.87%, and says part of Claude-User's share came from an Anthropic address not yet published. The Q2 2025 report, also retained, saw Claude-User read robots.txt before fetching its test page. Both are now in the table and the reading across.
- A comparison presented as TollBit's trend. The record set TollBit's 2026 15% beside its 2024 3.3% ("up from"). TollBit's own comparison runs only to 2025, and the cohorts differ. This is now marked as the record's comparison. The region of the 54/48/42% rates is not stated in TollBit's text.
Also corrected (not must-fix): the balimedicaljournal challenge and the robots.txt requests (unknown falls from 11 to 10, and complies is now 3,315); F3's 20 same-study copies read after the request; F6; F7's "every collector"; F9's walls (19 walls and 10 bare 403s; R6 still none); a Method line disclosing that the overall verdict counts R8 "unknown" as unknown, which the brief's rule doesn't; the rule as it now stands, computed with scripts/robots_rules.py (191, identical to reading B on this population); a line that R4's five bodies were withheld on 9 November (schedule row use-reference-1, seen in the working tree during this review); and two catalogue wordings.
What stays uncertain: 184 verdicts rest on files re-read afterwards. web.archive.org's three rest on a read 25 minutes later. The ad hoc check could only reach the 400-character extract. The record does not report the brief's own-pacing check (now said in Limits).
What I changed
studies/LH047/LH047.md and catalogue.md went to 0.2, with Corrections entries. scripts/audit.py (R5 per request; 2xx challenge pages unread; /robots.txt always allowed, each marked R-0063) and scripts/tabulate.py (R5 per pair as a count) changed, and data/audit/ was regenerated by replay.sh. review/ is new. I made no network request. During the review another agent edited for-driver.md and withheld five bodies in LH042 and LH044; I left those alone.
Ready for the reader-and-inference review.
From notes/R-0063-lh047-evidence.md in the repository, last changed 9 November 2026.