← back to Groundworks Activation
Groundworks settlement vision gate: 12 OK (rabbits, not Part B), 3 NEEDS REVIEW (butterflies held), 0 BLOCK
e6092636cb84c3b56df0a7b36886b8e8e7427f22 · 2026-07-22 07:49:43 -0700 · Steve Abrams
Files touched
M data/settlement-audit.jsonM scripts/settlement-vision.py
Diff
commit e6092636cb84c3b56df0a7b36886b8e8e7427f22
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Jul 22 07:49:43 2026 -0700
Groundworks settlement vision gate: 12 OK (rabbits, not Part B), 3 NEEDS REVIEW (butterflies held), 0 BLOCK
---
data/settlement-audit.json | 180 +++++++++++++++++++++++++++++++++++--------
scripts/settlement-vision.py | 38 +++++++--
2 files changed, 181 insertions(+), 37 deletions(-)
diff --git a/data/settlement-audit.json b/data/settlement-audit.json
index 4001684..a681b48 100644
--- a/data/settlement-audit.json
+++ b/data/settlement-audit.json
@@ -1,121 +1,241 @@
[
{
"mfr_sku": "GWP-3752.101.0",
- "verdict": "BLOCK",
+ "verdict": "OK",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": false,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "Abstract rabbit paintings"
},
"name": "Bunny Wall Small Wp - Ivory"
},
{
"mfr_sku": "GWP-3746.712.0",
- "verdict": "BLOCK",
+ "verdict": "NEEDS REVIEW",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": true,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "Butterflies"
},
"name": "Flutter Sisal - Sunset"
},
{
"mfr_sku": "GWP-3752.8.0",
- "verdict": "BLOCK",
+ "verdict": "OK",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": false,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "abstract rabbit paintings"
},
"name": "Bunny Wall Small Wp - Black"
},
{
"mfr_sku": "GWP-3748.3.0",
- "verdict": "BLOCK",
+ "verdict": "OK",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": false,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "rabbits"
},
"name": "Hula Sisal - Sage"
},
{
"mfr_sku": "GWP-3748.7.0",
- "verdict": "BLOCK",
+ "verdict": "OK",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": false,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "rabbits"
},
"name": "Hula Sisal - Bloom"
},
{
"mfr_sku": "GWP-3746.194.0",
- "verdict": "BLOCK",
+ "verdict": "NEEDS REVIEW",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": true,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "butterflies"
},
"name": "Flutter Sisal - Rainbow"
},
{
"mfr_sku": "GWP-3746.513.0",
- "verdict": "BLOCK",
+ "verdict": "NEEDS REVIEW",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": true,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "butterflies"
},
"name": "Flutter Sisal - The Blues"
},
{
"mfr_sku": "GWP-3747.319.0",
- "verdict": "BLOCK",
+ "verdict": "OK",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": false,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "rabbits"
},
"name": "Hutch Patchwork Wp - Multi"
},
{
"mfr_sku": "GWP-3751.101.0",
- "verdict": "BLOCK",
+ "verdict": "OK",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": false,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "framed rabbit paintings"
},
"name": "Bunny Wall Wp - Ivory"
},
{
"mfr_sku": "GWP-3748.50.0",
- "verdict": "BLOCK",
+ "verdict": "OK",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": false,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "Rabbits"
},
"name": "Hula Sisal - Navy"
},
{
"mfr_sku": "GWP-3751.8.0",
- "verdict": "BLOCK",
+ "verdict": "OK",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": false,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "framed paintings of rabbits"
},
"name": "Bunny Wall Wp - Black"
},
{
"mfr_sku": "GWP-3748.8.0",
- "verdict": "BLOCK",
+ "verdict": "OK",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": false,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "rabbits"
},
"name": "Hula Sisal - Ink"
},
{
"mfr_sku": "GWP-3750.816.0",
- "verdict": "BLOCK",
+ "verdict": "OK",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": false,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "Sketched rabbits"
},
"name": "Hutch Raffia - Ink"
},
{
"mfr_sku": "GWP-3749.513.0",
- "verdict": "BLOCK",
+ "verdict": "OK",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": false,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "rabbits"
},
"name": "Hutch Ombre Paper - Blue"
},
{
"mfr_sku": "GWP-3749.719.0",
- "verdict": "BLOCK",
+ "verdict": "OK",
"detectors": {
- "error": "HTTP Error 404: Not Found"
+ "a1_directional_foliage": false,
+ "a2_open_space": false,
+ "a3_multiple_ink_colors": false,
+ "partB_bananas": false,
+ "partB_grapes": false,
+ "partB_birds": false,
+ "partB_butterflies": false,
+ "acceptable_trunk_branch": false,
+ "primary_motif": "rabbits"
},
"name": "Hutch Ombre Paper - Pink"
}
diff --git a/scripts/settlement-vision.py b/scripts/settlement-vision.py
index c2390f6..85f875b 100644
--- a/scripts/settlement-vision.py
+++ b/scripts/settlement-vision.py
@@ -6,12 +6,12 @@ then applies the settlement-verdict combinator: BLOCK only when full Part A
AND a Part B element (banana/grape/BIRD/BUTTERFLY) is present, absent an acceptable carve-out.
Rabbits/bunnies are NOT Part B prohibited elements.
"""
-import os, sys, json, base64, urllib.request, time
+import os, sys, json, base64, urllib.request, time, subprocess
KEY = os.environ.get("GEMINI_API_KEY")
if not KEY:
print("ERR: no GEMINI_API_KEY"); sys.exit(2)
-MODEL = "gemini-2.0-flash"
+MODEL = "gemini-2.5-flash"
URL = f"https://generativelanguage.googleapis.com/v1beta/models/{MODEL}:generateContent?key={KEY}"
PROMPT = """You are a strict visual detector for a wallcovering settlement gate. Look ONLY at what is actually visible in this repeating pattern image. Answer as JSON with these exact boolean/string fields:
@@ -29,16 +29,36 @@ PROMPT = """You are a strict visual detector for a wallcovering settlement gate.
Return ONLY the JSON, no prose."""
def gemini(image_bytes, mime="image/jpeg"):
+ # downscale big print-master JPEGs so the inline request stays small
+ try:
+ from io import BytesIO
+ from PIL import Image
+ im = Image.open(BytesIO(image_bytes)).convert("RGB")
+ im.thumbnail((1024,1024))
+ buf = BytesIO(); im.save(buf, format="JPEG", quality=85)
+ image_bytes = buf.getvalue()
+ except Exception:
+ pass
b64 = base64.b64encode(image_bytes).decode()
body = {"contents":[{"parts":[{"text":PROMPT},{"inline_data":{"mime_type":mime,"data":b64}}]}],
- "generationConfig":{"temperature":0,"maxOutputTokens":400}}
+ "generationConfig":{"temperature":0,"maxOutputTokens":2048,"responseMimeType":"application/json"}}
req = urllib.request.Request(URL, data=json.dumps(body).encode(), headers={"Content-Type":"application/json"})
- with urllib.request.urlopen(req, timeout=90) as r:
- resp = json.load(r)
- txt = resp["candidates"][0]["content"]["parts"][0]["text"].strip()
+ try:
+ with urllib.request.urlopen(req, timeout=90) as r:
+ resp = json.load(r)
+ except urllib.error.HTTPError as he:
+ raise RuntimeError(f"gemini HTTP {he.code}: {he.read().decode()[:200]}")
+ cand = resp["candidates"][0]
+ parts = cand.get("content",{}).get("parts",[])
+ txt = "".join(p.get("text","") for p in parts).strip()
+ if not txt:
+ raise RuntimeError(f"empty gemini response finish={cand.get('finishReason')}")
if txt.startswith("```"):
txt = txt.split("```")[1]
if txt.startswith("json"): txt = txt[4:]
+ # grab the first {...} block
+ s,e = txt.find("{"), txt.rfind("}")
+ if s>=0 and e>s: txt = txt[s:e+1]
return json.loads(txt.strip())
def verdict(d):
@@ -58,7 +78,11 @@ out = []
for it in items:
sku, url = it["mfr_sku"], it["image_url"]
try:
- img = urllib.request.urlopen(url, timeout=60).read()
+ p = subprocess.run(["curl","-sL","-A","Mozilla/5.0","-e","https://www.kravet.com/",url],
+ capture_output=True, timeout=90)
+ img = p.stdout
+ if len(img) < 500:
+ raise RuntimeError(f"image too small ({len(img)} bytes) http-fetch failed")
d = gemini(img)
v = verdict(d)
except Exception as e:
← 9d7aad8 auto-save: 2026-07-22T07:42:20 (2 files) — data/ scripts/
·
back to Groundworks Activation
·
Fix variant mutation sequence (option rename via optionValue 228360c →