← 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
M YOLO_BACKLOG.mdA data/mural-batch-monterey.jsonA scripts/curate-monterey-batch.py
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 →