* 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>
25 KiB
25 KiB