fix(wiki): canonicalize whitespace across a whole section, not just its ends
CI / Lint / Test / Vet (pull_request) Successful in 38s
CI / Mirror to GitHub (pull_request) Skipped

Review of PR #129 found MergeReport's disagreement check compared
strings.TrimSpace(sA.content) against strings.TrimSpace(sB.content) --
only leading/trailing whitespace is tolerated. Every other content
comparison in this file (appendNew, mergeBullets) already canonicalizes
internal whitespace runs too, because a re-extraction's exact spacing
isn't byte-stable (#103). A mid-line double-space would false-positive
as a "disagreement" here even though the file's own established
tolerance says it shouldn't.

canonicalBlock applies the existing canonicalLine per line of a
multi-line section body. A genuine content difference is still caught
(TestMerge_ReportsSectionsWhereTheFreshVersionWasDiscarded stays green);
only internal-whitespace-only variants stop false-positiving.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-23 07:20:40 +02:00
co-authored by Claude Sonnet 5
parent 719eb8c2d6
commit b05e9c48f4
2 changed files with 45 additions and 1 deletions
+29
View File
@@ -385,3 +385,32 @@ Appetite is fixed, scope is variable.
_, conflicts := MergeReport(page, page)
assert.Empty(t, conflicts, "identical content is not a disagreement")
}
func TestMerge_ReportsNothingForInternalWhitespaceVariantsOnly(t *testing.T) {
// Found in review of PR #129: the conflict comparison used raw
// strings.TrimSpace, which only tolerates LEADING/TRAILING whitespace —
// unlike appendNew/mergeBullets, which already canonicalize internal
// whitespace runs too (#103: a re-extraction's spacing isn't guaranteed
// byte-stable). A mid-line double-space from re-extraction would
// false-positive as a "disagreement" here even though every other
// whitespace-sensitive comparison in this file already tolerates it.
existing := Page{Path: "wiki/sources/x.md", Content: `---
title: 'X'
---
## Summary
Appetite is fixed, scope is variable.
`}
fresh := Page{Path: "wiki/sources/x.md", Content: `---
title: 'X'
---
## Summary
Appetite is fixed, scope is variable.
`}
_, conflicts := MergeReport(existing, fresh)
assert.Empty(t, conflicts, "internal whitespace differences alone are not a disagreement")
}