[object Object]

← back to Crazy News Channel Shadowman

Cartoon batch: verify output file + manifest entry (not just exit 0); grant headless claude scoped edit/test tools

5aff77e27111bfa19a9b3874504bc4371ac1f4f8 · 2026-09-24 09:54:34 -0700 · Steve Abrams

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DqUe1Hvqsnrkxpe4R6jrk1

Files touched

Diff

commit 5aff77e27111bfa19a9b3874504bc4371ac1f4f8
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Sep 24 09:54:34 2026 -0700

    Cartoon batch: verify output file + manifest entry (not just exit 0); grant headless claude scoped edit/test tools
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01DqUe1Hvqsnrkxpe4R6jrk1
---
 scripts/build-cartoon-batch.sh | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/scripts/build-cartoon-batch.sh b/scripts/build-cartoon-batch.sh
index 85e9ae6..0cbdb30 100644
--- a/scripts/build-cartoon-batch.sh
+++ b/scripts/build-cartoon-batch.sh
@@ -80,10 +80,22 @@ for b in q['briefs']:
         print(f"[DRY RUN] would build: {b['id']} — {b['title']}")
         continue
     print(f"Building {b['id']} — {b['title']} ...")
-    r = subprocess.run(["claude", "-p", prompt], cwd=root, capture_output=True, text=True, timeout=1800)
-    ok = r.returncode == 0
+    tools = "Read Write Edit Glob Grep Bash(node:*) Bash(git add:*) Bash(git commit:*) Bash(git status:*) Bash(git diff:*) Bash(tk:*) Bash(/Users/macstudio3/Projects/ticket-system/tk:*)"
+    try:
+        r = subprocess.run(["claude", "-p", prompt, "--permission-mode", "acceptEdits", "--allowedTools", tools],
+                           cwd=root, capture_output=True, text=True, timeout=1800)
+        rc = r.returncode
+    except subprocess.TimeoutExpired:
+        rc = 124
+    # exit 0 is not proof: require the file on disk AND a manifest entry for it.
+    out = os.path.join(root, "cartoons", b["slug"] + ".html")
+    man = open(os.path.join(root, "cartoons", "manifest.js")).read()
+    has_file, in_manifest = os.path.isfile(out), (b["slug"] + ".html") in man
+    ok = rc == 0 and has_file and in_manifest
     with open(log, "a") as f:
-        f.write(json.dumps({"ts": ts, "id": b["id"], "title": b["title"], "exit": r.returncode, "ok": ok}) + "\n")
+        f.write(json.dumps({"ts": ts, "id": b["id"], "title": b["title"], "exit": rc,
+                            "file": has_file, "manifest": in_manifest, "ok": ok,
+                            "verdict": "PASS" if ok else "FAIL"}) + "\n")
     b['status'] = 'built' if ok else 'failed'
 json.dump(q, open(qfile, 'w'), indent=2)
 PYEOF

← 30215fc Cartoon batch: set PATH for launchd so node/claude resolve;  ·  back to Crazy News Channel Shadowman  ·  Cartoon batch: exit non-zero when any cartoon fails verifica 2d5e99e →