fix: concurrent runs corrupt history.json, and a corrupt one stops startup - #116
Merged
Conversation
…artup Every process wrote to the same history.tmp, so parallel runs interleaved into it and the replace raced. The temp path is now unique per process. _read_json caught only OSError, so a JSONDecodeError from a damaged file propagated out of startup and stopped the tool parsing evidence. It now logs, keeps the file as .corrupt.bak, and continues. Verified with 180 concurrent writes from 6 processes: valid JSON, no leftover temp files. Levelled from iLEAPP so the five cores stay identical. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 9, 2026
Merged
Merged
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two defects in the run-history file, neither platform specific. Levelled across all five cores so they stay in step.
1. Concurrent runs corrupt history.json
_atomic_write_jsonwrites to a temp file and thenos.replaces it, which is correct on its own. But every process uses the same temp path,history.tmp. Run two parses at once and they interleave into that one file, so the document that lands inhistory.jsoncan be two documents concatenated, and whichever process replaces second fails withNo such file or directory: history.tmp.The temp path is now unique per process.
2. A corrupt history.json stops the tool parsing evidence
_read_jsoncatches onlyOSError. AJSONDecodeErrorpropagates out of startup and kills the run before any artifact executes:A damaged convenience file should never prevent evidence being parsed. It now logs, preserves the file as
.corrupt.bak, and continues with defaults.How this surfaced
Running five parses in parallel against a corpus. The history file was left holding two concatenated JSON documents, and every subsequent run then died at startup with the traceback above until the file was moved aside. A
history.json.corrupt.bakdated 27 June was already sitting next to it, so this had happened before.Verification (live, on real runs)
Six simultaneous runs against a deliberately corrupted
history.json, three rounds, each killed once past the history write. Everything relevant happens at startup, so there is no need to let parsing finish:The damaged file is preserved as
history.json.corrupt.bakrather than discarded.Levelled across the cores
Same fix in all five, byte-identical files so they do not drift: iLEAPP #1915, ALEAPP #1080, DLEAPP #60, RLEAPP #400.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com