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
{{ message }}
Repository navigation
Commit da8c088
Browse filesBrowse the repository at this point in the historyBrowse files
fix(pm): read every Blocked-by: directive on a line, and every ref in one
`check-half-states.mjs` took ONE target from a line stating several, and for a
directive whose remainder is prose it took whichever number the ref walk
reached first. Both readings under-report a block that H19's row then releases:
a live body with nine `·`-separated backticked directives resolved 1 target and
printed 「1 of 1 CLOSED」, and a body whose directive opens with a possessive
resolved that possessive — a card that was never a blocker — and dropped both
real blockers.
Two halves, in the two places they belong:
- the shared decorated-directive reader now splits a line at every FURTHER key
that follows a separator run, so each directive yields its own value and the
whole directive family gains it. A key after a WORD is still prose.
- the `Blocked-by:` walk now takes EVERY ref in a directive's value instead of
the leading run. The run was taken to keep a context `#N` out of the index,
and it did not: a prose-opening value filed a phantom AND dropped the real
blockers. An extra target can only withhold a discharge; a dropped one
releases a live block.
Self-test: the two measured live shapes as fixtures (9 targets, both real
blockers), the two dark controls (one directive is one target; prose outside a
directive invents nothing), the family pin on a non-`Blocked-by:` key, and the
end-to-end count 「1 of 2」 from a two-directive body line.
Claude-Session: https://claude.ai/code/session_017ETYWqMQD4qMtZzAGovWNi
Co-authored-by: Claude <noreply@anthropic.com>
@@ -26713,13 +26755,13 @@ async function selfTest() {
26713
26755
numbersOf(blockedByTargets('Blocked-by: #9689 (the relocation it needs is the same edit; doing them in the other order means touching the line twice).')),
26714
26756
'9689',
26715
26757
);
26716
-
// The reason only the LEADING run is taken: a `#N` inside the trailing prose
26717
-
// is context, not a blocker, and indexing it would file a phantom
26718
-
// missing-cache row against a third card that did nothing wrong.
26758
+
// ⭐ The leading run is GONE: a `#N` in the trailing prose is now a target
26759
+
// too. It can only WITHHOLD a discharge, while the run it replaces
26760
+
// SUBSTITUTED a false blocker for two real ones (the #8093 shape below).
26719
26761
t(
26720
-
'blockedByTargets: a ref inside the trailing prose is NOT a blocker',
26762
+
'blockedByTargets: a ref inside the trailing prose is a target too, and can only withhold',
26721
26763
numbersOf(blockedByTargets('Blocked-by: #123 (see #456 for the background)')),
26722
-
'123',
26764
+
'123,456',
26723
26765
);
26724
26766
t('blockedByTargets: a comma-separated run is all blockers', numbersOf(blockedByTargets('Blocked-by: #6234, #6245')), '6234,6245');
26725
26767
t('blockedByTargets: the `and` connector is a separator', numbersOf(blockedByTargets('Blocked-by: #1 and #2')), '1,2');
@@ -26748,6 +26790,34 @@ async function selfTest() {
26748
26790
// live machinery and must be reported as part of the index it feeds.
26749
26791
t('blockedByTargets: a fenced line still counts (this reader greps, it does not read prose)', numbersOf(blockedByTargets('```\nBlocked-by: #42\n```')), '42');
26750
26792
26793
+
// -- Multiplicity and substitution, both MEASURED on live bodies ----------
26794
+
// objectui#8347: NINE `·`-separated backticked directives on ONE line. The
26795
+
// reader took the first and H19 printed 「1 of 1 … CLOSED」 — the row the
26796
+
// unlock scan releases from — while three of the nine were open.
t('blockedByTargets: the #8347 shape — nine directives on one line are NINE targets', numbersOf(blockedByTargets(nineOnOneLine)), '8345,8648,8649,8650,8651,8652,8653,8654,8655');
26801
+
t('directiveValues: …and each directive is its own CLEAN value, decoration stripped per directive', directiveValues(nineOnOneLine, 'Blocked-by').join('|'), '#8345|#8648|#8649|#8650|#8651|#8652|#8653|#8654|#8655');
26802
+
// objectui#8093: ONE directive whose remainder is prose naming three
26803
+
// numbers. The leading run returned the POSSESSIVE — never a blocker — and
26804
+
// dropped both real ones: a substituted target answers the liveness
26805
+
// question about the wrong card, which is the worse of the two failures.
26806
+
const proseRemainder =
26807
+
"`Blocked-by:` objectui#7434's PR #8090 (the `AGENTS.md` half, draft, awaiting human merge) " +
26808
+
'and whatever PR repairs objectui#8065 (the `skills/objectui` half).';
26809
+
t('blockedByTargets: the #8093 shape — both REAL blockers are read, not dropped', blockedByTargets(proseRemainder).map((r) => `${r.repo ?? ''}#${r.number}`).join(','), 'objectui#7434,#8090,objectui#8065');
26810
+
// The dark controls: one directive is one target, and prose OUTSIDE a
26811
+
// directive is not a directive however many numbers it names.
26812
+
t('blockedByTargets: ONE directive still yields exactly one target', numbersOf(blockedByTargets('`Blocked-by: #4242`')), '4242');
26813
+
t('blockedByTargets: prose naming `#n` OUTSIDE any directive invents nothing', numbersOf(blockedByTargets('We will wait for #9 and #10 before starting.')), '');
26814
+
t('blockedByTargets: a URL fragment inside a value is not a target', numbersOf(blockedByTargets('Blocked-by: #12 (trail: https://example.test/issues/8347#40)')), '12');
26815
+
// The whole directive family reads through `directiveValues`, so all of it
26816
+
// gains the multiplicity — pinned on a NON-`Blocked-by:` key, beside the pin
26817
+
// that a key after a WORD is still prose and invents nothing.
26818
+
t('directiveValues: a second directive on one line is read for EVERY family', directiveValues('`Restart-when: closed acme/w#9` · `Restart-when: manual — x`', 'Restart-when').join('|'), 'closed acme/w#9|manual — x');
26819
+
t('directiveValues: …and a key after a WORD is still prose, not a second directive', directiveValues('Restart-when: closed acme/w#9 — seats park the `Restart-when: manual` line in comments', 'Restart-when').length, 1);
t('H19: a two-directive line resolves TWO targets', twoResolved.map((tg) => tg.number).join(','), '2,3');
27222
+
t('H19: …so the row reads 1 of 2, never 1 of 1', h19row(twoOnOneLine, twoResolved, REPO_OS).includes('1 of 2 `Blocked-by:` target(s)'), true);
27223
+
t('H19: …and calls it a PARTIAL discharge rather than a full one', h19row(twoOnOneLine, twoResolved, REPO_OS).includes('Every target it names is closed'), false);
27145
27224
27146
27225
// UNRESOLVED — never reads as clean, and never reads as closed either.
0 commit comments