You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pm(half-states): name the POPULATION each H22 docblock number was measured on (#17793)
Fixes#17626
H22 pages its closed-card window through `closedWindowPagePath` — `GET
/repos/{repo}/issues?state=closed&sort=updated&direction=desc&per_page=100&page=N`.
Two callers issue the byte-identical request and get different
POPULATIONS: the scheduled patrol runner's pages come back
**card-only**, a proxied agent container's come back **49.6% pull
requests**. Four prose sites in `scripts/pm/check-half-states.mjs`
quoted the container's stream while describing the patrol's, so the
measurement recipe they carry — followed correctly — yields the wrong
number. This is prose only: **no constant moves**
(`MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY` stays 139.4,
`CLOSED_ISSUE_WINDOW_PAGE_CEILING` stays 40), no H-row, no self-test
change.
## The boundary this card asked to survive the fix
The population difference itself is **MEASURED**, through the sweep's
own numbers. **The runner's `permissions:` block as the MECHANISM is NOT
claimed** — the runner's raw response was never read. Every new sentence
below is written that way, and the ⚠️ Cost note says it in those words.
## The four sites, before and after
**1. The ⚠️ Cost note under `CLOSED_ISSUE_WINDOW_DAYS`**
- before: «46% of the rows this stream returns are PULL REQUESTS,
filtered out after paging. The horizon is therefore reached in roughly
twice the pages a card-only stream would need.»
- after: the 46% is named as a **container** reading (49.6%, read
2026-09-11T04:22:36Z, 12 pages / 1,200 rows), the patrol's stream is
named card-only, and the runner side is quoted from the sweep's own
numbers — the 2026-09-11T01:55:32Z run (34552285557, `2f8ad091`) reports
5 pages, 428 in-window closures, reach 2026-09-07; 428 in-window
closures cannot come out of 5 PR-inclusive pages, since only ~250 of
those 500 rows would be cards. The 2026-09-09 run is the same shape at 6
pages.
**2. The same docblock's present-tense divisor sentence**
- before: «re-pin (#16419: the divisor below now reads 415.1)» — present
tense against a divisor that now reads 139.4.
- after: restated as history — #16419 re-pinned 415.1 on 2026-09-06 from
the container stream; #17254 re-pinned on 2026-09-11 from the card-only
slice, and the divisor below now reads 139.4. The `~13 pages` this note
derives is also marked as a 2026-09-06 container reading, and explicitly
**not** comparable to today's 5 pages on population alone — the two
readings are five days AND one population apart, with the decomposition
left where PR #17627 put it, in `MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY`.
**3. `CLOSED_ISSUE_WINDOW_PAGE_CEILING`'s derivation**
- before: «4,000 rows reached 12.8 days on the read above (~312/day
averaged over that depth), against a 3-day horizon: ~4.3x headroom.»
- after: the derivation stands, with a ⚠️ POPULATION note beneath it —
that read was container-taken, so only ~2,000 of its 4,000 rows were
cards. 40 pages return 4,000 rows either way, but on the runner all
4,000 are cards, so the same ceiling reaches **about twice** as far
back: ~25 days rather than 12.8, ~8x headroom rather than ~4.3x. Written
as a **note, not a change**: the direction is more headroom and not
less, 40 is unchanged, and re-deriving it properly needs a card-only
read at depth that nobody has taken.
**4. `listRecentlyClosedIssues`'s `rateRows` comment**
- before: «the pin this rate is checked against was measured over the
RAW stream (400 rows / 0.964 days)» — a description of the 188.3 pin,
two re-pins ago.
- after: the pin's population as it now stands (500 rows / 3.586 days,
read 2026-09-11), plus why the distinction lives at this line: on the
patrol runner the stream is card-only, so `rateRows` holds cards and the
observed rate is counted on the same population the pin was; the same
request from a container returns 49.6% pull requests and `rateRows`
would count those too — a rate on one population checked against a pin
on another. The `READ` vs `ADMITTED` argument (#4690 with the numbers
the right way up) is unchanged.
## The re-measure recipe the file now carries
Stated once, in the ⚠️ Cost note, and pointed at from sites 3 and 4:
> A container read is NOT the patrol's stream. Filter pull requests OUT
of every page BEFORE counting pages or rating rows, and quote the
card-only slice.
On the 2026-09-11T04:22:36Z container read that slice gives **5 pages /
426 rows / ~139.4 per day**, against **9 pages / 426 / ~256.2 per day**
on the whole stream. The slice reproduces the runner's own 5 pages; the
raw stream does not. That is the operative half — a seat following the
old note from a container reproduced #17254's false `RATE PREMISE
DRIFTED` alarm every time.
## Verification
All of it taken on the final commit `034c09ace`. Gate families derived
with `node scripts/pm/dispatch-gates.mjs --commands` (no paths passed —
it takes its own change set from the merge base), each command run with
its exit code captured **before any pipe**, then reconciled:
> `✓ dispatch-gates --ran: 40 derived famil(ies) accounted for — 40 run,
0 NOT-MEASURED (a DERIVED zero — all 40 recorded an exit code and none
of them is 3).`
Every one of the 40 exits 0, including `pnpm check:pm-dispatch-gates`
(detached — it runs past the foreground cap — and waited on with `tail
--pid`). Named readings:
- `pnpm check:pm-half-states` — self-test **3656 cases pass** on the
base file (`8fa3fe63d`) and **3656 cases pass** after; the count is
unchanged because no pin moved and no self-test assertion names any of
the rewritten sentences (grepped `46% of the rows`, `415.1`, `0.964`,
`312/day` across the tree — the only hits outside this file's own prose
are two historical mentions this PR does not touch).
- `pnpm check:nul-bytes` — `check-nul-bytes: OK (scanned 8451 text
file(s) ... no raw ASCII control bytes)`; plus a self-scan of the edited
file, `grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'`, zero hits.
- `node scripts/check-comment-mask-corpus.mjs` — `6640 files, 0
disagree, 0 unparseable`.
- `node scripts/check-scripts-symbol-anchors.mjs` — `3186 anchors across
248 scripts resolve`.
- The remaining 36 derived commands exit 0.
Repository-wide scans (`pnpm lint` first among them) are CI's run, not
this PR's.
## Acceptance notes
- noted, not filed: `MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY`'s docblock
(landed by PR #17627, outside this card's declared surface) states the
runner's token scopes as part of its population paragraph. It does label
the reading «Measured, not inferred from the workflow file», so it is
not a mechanism claim, but it sits closer to one than the ⚠️ Cost note
now does. Successor: the next seat re-pinning that divisor.
- noted, not filed: the card names a second possible route — declaring
`pull-requests: read` on `half-state-patrol.yml` so the runner and a
container read the same stream. This PR takes the recipe route the
dispatch chose; the permission route is untouched and its cost (roughly
doubling H22's page bill) is unmeasured.
- `skip-changeset`: `scripts/pm/**` is not published — no package's
`files[]` ships this script.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01MCLBsUgfykL74aU716rzVK)_
---
_Generated by [Claude Code](https://claude.ai/code)_
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments