[object Object]

← back to Wallco Ai

mural-batch: curate-monterey-batch.py → 12 hue-spread published Monterey manifest [yolo Q3, local-only, read-only DB]

52b7c2fc73a1a004cd21ab64a97500cf647d4eeb · 2026-06-03 08:51:08 -0700 · Steve Abrams

Read-only selector picks N published Monterey scenes spread across the hue wheel
(visual range, not 12 near-identical colorways) → data/mural-batch-monterey.json
with the ready-to-run batch + estimate commands. No DB writes, no spend. The
paid 12x11ft batch is now one command away on Steve's go.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 52b7c2fc73a1a004cd21ab64a97500cf647d4eeb
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Jun 3 08:51:08 2026 -0700

    mural-batch: curate-monterey-batch.py → 12 hue-spread published Monterey manifest [yolo Q3, local-only, read-only DB]
    
    Read-only selector picks N published Monterey scenes spread across the hue wheel
    (visual range, not 12 near-identical colorways) → data/mural-batch-monterey.json
    with the ready-to-run batch + estimate commands. No DB writes, no spend. The
    paid 12x11ft batch is now one command away on Steve's go.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 YOLO_BACKLOG.md                  |   2 +
 data/mural-batch-monterey.json   |  93 ++++++++++++++++++++++++++++++++++++
 scripts/curate-monterey-batch.py | 100 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 195 insertions(+)

diff --git a/YOLO_BACKLOG.md b/YOLO_BACKLOG.md
index ded79a8..2317045 100644
--- a/YOLO_BACKLOG.md
+++ b/YOLO_BACKLOG.md
@@ -133,3 +133,5 @@ $ per mural + the low-res demotion is customer-facing; both await Steve's go.
 
 ## Ledger
 - (ticks appended below)
+- T1 · 2026-06-03 ~08:1x · Q2 build-mural-master --estimate (no-spend cost est) · done · d43631e · CNCP win-2026-06-03-wallco-ai-9
+- T2 · 2026-06-03 ~08:2x · Q3 curate-monterey-batch.py → 12 hue-spread published Monterey → data/mural-batch-monterey.json · done (read-only DB) · CNCP pending
diff --git a/data/mural-batch-monterey.json b/data/mural-batch-monterey.json
new file mode 100644
index 0000000..030e56f
--- /dev/null
+++ b/data/mural-batch-monterey.json
@@ -0,0 +1,93 @@
+{
+  "category": "monterey-mural",
+  "n": 12,
+  "spec": {
+    "print_ft": 12,
+    "height_ft": 11,
+    "bleed_in": 6,
+    "panels": [
+      24,
+      36,
+      54
+    ]
+  },
+  "selection": "hue-spread across published Monterey (visual range)",
+  "ids": [
+    27151,
+    14681,
+    21079,
+    21976,
+    14136,
+    20213,
+    14450,
+    12635,
+    16204,
+    11308,
+    31169,
+    12599
+  ],
+  "items": [
+    {
+      "id": 27151,
+      "dominant_hex": "#38241d",
+      "local_path": "/Users/stevestudio2/Projects/wallco-ai/data/generated/1779292386636_1863399989.png"
+    },
+    {
+      "id": 14681,
+      "dominant_hex": "#442e1e",
+      "local_path": "/Users/stevestudio2/Projects/wallco-ai/data/generated/1779273166085_2012825945.png"
+    },
+    {
+      "id": 21079,
+      "dominant_hex": "#bb8f5a",
+      "local_path": "/Users/stevestudio2/Projects/wallco-ai/data/generated/1779279719211_1211482687.png"
+    },
+    {
+      "id": 21976,
+      "dominant_hex": "#3c362b",
+      "local_path": "/Users/stevestudio2/Projects/wallco-ai/data/generated/1779280649902_1263199119.png"
+    },
+    {
+      "id": 14136,
+      "dominant_hex": "#e6dab8",
+      "local_path": "/Users/stevestudio2/Projects/wallco-ai/data/generated/1779272608611_79122496.png"
+    },
+    {
+      "id": 20213,
+      "dominant_hex": "#a9a78a",
+      "local_path": "/Users/stevestudio2/Projects/wallco-ai/data/generated/1779278839653_957644793.png"
+    },
+    {
+      "id": 14450,
+      "dominant_hex": "#d4dbbc",
+      "local_path": "/Users/stevestudio2/Projects/wallco-ai/data/generated/1779272933057_483747888.png"
+    },
+    {
+      "id": 12635,
+      "dominant_hex": "#708074",
+      "local_path": "/Users/stevestudio2/Projects/wallco-ai/data/generated/1779271030559_1146357644.png"
+    },
+    {
+      "id": 16204,
+      "dominant_hex": "#136c7c",
+      "local_path": "/Users/stevestudio2/Projects/wallco-ai/data/generated/1779274725819_878426997.png"
+    },
+    {
+      "id": 11308,
+      "dominant_hex": "#959389",
+      "local_path": "/Users/stevestudio2/Projects/wallco-ai/data/generated/1779269704427_406092530.png"
+    },
+    {
+      "id": 31169,
+      "dominant_hex": "#323533",
+      "local_path": "/Users/stevestudio2/Projects/wallco-ai/data/generated/1779296617990_1000052140.png"
+    },
+    {
+      "id": 12599,
+      "dominant_hex": "#2a2521",
+      "local_path": "/Users/stevestudio2/Projects/wallco-ai/data/generated/1779270987318_1919163578.png"
+    }
+  ],
+  "batch_command": "for id in 27151 14681 21079 21976 14136 20213 14450 12635 16204 11308 31169 12599; do python3 scripts/build-mural-master.py $id; done",
+  "estimate_command": "python3 scripts/build-mural-master.py --estimate 12"
+}
\ No newline at end of file
diff --git a/scripts/curate-monterey-batch.py b/scripts/curate-monterey-batch.py
new file mode 100644
index 0000000..6045d0b
--- /dev/null
+++ b/scripts/curate-monterey-batch.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python3
+"""
+curate-monterey-batch.py — READ-ONLY selector for the first hi-res Monterey
+mural batch. Picks N published Monterey scenes spread across the hue wheel (so
+the launch line has visual range, not 12 near-identical colorways) and writes a
+manifest the operator feeds to build-mural-master.py.
+
+NO writes to the DB, NO spend. Just a SELECT + a JSON manifest.
+
+Usage:
+  python3 scripts/curate-monterey-batch.py            # top 12 → data/mural-batch-monterey.json
+  python3 scripts/curate-monterey-batch.py --n 25
+"""
+import argparse
+import importlib.util
+import json
+from pathlib import Path
+
+from psycopg2.extras import RealDictCursor
+
+ROOT = Path(__file__).resolve().parents[1]
+_spec = importlib.util.spec_from_file_location("buildtif", str(ROOT / "scripts" / "build-tif.py"))
+_bt = importlib.util.module_from_spec(_spec); _spec.loader.exec_module(_bt)
+
+
+def hue(hexstr):
+    import colorsys
+    s = (hexstr or "").lstrip("#")
+    if len(s) != 6:
+        return -1.0
+    try:
+        r, g, b = (int(s[i:i+2], 16) / 255 for i in (0, 2, 4))
+    except ValueError:
+        return -1.0
+    mx, mn = max(r, g, b), min(r, g, b)
+    if mx - mn < 0.06:
+        return 1000 + (1 - mx)        # greys → end, light→dark
+    return colorsys.rgb_to_hls(r, g, b)[0] * 360
+
+
+def main():
+    ap = argparse.ArgumentParser()
+    ap.add_argument("--n", type=int, default=12)
+    ap.add_argument("--out", default=str(ROOT / "data" / "mural-batch-monterey.json"))
+    a = ap.parse_args()
+
+    conn = _bt.db()
+    with conn.cursor(cursor_factory=RealDictCursor) as cur:
+        cur.execute("""
+            SELECT id, dominant_hex, local_path
+              FROM all_designs
+             WHERE category ILIKE 'monterey%' AND is_published
+               AND local_path IS NOT NULL
+             ORDER BY id DESC
+        """)
+        rows = [r for r in cur.fetchall() if Path(r["local_path"]).exists()]
+    conn.close()
+
+    # Spread across the hue wheel: bucket into N hue slots, take the newest
+    # (already id-DESC) per slot, then fill any short slots from the remainder.
+    rows.sort(key=lambda r: hue(r["dominant_hex"]))
+    picks, seen = [], set()
+    if rows:
+        step = max(1, len(rows) // a.n)
+        for i in range(0, len(rows), step):
+            if len(picks) >= a.n:
+                break
+            r = rows[i]
+            if r["id"] not in seen:
+                picks.append(r); seen.add(r["id"])
+        for r in rows:                      # backfill if buckets came up short
+            if len(picks) >= a.n:
+                break
+            if r["id"] not in seen:
+                picks.append(r); seen.add(r["id"])
+
+    manifest = {
+        "category": "monterey-mural",
+        "n": len(picks),
+        "spec": {"print_ft": 12, "height_ft": 11, "bleed_in": 6, "panels": [24, 36, 54]},
+        "selection": "hue-spread across published Monterey (visual range)",
+        "ids": [p["id"] for p in picks],
+        "items": [{"id": p["id"], "dominant_hex": p["dominant_hex"],
+                   "local_path": p["local_path"]} for p in picks],
+        "batch_command": "for id in " + " ".join(str(p["id"]) for p in picks) +
+                         "; do python3 scripts/build-mural-master.py $id; done",
+        "estimate_command": f"python3 scripts/build-mural-master.py --estimate {len(picks)}",
+    }
+    Path(a.out).write_text(json.dumps(manifest, indent=2))
+    print(f"curated {len(picks)} Monterey murals (hue-spread) → {a.out}")
+    for p in picks:
+        print(f"  #{p['id']:6}  {p['dominant_hex']}")
+    print(f"\nbatch is ready — review then run:\n  {manifest['estimate_command']}\n"
+          f"  {manifest['batch_command']}")
+    return 0
+
+
+if __name__ == "__main__":
+    import sys
+    sys.exit(main())

← 2be769b loop tick1: fleet compliance sweep — 0 settlement-block live  ·  back to Wallco Ai  ·  refresh_designs_snapshot: admit all gemini-%image% generator f7b76dd →