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
fix(pm): H14's strip direction declines on a seam card instead of accusing it (#13990)
`pm:blocking` is a derived cache of the `Blocked-by:` reverse index, and the
patrol builds that index from THIS repo's open listing only. Seam cards exist
to be read from another repo — the protocol keeps them here carrying
`repo:cloud` / `repo:objectui` / `repo:hotcrm` precisely so a sibling's work can
depend on them — so for exactly those cards "no open card here points at me" is
not evidence that nobody is waiting. It is the reading the index is
structurally unable to make.
The stale direction now DECLINES on a card carrying any `repo:*` label: the row
is still emitted (a suppressed row makes the seam card invisible to the patrol,
which is the second defect, not the fix), carries `UNJUDGED_MARKER` so the
markdown trim can never be what removes it, and says it is declining and why.
The ADD direction is untouched — a cross-repo edge the index cannot see can
only make that one under-label, which is the status quo.
The surviving stale rows now name their scope in the head clause and disclose
the predicate's measured under-coverage: on the 2026-08-31 board, 58 of the 67
open cards naming a sibling-repo issue carry no `repo:*` label, so the absence
of the label is not evidence of an in-repo-only audience.
Report-only throughout: no label write, no exit-code change, no row made
build-failing.
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
Co-authored-by: Claude <noreply@anthropic.com>
// The predicate, alone: one reading of the `repo:*` family, `censusLanesOf`'s.
12733
+
t('H14 seam: the predicate reads the repo:* family', seamRepoLabels(seamCard).join(','), 'repo:cloud');
12734
+
t('H14 seam: …and is empty on a card carrying none', seamRepoLabels(nonSeamCard).length, 0);
12735
+
t('H14 seam: …and a domain lane is not a repo lane', seamRepoLabels(carded(1, ['domain:spec', 'pm:blocking'])).length, 0);
12736
+
t('H14 seam: …and more than one repo label is all of them', seamRepoLabels(carded(1, ['repo:cloud', 'domain:spec', 'repo:hotcrm'])).join(','), 'repo:cloud,repo:hotcrm');
12737
+
t('H14 seam: …and a missing issue does not crash', seamRepoLabels(undefined).length, 0);
12738
+
12739
+
// The decline: EMITTED, never suppressed (the row is the seam card's only
12740
+
// trace in the report — H32's silent `foreign` return is the other shape,
12741
+
// and it belongs to a row whose POPULATION is out of scope, not one whose
12742
+
// evidence is unreadable).
12743
+
t('H14 seam: a seam card in the stale position still EMITS a row', typeof h14BlockingCacheIncoherent(seamCard, seamIdx, swept), 'string');
12744
+
t('H14 seam: …and the row declines rather than accusing', h14row(seamCard, seamIdx, swept).includes('DECLINES to judge'), true);
12745
+
t('H14 seam: …and names the label it declined on', h14row(seamCard, seamIdx, swept).includes('`repo:cloud`'), true);
12746
+
t('H14 seam: …and says the evidence is UNREADABLE, not absent', h14row(seamCard, seamIdx, swept).includes('UNREADABLE'), true);
12747
+
t('H14 seam: …and that no re-run resolves it', h14row(seamCard, seamIdx, swept).includes('no re-run resolves it'), true);
12748
+
t('H14 seam: …and reads as UNJUDGED, never as a stale cache', h14row(seamCard, seamIdx, swept).includes('stale derived cache'), false);
12749
+
t('H14 seam: …so it never prescribes the strip', h14row(seamCard, seamIdx, swept).includes('drops the label'), false);
12750
+
t('H14 seam: …and forbids the hand-strip as well as the hand-apply', h14row(seamCard, seamIdx, swept).includes('hand-stripped'), true);
12751
+
// The trim-order rank, which is what makes "emitted" mean "still there in the
12752
+
// rendered body" (#11218). Without it a decline is a suppression on a delay.
12753
+
t('H14 seam: …and the row carries the UNJUDGED rank', isUnjudgedFinding(h14row(seamCard, seamIdx, swept)), true);
12754
+
t('H14 seam: …while the ordinary stale row does NOT (it made a determination)', isUnjudgedFinding(h14row(nonSeamCard, seamIdx, swept)), false);
12755
+
// Report-only and never loud, the H14–H16 property the decline must not break.
12756
+
t('H14 seam: …and the decline is not a loud finding', isLoudFinding(h14row(seamCard, seamIdx, swept)), false);
12757
+
// The card's own re-check (`grep -E "H14 .*carried while no open"`) has to
12758
+
// keep listing BOTH shapes, or the seam cards vanish from the one-liner the
12759
+
// filing seat used to find them.
12760
+
t('H14 seam: …and the row head still answers the card\'s re-check grep', /carried while no open/u.test(h14row(seamCard, seamIdx, swept)), true);
12761
+
12762
+
// The paired negative: the same position, no `repo:*` label -> still fires.
12763
+
t('H14 seam: a NON-seam card in the same position still fires', h14row(nonSeamCard, seamIdx, swept).includes('stale derived cache'), true);
12764
+
t('H14 seam: …and its row names its own scope', h14row(nonSeamCard, seamIdx, swept).includes('no dependent found in this repo'), true);
12765
+
t('H14 seam: …and says the missing label is NOT evidence of an in-repo audience', h14row(nonSeamCard, seamIdx, swept).includes('58 of the 67'), true);
12766
+
12767
+
// An earned label is clean whether or not the card is a seam: the decline
12768
+
// fires on the stale position only, never on the population.
12769
+
t('H14 seam: a seam card with a real in-repo dependent -> clean', h14BlockingCacheIncoherent(seamCard, idx([carded(10, [], 'Blocked-by: #12931')]), swept), null);
12770
+
// Suspension outranks the decline: an index known incomplete silences the
12771
+
// whole direction, unchanged by this row.
12772
+
t('H14 seam: an incomplete index still silences the direction outright', h14BlockingCacheIncoherent(seamCard, seamIdx, { ...swept, indexComplete: false }), null);
12773
+
12774
+
// ⛔ The ADD direction is untouched on a seam card, and byte-identically so:
12775
+
// a cross-repo edge the index cannot see can only make THAT direction
12776
+
// under-label, which is the status quo and starves nobody.
t('H14 seam: a label naming the swept repo declines too (the predicate is literal)', h14row(ownRepoCard, seamIdx, swept).includes('DECLINES to judge'), true);
12792
+
t('H14 seam: …and says that decline is CONSERVATIVE', h14row(ownRepoCard, seamIdx, swept).includes('CONSERVATIVE'), true);
t('H14 seam: …and a seam label there is still structural', h14row(ownRepoCard, seamIdx, { ownerRepo: 'objectstack-ai/cloud' }).includes('CONSERVATIVE'), false);
12798
+
12593
12799
// The summary line carries the third `read X of Y` pair, and says out loud
12594
12800
// when the shortfall cost H14 its stale direction.
0 commit comments