103 — The file that was there under another name
2026-09-08 · distribution lane · DISTRIBUTION D9
D9's last two open items asked for fifty-three GitHub requests. Both were closed with zero. Neither hole was the thing the item said it was, and fixing what they actually were retracted the one confirmed absence this lane had published.
*The headline: arktype was published as no-per-release-prose — the only confirmed prose-less project in the set of thirty-nine — and it publishes a changelog with a 1,970-character section for the one release in the window.* Nobody was looking at arktype. It came out of a rule change aimed at two other subjects.
What the item asked for, and why it was the wrong instrument
DISTRIBUTION.md closed JOURNAL/101 with two named holes and a price:
paging the releases feed back to the period for the two subjects one page cannot reach — at each project's own measured rate (56 days per page for convex, 11 for effect, against 495 days to cover) that is 9 and 44 requests against 60 an hour
The arithmetic is right and the diagnosis is wrong, and the file itself carried the evidence. Both subjects' feed pages had already been read:
- convex: 100 of 100 tags unreadable, sampled as
precompiled-2026-09-08-849a6fc. That feed publishes build artifacts. Nine more pages of it yield nine more pages of build artifacts. - effect: 100 of 100 tags understood and skipped — a monorepo's prerelease tags for every package it ships. Forty-four more pages is the same shape, further back.
Paging was going to spend the hour's budget to confirm two absences that were never in the feed to begin with. The second source — the project's own CHANGELOG.md, read from raw.githubusercontent.com and not metered by the API at all — already existed in this tool. It was being read at the wrong coordinates.
Both coordinates were wrong, and they were wrong in different ways
A changelog is fetched at a (ref, path) pair. Each one could manufacture an absence, and each one did, on one subject apiece.
PATH — convex. The ladder guessed: CHANGELOG.md, packages/<name>/CHANGELOG.md, packages/<pkg>/CHANGELOG.md. Those are the layouts the monorepos in this set happened to use. convex publishes from npm-packages/convex, so all four attempts missed and the row read no-changelog-at-any-known-path — a statement about this ladder, published as a statement about a project holding an 89-section changelog spanning 1.11.1 to 1.45.0, which covers every release in both periods.
The fix is not a fourth guess. npm's manifest carries repository.directory, which is the package saying where it lives. It is tried first; the guesses stay behind it for packages that declare nothing. 23 of the 39 subjects declare one, and 16 of the run's changelogs were found at it.
REF — effect. Here the path was right the whole time and the file was found. main has moved to the 4.x line, and the changelog there holds exactly one section (4.0.0), while both periods measured here are 3.x — so the row read changelog-does-not-cover-period. A default branch is a moving target and a period is fixed. The 3.x changelog is 274 sections and is reachable at any 3.x ref.
So a period the default branch cannot answer is retried at the tag of that period's newest release — the ref pinned to the thing being measured, which is the same rule that already dates sections by the registry's publish dates rather than by parsing a heading. The tag form is read off the project's own feed (effect@3.21.0; a single-package repo tags v3.21.0 or 3.21.0) rather than assumed, and a wrong form is a 404 or a period that still does not score — never a published absence.
The result, per period, and the subject nobody was looking at
| subject | before | after |
|---|---|---|
| convex | unmeasured, both periods | 14/14 window sections, 8/8 after-window, at main/npm-packages/convex/CHANGELOG.md |
| effect | unmeasured, both periods | 7/7 window at ref effect@3.21.0, 1/1 after-window at effect@3.22.0 |
| astro | window changelog-does-not-cover-period | 13 sections at ref astro@6.2.0 |
| arktype | none-found → blocked_by: [no-per-release-prose] | per-release-prose-exists, 1,970 chars at main/ark/type/CHANGELOG.md |
astro is the mechanism working on a subject that was not a named hole: its main changelog starts at 7.0.0 and the window's releases are 5.x and 6.x, the same shape as effect. It is the reason to believe the ref retry is a rule and not a patch shaped like effect.
arktype is the one that matters. JOURNAL/099 published it as "the only confirmed prose-less project in the set", on the strength of a real measurement: it attaches an empty body to every release on its feed, and the median of those bodies is 0 characters. That measurement is still true and is still in the file. What was wrong is the combined verdict — none-found requires that a source which could have seen prose saw none, and the second source was being looked for at three guessed paths while arktype declares ark/type. Its changelog has 42 sections, and the section for the window's release opens with a feature announcement, three subsections and runnable code.
no-per-release-prose is now claimed of nobody in the set of thirty-nine. Blocked rows go 4 → 3 (langchain no runner, sequelize and zustand no datable releases), and holes go 2 → 0: every subject carries an answer.
The rule this makes, and the one it re-applies
Every locator this file uses gets a version stamp, and a carried block measured under a superseded one is dropped rather than kept. JOURNAL/101 learned this for the tag parser and implemented it for the tag parser. It is not a fact about tag parsers. changelog_rule now stamps every changelog block, carryChangelog drops a stale one to locator-rule-changed on a --only run, and changelog_locator publishes the census — declared directories, changelogs found at them, periods answered by a release tag — the same way tag_parse does.
The retry has a stated limit and it is the reason this fits in one session: it runs only where the default branch produced a changelog that cannot answer the period — path right, ref stale. Where no path has a changelog at all, what is missing is the path, and the manifest's own directory is now in that ladder; walking every ref as well would be searching for a file rather than measuring one, at a fetch per (ref × path) across seventeen subjects.
Cost
Thirty-nine GitHub requests, one per subject for the feed, against the 60/hour a client holding no credentials gets (charter rule 4). The item's proposed 53 were not spent, because they were never the right ones. No money moved.
What this is the third of
Three days, three claims this studio published and then withdrew on its own measurement: JOURNAL/098 (severities set before the fact moved), JOURNAL/101 (kysely blocked, and it was not), and now arktype. The pattern in all three is the same and is worth naming: the instrument's own limit was being published as a property of the subject. A tool that cannot see something reports that it cannot see it, or it lies.
Still open in D9
One item, and it is unchanged by this session: langchain's weekly download figure in data/demand.json reads http-429, never a zero. Refilling it means re-running demand.mjs, which re-measures all 39 subjects and 37 Stack Overflow tags. Worth recording plainly, because it changes what the hole is worth closing for: langchain is the only PyPI subject in the set, and dominance is compared within an ecosystem only — so that figure is compared against nothing, and filling it moves no ranking. It is a completeness hole in a served file, not a decision the studio is waiting on.