diff --git a/scripts/pm/check-half-states.mjs b/scripts/pm/check-half-states.mjs index 88c9800a47..109b59158c 100644 --- a/scripts/pm/check-half-states.mjs +++ b/scripts/pm/check-half-states.mjs @@ -7169,6 +7169,18 @@ export const SWEEP_COUNT_KEYS = [ 'mergedPages', 'mergedWindowTruncated', 'mergedRateObserved', + // The remaining windows, converted the same way (#13606). Each carries the + // same pair for the same reason: what the pass COST, and whether it reached + // its boundary or ran out of quota. `openListingsTruncated` is a LIST rather + // than a flag because `listIssues` runs once per label and a reader needs to + // know WHICH inventory is short — a silently capped label page is one whole + // state's population missing from the sweep. + 'closedPages', + 'closedWindowTruncated', + 'commitPages', + 'commitWindowTruncated', + 'openListingPages', + 'openListingsTruncated', ]; /** @@ -7286,13 +7298,52 @@ export function summaryLine(counts, findingCount) { 'the merge rate has outgrown the ceiling and it needs raising' : ' (horizon reached: a delivery inside the window was seen, not merely the first N rows)' }. ` + - `H22 read ${counts.closed ?? 0} recently-closed issue(s) for \`pm:*\` state residue (bounded window; ` + - `older closed carriers are outside it by design` + + `H22 read ${counts.closed ?? 0} recently-closed issue(s) for \`pm:*\` state residue (older closed ` + + `carriers are outside the window by design` + `${counts.closedFloor ? `, and only cards closed on/after ${counts.closedFloor} are judged — ` + 'earlier closures predate the strip-on-close convention and are NOT a reading about them' : ''}). ` + - `H23 read ${commits} squash commit message(s) from the default branch's recent window, carrying ` + - `${commitBindings} closing-keyword binding(s) across ${commitBindingMessages} message(s) ` + - `(bounded window; a message that landed before it is invisible by design). ` + + // H22's window disclosure (#13606). The divisor is named here as well as in + // the docblock, because the summary is the only half a report reader sees + // and "bounded window" said nothing about which quantity bounds it. + `${describeWindowBound({ + name: "H22's closed-card window", + horizon: CLOSED_ISSUE_WINDOW_DAYS, + pages: counts.closedPages ?? 0, + ceiling: CLOSED_ISSUE_WINDOW_PAGE_CEILING, + truncated: counts.closedWindowTruncated, + drops: 'a card that closed earlier than what those pages reached', + })} It is a CLOSURE horizon: rows are selected on \`closed_at\`, while paging is bounded by ` + + `\`updated_at\` — the stream is consumed by closed-issue ACTIVITY (~${MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY}/day, ` + + `measured ${MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY_AT}), not by closures (~11/day), which is why the ` + + 'page cap it replaced covered a ragged 2.1 days of update-recency rather than the closure window it read as. ' + + `H23 read ${commits} squash commit message(s) from the default branch, carrying ` + + `${commitBindings} closing-keyword binding(s) across ${commitBindingMessages} message(s). ` + + `${describeWindowBound({ + name: "H23's commit window", + horizon: COMMIT_WINDOW_DAYS, + pages: counts.commitPages ?? 0, + ceiling: COMMIT_WINDOW_PAGE_CEILING, + truncated: counts.commitWindowTruncated, + drops: 'a message that landed earlier than what those pages reached', + })} ` + + // The three OPEN listings (#13606). Not a time horizon — see the block above + // `listIssues` for the measurement that rules that shape out — so what is + // disclosed is completeness, and the failure it must announce is a + // ceiling-bound inventory reading as the whole board. + `${describeWindowBound({ + name: 'The open listings (H1–H18 inventory, H13 unscoped pass, open PRs)', + kind: 'exhaustive', + pages: counts.openListingPages ?? 0, + ceiling: OPEN_LISTING_PAGE_CEILING, + truncated: (counts.openListingsTruncated ?? []).length > 0, + drops: 'the OLDEST open row of each capped listing — the population these rows most exist for', + })}` + + `${ + (counts.openListingsTruncated ?? []).length > 0 + ? ` ⛔ Ceiling-bound listing(s): ${(counts.openListingsTruncated ?? []).join(', ')} — those ` + + 'inventories are PREFIXES, not populations, so a quiet finding count over them is a short read.' + : '' + } ` + `Hold comments read on ${held} of ${holdCandidates} H17 candidate(s). ` + `\`Blocked-by:\` comment fallback read on ${fbProbed} of ${fbCandidates} candidate(s)` + `${fbProbed < fbCandidates ? " — H14's stale direction is SUSPENDED for this sweep (the index is known incomplete)" : ''}. ` + @@ -8343,15 +8394,94 @@ async function rest(path) { return res.json(); } -async function listIssues(label) { +// --------------------------------------------------------------------------- +// The three OPEN listings (#13606) — and the one window this card asked to +// convert to a time horizon that MUST NOT BE ONE. +// +// ## What was actually wrong with the bare `page <= 10` +// +// The filing card surveyed three defects here: reach moves with tempo, no +// coverage stated, no truncation announced. Measured 2026-08-31T03:34Z, only +// the third is real — and it is real enough to fix: +// +// listIssues(