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(spec-tooling): a hard-wrapped mention is not a migration label (#7094) (#7805)
Branch 1 of the ADR-0087 completeness gate reads the one character to the left
of the `FROM`/`TO` placeholder to tell a label from a mention. Prose here is
hard-wrapped at ~80 columns, so a mention that wraps onto a fresh line has
nothing to its left and was read as a declaration -- the over-match direction,
which hard-blocks an author with no disposition left but rewording true prose.
When the placeholder opens its line the question is now asked of the line
above, and it is a narrower question there: within a line adjacency is the
evidence, but a line break is ambiguous, so only a closed class of determiners,
possessives and complement-taking prepositions counts. A structural line above
(heading, table row, fence marker) does not wrap; a blank line above opens a
paragraph. Both keep their previous reading.
Measured over the whole 1792-changeset stock before and after: 176 hits / 132
declared-breaking -> 174 / 132. The two that leave are the reported specimen
`changelog-ships-in-tarball.md` and `notification-retirement-evidence-
corrected.md`, both mentions on inspection and neither declaring a breaking
change; the `--audit-stock` worklist is byte-identical at residue 97 / 52
candidates. The wider version -- reusing the in-line "any letter governs" test
across the wrap -- was written first and killed by its own positive control,
now pinned as P52. Self-test 142 -> 153 assertions.
Claude-Session: https://claude.ai/code/session_01PJS4XSauE4SRNAvRUMyw2Z
Co-authored-by: Claude <noreply@anthropic.com>
'P50: the evidence line is the placeholder\'s OWN line -- the match may open on the newline that ends the line above, which used to be reported instead',
2486
2574
);
2487
2575
2576
+
// --- P51-P60: the HARD-WRAPPED mention, and the floors that keep the cure from
2577
+
// --- being worse than the disease (#7094).
2578
+
//
2579
+
// Branch 1 reads the ONE character before the placeholder. When the placeholder
2580
+
// opens its line there is no such character, and #7078 read that as "a label
2581
+
// opens a segment" -- true under a blank line, false under a sentence that simply
2582
+
// ran out of columns. These pin BOTH directions: the wrapped MENTION now loses,
2583
+
// and every other way of opening a line keeps what it had. P52 is the positive
2584
+
// control the specimen assertions are worthless without -- if it ever goes red
2585
+
// with P51 green, the arm has stopped seeing rather than started discriminating.
2586
+
assert(
2587
+
!hasMigrationPrescription(
2588
+
'The AGENTS.md post-task checklist requires breaking changesets to carry their\nFROM → TO migration because "this text ships to consumers as `CHANGELOG.md`\ninside the npm package and is what an upgrading agent greps after the tombstone\nerror."\n',
2589
+
),
2590
+
'P51: the #7094 specimen VERBATIM -- `carry their` ends the line above, so the wrap does not make a mention a label (`changelog-ships-in-tarball.md`)',
2591
+
);
2592
+
assert(
2593
+
findMigrationPrescription('prose that wraps at eighty columns and ends the line here\nFROM → TO: delete the block\n')?.branch==='from-to-label',
2594
+
'P52: POSITIVE CONTROL -- a wrapped LABEL under a line ending on a word that governs nothing still matches, with NO concrete rewrite in the body to fall back on',
2595
+
);
2596
+
assert(
2597
+
findMigrationPrescription('The RLS compiler never read it.\nFROM → TO: a set a policy needs is now supplied\n')?.branch==='from-to-label',
2598
+
'P53: ...and so does one under a FINISHED sentence -- punctuation is a boundary across the wrap exactly as it is within the line (P43)',
2599
+
);
2600
+
assert(
2601
+
findMigrationPrescription('an ordinary paragraph about something else\n\nFROM → TO:\n')?.branch==='from-to-label',
2602
+
'P54: a placeholder opening a PARAGRAPH is a label -- 46 of the stock\'s 49 line-opening occurrences are this shape and none of them moved',
'P55: a HEADING does not wrap into the line below it, so the placeholder under one still opens a segment',
2607
+
);
2608
+
assert(
2609
+
findMigrationPrescription('| You wrote | Write instead |\nFROM → TO:\n')?.branch==='from-to-label',
2610
+
'P56: nor does a table row -- structure above is not a sentence running on',
2611
+
);
2612
+
assert(
2613
+
!hasMigrationPrescription('这次改动只是把发布说明搬了个地方,真正的\nFROM → TO 落在部署方自己的代理配置上。\n'),
2614
+
'P57: the Chinese spelling wraps too -- `的` ending the line above governs the placeholder below it (P40 across a wrap)',
2615
+
);
2616
+
assert(
2617
+
!hasMigrationPrescription('- the checklist requires every breaking changeset to carry its own\n FROM → TO guide, which is where the prescriptions live\n'),
2618
+
'P58: a wrapped BULLET is prose that runs on -- the arm reads the line above whether the placeholder is at column 0 or merely indented',
2619
+
);
2620
+
assert(
2621
+
findMigrationPrescription('- a bullet that ended cleanly\n\n FROM → TO: delete the block\n')?.branch==='from-to-label',
2622
+
'P59: ...and an INDENTED label under a blank line is still a label -- indentation is not the test, which is the tightening this fix had to avoid',
2623
+
);
2624
+
assert(
2625
+
findMigrationPrescription('the checklist requires each changeset to carry their\nFROM → TO guide\n\n- `objectPermissions` → `objectPermission`\n')?.branch==='from-to-label',
2626
+
'P60: the corroboration floor survives the wrap -- a wrapped mention is still taken at face value once the body SHOWS a concrete rewrite (P47)',
2627
+
);
2628
+
assert(
2629
+
findMigrationPrescription('**Migration (FROM → TO).** Replace each legacy value with the primitive\n\nit is NOT a parse error: `stripLegacyApiMethods` strips it with a\nFROM→TO warning (canonicalize-and-warn)\n')?.line==='**Migration (FROM → TO).** Replace each legacy value with the primitive',
2630
+
'P61: a body holding a real label AND a wrapped mention keeps the LABEL as its evidence -- `apimethod-enum-shrink.md`, declared-breaking, the stock\'s own control for this arm',
2631
+
);
2632
+
2488
2633
// ---- S1-S5: the `--audit-stock` classifier (#6350) ------------------------
2489
2634
//
2490
2635
// The stock audit's classifier decides which rows a human ever reads, so a
0 commit comments