Describe the bug
The sweep state files (.claude/sweep-*-state.csv) carry merge=union in .gitattributes so parallel sweep agents can append rows without clobbering each other. Union merge is line-based: it unions and dedupes physical lines. The sweep writers use csv.DictWriter with QUOTE_MINIMAL, which is valid CSV but writes a newline-containing note as a quoted field spanning several physical lines.
When two agents append concurrently, union merge splits those multi-line records on their internal newlines. The file ends up with phantom rows, duplicate header lines, and notes torn apart mid-sentence. PR #2679 repaired the latest instance in sweep-test-coverage-state.csv (31 corrupted physical lines collapsed back to 7 clean records).
The "notes": "<single-line notes or empty>" placeholder in the writer is a hint, not enforcement. Nothing stops an agent from writing a note that contains a newline.
Expected behavior
Each record occupies exactly one physical line on disk regardless of note content, so union merges stay record-aligned and cannot corrupt the file.
Fix
In every sweep writer (.claude/commands/sweep-*.md and deep-sweep.md), sanitize each field to collapse embedded CR/LF to a " | " separator right before writerow, so a record is always one physical line. This enforces the invariant in code rather than relying on the unenforced placeholder hint.
Additional context
Affects all seven sweep commands plus the deep-sweep reset path. The OS/browser/device fields from the bug template do not apply; this is repository tooling, not a runtime code path.
Describe the bug
The sweep state files (
.claude/sweep-*-state.csv) carrymerge=unionin.gitattributesso parallel sweep agents can append rows without clobbering each other. Union merge is line-based: it unions and dedupes physical lines. The sweep writers usecsv.DictWriterwithQUOTE_MINIMAL, which is valid CSV but writes a newline-containing note as a quoted field spanning several physical lines.When two agents append concurrently, union merge splits those multi-line records on their internal newlines. The file ends up with phantom rows, duplicate header lines, and notes torn apart mid-sentence. PR #2679 repaired the latest instance in
sweep-test-coverage-state.csv(31 corrupted physical lines collapsed back to 7 clean records).The
"notes": "<single-line notes or empty>"placeholder in the writer is a hint, not enforcement. Nothing stops an agent from writing a note that contains a newline.Expected behavior
Each record occupies exactly one physical line on disk regardless of note content, so union merges stay record-aligned and cannot corrupt the file.
Fix
In every sweep writer (
.claude/commands/sweep-*.mdanddeep-sweep.md), sanitize each field to collapse embedded CR/LF to a" | "separator right beforewriterow, so a record is always one physical line. This enforces the invariant in code rather than relying on the unenforced placeholder hint.Additional context
Affects all seven sweep commands plus the deep-sweep reset path. The OS/browser/device fields from the bug template do not apply; this is repository tooling, not a runtime code path.