← back to Wallco Ai
Fix publish-gate.py prod fail-closed: use resolved image path for seam scan (not dead Mac2 local_path) + PIL resize instead of macOS-only sips for vision JPEG
89d7ad5f77dbd10bbf9dd2952c0b5ab3d98a1d44 · 2026-05-29 12:52:35 -0700 · Steve
Files touched
M scripts/publish-gate.py
Diff
commit 89d7ad5f77dbd10bbf9dd2952c0b5ab3d98a1d44
Author: Steve <steve@designerwallcoverings.com>
Date: Fri May 29 12:52:35 2026 -0700
Fix publish-gate.py prod fail-closed: use resolved image path for seam scan (not dead Mac2 local_path) + PIL resize instead of macOS-only sips for vision JPEG
---
scripts/publish-gate.py | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/scripts/publish-gate.py b/scripts/publish-gate.py
index bdd5224..cee0fca 100644
--- a/scripts/publish-gate.py
+++ b/scripts/publish-gate.py
@@ -73,10 +73,13 @@ def _resolve_image(lp, image_url):
for q in _QUAR: cands.append(str(q / iub))
for c in cands:
if c and os.path.isfile(c):
- try: return Image.open(c).convert('RGB')
+ try: return Image.open(c).convert('RGB'), c
except Exception: pass
- return None
-img = _resolve_image(lp, image_url)
+ return None, None
+# Return BOTH the PIL image AND the resolved on-disk path. The seam scan + vision
+# check below must use the resolved path, NOT the raw Mac2 `local_path` (which
+# doesn't exist on prod) — otherwise both fail-closed on every prod design.
+img, img_path = _resolve_image(lp, image_url)
if img is None:
print(json.dumps({'pass': False, 'id': ID, 'reasons': ['image file missing/unreadable']})); sys.exit(1)
W, H = img.size
@@ -87,7 +90,7 @@ if is_mural:
checks['seamless'] = True # murals don't tile
else:
try:
- r = es.scan_path(Path(lp))
+ r = es.scan_path(Path(img_path))
ok = r.get('ok') and r['edges_max'] <= 5 and r['mids_max'] <= 5
checks['seamless'] = bool(ok)
if not ok: reasons.append(f"seam ΔE edge={r.get('edges_max','?')} center={r.get('mids_max','?')} (need ≤5)")
@@ -136,7 +139,9 @@ PROMPT = (f"This is a wallpaper tile meant to be a '{subject}' design. Answer st
f"Answer with exactly 'PASS' or 'FAIL: <short reason>'.")
try:
jpg = f'/tmp/pg_{ID}.jpg'
- subprocess.run(['sips', '-Z', '512', '-s', 'format', 'jpeg', lp, '--out', jpg], capture_output=True)
+ # PIL resize (cross-platform) — the old `sips` call is macOS-only and threw
+ # FileNotFoundError on Linux/prod, making on_concept fail-closed every time.
+ _v = img.copy(); _v.thumbnail((512, 512)); _v.save(jpg, 'JPEG', quality=85)
b64 = base64.b64encode(open(jpg, 'rb').read()).decode()
body = json.dumps({"model": VMODEL, "prompt": PROMPT, "images": [b64], "stream": False,
"options": {"temperature": 0, "num_predict": 30}}).encode()
← 96e8588 fix: /api/design/:id/fix reads all_designs first (spoon fall
·
back to Wallco Ai
·
cactus-curator: auto-select 'Publish anyway' on gate-held (p 2547596 →