Skip to content

Commit 108fae9

Browse files
Jack Qclaude
andauthored
fix(pm): H14's stale-pm:blocking row stops claiming completeness across repos (#10239)
The STALE direction's row text read "judged against the full two-channel index" and prescribed an unconditional label drop, but buildBlockingIndex only ever scans this repo's open-issue listing — a real dependent living in a sibling repo (e.g. objectui#4356's Blocked-by: #7917) is invisible to it by construction, not by any read failure. The row now names the repo boundary explicitly ("no dependent found in this repo; cross-repo dependents are not swept") and makes the remedy conditional on verifying cross-repo dependents before the triage sweep's derivation pass drops the label, rather than instructing an outright drop. H15 was checked for the same exhaustiveness claim and does not carry one — its row measures this-repo pm:blocking card age, not blocked-by index completeness — so it is unchanged. Self-test: 4 new pins (repo-boundary wording present, old exhaustive phrasing gone), 558 -> 562 cases, all passing. Co-authored-by: Claude <noreply@anthropic.com>
1 parent a38c3ff commit 108fae9

1 file changed

Lines changed: 35 additions & 8 deletions

File tree

scripts/pm/check-half-states.mjs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,6 +1549,21 @@ export const BLOCKING_DEPENDENT_LIST_CAP = 5;
15491549
* stale」): the measured false stales #9465 and #9968 were both cards whose
15501550
* dependents state the wait in a COMMENT, and both are pinned in the self-test.
15511551
*
1552+
* ## STALE is also repo-local, and the row says so (#10139)
1553+
*
1554+
* `buildBlockingIndex` only ever scans THIS repo's open-issue listing, so
1555+
* `indexComplete` measures whether the comment fallback read every candidate
1556+
* — it says nothing about sibling repos. A dependent living in `objectui` or
1557+
* `cloud` with a `Blocked-by:` line naming this card is invisible to the
1558+
* index by construction, not by any read failure, so `indexComplete` cannot
1559+
* gate it and never claims to. The STALE sentence therefore does not read as
1560+
* exhaustive over "no dependent anywhere" — only "no dependent in this
1561+
* repo" — and its remedy is conditional on a cross-repo check rather than an
1562+
* instruction to drop the label outright: `Blocked-by:` edges are
1563+
* protocol-legal across repos (contract-first splits use them routinely),
1564+
* and #7917 / objectui#4356 is a live one this row would otherwise have
1565+
* instructed a reader to sever.
1566+
*
15521567
* @param {object} issue — an OPEN issue.
15531568
* @param {Map<number, number[]>} index — from `buildBlockingIndex`.
15541569
* @param {{ indexComplete?: boolean }} [options] — `false` when any gated
@@ -1561,14 +1576,16 @@ export function h14BlockingCacheIncoherent(issue, index, options = {}) {
15611576
if (carries && dependents.length === 0) {
15621577
if (!indexComplete) return null;
15631578
return (
1564-
'`pm:blocking` carried while NO open card\'s `Blocked-by:` line — body OR comment — targets ' +
1565-
'it, judged against the full two-channel index — a stale ' +
1566-
'derived cache. The label is not a state a seat sets: the triage sweep derives it from the ' +
1567-
'`Blocked-by:` reverse index, and the lane selection order ranks it second only to ' +
1568-
'`priority:p0`. So a stale one is worse than an absent one — it boosts a card nothing depends ' +
1569-
'on, with authority. Report-only: the remedy is the triage sweep\'s derivation pass dropping ' +
1570-
'the label (or the missing `Blocked-by:` line landing on the card that really is waiting), ' +
1571-
'never a label written from this script.'
1579+
'`pm:blocking` carried while no open card\'s `Blocked-by:` line — body OR comment — targets ' +
1580+
'it, judged against the two-channel index — a stale derived cache, scoped to THIS REPO ONLY: ' +
1581+
'no dependent found in this repo; cross-repo dependents are not swept, so this is not a claim ' +
1582+
'of exhaustiveness over the population — `Blocked-by:` edges are legally cross-repo. The label ' +
1583+
'is not a state a seat sets: the triage sweep derives it from the `Blocked-by:` reverse index, ' +
1584+
'and the lane selection order ranks it second only to `priority:p0`. So a stale one is worse ' +
1585+
'than an absent one — it boosts a card nothing depends on, with authority. Report-only: verify ' +
1586+
'cross-repo dependents before the triage sweep\'s derivation pass drops the label (or the ' +
1587+
'missing `Blocked-by:` line landing on the card that really is waiting), never a label written ' +
1588+
'from this script.'
15721589
);
15731590
}
15741591
if (!carries && dependents.length > 0) {
@@ -4075,6 +4092,16 @@ function selfTest() {
40754092
t('H14-A: …and it names the stale-cache reading', h14BlockingCacheIncoherent(carded(7276, ['pm:blocking']), idx([])).includes('stale derived cache'), true);
40764093
t('H14-A: …and prescribes the derivation pass, never a label from here', h14BlockingCacheIncoherent(carded(7276, ['pm:blocking']), idx([])).includes('derivation pass'), true);
40774094
t('H14-A: …and says why stale is worse than absent', h14BlockingCacheIncoherent(carded(7276, ['pm:blocking']), idx([])).includes('with authority'), true);
4095+
// The repo-boundary wording (#10139): STALE reads as "no dependent in this
4096+
// repo", never as exhaustive over the population, and the remedy is
4097+
// conditional on a cross-repo check rather than an outright drop.
4098+
t('H14-A: …names the repo boundary', h14BlockingCacheIncoherent(carded(7276, ['pm:blocking']), idx([])).includes('no dependent found in this repo'), true);
4099+
t('H14-A: …and says cross-repo dependents are not swept', h14BlockingCacheIncoherent(carded(7276, ['pm:blocking']), idx([])).includes('cross-repo dependents are not swept'), true);
4100+
t('H14-A: …and the remedy is conditional on verifying cross-repo dependents', h14BlockingCacheIncoherent(carded(7276, ['pm:blocking']), idx([])).includes('verify cross-repo dependents before'), true);
4101+
// The negative: the old exhaustive phrasing ("the full two-channel index",
4102+
// instructing an unconditional drop) must be gone — it is what would have
4103+
// told a reader to sever the live #7917 / objectui#4356 edge.
4104+
t('H14-A: …and the old exhaustive phrasing is GONE', h14BlockingCacheIncoherent(carded(7276, ['pm:blocking']), idx([])).includes('full two-channel index'), false);
40784105
// The negative for direction A: the label is EARNED, so nothing to report.
40794106
t(
40804107
'H14-A: pm:blocking with a real dependent -> clean',

0 commit comments

Comments
 (0)