Files
msd-core/tests
Tom Boucher 30c40e0fe2 fix(#4302): bound restatement detector's deferral window structurally, not by a flat char count (#4303)
* test(#4302): add failing regression test for deferral-window paragraph leak

RED: hasNearbyDeferralMarker's 500-char trailing window has no structural
boundary, so a compact citation-free restatement immediately followed by an
unrelated section that cites tdd.md borrows that neighbor's citation and
evades restatesCycleStructurally(). Reproduces the exact shape confirmed via
mutation testing against the real agents/gsd-executor.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(#4302): bound the deferral window at the next heading, not a flat char count

hasNearbyDeferralMarker's 500-char trailing window had no structural
boundary, so a compact citation-free restatement immediately followed by an
unrelated section that cites tdd.md borrowed that neighbor's citation and
evaded restatesCycleStructurally() (confirmed on the real gsd-executor.md,
whose next section after the cycle pointer has its own independent citation
82 chars past the REFACTOR anchor).

First attempt bounded at the next blank line instead, and was rejected after
it broke a real case caught by direct execution before committing:
execute-plan.md's FIRST RED/GREEN/REFACTOR occurrence is a numbered list's
own intro sentence, separated by a genuine blank line from the list item
that actually carries the citation — a blank line is not reliably "still the
same statement" once list structure is involved.

Bounds at the next markdown heading (`\n#`) instead, capped at 500 chars as
before when no heading appears. Verified against both real files, the new
regression fixture, and every pre-existing #4268 fixture/property test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(#4302): close a narrower same-section evasion found by orthogonal review

The heading-only fix left a narrower gap: a citation-free restatement
followed by a blank line and an unrelated PROSE paragraph (no heading) that
cites tdd.md for an unrelated reason still evaded detection — confirmed by
the reviewer via execution.

Generalizes the boundary rule: any blank line whose following line is NOT a
markdown list continuation is now also a boundary (in addition to the
existing heading boundary), reconciling with the earlier-rejected flat
blank-line bound by adding the list-continuation exception that
execute-plan.md's real shape (a numbered list's intro sentence, then a
blank line, then the list item carrying the citation) needs. Verified
against both real files, all three restatement fixtures (heading-bounded,
prose-bounded, list-continuation negative-space), every pre-existing #4268
fixture, and the fast-check property test (200 runs).

Also restores an honest, updated limitation disclosure describing the one
narrower residual case not resolved by this design (a citation reachable via
exactly one list-item hop from an unrelated list) — matching this repo's
disclosed-not-silently-deferred practice from the original #4268 PR.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: sim <sim@local>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 21:35:30 -04:00
..