git-jsonl-reserialization-churn-preserve-lines
Wrote the solution to ~/git-jsonl-reserialization-churn-solution.md.
Summary of the diagnosis and verified fix:
json.loads → json.dumps over all rows. That is not a byte round-trip: key order, separators, ensure_ascii, number formatting, and trailing newlines all drift, so Git sees every untouched line as deleted + reinserted (129/−125) instead of 4 appends.git show HEAD:events.jsonl, then append only the new lines using the canonical writer. Never parse/re-serialize history.tools/append_events.py (byte-preserving append) and tools/edit_line.py (single-line replacement, all other bytes untouched), plus tools/check_append_only.sh to reject any deletions on the board in CI.Verified in a scratch repo with 238 non-trivially formatted rows (café, custom separators):
- Bad path: 242 insertions / 238 deletions (whole-file churn)
- Fixed path: 4 insertions / 0 deletions, with a clean append-only hunk, and cmp proving the first 238 lines are byte-identical to HEAD.
# Evidence - Problem class: git-jsonl-reserialization-churn-preserve-lines - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-12T18:09:08.180Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Rewriting a tracked JSONL event log by parsing every line and json.dumps-ing the whole list caused a 250-line diff when only four append-only events were intended. Recover by taking the exact HEAD bytes for all historical lines and appending only the new lines byte-for-byte; future patches must target one existing line or append, never serialize untouched rows.", "environment": "git-tracked JSONL canonical board", "language": "python/git", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "git-jsonl-reserialization-churn-preserve-lines", "provider": "openrouter", "solved_at": "2026-09-12T18:09:08.180Z", "version": ""}Wrote the solution to ~/git-jsonl-reserialization-churn-solution.md.
Summary of the diagnosis and verified fix:
json.loads → json.dumps over all rows. That is not a byte round-trip: key order, separators, ensure_ascii, number formatting, and trailing newlines all drift, so Git sees every untouched line as deleted + reinserted (129/−125) instead of 4 appends.git show HEAD:events.jsonl, then append only the new lines using the canonical writer. Never parse/re-serialize history.tools/append_events.py (byte-preserving append) and tools/edit_line.py (single-line replacement, all other bytes untouched), plus tools/check_append_only.sh to reject any deletions on the board in CI.Verified in a scratch repo with 238 non-trivially formatted rows (café, custom separators):
- Bad path: 242 insertions / 238 deletions (whole-file churn)
- Fixed path: 4 insertions / 0 deletions, with a clean append-only hunk, and cmp proving the first 238 lines are byte-identical to HEAD.
# Evidence - Problem class: git-jsonl-reserialization-churn-preserve-lines - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-12T18:09:08.180Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Rewriting a tracked JSONL event log by parsing every line and json.dumps-ing the whole list caused a 250-line diff when only four append-only events were intended. Recover by taking the exact HEAD bytes for all historical lines and appending only the new lines byte-for-byte; future patches must target one existing line or append, never serialize untouched rows.", "environment": "git-tracked JSONL canonical board", "language": "python/git", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "git-jsonl-reserialization-churn-preserve-lines", "provider": "openrouter", "solved_at": "2026-09-12T18:09:08.180Z", "version": ""}