From 31c627823773afc38d2d534a84daed1eefdb6284 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 6 Sep 2026 19:02:08 +0000 Subject: [PATCH] tooling(pm): give H22's pinned closed-update divisor the staleness alarm H8 carries H22's page budget converts to a coverage-in-days by dividing by MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY, a hand measurement carrying its own date and nothing else. Re-measured on 2026-09-06 the board ran ~312 closed-issue updates/day over 40 pages and ~414 over the leading 12, against a pin of 188.3 -- a factor of 1.66 to 2.2 accumulated in six days, announced by no run. H8 has carried a mechanical alarm for exactly this shape since #13499. Apply it rather than copy it: the observed-rate reader becomes generic over the stamp it counts (observedMergeRatePerDay delegates to it, byte-identical), classifyRatePremise takes a premise descriptor so the band, the horizon and the three verdicts are shared by construction, and the closed pass reports the update rate it observed from the pages it already read. The census clause states the pinned rate, the observed one, the factor and the act, on every run and in every state. The pin is CHECKED, never overwritten -- H8's rule. The act it names is a hand re-measure and re-pin. Self-test: 2588 -> 2636 cases, exit 0. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox --- scripts/pm/check-half-states.mjs | 335 ++++++++++++++++++++++++++++--- 1 file changed, 305 insertions(+), 30 deletions(-) diff --git a/scripts/pm/check-half-states.mjs b/scripts/pm/check-half-states.mjs index 584efeb022..0671dc4f7a 100644 --- a/scripts/pm/check-half-states.mjs +++ b/scripts/pm/check-half-states.mjs @@ -9579,6 +9579,13 @@ export const SWEEP_COUNT_KEYS = [ // measurement nobody can act on, and this is the one number that separates // "everything closed since the 4th was judged" from "the pass was short". 'closedReachedAt', + // H22's DIVISOR reading (#16393) — the closed-issue update rate this pass + // observed, which the census clause checks the pinned divisor against. It + // rides here for `closedReachedAt`'s reason: a quantity gathered in the pager + // and dropped on the way to the summary is a measurement nobody can act on, + // and this is the one that says whether the window's stated coverage in days + // still describes the board. + 'closedRateObserved', 'commitPages', 'commitWindowTruncated', 'openListingPages', @@ -9759,6 +9766,13 @@ export function summaryLine(counts, findingCount) { `\`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. ' + + // H22's DIVISOR alarm (#16393). Stated here, inside the clause that already + // quotes the pin, and stated on EVERY run in every state — for + // `renderRatePremise`'s reason: a check visible only when it fires is + // indistinguishable from a check that was deleted, which is the shape of + // the defect this leg closes. Report-only: it names the re-measure, it + // never performs one. + `${h22RatePremiseClause(counts.closedRateObserved)} ` + `H23 read ${commits} squash commit message(s) from the default branch, carrying ` + `${commitBindings} closing-keyword binding(s) across ${commitBindingMessages} message(s). ` + `${describeWindowBound({ @@ -11750,6 +11764,10 @@ async function sweep(options = {}) { // ⛔ null, not a date: a sweep that throws before H22's pass reached // nowhere, and the clause must say so rather than render today. closedReachedAt: null, + // ⛔ null, not 0: a sweep that threw before H22's pass observed NO rate, and + // a zero would classify as a collapse of the board rather than as the + // absence of a reading (#16393). + closedRateObserved: null, commitPages: 0, commitWindowTruncated: false, openListingPages: 0, @@ -12152,29 +12170,80 @@ export const RATE_PREMISE_BAND = 2; export const RATE_PREMISE_STALE_DAYS = 30; /** - * The merge rate this sweep OBSERVED, derived from rows it already holds. + * The premise descriptors — what a pinned rate is ABOUT, carried as data so the + * classifier below can be SHARED by every pinned rate in this file (#16393). + * + * ## Why a descriptor rather than a second classifier + * + * H8's rate premise and H22's are the same object in two costumes: a + * hand-measured rate, the date it was measured on, a band, a re-measure + * horizon, and a rank of docblocks that state their own coverage by dividing by + * it. The only things that differ are the WORDS — which constant, which stamp, + * which quantity is counted per day, and what a stale divisor misdescribes. + * Copying the classifier to change four strings is how the two premises would + * come to disagree in the one dimension that matters: a report where one + * premise says EXPIRED and the other quietly says nothing is worse than either + * wording alone. That is the argument `describeWindowBound` already settled for + * the window disclosures, settled the same way. + * + * ⛔ `pinned` / `pinnedAt` ride here as DEFAULTS only. Both stay accepted as + * top-level inputs to `classifyRatePremise`, because the self-test drives + * synthetic pins through it and a descriptor that owned them outright would + * make those cases unwritable. + * + * @typedef {{ constant: string, noun: string, plural: string, stamp: string, + * pinned: number, pinnedAt: string, consequence: string, expiredAct: string }} RatePremise + */ + +/** H8's premise: merges per day, the divisor behind every merged-window reach. */ +export const MERGE_RATE_PREMISE = { + constant: 'MEASURED_MERGES_PER_DAY', + noun: 'merge', + plural: 'merges', + stamp: 'merged_at', + pinned: MEASURED_MERGES_PER_DAY, + pinnedAt: MEASURED_MERGES_PER_DAY_AT, + consequence: + 'Every page-capped window below states its reach by dividing by that constant, so each of ' + + 'those docblocks is now misdescribing its own coverage by the same factor.', + expiredAct: + 'Re-measure and update the constant, its date, and the coverage numbers the page-capped ' + + 'windows quote. A rate premise that outlives its measurement is how `~18/day` came to ' + + 'justify a window covering a day and a half (#11118, #13499).', +}; + +/** + * The rate a sweep OBSERVED, derived from rows it already holds — ONE + * instrument for every pinned rate in this file (#13499 repair ②, #16393). * * This is repair ② of #13499 and the reason that card exists: the premise was a * number typed into a comment, so no reader and no run could ever disagree with - * it. Now every sweep re-derives the quantity from its own merged-PR window and - * compares. ⛔ The pinned constant is deliberately NOT overwritten from this — - * a self-updating premise is a premise nobody reviews — it is CHECKED against + * it. Now every sweep re-derives the quantity from its own window and compares. + * ⛔ The pinned constant is deliberately NOT overwritten from this — a + * self-updating premise is a premise nobody reviews — it is CHECKED against * it, and a mismatch is reported. * - * `null` when the rows cannot support a rate: fewer than two readable - * `merged_at` stamps, or a degenerate span. An unmeasurable rate must not read - * as agreement (#4690) — the classifier below reports it as unobserved. + * `field` is the stamp the rate is counted over, and it is the ONLY thing that + * differs between the premises this file carries: H8 counts `merged_at` on the + * merged PRs of its window, H22 counts `updated_at` on the rows its closed pass + * read. One function rather than two, because a copied instrument is how the + * two would come to disagree about what "per day" even means. * - * ⚠️ Measured over the window's OWN merge span rather than back from `now`, - * because the newest merge may be minutes old and dividing by a span that - * includes an empty tail would understate the rate. + * `null` when the rows cannot support a rate: fewer than two readable stamps, + * or a degenerate span. An unmeasurable rate must not read as agreement + * (#4690) — the classifier below reports it as unobserved. * - * @param {{ merged_at?: string }[]} mergedPrs - * @returns {number|null} merges per day + * ⚠️ Measured over the rows' OWN span rather than back from `now`, because the + * newest row may be minutes old and dividing by a span that includes an empty + * tail would understate the rate. + * + * @param {any[]} rows + * @param {string} field — the timestamp each row carries. + * @returns {number|null} rows per day */ -export function observedMergeRatePerDay(mergedPrs) { - const stamps = (mergedPrs ?? []) - .map((pr) => Date.parse(pr?.merged_at ?? '')) +export function observedRatePerDay(rows, field) { + const stamps = (rows ?? []) + .map((row) => Date.parse(row?.[field] ?? '')) .filter((n) => Number.isFinite(n)) .sort((a, b) => a - b); if (stamps.length < 2) return null; @@ -12183,24 +12252,44 @@ export function observedMergeRatePerDay(mergedPrs) { return stamps.length / days; } +/** + * H8's half of that instrument: merged PRs, counted over `merged_at`. Kept as a + * named function rather than inlined at the call site so H8's premise reads as + * a premise rather than as a field name passed in passing. + * + * @param {{ merged_at?: string }[]} mergedPrs + * @returns {number|null} merges per day + */ +export function observedMergeRatePerDay(mergedPrs) { + return observedRatePerDay(mergedPrs, 'merged_at'); +} + /** * Is the pinned rate premise still good? Pure, three outcomes, and the third is * the one #4690 insists on. * - * @param {{ observed: number|null, pinned?: number, pinnedAt?: string, nowMs?: number }} input + * `premise` selects WHICH pinned rate is being judged — H8's merges per day by + * default, H22's closed-issue updates per day when that descriptor is handed in + * (#16393). Every difference between the two lives in the descriptor, so the + * verdict logic, the band and the horizon are shared by construction rather + * than by two authors remembering to keep them equal. + * + * @param {{ observed: number|null, pinned?: number, pinnedAt?: string, + * nowMs?: number, premise?: RatePremise }} input * @returns {{ state: 'ok'|'drifted'|'expired'|'unobserved', message: string, * observed: number|null, pinned: number, ageDays: number|null, ratio: number|null }} */ export function classifyRatePremise(input = {}) { - const pinned = Number.isFinite(input.pinned) ? input.pinned : MEASURED_MERGES_PER_DAY; - const pinnedAt = input.pinnedAt ?? MEASURED_MERGES_PER_DAY_AT; + const subject = input.premise ?? MERGE_RATE_PREMISE; + const pinned = Number.isFinite(input.pinned) ? input.pinned : subject.pinned; + const pinnedAt = input.pinnedAt ?? subject.pinnedAt; const nowMs = Number.isFinite(input.nowMs) ? input.nowMs : Date.now(); const observed = Number.isFinite(input.observed) ? input.observed : null; const at = Date.parse(`${pinnedAt}T00:00:00Z`); const ageDays = Number.isFinite(at) ? (nowMs - at) / 86_400_000 : null; const ratio = observed !== null && pinned > 0 ? observed / pinned : null; const shared = - `pinned \`MEASURED_MERGES_PER_DAY\` = ${pinned}/day, measured ${pinnedAt}` + + `pinned \`${subject.constant}\` = ${pinned}/day, measured ${pinnedAt}` + (ageDays === null ? '' : ` (${ageDays.toFixed(0)}d ago)`); if (observed === null) { @@ -12211,9 +12300,10 @@ export function classifyRatePremise(input = {}) { ageDays, ratio, message: - `RATE PREMISE UNOBSERVED — this sweep could not derive a merge rate from its own window ` + - `(fewer than two readable \`merged_at\` stamps), so ${shared} was not checked against ` + - `anything. ⚠️ This is not agreement: it is the one reading that says nothing.`, + `RATE PREMISE UNOBSERVED — this sweep could not derive a ${subject.noun} rate from its ` + + `own window (fewer than two readable \`${subject.stamp}\` stamps), so ${shared} was not ` + + `checked against anything. ⚠️ This is not agreement: it is the one reading that says ` + + `nothing.`, }; } if (ageDays !== null && ageDays > RATE_PREMISE_STALE_DAYS) { @@ -12225,10 +12315,7 @@ export function classifyRatePremise(input = {}) { ratio, message: `RATE PREMISE EXPIRED — ${shared}, past the ${RATE_PREMISE_STALE_DAYS}-day re-measure ` + - `horizon; this sweep observed ~${observed.toFixed(1)}/day. Re-measure and update the ` + - `constant, its date, and the coverage numbers the page-capped windows quote. A rate ` + - `premise that outlives its measurement is how \`~18/day\` came to justify a window ` + - `covering a day and a half (#11118, #13499).`, + `horizon; this sweep observed ~${observed.toFixed(1)}/day. ${subject.expiredAct}`, }; } if (ratio !== null && (ratio > RATE_PREMISE_BAND || ratio < 1 / RATE_PREMISE_BAND)) { @@ -12239,10 +12326,9 @@ export function classifyRatePremise(input = {}) { ageDays, ratio, message: - `RATE PREMISE DRIFTED — this sweep observed ~${observed.toFixed(1)} merges/day against a ` + - `${shared}: a factor of ${ratio.toFixed(2)}, outside the ${RATE_PREMISE_BAND}x band. Every ` + - `page-capped window below states its reach by dividing by that constant, so each of those ` + - `docblocks is now misdescribing its own coverage by the same factor. Re-measure.`, + `RATE PREMISE DRIFTED — this sweep observed ~${observed.toFixed(1)} ${subject.plural}/day ` + + `against a ${shared}: a factor of ${ratio.toFixed(2)}, outside the ${RATE_PREMISE_BAND}x ` + + `band. ${subject.consequence} Re-measure.`, }; } return { @@ -12582,6 +12668,70 @@ export const MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY = 188.3; /** WHEN `MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY` was measured. */ export const MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY_AT = '2026-08-31'; +/** + * H22's premise, in the shape `classifyRatePremise` judges (#16393). + * + * ## The state this closes + * + * The divisor above was a hand measurement with a date on it and NOTHING + * watching it — the same artefact H8 carried until #13499, and it drifted the + * same way. Re-measured on 2026-09-06 the board ran ~312 closed-issue updates + * per day over 40 pages and ~414 over the leading 12, against a pin of 188.3 + * that nothing had contradicted since it was typed: a factor of 1.66 to 2.2, + * accumulated in six days, announced by no run. H22's window states its reach + * in DAYS by dividing by this constant, so a drift of that size misstates the + * window's own coverage by the same factor — silently, four times a day, in + * the very sentence a reader trusts for it. + * + * ⛔ The alarm REPORTS; it never writes. H8's rule — a pinned premise is + * CHECKED against a sweep, never overwritten by one — is what keeps this + * constant a measurement somebody reviewed rather than whatever the last run + * happened to see, and it is why the act named below is "re-measure and re-pin + * by hand" rather than an assignment. A self-updating divisor would make every + * window's stated coverage true by construction and worth nothing. + * + * @type {RatePremise} + */ +export const CLOSED_UPDATE_RATE_PREMISE = { + constant: 'MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY', + noun: 'closed-issue update', + plural: 'closed-issue updates', + stamp: 'updated_at', + pinned: MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY, + pinnedAt: MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY_AT, + consequence: + "H22's window states its reach in days by dividing by that constant, so the coverage this " + + 'very line quotes is misdescribed by the same factor. ⛔ A sweep never overwrites the pin: ' + + 'it is re-pinned by hand, from a fresh measurement.', + expiredAct: + 'Re-measure and re-pin the constant and its date by hand; ⛔ a sweep never overwrites the ' + + "pin. H22's stated reach in days is a division by it, so every run past the horizon quotes " + + 'a coverage nothing has checked.', +}; + +/** + * H22's rate-premise clause, as the summary line renders it (#16393). + * + * Rendered on EVERY run, in every state, for the reason `renderRatePremise` + * gives for H8's: a check that is only visible when it fires cannot be + * distinguished from a check that was removed — which is the shape of the + * defect this leg exists to close. It rides INSIDE H22's own window clause + * rather than as a line of its own, because the pinned divisor is already + * quoted there and a reader comparing the two numbers should not have to leave + * the sentence to find the second one. + * + * ⛔ Report-only, like every other reading this file prints: nothing here + * writes a constant, a label or a card. + * + * @param {number|null|undefined} observed — the rate this sweep measured. + * @param {{ nowMs?: number }} [options] + * @returns {string} one sentence, marked loud unless the premise holds. + */ +export function h22RatePremiseClause(observed, { nowMs } = {}) { + const premise = classifyRatePremise({ observed, premise: CLOSED_UPDATE_RATE_PREMISE, nowMs }); + return premise.state === 'ok' ? premise.message : `⚠️ ${premise.message}`; +} + /** The instant at which H22's window ends. */ export function closedWindowHorizonMs(nowMs = Date.now(), days = CLOSED_ISSUE_WINDOW_DAYS) { return nowMs - days * 86_400_000; @@ -12698,12 +12848,24 @@ async function listRecentlyClosedIssues( // (#16217). Tracked across pages rather than taken from the last one because // a final page of unreadable stamps must not erase a reach already proven. let reachedMs = null; + // Every row this pass READ, projected to the one stamp the observed update + // rate is counted over (#16393). ⛔ Deliberately the rows READ and not the + // rows ADMITTED: the pin this rate is checked against was measured over the + // RAW stream (400 rows / 2.125 days), while `out` holds only the in-window + // closures — a strictly smaller population over a strictly shorter span. Rate + // them against each other and the difference between two quantities reads as + // drift in one of them, which is the #4690 inversion with the numbers the + // right way up. Projected rather than retained whole because one field is all + // the instrument reads, and these pages are the largest thing this sweep + // holds. + const rateRows = []; let page = 1; for (; page <= CLOSED_ISSUE_WINDOW_PAGE_CEILING; page++) { const batch = await fetchPage(page); // Selection reads `closed_at`; paging (below) reads `updated_at`. They are // deliberately different fields — see `pageExhaustsWindow`. out.push(...batch.filter((i) => !i.pull_request && issueClosedWithinWindow(i, horizon))); + rateRows.push(...batch.map((row) => ({ updated_at: row?.updated_at }))); const oldest = oldestPageStamp(batch, 'updated_at'); if (oldest !== null && (reachedMs === null || oldest < reachedMs)) reachedMs = oldest; if (pageExhaustsWindow(batch, horizon, 'updated_at')) { @@ -12717,6 +12879,11 @@ async function listRecentlyClosedIssues( // and a board whose first page is unreadable both reached NOWHERE, and a // clause that dated them would be the #4690 inversion in a new costume. stats.closedReachedAt = reachedDate(reachedMs); + // The divisor's staleness alarm (#16393) — the rate this pass OBSERVED, from + // the pages it read anyway, so the reading costs no request. ⛔ `null` when + // the pages cannot support a rate, which the classifier reports as + // unobserved rather than as agreement with the pin. + stats.closedRateObserved = observedRatePerDay(rateRows, 'updated_at'); return out; } @@ -18241,6 +18408,114 @@ async function selfTest() { t('H22 pager: …and still discloses which bound ended it', saidBy('h22Window', win13606(emptyStats)).includes('boundary reached'), true); t('H22 pager: the reach rides the enumerated forwarding contract', SWEEP_COUNT_KEYS.includes('closedReachedAt'), true); + // ---- H22's DIVISOR STALENESS ALARM (#16393) ----------------------------- + // + // The pin above is a hand-measured rate carrying its own date and nothing + // else: no run could disagree with it, so it drifted 1.66-2.2x in six days + // and announced nothing. H8 has carried an alarm for exactly this shape since + // #13499, and this leg is that alarm APPLIED to H22's divisor — the same + // classifier, the same band, the same horizon, reached through a descriptor — + // rather than a second copy of it that would drift from H8's the way the + // hand-copied window disclosures did before `describeWindowBound`. + + // The instrument is SHARED, and that is pinned by driving H8's own reader and + // the generic one over the same rows and requiring one answer. A copy would + // pass every case below and still be a copy. + const rateRows16393 = [{ merged_at: ago13606(4) }, { merged_at: ago13606(2) }, { merged_at: ago13606(0) }]; + t('#16393 instrument: H8\'s reader delegates to the generic one, unchanged', observedMergeRatePerDay(rateRows16393), observedRatePerDay(rateRows16393, 'merged_at')); + t('#16393 instrument: …and the generic one counts whichever stamp it is handed', Math.round(observedRatePerDay([{ updated_at: ago13606(4) }, { updated_at: ago13606(2) }, { updated_at: ago13606(0) }], 'updated_at') * 100) / 100, 0.75); + t('#16393 instrument: a stamp the rows do not carry cannot make a rate', observedRatePerDay([{ updated_at: ago13606(1) }, { updated_at: ago13606(0) }], 'closed_at'), null); + t('#16393 instrument: one readable stamp cannot make a rate', observedRatePerDay([{ updated_at: ago13606(1) }], 'updated_at'), null); + t('#16393 instrument: a zero span cannot make a rate', observedRatePerDay([{ updated_at: ago13606(1) }, { updated_at: ago13606(1) }], 'updated_at'), null); + + // The classifier is shared too, and reaches H22 through its descriptor. Both + // directions: H22's premise names H22's constant and quantity, and H8's is + // untouched by the parameterisation. + const h22Premise = (observed, extra = {}) => + classifyRatePremise({ observed, premise: CLOSED_UPDATE_RATE_PREMISE, nowMs: NOW13606, ...extra }); + t('#16393 premise: H22\'s premise defaults to H22\'s pinned divisor', h22Premise(MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY).pinned, MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY); + t('#16393 premise: …and names that constant in the message', h22Premise(MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY).message.includes('`MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY`'), true); + t('#16393 premise: ⛔ …and never H8\'s', h22Premise(MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY).message.includes('`MEASURED_MERGES_PER_DAY`'), false); + t('#16393 premise: …and counts what H22 counts, not merges', h22Premise(MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY * 3).message.includes('closed-issue updates/day'), true); + t('#16393 premise: …reading the stamp H22 pages by', h22Premise(null).message.includes('`updated_at` stamps'), true); + t('#16393 premise: H8\'s premise still defaults to H8\'s constant', classifyRatePremise({ observed: MEASURED_MERGES_PER_DAY, nowMs: NOW13499 }).pinned, MEASURED_MERGES_PER_DAY); + t('#16393 premise: …and still says merges/day when it drifts', classifyRatePremise({ observed: MEASURED_MERGES_PER_DAY * 3, nowMs: NOW13499 }).message.includes('merges/day'), true); + t('#16393 premise: …and still reads `merged_at` when it observes nothing', classifyRatePremise({ observed: null, nowMs: NOW13499 }).message.includes('`merged_at` stamps'), true); + + // The three verdicts, on H22's premise. The band and the horizon are H8's, so + // what is pinned here is that H22 is judged BY them rather than beside them. + t('#16393 premise: a rate at the pin is in band', h22Premise(MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY).state, 'ok'); + t('#16393 premise: a doubling is outside it', h22Premise(MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY * 2.1).state, 'drifted'); + t('#16393 premise: …and a halving too', h22Premise(MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY / 2.1).state, 'drifted'); + t('#16393 premise: exactly at the band edge still holds', h22Premise(MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY * RATE_PREMISE_BAND).state, 'ok'); + t('#16393 premise: ⛔ an unobservable rate is NOT agreement', h22Premise(null).state, 'unobserved'); + // The calendar leg — it fires REGARDLESS of drift, and it is the half that + // would have caught `~18/day` early. + const stale16393 = { pinnedAt: '2026-06-01' }; + t('#16393 premise: a pin past the re-measure horizon EXPIRES even at 1x', h22Premise(MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY, stale16393).state, 'expired'); + t('#16393 premise: …and at any other rate as well', h22Premise(MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY * 1.2, stale16393).state, 'expired'); + t('#16393 premise: …saying so loudly', h22Premise(MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY, stale16393).message.includes('EXPIRED'), true); + t('#16393 premise: …and naming the act as a HAND re-pin', h22Premise(MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY, stale16393).message.includes('never overwrites the pin'), true); + + // ---- The alarm on a real stream, through the REAL pager. The rate is + // measured over the rows the pass READ, because that is the population the + // pin was measured over; measuring it over the rows ADMITTED would rate two + // different quantities against each other and report the difference as drift. + const ratePage16393 = (daysAgo) => Array.from({ length: 100 }, (_, i) => closed13606(i, daysAgo, daysAgo)); + const rateStream16393 = (step) => + closedStream(Array.from({ length: 20 }, (_, i) => ratePage16393(step * (i + 1)))); + + // 2x the pin: 0.25-day steps, so the horizon falls on page 13 — 1300 rows + // read across a 3.0-day span is ~433.3/day against a pin of 188.3. + const driftedStats16393 = {}; + const driftedRows16393 = await listRecentlyClosedIssues(driftedStats16393, NOW13606, rateStream16393(0.25)); + t('#16393 stream: the pass stops on the first page past the horizon', driftedStats16393.closedPages, 13); + t('#16393 stream: …and the rate is over the rows READ', Math.round(driftedStats16393.closedRateObserved * 100) / 100, 433.33); + t('#16393 stream: ⛔ …not over the rows ADMITTED, which is a different number', Math.round(observedRatePerDay(driftedRows16393, 'updated_at') * 100) / 100 === Math.round(driftedStats16393.closedRateObserved * 100) / 100, false); + t('#16393 stream: …a board running 2x the pin FIRES the alarm', h22Premise(driftedStats16393.closedRateObserved).state, 'drifted'); + t('#16393 stream: …and the factor is stated so it can be acted on', h22Premise(driftedStats16393.closedRateObserved).message.includes('a factor of 2.30'), true); + t('#16393 stream: …with both rates beside it', h22Premise(driftedStats16393.closedRateObserved).message.includes('observed ~433.3 closed-issue updates/day') && h22Premise(driftedStats16393.closedRateObserved).message.includes('= 188.3/day'), true); + // ⛔ The rule that makes this an alarm rather than a self-healing constant. + t('#16393 stream: ⛔ a drifted sweep does NOT rewrite the pin', MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY, 188.3); + t('#16393 stream: …nor its date', MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY_AT, '2026-08-31'); + + // 1x the pin: 0.625-day steps, horizon on page 5 — 500 rows over 2.5 days is + // 200/day, a factor of 1.06, and the alarm stays silent. + const okStats16393 = {}; + await listRecentlyClosedIssues(okStats16393, NOW13606, rateStream16393(0.625)); + t('#16393 stream: an in-band board reaches its horizon in five pages', okStats16393.closedPages, 5); + t('#16393 stream: …and observes a rate at the pin', Math.round(okStats16393.closedRateObserved * 100) / 100, 200); + t('#16393 stream: …which raises NO alarm', h22Premise(okStats16393.closedRateObserved).state, 'ok'); + t('#16393 stream: a board with nothing dateable observes no rate at all', (await (async () => { const s = {}; await listRecentlyClosedIssues(s, NOW13606, closedStream([[{ number: 1, updated_at: 'nope' }]])); return s.closedRateObserved; })()), null); + t('#16393 stream: …and an empty board likewise', (await (async () => { const s = {}; await listRecentlyClosedIssues(s, NOW13606, closedStream([])); return s.closedRateObserved; })()), null); + t('#16393: the observed rate rides the enumerated forwarding contract', SWEEP_COUNT_KEYS.includes('closedRateObserved'), true); + + // ---- The clause. Wording is pinned through the clause builder with a fixed + // `nowMs`, because the summary line reads the real clock and a case asserting + // a verdict through it would go red on a calendar date rather than on a + // defect — the permanently-red gate this repo retires. + const clause16393 = (observed, extra = {}) => h22RatePremiseClause(observed, { nowMs: NOW13606, ...extra }); + t('#16393 clause: a drifted divisor is marked loud', clause16393(433.33).startsWith('⚠️ RATE PREMISE DRIFTED'), true); + t('#16393 clause: …and names the re-measure act', clause16393(433.33).includes('re-pinned by hand, from a fresh measurement'), true); + t('#16393 clause: an expired pin is marked loud too', clause16393(188.3, { nowMs: Date.parse('2026-11-01T00:00:00Z') }).startsWith('⚠️ RATE PREMISE EXPIRED'), true); + t('#16393 clause: an unobserved rate is marked loud, never silent', clause16393(null).startsWith('⚠️ RATE PREMISE UNOBSERVED'), true); + t('#16393 clause: an in-band divisor is NOT marked loud', clause16393(200).includes('⚠️'), false); + // ⛔ …but it still SPEAKS. A check that is only visible when it fires cannot + // be told apart from a check somebody deleted — `renderRatePremise`'s rule. + t('#16393 clause: …and still speaks, so a deleted check cannot pass for a healthy board', clause16393(200).startsWith('rate premise OK'), true); + t('#16393 clause: …naming both rates even when it agrees', clause16393(200).includes('observed ~200.0/day') && clause16393(200).includes('= 188.3/day'), true); + + // ---- The clause on the summary line. Only time-INDEPENDENT properties are + // asserted here, for the reason above; the verdict wording is pinned by the + // builder cases. + t('#16393 summary: the clause rides inside H22\'s own window clause', saidBy('h22Window', win13606({ closedPages: 6, closedRateObserved: 433.33 })).includes('RATE PREMISE'), true); + t('#16393 summary: ⛔ …and not in a neighbour\'s', saidBy('h23Window', win13606({ closedPages: 6, closedRateObserved: 433.33 })).includes('RATE PREMISE'), false); + t('#16393 summary: it names the pinned constant beside the number already quoted', saidBy('h22Window', win13606({ closedPages: 6, closedRateObserved: 433.33 })).includes('`MEASURED_CLOSED_ISSUE_UPDATES_PER_DAY`'), true); + // A sweep that never ran the pass says UNOBSERVED — which outranks every + // other verdict, so this case does not move with the calendar. + t('#16393 summary: a bare line reports the divisor UNCHECKED, not agreed with', saidBy('h22Window', summaryLine({}, 0)).includes('RATE PREMISE UNOBSERVED'), true); + t('#16393 summary: …and renders numbers, never `undefined`', saidBy('h22Window', summaryLine({}, 0)).includes('undefined'), false); + // -- H26: a block whose target can never close, + the stale chain (#11219) -- // The measured cards, by name, and both directions of every leg. const waiting = (number = 1119) => ({