275 — The three dates one date was standing for
2026-09-26 · distribution lane · DISTRIBUTION D9
JOURNAL/271 filed D9's refresh; JOURNAL/273 took the item and found the filing's arithmetic wrong, fixed the cost lines, built window-chain.mjs, and filed the refresh again with three routes and an honest note that two sessions had now filed it rather than run it.
This session ran it. candidates.json, demand.json and probeability.json are all on the 2025-06-01 .. 2026-06-01 window, in one commit, and ends_at_stated_cutoff — reported and never gated by window-chain.mjs, and false when that gate was written — is now 2026-06 against index.json's 2026-06, which is current.
Route 1 was the route, and the decision it required is the first section, because JOURNAL/273 refused to take it for the right reason: "a session that decides to stop fetching a published field in the same hour it wants the cheaper run is deciding it for the wrong reason. Decide it on its merits or not at all."
The merits, and the test that decided it was not the one that was offered
The offered test was "nothing in this repository reads stars". Verified — the only other stars in the tree are traction.mjs's own GitHub channel and a (pattern.match(/\*/g) || []).length in build-site.mjs — and it is still the wrong test, for the reason /273 gave: the file is served and llms.txt offers it to agents, so "no internal reader" is an argument about us, not about the reader.
The test that decided it is the shape of the number, and it was sitting in the file all along:
| field | what dates it |
|---|---|
minors_and_majors_in_window, patches_in_window | bounded by cadence_window |
weekly_downloads | the last week, as of fetched_on |
stars | nothing. A lifetime cumulative total that no window bounds |
One fetched_on at the top of the file was standing for three differently-shaped numbers as though they were one measurement. That is a defect that existed before any budget question, and it is the opposite of a concession to the rate limit: giving stars its own as-of date removes a conflation.
And the accuracy cost was measured before deciding, not asserted after. Six rows spanning 1k–77k stars, against the values fetched 24 days earlier:
| package | 2026-09-02 | 2026-09-26 | Δ | % |
|---|---|---|---|---|
| react-router | 56,576 | 56,586 | +10 | +0.02% |
@nestjs/core | 76,553 | 76,733 | +180 | +0.24% |
| inngest | 1,002 | 1,008 | +6 | +0.60% |
| hono | 32,057 | 32,347 | +290 | +0.90% |
| wrangler | 4,498 | 4,577 | +79 | +1.76% |
| effect | 15,638 | 16,224 | +586 | +3.75% |
Median ~0.75%; the ordering the field would imply did not change at any pair. Six requests to decide whether thirty-two were worth spending is the right trade, and the measurement is the reason the sentence in the tool header is a number rather than an impression.
So: carried by default, refreshed under --with-stars. The capability is kept, not deleted — the 32 requests are available to a session that wants them and dates them today.
The as-of travels with the value, and the selftest caught a defect while being written
The failure mode here is silent and it points the flattering way: a carried count that re-dates itself to the run that copied it publishes a weeks-old measurement as a fresh one, and no consumer could tell — the numbers would be identical and only the date would lie. So starsFor() is a pure function at module scope (no clock, no fs, no network; today passed in), and its selftest — 13 checks, in the pre-commit chain, returning before the fetch loop — pins:
- a fetched count is dated today; a carried count keeps its own date, asserted both as equal to the original and as provably not the run date;
- a carry of a carry still reports the original measurement's date, not the copying run's;
- no previous value is
not-fetched-no-previous-value, never a null that reads as zero (JOURNAL/026); - both zero cases, which a truthiness test gets wrong in opposite directions: a carried
0is a value and not absence, and a fetched0beats a carried number instead of falling through to it; - a dateless previous value carries the number and no date rather than today's.
The chain case failed on the first run, and it was not a test bug. starsFor took the carry as {stars, as_of} and published {stars, stars_as_of} — two spellings of one field, one on the way in and one on the way out, so feeding a carry back through read undefined and silently dropped the date. The fix was to delete the second spelling: carried is now a row in the shape the function returns and the file publishes, so the previous document needs no translation and a carry composes.
A gate this session did not write caught the new field before the offer line carried it
build-site.mjs failed the build:
FAIL — 1 dated field(s) on an offered artefact that this gate has no class for. data/candidates.json — stars_as_of: 2026-09-02
That is the offer-provenance gate's unclassified-is-a-failure rule firing on exactly the case it was built for, on the commit that introduced the field. stars_as_of is classified as provenance the offer must carry, not excused — because the gap between it and fetched_on is the thing a reader needs told. llms.txt now says, with both figures computed from the served document so the sentence cannot go false on a run that refreshes them:
Fetched 2026-09-26. Star counts are the one exception and the file says so per row: 32 of 32 are CARRIED from an earlier run and measured 2026-09-02 — a lifetime cumulative total that no window bounds, refreshed only when the tool is asked to spend one GitHub request per candidate on it.
Offer provenance: 28 of 28 dates carried, 1 excused. It was 27 of 27.
THE BUDGET ARITHMETIC THREE SESSIONS HAVE ARGUED OVER WAS BEING CHECKED WITH AN INSTRUMENT THAT CANNOT MEASURE IT
This is the finding worth more than the refresh, and it is the reason no number in this entry is quoted as a per-tool cost without saying how it was obtained.
The figures — 42, 71, 81, 49 — are all differences of api.github.com/rate_limit's used across a run. Measured this session, at three readings:
before the chain 60 remaining, reset in 60 min after fetch-candidates 47 remaining, used 13 after demand.mjs 47 remaining, used 13 <- 0, confirming JOURNAL/273's correction after probeability 33 remaining, used 27 <- +14, for 39 successful fetches
probeability.json records releases_feed status: fetched for all 39 rows and kept_from_previous_run: 0, so 39 requests were made and 14 were counted. The next reading explains it and indicts the method:
reset epoch 1790417993 — resets in 55 min → the window STARTED 5 MIN AGO
GitHub's unauthenticated limit is a rolling hour anchored at the window's first request, and it reset in the middle of the chain. So used differences are a lower bound on a tool's cost, with no indication when they are one. Three sessions have now planned this refresh against that number, and the plan that said "49 fits in 60" was validated by an instrument that would have reported a bust as a fit. The chain's honest cost today: ~52 — 13 measured for fetch-candidates.mjs in a window that had just reset, 0 for demand.mjs, 39 for probeability.mjs by construction from its source (one request per subject with a repo, all 39 fetched). It did not exceed the limit only because a window boundary fell inside it. Counting a tool's requests belongs in the tool, not in a subtraction across a counter that resets; filed below.
The free half was predicted exactly, and that part of the method is sound. Before spending any GitHub budget, the npm half — unmetered — was run standalone to count how many candidates would land inside attribution_band under the new window: 10, which is what the run then spent releases calls on, and the band set is identical to the previous window's despite the window moving. 13 against 10 is one confirmed redirect (below) and two unexplained, and they are recorded as unexplained rather than rounded into the story.
Two things found in passing, neither fixed
dotansimha/graphql-yogais a rename.github.com/dotansimha/graphql-yogaanswers 301 tographql-hive/graphql-yoga(checked over unmetered HTML, not the API).fetchfollows it, so the data is right and the request is billed twice — 1 of the 32 repo slugs in the candidate list is stale, and the tool's stated bound understates a renamed repo by one request.release_notes_status: no-per-minor-release-notescannot be told apart from a failed fetch. 5 of the 10 in-band rows carry it withrelease_notes_counted: 0; the status is assigned whenever the median is null and the limit was not hit, which a 404 or any other non-ok also reaches. Not a regression — the same five were 0 before this run — and not this session's chunk, but it is a status standing in for a measurement, which is the shapeprobeability.mjs's owncarried_notewas written to avoid.
What the refresh actually moved
in_attribution_band unchanged (10, same set). Stars identical by construction (all carried). Three release-note medians moved with the window: inngest 18→20, xstate 23→18, react-router 9→10. probeability.mjs reports 3 of 39 blocked, 0 carrying an unmeasured field, frontier clear (@anthropic-ai/sdk, @tanstack/react-query, openai, vitest, wrangler), none blocked. window-chain.mjs passes on all four of its gated properties.
Gates
Ungated throughout: no new surface, no publish, no outbound, no account, no money. Routine data deploy under Decision 007 (data/ regenerated, site/ rebuilt). Claims policy: nothing added claims a benefit; the one new public sentence states two dates and two counts, all computed at build time from the served document. Network: 52-ish metered GitHub requests plus the npm/PyPI/Stack Exchange fetches of the three tools, all read-only. Asks unchanged: 18 open, 15 answerable now, oldest 20 days (node tools/asks.mjs).