[object Object]

← back to Rejected Prompts Viewer

harden: fix contrarian HOLE 1 (bare :9858 substring over-excluded ~10 transcripts, recovered 4 candidates) + HOLE 3 (error-verdict now retries instead of self-cementing in cache); v1.2.3

2904d3f663e48a4dc935e4dd59b936f649609c18 · 2026-08-19 12:16:00 -0700 · Steve Abrams

Files touched

Diff

commit 2904d3f663e48a4dc935e4dd59b936f649609c18
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Aug 19 12:16:00 2026 -0700

    harden: fix contrarian HOLE 1 (bare :9858 substring over-excluded ~10 transcripts, recovered 4 candidates) + HOLE 3 (error-verdict now retries instead of self-cementing in cache); v1.2.3
---
 __pycache__/refresh.cpython-314.pyc | Bin 9179 -> 9294 bytes
 __pycache__/scan.cpython-314.pyc    | Bin 7073 -> 7071 bytes
 package.json                        |   2 +-
 refresh.py                          |   8 +++++---
 scan.py                             |   6 ++++--
 5 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/__pycache__/refresh.cpython-314.pyc b/__pycache__/refresh.cpython-314.pyc
index 5b13872..352e824 100644
Binary files a/__pycache__/refresh.cpython-314.pyc and b/__pycache__/refresh.cpython-314.pyc differ
diff --git a/__pycache__/scan.cpython-314.pyc b/__pycache__/scan.cpython-314.pyc
index cae9f94..637e8f8 100644
Binary files a/__pycache__/scan.cpython-314.pyc and b/__pycache__/scan.cpython-314.pyc differ
diff --git a/package.json b/package.json
index e0bab9d..24af2ef 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "rejected-prompts-viewer",
-  "version": "1.2.2",
+  "version": "1.2.3",
   "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 505cda7..b6fd186 100755
--- a/refresh.py
+++ b/refresh.py
@@ -65,19 +65,21 @@ def main():
     t0 = time.time()
     for c in cands:
         prev = cache.get((c.get('file'), c.get('ts')))
-        if prev:  # reuse prior verdict — no model call
-            conf, cat, rsn = prev.get('confirmed', False), prev.get('category', 'other'), prev.get('reason', '')
+        if prev and not prev.get('error'):  # reuse only GOOD prior verdicts; error verdicts retry next run
+            conf, cat, rsn, err = prev.get('confirmed', False), prev.get('category', 'other'), prev.get('reason', ''), False
         else:
+            err = False
             try:
                 v = classify(c['user'], c['refusal'])
             except Exception as e:  # noqa: BLE001 — intentional resilience; KeyboardInterrupt/SystemExit still propagate
                 print(f"[warn] classify failed for {c.get('file')} ts={c.get('ts')}: {e}", file=sys.stderr)
                 v = {"refusal": False, "category": "other", "reason": "(unclassified — model unavailable)"}
+                err = True  # flag so this item is NOT cached-reused — it re-classifies next run until the model answers
             conf, cat, rsn = bool(v.get('refusal')), v.get('category', 'other'), v.get('reason', '')
             new += 1
         items.append({'user': c['user'], 'refusal': c['refusal'], 'confirmed': conf,
                       'category': cat, 'reason': rsn, 'net': c.get('net', 'A'),  # 'A' = Net A (keyword net); 'B' = tone-only net
-                      'ts': c['ts'], 'file': c['file'],
+                      'error': err, 'ts': c['ts'], 'file': c['file'],
                       'project': basename_project.get(c.get('file', ''), '—')})
     items.sort(key=lambda x: (x['ts'] or ''), reverse=True)
 
diff --git a/scan.py b/scan.py
index a4a958a..b66cbcf 100644
--- a/scan.py
+++ b/scan.py
@@ -36,8 +36,10 @@ for f in glob.glob(os.path.join(PROJROOT, '**', '*.jsonl'), recursive=True):
     except Exception:
         continue
     # file-level exclusion: skip any transcript that is ABOUT building this tool (self-pollution)
-    if any(sig in raw for sig in ('rejected-prompts-viewer', ':9858', 'refusal_cands',
-            'refusal_classified', 'qwen3.8-27b-heretic', 'Rejected Prompts', 'borderline candidate')):
+    # specific signatures only — bare ':9858' matched token counts like ':985835' and
+    # spuriously excluded ~10 real transcripts (contrarian HOLE 1, verified 2026-08-19)
+    if any(sig in raw for sig in ('rejected-prompts-viewer', 'http://127.0.0.1:9858',
+            'rejected.agentabrams', 'refusal_cands', 'refusal_classified', 'qwen3.8-27b-heretic')):
         continue
     lines = raw.splitlines()
     prev_user = None

← fde4c52 harden: atomic write (tmp+os.replace) in refresh.py + build-  ·  back to Rejected Prompts Viewer  ·  data: refresh to 90 candidates (4 recovered from HOLE 1 fix) 1a42d25 →