Lighthouse

Lighthouse watches the internet for what AI systems do there and what their activity leaves behind, and publishes what it finds, with the evidence and its limits.

Studies LH041

LH041: what shared files should gain (for the driving session)

Brief committed at 147e953 before any record was read; read 1 and tables at 1cccfb2; record version 0.1 at 65e3d4a, 0.2 after the evidence review (notes/R-0057-lh041-evidence.md) at 1506a3c, and 0.3 after the reader-and-inference review (notes/R-0061-lh041-reader.md), 9 November 2026. The lines below were rewritten for 0.3; the 0.1 lines they replace said "one account" for AntV, "unreviewed" and dropped the post hoc label. Snyk's one-account reading of AntV stays in the record, attributed and labelled interpretation, and is left off these short lines. The resolution in 0.3 still needs one recheck by a fresh agent before any of these lines goes public (AGENTS.md step 4).

schedule/due.csv rows

LH041-read-1,LH041,"Read 1 under studies/LH041/brief.md (collect.py --read <label>), tabulate.py with and without --posthoc, draw_figure.py, interim record 0.1",2026-11-08,2026-11-08,done,2026-11-08,"research subagent for the driving session 2026-11-08 (Claude Code, Anthropic cloud)","studies/LH041/LH041.md (0.1, not reviewed); read 2026-11-08T1910Z",
LH041-reviews,LH041,"Evidence review, then the reader-and-inference review, then one recheck by a fresh agent of the resolution; all before any public line",2026-11-09,2026-11-16,open,2026-11-08,,"notes/R-0057-lh041-evidence.md (record 0.2); notes/R-0061-lh041-reader.md (record 0.3); recheck to come","the record carries post hoc readings, labelled; check that no private maintainer is named"
LH041-read-2,LH041,"Read 2: python3 -I studies/LH041/scripts/collect.py --read <UTC label>, then replay.sh <label> and the three post hoc analyses of brief amendment 2 (vendor package lists beside OSV; review/simultaneous_starts.py <label> brief and posthoc; cluster counts under two other groupings); report records OSV added or changed and versions removed since read 1, and whether the post hoc view holds",2026-12-07,2026-12-21,open,2026-11-08,,,"brief amendment 2 (9 November 2026, post hoc): the scripts for its analyses 1 and 3 are committed before this read; first read under the robots gate (amendment of 9 November)"
LH041-record,LH041,"Record version 1.0 after read 2 and the reviews",2026-12-07,2026-12-31,open,2026-11-08,,,

Investigation page, "Where the evidence stands" (investigations/ai-cost-and-spread.md)

Replace the bullet that begins "**Spread run by people: the registry worms (record 0.2" with:

  • Spread run by people: the registry worms (record 0.3, reviewed by an evidence review and a reader-and-inference review). Of thirteen worm waves security firms name since September 2025, OSV's public malware records identify seven by the firms' own indicators and two more by date, one of those two (Miasma) only under a reading chosen after the counts were seen; nine waves have npm publish times and four have none. By npm's own clock, in a view chosen after the counts were seen (two choices, each a single alternative to the brief's rule), malicious versions in the two largest went up within hours under many groups of packages that share a current maintainer: 88 groups in under 15 hours for Shai-Hulud 2.0 on 24 November 2025, and 13 in under 4 hours for ChainDrop on 4 August 2026. A group isn't a victim, an account or a step of the worm: 14 of Shai-Hulud 2.0's 87 later groups and 2 of ChainDrop's 12 began within a minute of the group before them, some in the same second (also counted after the data were seen, at two thresholds). In the AntV wave 316 of its 359 packages fall in one maintainer group; two smaller groups followed, one nearly a week later, and may not belong to the wave. Each count is at most how many of the groups in OSV's records were reached without a person's new act, since the records can't say whether an operator published by hand in between; OSV's records are incomplete, so a wave's whole reach may be larger. Every report read says people run these worms. A second read in December sets the vendors' package lists beside OSV's, times the groups that began together and regroups the packages other ways (amendment 2 to the brief), though on the same waves, so it can't test the readings on data not yet seen. The record.

programme.md, Next

Checkpoint, 9 November 2026: the registry worms, dated (LH041 0.3)

LH041 tried to date thirteen named waves of the token-stealing registry worms from OSV's malicious-package records and npm's publish times, under a brief fixed before any record was read. Record 0.3, reviewed by an evidence review and a reader-and-inference review, not released: seven waves are found by the vendors' indicators and two by date, one of them (Miasma) only post hoc; nine have registry times and four have none, PyPI's Hades among them, since every malicious PyPI release read is gone. In a view chosen after the counts (two decisions, each a single alternative to the brief's rule), Shai-Hulud 2.0's and ChainDrop's malicious versions went up within hours under 88 and 13 groups of packages sharing a current maintainer. A group isn't a victim, an account or a step of the worm: 14 and 2 of those groups began within a minute of the group before them (post hoc, two thresholds). Each count is at most how many of the groups in OSV's records were reached without a person's new act, and OSV's records are incomplete. In the AntV wave 316 of its 359 packages are one maintainer group, and two smaller groups followed, one nearly a week later. Three options were weighed: continue with read 2 in December; repair the join for the waves OSV's text does not name (April's two and July's) with the vendors' package lists; or an outward question, dated counts of the worms' public exfiltration repositories, in aggregate and naming no account. The reader-and-inference review found that read 2 as written can't tell a chain of worm infections from one publishing run or one operator's pool of stolen tokens, so amendment 2 to the brief (9 November, post hoc) adds the repair, the timing of groups that began together and whether the group counts hold under two other groupings; all three run on the same waves, so none is a test on unseen data, and they can only lower the ceiling on how many groups were separate steps. Read 2 stays cheap and goes ahead with them. The outward question goes to proposals.md, with account names discarded at collection. No literature search was run beyond the brief's nineteen sources, because the amendment brings in no explanation from outside the record.

sources.md, proposed entries

  • OpenSSF malicious-packages. OpenSSF's repository of malicious-package reports in OSV format (MAL- ids), merged from sources such as GitHub's malware advisories (ghsa-malware), Amazon Inspector, Google's open source security team, kam193, ReversingLabs and OpenSSF Package Analysis; each record names its origins and import times; OSV serves the same records in its exports. Records are one per package, so a package compromised twice holds both episodes' versions. LH041 read the README, contributing guide, schema additions and config on 8 November 2026 and spot-checked 20 records (all matched OSV's copies). https://github.com/ossf/malicious-packages (raw files via raw.githubusercontent.com).
  • The npm registry's package documents. registry.npmjs.org/<package>: per-version publish times (time), which LH041 found kept for many removed malicious versions, the current maintainers, dist-tags and surviving version documents. Read anonymously; deleted packages answer 404. LH041 read 2,198 on 8 November 2026 (84 answered 404).
  • S26 OSV, add: the exports at osv-vulnerabilities.storage.googleapis.com/<ecosystem>/all.zip carry a GCS generation per version; LH041 read the npm and PyPI exports on 8 November 2026 (223,208 and 12,013 MAL- records). Some MAL- records carry a published time at bare midnight (date precision).

proposals.md, a backlog lead

  • The worms' public exfiltration repositories as a dated count: how many public repositories carry each wave's published description ("Sha1-Hulud: The Second Coming", "Shai-Hulud: Here We Go Again" and others the vendors print), by creation date, in aggregate only, naming no account and identifying no victim (the keeper's caution of 8 November 2026); since collecting would meet victims' account names, its brief keeps only dated counts and discards names at collection (R-0061). Would date the worms' reach on developer machines and CI, which the registry records cannot see. From LH041's Next.

Notes for the driver

  • The collector's first attempt crashed on a null field after downloading; it was fixed and re-run on the same bytes (record, Method).
  • Email addresses were withheld under the keeper's new rule; the vendor pages in 147e953 held addresses and were redacted in 1cccfb2 (history keeps the earlier bytes).
  • Model spend of this subagent: price it with harbour/hb tokens --latest.
  • 0.3 (resolution of R-0061): the figure's wording changed (headline, subtitle, footnote, description; scripts/draw_figure.py), no data. StepSecurity's retained ChainDrop post prints only part of its package list; it says the full list is served by an authenticated enterprise endpoint, so amendment 2 compares only what a public page prints. The proposals.md lead below should say its brief keeps dated counts and discards account names when collecting (R-0061).

From studies/LH041/for-driver.md in the repository, last changed 9 November 2026.