← back to Rejected Prompts Viewer
harden: atomic write (tmp+os.replace) in refresh.py + build-data.py so an unattended launchd kill can't truncate the data file; v1.2.2
fde4c529fc76462118255b891102c52438e77564 · 2026-08-19 12:00:52 -0700 · Steve Abrams
Files touched
M __pycache__/build-data.cpython-314.pycM __pycache__/refresh.cpython-314.pycM build-data.pyM data/rejections.jsonM package.jsonM refresh.py
Diff
commit fde4c529fc76462118255b891102c52438e77564
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Aug 19 12:00:52 2026 -0700
harden: atomic write (tmp+os.replace) in refresh.py + build-data.py so an unattended launchd kill can't truncate the data file; v1.2.2
---
__pycache__/build-data.cpython-314.pyc | Bin 4197 -> 4430 bytes
__pycache__/refresh.cpython-314.pyc | Bin 9059 -> 9179 bytes
build-data.py | 5 ++++-
data/rejections.json | 4 ++--
package.json | 2 +-
refresh.py | 5 ++++-
6 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/__pycache__/build-data.cpython-314.pyc b/__pycache__/build-data.cpython-314.pyc
index fc64563..204225d 100644
Binary files a/__pycache__/build-data.cpython-314.pyc and b/__pycache__/build-data.cpython-314.pyc differ
diff --git a/__pycache__/refresh.cpython-314.pyc b/__pycache__/refresh.cpython-314.pyc
index f7b6d08..5b13872 100644
Binary files a/__pycache__/refresh.cpython-314.pyc and b/__pycache__/refresh.cpython-314.pyc differ
diff --git a/build-data.py b/build-data.py
index 1246a92..1ba8b59 100644
--- a/build-data.py
+++ b/build-data.py
@@ -50,5 +50,8 @@ out = {
'items': items,
}
os.makedirs(os.path.join(HERE, 'data'), exist_ok=True)
-json.dump(out, open(os.path.join(HERE, 'data', 'rejections.json'), 'w'), indent=1)
+_data = os.path.join(HERE, 'data', 'rejections.json')
+with open(_data + '.tmp', 'w') as _fh: # atomic write — never leave a truncated data file
+ json.dump(out, _fh, indent=1)
+os.replace(_data + '.tmp', _data)
print(f"wrote {len(items)} items ({confirmed_count} confirmed + {len(items)-confirmed_count} borderline), scanned {scanned} transcripts -> data/rejections.json")
diff --git a/data/rejections.json b/data/rejections.json
index b599984..960ffab 100644
--- a/data/rejections.json
+++ b/data/rejections.json
@@ -1,6 +1,6 @@
{
- "generated": "2026-08-19T11:37:15.634026-07:00",
- "scanned_files": 5197,
+ "generated": "2026-08-19T12:00:36.768055-07:00",
+ "scanned_files": 5201,
"total_candidates": 86,
"confirmed_count": 15,
"items": [
diff --git a/package.json b/package.json
index 34a658d..e0bab9d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "rejected-prompts-viewer",
- "version": "1.2.1",
+ "version": "1.2.2",
"private": true,
"description": "Web viewer of prompts Claude declined on copyright/trademark/website-ToS/IP grounds, mined from Claude Code transcripts.",
"scripts": {
diff --git a/refresh.py b/refresh.py
index 01aa3a0..505cda7 100755
--- a/refresh.py
+++ b/refresh.py
@@ -87,8 +87,11 @@ def main():
'confirmed_count': sum(1 for i in items if i['confirmed']),
'items': items}
os.makedirs(os.path.dirname(DATA), exist_ok=True)
- with open(DATA, 'w') as fh:
+ # atomic write: a launchd SIGTERM/timeout mid-dump must never truncate the viewer's only data file
+ tmp = DATA + '.tmp'
+ with open(tmp, 'w') as fh:
json.dump(out, fh, indent=1)
+ os.replace(tmp, DATA)
print(f"[{out['generated']}] refresh: {len(items)} items ({out['confirmed_count']} confirmed), {new} newly classified, {time.time()-t0:.0f}s")
← 777dc1e chore: lint, refactor, v1.2.1 (session close) — with-blocks,
·
back to Rejected Prompts Viewer
·
harden: fix contrarian HOLE 1 (bare :9858 substring over-exc 2904d3f →