← back to Wallco Ai
la-toile: add palm vision-gate + tighten panel gate (negative prompt alone wasn't beating SDXL toile-palm prior; #56222 band leaked through old PANEL_Q)
b62bf3af24056c93502ed0d53cdced54fd073bed · 2026-06-02 08:55:47 -0700 · Steve Abrams
Files touched
A scripts/build-la-toile-gallery.jsM scripts/generate-la-toile-clean.js
Diff
commit b62bf3af24056c93502ed0d53cdced54fd073bed
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jun 2 08:55:47 2026 -0700
la-toile: add palm vision-gate + tighten panel gate (negative prompt alone wasn't beating SDXL toile-palm prior; #56222 band leaked through old PANEL_Q)
---
scripts/build-la-toile-gallery.js | 104 +++++++++++++++++++++++++++++++++++++
scripts/generate-la-toile-clean.js | 16 +++++-
2 files changed, 119 insertions(+), 1 deletion(-)
diff --git a/scripts/build-la-toile-gallery.js b/scripts/build-la-toile-gallery.js
new file mode 100644
index 0000000..2558fbb
--- /dev/null
+++ b/scripts/build-la-toile-gallery.js
@@ -0,0 +1,104 @@
+// Build a before/after LA Toile gallery from pass snapshots.
+// AFTER = pass-2 (first complete post-fix run, DENSITY_MAX=0.58 + palm removal + BH palette).
+// BEFORE = pass-1 (pre-fix: TONE_ON_TONE monochrome + palms + over-tight density).
+const fs = require('fs');
+
+const SCENES = [
+ 'Hollywood Sign + Griffith Observatory domes',
+ 'Venice Beach boardwalk, pier, surf',
+ 'Downtown LA skyline + City Hall',
+ 'Jacaranda-lined Sunset Boulevard',
+ 'Beverly Hills Spanish-revival bungalows',
+ 'Santa Monica Pier Ferris wheel',
+ 'Chinatown paifang gate + lanterns',
+ 'Echo Park Lake paddle boats + lotus',
+ 'Mid-century Case Study glass houses',
+ '1960s convertibles on Mulholland Drive',
+ 'Watts Towers mosaic spires',
+ 'LA Aqueduct cascade + San Gabriels',
+ 'Olvera Street market stalls',
+ 'Griffith Park oak trails + mule deer',
+ 'Malibu coastline + surfers + lighthouse',
+ 'Art-Deco movie palaces + marquees',
+ 'Old-LA citrus groves + packing sheds',
+ 'Union Station + streamliner train',
+ 'Golden-age studio backlot',
+ 'Pasadena Rose Parade floats',
+ 'Angels Flight funicular railway',
+ 'La Brea Tar Pits + mammoths',
+ 'Bradbury Building atrium stairs',
+ 'Mulholland overlook + coyote at dusk',
+ 'Silver Lake reservoir + modernist homes',
+ 'Original Farmers Market clock tower',
+ 'Topanga Canyon cabins + oaks',
+ 'Googie LAX Theme Building arches',
+ 'Dodger Stadium grandstands',
+ 'Jacaranda residential streets in bloom',
+];
+
+const before = JSON.parse(fs.readFileSync('/tmp/la-toile-pass-1.json', 'utf8'));
+const after = JSON.parse(fs.readFileSync('/tmp/la-toile-pass-2.json', 'utf8'));
+const BASE = 'http://127.0.0.1:9905/designs/img/by-id/';
+
+const rows = SCENES.map((label, i) => {
+ const slug = 'la-toile-' + String(i + 1).padStart(2, '0');
+ return { slug, label, before: before[slug] || null, after: after[slug] || null };
+}).filter(r => r.after); // show scenes that have a post-fix winner
+
+const cells = rows.map(r => `
+ <div class="card">
+ <div class="lbl"><b>${r.slug}</b> · ${r.label}</div>
+ <div class="pair">
+ <figure>
+ <div class="tag tag-b">BEFORE · pre-fix</div>
+ ${r.before
+ ? `<a href="${BASE}${r.before}" target="_blank"><img loading="lazy" src="${BASE}${r.before}"></a><figcaption>#${r.before} · monochrome / palmy / sparse</figcaption>`
+ : `<div class="missing">no pre-fix winner<br>(scene failed gates in pass 1)</div>`}
+ </figure>
+ <figure>
+ <div class="tag tag-a">AFTER · fixed</div>
+ <a href="${BASE}${r.after}" target="_blank"><img loading="lazy" src="${BASE}${r.after}"></a>
+ <figcaption>#${r.after} · BH multi-color · palm-free · density 0.58</figcaption>
+ </figure>
+ </div>
+ </div>`).join('\n');
+
+const html = `<!doctype html><html><head><meta charset="utf-8">
+<title>LA Toile de Jouy — before / after (pass 2, post-fix)</title>
+<style>
+ :root{--ink:#1a1713;--line:#e2dcd0;--bg:#f6f2ea}
+ *{box-sizing:border-box}
+ body{margin:0;background:var(--bg);color:var(--ink);font:15px/1.5 -apple-system,Georgia,serif;padding:28px 32px}
+ h1{font:600 26px/1.2 Georgia,serif;margin:0 0 4px}
+ .sub{color:#6b6357;margin:0 0 24px;font-size:14px}
+ .sub b{color:var(--ink)}
+ .grid{display:grid;grid-template-columns:1fr;gap:22px;max-width:1180px}
+ .card{background:#fff;border:1px solid var(--line);border-radius:12px;padding:14px 16px;box-shadow:0 1px 3px rgba(0,0,0,.04)}
+ .lbl{font-size:14px;margin-bottom:10px;color:#3a342b}
+ .lbl b{font-size:13px;letter-spacing:.02em;color:#8a7f6c;font-variant:all-small-caps}
+ .pair{display:grid;grid-template-columns:1fr 1fr;gap:14px}
+ figure{margin:0;position:relative}
+ img{width:100%;aspect-ratio:1/1;object-fit:cover;border-radius:8px;display:block;background:#eee}
+ .missing{width:100%;aspect-ratio:1/1;border-radius:8px;display:flex;align-items:center;justify-content:center;text-align:center;color:#a99;background:#faf6f3;border:1px dashed #e2c9c9;font-size:13px}
+ figcaption{font-size:12px;color:#6b6357;margin-top:6px}
+ .tag{position:absolute;top:8px;left:8px;font:600 10px/1 -apple-system;letter-spacing:.06em;padding:5px 8px;border-radius:5px;z-index:2;color:#fff}
+ .tag-b{background:#9a6b63}.tag-a{background:#3f6b4e}
+ .legend{display:flex;gap:18px;margin-bottom:20px;font-size:13px;flex-wrap:wrap}
+ .legend span{display:inline-flex;align-items:center;gap:6px}
+ .dot{width:10px;height:10px;border-radius:3px;display:inline-block}
+</style></head><body>
+<h1>LA Toile de Jouy — before / after</h1>
+<p class="sub">Pass 2 (first complete post-fix run) vs pass 1 (pre-fix). Fixes: <b>BH multi-color palette wins</b> (removed conflicting tone-on-tone monochrome suffix) · <b>palms removed</b> from positive prompt · <b>density 0.52→0.58</b>. ${rows.length} scenes with a post-fix winner.</p>
+<div class="legend">
+ <span><i class="dot" style="background:#9a6b63"></i> BEFORE — pale monochrome, palms everywhere, over-rejected breathing room</span>
+ <span><i class="dot" style="background:#3f6b4e"></i> AFTER — full BH colorway, no palms, classic toile density</span>
+</div>
+<div class="grid">
+${cells}
+</div>
+</body></html>`;
+
+fs.writeFileSync('/tmp/la-toile-gallery-after.html', html);
+console.log('wrote /tmp/la-toile-gallery-after.html — ' + rows.length + ' scenes (' +
+ rows.filter(r => r.before).length + ' with before/after pair, ' +
+ rows.filter(r => !r.before).length + ' after-only)');
diff --git a/scripts/generate-la-toile-clean.js b/scripts/generate-la-toile-clean.js
index 3511663..de24f4c 100644
--- a/scripts/generate-la-toile-clean.js
+++ b/scripts/generate-la-toile-clean.js
@@ -33,6 +33,16 @@ const CONCEPT_Q = process.env.CONCEPT_Q ||
// This gate now blocks ONLY Part-B elements; that is the sole settlement guard, so keep it strict.
const SETTLEMENT_Q = process.env.SETTLEMENT_Q ||
"Does this image contain any bird, butterfly, banana, banana plant or leaf, or bunch of grapes? Answer yes only if one of those is clearly visible.";
+// Anti-panel gate (Steve 2026-06-02) — reject blocky abstract blocks, register-band
+// rows, and horizontal-bar/shelf artifacts; keep only continuous all-over scenes.
+const PANEL_Q = process.env.PANEL_Q ||
+ "Look for a horizontal strip, bar, or band running across the image that is noticeably emptier (mostly blank ground color) than the scenery above and below it, OR a flat rectangular block/panel of solid color, OR a collage of separate boxed-off panes. Answer yes if ANY such empty band, blank block, or boxed panel is present — even a single horizontal empty strip cutting across counts. Answer no only if the illustrated scene reads as continuous edge to edge with no empty band slicing through it.";
+// Anti-palm gate (Steve 2026-06-02) — the prompt depicts LA's cypress/oak/jacaranda/
+// olive/eucalyptus, NEVER palms. Negative conditioning alone doesn't beat SDXL's
+// strong toile-palm prior, so reject any roll showing palms at the gate (this is an
+// AESTHETIC gate, separate from SETTLEMENT_Q which treats a lone palm as non-violation).
+const PALM_Q = process.env.PALM_Q ||
+ "Does this image contain any palm tree, palm frond, or palm-like tree with a tall bare trunk topped by a fan or feather of fronds (date palm, fan palm, coconut palm, or any palm silhouette)? Answer yes if any palm is visible anywhere in the scene, even a small one in the background.";
// Beverly Hills style-guide colorways (see ~/Projects/dw-style-guides/index.html).
// Each toile is MONOCHROME single-ink (settlement A3=false → bulletproof). The ink
@@ -159,8 +169,12 @@ function evalRoll(id) {
// MANDATORY settlement Part-B gate: any bird/butterfly/banana/grape => violation => reject.
const partB = visionAsk(lp, SETTLEMENT_Q);
if (partB === 'yes') return { aesthetic: false, om: null, why: 'SETTLEMENT: part-B element present' };
+ const panels = visionAsk(lp, PANEL_Q);
+ if (panels === 'yes') return { aesthetic: false, om: null, why: 'panels/bands (not continuous)' };
+ const palms = visionAsk(lp, PALM_Q);
+ if (palms === 'yes') return { aesthetic: false, om: null, why: 'palm tree present (LA toile uses cypress/oak, not palms)' };
const om = seamOf(id);
- return { aesthetic: true, om, why: `colors ${major} concept yes settlement OK seam ${om}` };
+ return { aesthetic: true, om, why: `colors ${major} concept yes settlement OK panels no palms no seam ${om}` };
}
// Heal the seam boxes of a concept-clean roll → new healed id + post-heal seam.
function healSeam(id) {
← 7b073e5 pilot-build-tifs.py: --all batch mode (published ids, disk g
·
back to Wallco Ai
·
hires: cache TIF-lookup HITS only, never misses bc1d6d8 →