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 LH013

LH013 amendments

Amendment 4, 2 November 2026, before any count of W1 or W2 was read

Made by the research agent that ran the study (Claude Code, Opus 5.5, dispatched by the driving session of run 2026-11-02T1524Z). Written after the eligibility check, the days-held listing, the PyPI metadata read and the two fixed documentation reads, and before the W0 baseline check and any count of W1 or W2. It settles how the brief's fixed measures are computed where the brief leaves the mechanics open. No question, week, reference release, measure, field, threshold or convention changes.

  • Eligibility, read again. LH012's coverage query, run at 15:30 UTC on 2 November 2026, found 1 November 2026 as the last day held in all five per-day tables for all 37 projects (185 of 185), so the condition is met. The preflight of 22 October (03:59 UTC) had found 21 October, so it was met by then. When it was first met the source cannot say: a read of system.parts for the parts holding 12 October returned no rows, since none of these tables is partitioned by date (their partition key is empty, studies/LH012/data/clickpy_schema.csv), so parts carry no dates. The days-held listing found all 14 days of W1 and W2 for all 37 projects (518 of 518).
  • Admission is constant within each week. From PyPI's metadata read at 15:30 UTC, no version at or above R0 (nor at or above R1 or R2 for the secondary) uploaded during either week changes whether any of Python 2.7 and 3.4 to 3.15 is admitted on any day of it (data/frame/python_admission.csv, column changes_within_week, all False). So P is computed from weekly sums by version and Python minor, with admission by each week's end, which equals admission on each of its days. No yanking or Requires-Python of a version uploaded before LH012's read changed (data/frame/metadata_changes.csv is empty).
  • Classes. At R0, a version PyPI lists is older when it parses and is below R0 (pre-releases below R0 included, as in LH012), at or newer when it is a final release at or above R0, and other when it is a pre- or dev-release above R0 or does not parse; a version ClickPy holds that PyPI does not list is other (measure 1). The same rule at R1 and R2 gives the secondary (data/frame/classes.csv). R1 differs from R0 for 9 projects and R2 for 11.
  • Gap rule. LH011's rule needs the 37 projects' daily totals for three days either side of each day, so daily totals from 25 September to 14 October 2026 are read once (pypi_downloads_per_day). The days 12 to 14 October enter only the gap rule, and 25 to 27 September are W0 days. A gap day is left out of every table read for that project and week.
  • Weekly sums. Per project, one query of pypi_downloads_per_day_by_version for both weeks, grouped by week and version, and one of pypi_downloads_per_day_by_version_by_python, grouped by week, version and Python minor, split by week and by groups of Python minors when a result would pass 10,000 rows.
  • Cells. Per project and week, one query of pypi.pypi groups downloads by class and the six fields, and computes server side the totals by class and CI flag (amendment 3, with ClickPy's unknown kept apart), and, for the six fields, for the five (C5) and for each over older downloads only, the number of cells, the largest cell's values and the sizes of the 1,001 largest cells in descending order. C is the largest size over the total; the number of cells carrying half is counted offline from the sizes, from the largest down, until their sum reaches half of the downloads, and is "more than 1,000" when the 1,000 largest do not reach half. An empty field is a value like any other. If the pass's total differs from the per-version table's weekly total by more than 2 per cent, that project's C and C5 for the week are described only, as the brief does for P.
  • The baseline check compares, per project, the sum of W0's daily totals read now from pypi_downloads_per_day_by_version with LH012's retained total (studies/LH012/data/analysis/week.csv, total, and the daily sums of studies/LH012/data/week/versions/).
  • Version profile and the tests. Measure 4 is computed with the code of studies/LH012/review/r0018_walkshare.py, unchanged in its definitions, over each week's by-Python sums, with admission and edges at R0 by each week's end and older downloads from the by-Python table as its denominator, as that script used python.csv's older_W2. The boto3 tests are computed as LH012's scripts/post_hoc.py (the share of all of boto3's by-Python downloads reporting 3.9; boto3's and botocore's fetches on 3.9 and over all Pythons, from the by-Python table) and scripts/driver_checks.py (boto3's 3.9 downloads below, at and above 1.42.97); each script is first rerun on W0's retained files to confirm it gives LH012's figures. "Holds" counts, across projects, only projects whose outcome is known: for O and P, W0 confirmed by the baseline check and the project known in both weeks.
  • Documentation. The fixed read of the package index's statement of what its download table counts was made at 15:31 UTC (https://docs.pypi.org/api/bigquery/): it says the table is populated through linehaul by streaming PyPI's download logs, and says nothing of requests for PEP 658 metadata files. linehaul's log parser (https://raw.githubusercontent.com/pypi/linehaul-cloud-function/main/linehaul/events/parser.py, read at 15:31 UTC) parses lines the content network sends as "download" or "simple" events and takes the file name from the URL; which requests the network logs as downloads is set outside it. Whether a metadata-file request is counted stays unknown. Both bodies are kept in data/docs/.

Amendment 3, 22 October 2026, before any count of W1 or W2 was read

The programme's 30 September checkpoint selected an additional descriptive reading from LH017: for each of the same 37 projects in each fixed week, report the proportion of older-version downloads carrying ci=true and the proportion of at-or-newer downloads carrying ci=true, at fixed R0, plus their difference. These are reported client flags, not an independently identified build population. Exclude versions that LH012 calls "other" from this paired split, show their counts separately, and preserve unknown when a classification or field is absent. Compute these within the already planned per-project and per-day pypi.pypi pass for C and C5; do not spend another whole-table pass. Summarise the paired differences across projects descriptively, with no new "holds" threshold or causal inference. This is 74 project-week pairs and one across-project description, added before either week's counts were read.

The eligibility preflight on 22 October returned dates only. All five checked per-day tables held through 21 October for all 37 projects, and every project had a row on all 14 W1/W2 days in pypi_downloads_per_day. Its six anonymous queries, exact SQL, raw CSV bodies, headers, hashes and UTC times are retained in data/preflight-2026-10-22/. No W1 or W2 download count has been requested. The original brief's windows, definitions, tests and ceiling remain fixed.

Amendment 1, 29 September 2026, before any count of W1 or W2 was read

Made by the driving session of the afternoon of 29 September 2026, from a finding of LH014's research agent while it wrote LH014's brief (studies/LH014/brief.md, "Resource ceiling"). The demo user's read_overflow_mode is break (studies/LH014/data/clickpy_settings.csv, read 12:28 UTC), which by ClickHouse's documentation (https://clickhouse.com/docs/operations/settings/query-complexity, read by that agent at 12:30 UTC) stops a query at 1,000,000,000 rows or 50 GB read and returns the partial result "as if the source data ran out", without an error. LH013's passes over pypi.pypi read about 9.4 billion rows a week and are split by project and by day, so a split that still passed the limit would return a count cut short.

  • Every LH013 query of the pypi database sets read_overflow_mode = 'throw', which the demo user may do (checked by LH014's agent at 12:30 UTC, studies/LH014/data/clickpy_overflow_setting.csv).
  • A query that reports reading either limit counts as failed and is split again.
  • No measure, week, threshold, field or convention changes, and the brief's snapshot hash on issue #15 still holds for brief.md.

LH011's and LH012's logged queries were checked the same afternoon: none read more than 233,086,976 rows or came near 50 GB (studies/LH011/data/read_log.csv; studies/LH012/data/read_log.csv and read_log_phase2.csv), so none of their counts was cut short by this limit.

Amendment 2, 29 September 2026, late evening, before any count of W1 or W2 was read

Made by the driving session of the correction round of 29 September 2026, after the reader-and-inference review of that round (notes/R-0025.md) raised two points. No count of either week has been read, and no measure, week, threshold, field or convention of the brief changes; the brief's snapshot hash on issue #15 still holds for brief.md.

  • The pip date. The brief's Sources say that "since 22.3 (15 October 2022) it reads PEP 658 metadata files instead of downloading each candidate, where the index offers them". PyPI began to offer those files only in 2023, and in its JSON index under the key core-metadata (PEP 714, accepted 27 June 2023), which pip reads from 23.2 (15 July 2023); pip 23.1.2 reads only dist-info-metadata from a JSON index, which it asks for first. So from PyPI, pips older than 23.2 fetch each candidate in full (studies/LH012/review/v04_pip_metadata_read.txt, read 21:49 to 21:50 UTC). Where this study's Limits or its record speak of which pips can make a walk-shaped profile, they use 23.2.
  • A version that walks skip, described. Beside the walk test, the study describes, and does not test, boto3's Python 3.9 downloads of 1.42.87 as a fraction of the mean of its neighbours 1.42.86 and 1.42.88, in each week. In W0 it was 0.55 (studies/LH012/review/r0025_walk_dip.txt, 2), with 0.99 and 0.91 on Python 3.10 and 3.11, and the three versions' metadata are alike. The reading, made after W0's counts by the review and not tested, is that a resolver walking from environments that already hold 1.42.87 installed takes that installed copy without fetching it; on that reading the dip stays at 1.42.87 until those environments are rebuilt. It is one more reading, beside the brief's comparisons, not among them.

From studies/LH013/amendments.md in the repository, last changed 2 November 2026.