[object Object]

← back to Pattern Vault

pattern-vault: generate + settlement post-gen-vision 8 trend briefs (16 variants, curator-mode is_published=FALSE)

1a983940dc25090c5cc5735dc4e175ca9db0fe4a · 2026-07-02 12:00:16 -0700 · Steve Abrams

Files touched

Diff

commit 1a983940dc25090c5cc5735dc4e175ca9db0fe4a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Jul 2 12:00:16 2026 -0700

    pattern-vault: generate + settlement post-gen-vision 8 trend briefs (16 variants, curator-mode is_published=FALSE)
---
 assets/generated/_gen_manifest.json   | 134 +++++++++++++++++++
 assets/generated/_postgen_vision.json | 242 ++++++++++++++++++++++++++++++++++
 scripts/gen_briefs.py                 | 100 ++++++++++++++
 scripts/postgen_vision.py             |  64 +++++++++
 4 files changed, 540 insertions(+)

diff --git a/assets/generated/_gen_manifest.json b/assets/generated/_gen_manifest.json
new file mode 100644
index 0000000..7a0a685
--- /dev/null
+++ b/assets/generated/_gen_manifest.json
@@ -0,0 +1,134 @@
+{
+  "results": [
+    {
+      "tag": "BRIEF-2026-animalprint-01_v1",
+      "brief": "BRIEF-2026-animalprint-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-animalprint-01_v1.png",
+      "status": "ok",
+      "predict_time": 4.290665836,
+      "prompt": "Original seamless repeat of stylised cheetah-rosette markings, hand-painted look, scattered on a warm plaster ground; skin-print abstraction only, no animal figures; rose-clay and cocoa spots on oatmeal. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Rose-clay + cocoa on oatmeal."
+    },
+    {
+      "tag": "BRIEF-2026-animalprint-01_v2",
+      "brief": "BRIEF-2026-animalprint-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-animalprint-01_v2.png",
+      "status": "ok",
+      "predict_time": 4.111578628,
+      "prompt": "Original seamless repeat of stylised cheetah-rosette markings, hand-painted look, scattered on a warm plaster ground; skin-print abstraction only, no animal figures; rose-clay and cocoa spots on oatmeal. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Rose-clay + cocoa on oatmeal."
+    },
+    {
+      "tag": "BRIEF-2026-animalprint-02_v1",
+      "brief": "BRIEF-2026-animalprint-02",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-animalprint-02_v1.png",
+      "status": "ok",
+      "predict_time": 4.028140011,
+      "prompt": "Original painterly tiger-stripe skin-print abstraction (no animal figure) in forest and moss green on deep ink; brushy irregular hand-inked stripes reading as luxe textile. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Forest + moss on ink."
+    },
+    {
+      "tag": "BRIEF-2026-animalprint-02_v2",
+      "brief": "BRIEF-2026-animalprint-02",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-animalprint-02_v2.png",
+      "status": "ok",
+      "predict_time": 4.099763555,
+      "prompt": "Original painterly tiger-stripe skin-print abstraction (no animal figure) in forest and moss green on deep ink; brushy irregular hand-inked stripes reading as luxe textile. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Forest + moss on ink."
+    },
+    {
+      "tag": "BRIEF-2026-chinoiserie-sat-01_v1",
+      "brief": "BRIEF-2026-chinoiserie-sat-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-chinoiserie-sat-01_v1.png",
+      "status": "ok",
+      "predict_time": 4.039093406,
+      "prompt": "Original hand-painted-look chinoiserie of flowering branches, peonies and boughs on deep forest-green ground; gold + blush blooms. STRICTLY branches + flowers, NO birds, NO butterflies. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Gold + blush on forest green."
+    },
+    {
+      "tag": "BRIEF-2026-chinoiserie-sat-01_v2",
+      "brief": "BRIEF-2026-chinoiserie-sat-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-chinoiserie-sat-01_v2.png",
+      "status": "ok",
+      "predict_time": 4.030046462,
+      "prompt": "Original hand-painted-look chinoiserie of flowering branches, peonies and boughs on deep forest-green ground; gold + blush blooms. STRICTLY branches + flowers, NO birds, NO butterflies. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Gold + blush on forest green."
+    },
+    {
+      "tag": "BRIEF-2026-deco-01_v1",
+      "brief": "BRIEF-2026-deco-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-deco-01_v1.png",
+      "status": "ok",
+      "predict_time": 4.023890921,
+      "prompt": "Original Art-Deco geometric of repeating fan/sunburst arcs and stepped chevrons, metallic-gold linework on chartreuse ground; 1920s revival, crisp symmetry. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Metallic gold on chartreuse."
+    },
+    {
+      "tag": "BRIEF-2026-deco-01_v2",
+      "brief": "BRIEF-2026-deco-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-deco-01_v2.png",
+      "status": "ok",
+      "predict_time": 4.569517361,
+      "prompt": "Original Art-Deco geometric of repeating fan/sunburst arcs and stepped chevrons, metallic-gold linework on chartreuse ground; 1920s revival, crisp symmetry. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Metallic gold on chartreuse."
+    },
+    {
+      "tag": "BRIEF-2026-texture-01_v1",
+      "brief": "BRIEF-2026-texture-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-texture-01_v1.png",
+      "status": "ok",
+      "predict_time": 4.03807989,
+      "prompt": "Original photoreal woven linen/grasscloth texture as seamless near-plain wallcovering; visible warp/weft slubs; warm greige; illusion-of-tactility. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Warm greige linen."
+    },
+    {
+      "tag": "BRIEF-2026-texture-01_v2",
+      "brief": "BRIEF-2026-texture-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-texture-01_v2.png",
+      "status": "ok",
+      "predict_time": 4.063258845,
+      "prompt": "Original photoreal woven linen/grasscloth texture as seamless near-plain wallcovering; visible warp/weft slubs; warm greige; illusion-of-tactility. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Warm greige linen."
+    },
+    {
+      "tag": "BRIEF-2026-ditsy-01_v1",
+      "brief": "BRIEF-2026-ditsy-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-ditsy-01_v1.png",
+      "status": "ok",
+      "predict_time": 4.158441162,
+      "prompt": "Original tiny-scale ditsy floral micro-print, hand-drawn sprigs and dots evenly scattered on open cream ground; sized for small rooms; multiple colorways. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Sage + terracotta sprigs on bone."
+    },
+    {
+      "tag": "BRIEF-2026-ditsy-01_v2",
+      "brief": "BRIEF-2026-ditsy-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-ditsy-01_v2.png",
+      "status": "ok",
+      "predict_time": 4.386027514,
+      "prompt": "Original tiny-scale ditsy floral micro-print, hand-drawn sprigs and dots evenly scattered on open cream ground; sized for small rooms; multiple colorways. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Sage + terracotta sprigs on bone."
+    },
+    {
+      "tag": "BRIEF-2026-mural-01_v1",
+      "brief": "BRIEF-2026-mural-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-mural-01_v1.png",
+      "status": "ok",
+      "predict_time": 4.143222057,
+      "prompt": "Original full-wall painterly botanical garden panorama - layered ferns, hydrangea, foliage receding into mist on deep teal-green ground; fine-art scenery, single colorway. NO birds. fine-art wall mural panorama, painterly, cohesive scene. Colorway: Deep teal-green garden."
+    },
+    {
+      "tag": "BRIEF-2026-mural-01_v2",
+      "brief": "BRIEF-2026-mural-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-mural-01_v2.png",
+      "status": "ok",
+      "predict_time": 4.131720161,
+      "prompt": "Original full-wall painterly botanical garden panorama - layered ferns, hydrangea, foliage receding into mist on deep teal-green ground; fine-art scenery, single colorway. NO birds. fine-art wall mural panorama, painterly, cohesive scene. Colorway: Deep teal-green garden."
+    },
+    {
+      "tag": "BRIEF-2026-toile-01_v1",
+      "brief": "BRIEF-2026-toile-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-toile-01_v1.png",
+      "status": "ok",
+      "predict_time": 4.056281671,
+      "prompt": "Original toile-de-jouy pastoral scene - hand-engraved-look vignettes of meadow, trees, cottages and figures in a single-color line engraving on cream; classic toile rhythm. NO birds. Offer in oxblood, forest-green, and navy colorways. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Oxblood line on cream."
+    },
+    {
+      "tag": "BRIEF-2026-toile-01_v2",
+      "brief": "BRIEF-2026-toile-01",
+      "path": "/Users/stevestudio2/Projects/pattern-vault/assets/generated/BRIEF-2026-toile-01_v2.png",
+      "status": "ok",
+      "predict_time": 4.320639584,
+      "prompt": "Original toile-de-jouy pastoral scene - hand-engraved-look vignettes of meadow, trees, cottages and figures in a single-color line engraving on cream; classic toile rhythm. NO birds. Offer in oxblood, forest-green, and navy colorways. seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering. Colorway: Oxblood line on cream."
+    }
+  ],
+  "total_predict_secs": 66.490367064,
+  "est_cost_usd": 0.0482
+}
\ No newline at end of file
diff --git a/assets/generated/_postgen_vision.json b/assets/generated/_postgen_vision.json
new file mode 100644
index 0000000..ea6b084
--- /dev/null
+++ b/assets/generated/_postgen_vision.json
@@ -0,0 +1,242 @@
+[
+  {
+    "file": "BRIEF-2026-animalprint-01_v1.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": false,
+      "open_space": true,
+      "multiple_ink_colors": false,
+      "describe": "Leopard pattern with black spots on beige background"
+    }
+  },
+  {
+    "file": "BRIEF-2026-animalprint-01_v2.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": false,
+      "multiple_ink_colors": false,
+      "describe": "Black dots on a pink background, varying directions"
+    }
+  },
+  {
+    "file": "BRIEF-2026-animalprint-02_v1.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": false,
+      "multiple_ink_colors": true,
+      "describe": "Repeating green and white wavy lines forming a camouflage pattern."
+    }
+  },
+  {
+    "file": "BRIEF-2026-animalprint-02_v2.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": false,
+      "multiple_ink_colors": true,
+      "describe": "Abstract pattern of vertical lines with varying shades and directions."
+    }
+  },
+  {
+    "file": "BRIEF-2026-chinoiserie-sat-01_v1.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": false,
+      "multiple_ink_colors": true,
+      "describe": "Floral pattern with pink and white flowers, gold leaves on dark background."
+    }
+  },
+  {
+    "file": "BRIEF-2026-chinoiserie-sat-01_v2.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": false,
+      "multiple_ink_colors": true,
+      "describe": "Repeating floral pattern with pink flowers and green leaves on dark background."
+    }
+  },
+  {
+    "file": "BRIEF-2026-deco-01_v1.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": false,
+      "multiple_ink_colors": false,
+      "describe": "Repeating golden palm frond pattern on black background."
+    }
+  },
+  {
+    "file": "BRIEF-2026-deco-01_v2.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": false,
+      "multiple_ink_colors": false,
+      "describe": "Repeating geometric leaf-like motifs in gold on black background."
+    }
+  },
+  {
+    "file": "BRIEF-2026-ditsy-01_v1.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": false,
+      "multiple_ink_colors": true,
+      "describe": "Speckled pattern with various colored dots on a light background."
+    }
+  },
+  {
+    "file": "BRIEF-2026-ditsy-01_v2.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": false,
+      "multiple_ink_colors": true,
+      "describe": "Repeating pattern of orange and green dots on a white background."
+    }
+  },
+  {
+    "file": "BRIEF-2026-mural-01_v1.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": false,
+      "multiple_ink_colors": true,
+      "describe": "Fern-like foliage in varying shades of teal and gray, creating a textured forest effect."
+    }
+  },
+  {
+    "file": "BRIEF-2026-mural-01_v2.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": false,
+      "multiple_ink_colors": true,
+      "describe": "Forest trees with varying shades of green, directional foliage"
+    }
+  },
+  {
+    "file": "BRIEF-2026-texture-01_v1.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": false,
+      "open_space": false,
+      "multiple_ink_colors": false,
+      "describe": "Uniform beige textured fabric with subtle linear pattern"
+    }
+  },
+  {
+    "file": "BRIEF-2026-texture-01_v2.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": false,
+      "multiple_ink_colors": false,
+      "describe": "Vertical lines forming a textured, striped pattern."
+    }
+  },
+  {
+    "file": "BRIEF-2026-toile-01_v1.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": true,
+      "multiple_ink_colors": false,
+      "describe": "Rural landscape with house, trees, animals, and distant hills."
+    }
+  },
+  {
+    "file": "BRIEF-2026-toile-01_v2.png",
+    "verdict": "PASS",
+    "why": "no Part B prohibited element",
+    "vision": {
+      "birds": false,
+      "butterflies": false,
+      "bananas": false,
+      "grapes": false,
+      "foliage_directional": true,
+      "open_space": true,
+      "multiple_ink_colors": false,
+      "describe": "Rural landscape with house, trees, river, and people."
+    }
+  }
+]
\ No newline at end of file
diff --git a/scripts/gen_briefs.py b/scripts/gen_briefs.py
new file mode 100644
index 0000000..805f9a6
--- /dev/null
+++ b/scripts/gen_briefs.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python3
+"""Generate settlement-cleared brief variants via Replicate SDXL. Curator-mode, $0-local-first fallback."""
+import os, re, json, time, sys, urllib.request, urllib.error
+
+ROOT = "/Users/stevestudio2/Projects/pattern-vault"
+OUT = f"{ROOT}/assets/generated"
+os.makedirs(OUT, exist_ok=True)
+
+# token
+tok = None
+for p in [os.path.expanduser("~/Projects/secrets-manager/.env")]:
+    with open(p) as f:
+        m = re.search(r"REPLICATE_API_TOKEN=([A-Za-z0-9_-]+)", f.read())
+        if m: tok = m.group(1)
+assert tok, "no replicate token"
+
+briefs = json.load(open(f"{ROOT}/data/trend-board.json"))["briefs"]
+
+NEG = ("birds, bird, butterfly, butterflies, bananas, banana leaves, grapes, grape clusters, "
+       "tropical monstera palm fronds, text, watermark, signature, logo, blurry, low quality, "
+       "jpeg artifacts, seams, mismatched edges, frame, border, vignette")
+
+def sdxl_prompt(b):
+    base = b["prompt"]
+    if b["id"] == "BRIEF-2026-mural-01":
+        tile = "fine-art wall mural panorama, painterly, cohesive scene"
+        w, h = 1216, 832
+    else:
+        tile = "seamless repeating wallpaper pattern, tileable, flat lay, even lighting, high-end wallcovering"
+        w, h = 1024, 1024
+    return f"{base} {tile}. Colorway: {b['colorway']}.", w, h
+
+UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
+def post(url, payload, extra_headers=None):
+    hdr = {"Authorization": f"Bearer {tok}", "Content-Type": "application/json", "User-Agent": UA}
+    if extra_headers: hdr.update(extra_headers)
+    req = urllib.request.Request(url, data=json.dumps(payload).encode(), headers=hdr, method="POST")
+    with urllib.request.urlopen(req, timeout=120) as r:
+        return json.load(r)
+
+def get(url):
+    req = urllib.request.Request(url, headers={"Authorization": f"Bearer {tok}", "User-Agent": UA})
+    with urllib.request.urlopen(req, timeout=60) as r:
+        return json.load(r)
+
+MODEL = "stability-ai/sdxl"
+VERSION = get(f"https://api.replicate.com/v1/models/{MODEL}")["latest_version"]["id"]
+print(f"using {MODEL}@{VERSION[:12]}", flush=True)
+results = []
+total_secs = 0.0
+seeds = [101, 202]  # 2 variants/brief
+
+for b in briefs:
+    prompt, w, h = sdxl_prompt(b)
+    for i, seed in enumerate(seeds, 1):
+        tag = f"{b['id']}_v{i}"
+        payload = {"version": VERSION, "input": {
+            "prompt": prompt, "negative_prompt": NEG,
+            "width": w, "height": h, "num_inference_steps": 30,
+            "guidance_scale": 7.5, "seed": seed, "refine": "no_refiner"
+        }}
+        ok = False
+        for attempt in range(4):
+            try:
+                pred = post("https://api.replicate.com/v1/predictions", payload); ok = True; break
+            except urllib.error.HTTPError as e:
+                body = e.read().decode()[:150]
+                if e.code == 429:
+                    print(f"[{tag}] 429 throttled, backoff {6*(attempt+1)}s", flush=True)
+                    time.sleep(6*(attempt+1)); continue
+                print(f"[{tag}] HTTP {e.code}: {body}", flush=True); break
+        if not ok:
+            results.append({"tag": tag, "status": "error"}); continue
+        # poll if not done
+        for _ in range(60):
+            if pred.get("status") in ("succeeded", "failed", "canceled"): break
+            time.sleep(2); pred = get(pred["urls"]["get"])
+        st = pred.get("status")
+        secs = (pred.get("metrics") or {}).get("predict_time", 0) or 0
+        total_secs += secs
+        if st == "succeeded":
+            out = pred["output"]
+            imgurl = out[0] if isinstance(out, list) else out
+            dest = f"{OUT}/{tag}.png"
+            urllib.request.urlretrieve(imgurl, dest)
+            sz = os.path.getsize(dest)
+            print(f"[{tag}] OK {secs:.1f}s -> {dest} ({sz//1024}KB)", flush=True)
+            results.append({"tag": tag, "brief": b["id"], "path": dest, "status": "ok",
+                            "predict_time": secs, "prompt": prompt})
+        else:
+            print(f"[{tag}] {st}: {pred.get('error')}", flush=True)
+            results.append({"tag": tag, "brief": b["id"], "status": st})
+        time.sleep(1.5)
+
+# Replicate SDXL on A40 ~ $0.000725/sec (Nvidia A40 Large). Report both.
+RATE = 0.000725
+cost = total_secs * RATE
+print(f"\n=== TOTAL predict_time {total_secs:.1f}s  est cost ${cost:.4f} (rate ${RATE}/s A40) ===", flush=True)
+json.dump({"results": results, "total_predict_secs": total_secs, "est_cost_usd": round(cost,4)},
+          open(f"{OUT}/_gen_manifest.json", "w"), indent=2)
diff --git a/scripts/postgen_vision.py b/scripts/postgen_vision.py
new file mode 100644
index 0000000..be1f6da
--- /dev/null
+++ b/scripts/postgen_vision.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+"""settlement-post-gen-vision equivalent, run on LOCAL ollama vision ($0).
+Re-checks each produced image for Part B prohibited elements (birds/butterflies/
+bananas/grapes) + Part A signals, then applies the settlement verdict.
+BLOCK requires full Part A (directional foliage + open space + >1 ink color) AND a Part B element."""
+import os, io, json, base64, urllib.request, glob
+from PIL import Image
+
+OUT = "/Users/stevestudio2/Projects/pattern-vault/assets/generated"
+OLLAMA = "http://127.0.0.1:11434/api/generate"
+MODEL = "qwen2.5vl:7b"
+
+Q = ("You are a strict wallpaper-pattern compliance inspector. Look ONLY at what is literally "
+     "drawn in this image. Answer STRICT JSON, no prose:\n"
+     '{"birds": <true/false: any bird or bird silhouette present>,'
+     '"butterflies": <true/false: any butterfly or moth>,'
+     '"bananas": <true/false: banana fruit or banana leaves>,'
+     '"grapes": <true/false: grape clusters>,'
+     '"foliage_directional": <true/false: repeating leaves/fronds pointing in varied directions>,'
+     '"open_space": <true/false: visible empty background between motifs>,'
+     '"multiple_ink_colors": <true/false: foliage/motifs use more than one color>,'
+     '"describe": "<=12 words what the pattern actually shows"}')
+
+def jpeg_b64(path):
+    im = Image.open(path).convert("RGB")
+    im.thumbnail((768, 768))
+    b = io.BytesIO(); im.save(b, "JPEG", quality=88)
+    return base64.b64encode(b.getvalue()).decode()
+
+def ask(path):
+    payload = {"model": MODEL, "prompt": Q, "images": [jpeg_b64(path)],
+               "stream": False, "format": "json", "options": {"temperature": 0}}
+    req = urllib.request.Request(OLLAMA, data=json.dumps(payload).encode(),
+                                 headers={"Content-Type": "application/json"})
+    with urllib.request.urlopen(req, timeout=180) as r:
+        resp = json.load(r)["response"]
+    return json.loads(resp)
+
+def verdict(d):
+    partB = any([d.get("birds"), d.get("butterflies"), d.get("bananas"), d.get("grapes")])
+    partA = all([d.get("foliage_directional"), d.get("open_space"), d.get("multiple_ink_colors")])
+    # Settlement binding: violation requires FULL Part A AND a Part B element.
+    if partB and partA:
+        return "BLOCK", "full Part A + Part B prohibited element"
+    if partB:
+        # Part B element present but Part A not fully satisfied -> not a violation, but flag for review.
+        return "NEEDS-REVIEW", "Part B element present without full Part A (manual check)"
+    return "PASS", "no Part B prohibited element"
+
+rows = []
+for p in sorted(glob.glob(f"{OUT}/BRIEF-*.png")):
+    try:
+        d = ask(p)
+    except Exception as e:
+        rows.append({"file": os.path.basename(p), "verdict": "ERROR", "err": str(e)[:80]});
+        print(f"{os.path.basename(p)}: ERROR {e}", flush=True); continue
+    v, why = verdict(d)
+    rows.append({"file": os.path.basename(p), "verdict": v, "why": why, "vision": d})
+    flags = [k for k in ("birds","butterflies","bananas","grapes") if d.get(k)]
+    print(f"{os.path.basename(p)}: {v}  partB={flags or 'none'}  | {d.get('describe','')}", flush=True)
+
+json.dump(rows, open(f"{OUT}/_postgen_vision.json", "w"), indent=2)
+n_pass = sum(1 for r in rows if r["verdict"] == "PASS")
+print(f"\n=== {n_pass}/{len(rows)} PASS  (model={MODEL}, $0 local) ===")

← 9ecb329 Spoonflower: 14 Fernwick Studio originals uploaded to fernwi  ·  back to Pattern Vault  ·  gap-brief generation: 16 settlement-PASS originals staged + 8d1ba79 →