jsonl-torn-line-no-trailing-newline-append
Done. The solution document is saved at:
~/SOLUTION.jsonl-torn-line-no-trailing-newline-append.md
The repo/board files aren't checked out in this sandbox, so the deliverable is the self-contained solution document — but the core repair recipe was actually executed and verified against a synthetic corruption that matches the report exactly.
Root cause (distinct class):
1. A commit (tick 491, id 416) wrote the last events.jsonl line without a trailing \n (git's \ No newline at end of file).
2. The next tick's appender used open('a') + write and assumed a clean tail, so its idle_audit record glued onto the same line — junction }{ → ...{416}}{417...}.
3. json.loads() on that line then throws the exact reported JSONDecodeError: Extra data: line 1 column N (char N-1).
json.JSONDecoder().raw_decode split loop: returned 2 byte-preserving halves, each re-parses, objects identical to the originals, and the repaired file ends with \n → ALL CHECKS PASS.os.replace, split-verify-every-line, force trailing \n, backfill board.db max_id, sync board.jsonl header.a+, peek last char, write \n if missing), plus a commit/pre-commit hygiene check that rejects any JSONL file not ending in \n.Note: the doc on disk is complete and self-usable; I also cleaned the printf-style tables to plain tables for portability.
# Evidence - Problem class: jsonl-torn-line-no-trailing-newline-append - Model: openrouter/deepseek/deepseek-v4-flash-0731 - Solved: 2026-08-27T17:08:18.001Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Foreman board events.jsonl torn line: tick-491 audit event (id 416) was committed WITHOUT a trailing newline; the next tick's appender then glued its idle_audit event onto the same line. Both records intact, joined with '}{'. Root cause: a prior commit wrote the last JSONL line without trailing \\n (git diff showed '\\ No newline at end of file'), and the append path (open 'a' + write) does not ensure the file ends with a newline before appending. Repair: split the glued line with json.JSONDecoder().raw_decode loop (byte-preserving halves), re-verify every line parses, atomic temp+rename, backfill board.db max-id lockstep, sync board.jsonl header. Pre-verified split recipe exists (class jsonl-torn-line-recovery) but the ROOT-CAUSE class (missing trailing newline on committed last line -> next append glues) is distinct. Hardening: appender should ensure trailing newline before append; commit hygiene should check last line ends with \\n.", "environment": "linux, duckbrain repo, JSONL-canonical foreman board", "language": "python", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "jsonl-torn-line-no-trailing-newline-append", "provider": "openrouter", "solved_at": "2026-08-27T17:08:18.002Z", "version": ""}Done. The solution document is saved at:
~/SOLUTION.jsonl-torn-line-no-trailing-newline-append.md
The repo/board files aren't checked out in this sandbox, so the deliverable is the self-contained solution document — but the core repair recipe was actually executed and verified against a synthetic corruption that matches the report exactly.
Root cause (distinct class):
1. A commit (tick 491, id 416) wrote the last events.jsonl line without a trailing \n (git's \ No newline at end of file).
2. The next tick's appender used open('a') + write and assumed a clean tail, so its idle_audit record glued onto the same line — junction }{ → ...{416}}{417...}.
3. json.loads() on that line then throws the exact reported JSONDecodeError: Extra data: line 1 column N (char N-1).
json.JSONDecoder().raw_decode split loop: returned 2 byte-preserving halves, each re-parses, objects identical to the originals, and the repaired file ends with \n → ALL CHECKS PASS.os.replace, split-verify-every-line, force trailing \n, backfill board.db max_id, sync board.jsonl header.a+, peek last char, write \n if missing), plus a commit/pre-commit hygiene check that rejects any JSONL file not ending in \n.Note: the doc on disk is complete and self-usable; I also cleaned the printf-style tables to plain tables for portability.
# Evidence - Problem class: jsonl-torn-line-no-trailing-newline-append - Model: openrouter/deepseek/deepseek-v4-flash-0731 - Solved: 2026-08-27T17:08:18.001Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Foreman board events.jsonl torn line: tick-491 audit event (id 416) was committed WITHOUT a trailing newline; the next tick's appender then glued its idle_audit event onto the same line. Both records intact, joined with '}{'. Root cause: a prior commit wrote the last JSONL line without trailing \\n (git diff showed '\\ No newline at end of file'), and the append path (open 'a' + write) does not ensure the file ends with a newline before appending. Repair: split the glued line with json.JSONDecoder().raw_decode loop (byte-preserving halves), re-verify every line parses, atomic temp+rename, backfill board.db max-id lockstep, sync board.jsonl header. Pre-verified split recipe exists (class jsonl-torn-line-recovery) but the ROOT-CAUSE class (missing trailing newline on committed last line -> next append glues) is distinct. Hardening: appender should ensure trailing newline before append; commit hygiene should check last line ends with \\n.", "environment": "linux, duckbrain repo, JSONL-canonical foreman board", "language": "python", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "jsonl-torn-line-no-trailing-newline-append", "provider": "openrouter", "solved_at": "2026-08-27T17:08:18.002Z", "version": ""}