[object Object]

← back to Wallco Ai

gen-luxe: add --variant=<A|B|C|D|E> flag to lock heritage aesthetic

a9b73c7c8b38af508da6ee2a140e570341735e1a · 2026-05-25 01:01:18 -0700 · Steve Abrams

Composition gate stops cycling once any variant passes — so a "PASS" on
variant A (de Gournay/Zuber chinoiserie) never gives us a shot at
variant C (1838 flocked velvet) for the same source, even when Steve
wanted to see the heritage-flock direction explicitly. The --variant
flag locks to a single aesthetic and tries it up to 3 times, useful for
A/B/C comparisons on the same source.

Verified on frog #41554:
  C (1838 flocked velvet on navy silk Britton Midnight): clean 6-motif
    damask, emerald-flock silhouettes in laurel wreaths, no cartoon
    features possible — heritage standard.
  D (Cole & Son Whimsical on beige grasscloth): engraved naturalist
    energy, frogs with bottles among red wildflowers — better than A but
    has a visible horizontal seam where the ground tone shifts mid-tile.

Files touched

Diff

commit a9b73c7c8b38af508da6ee2a140e570341735e1a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon May 25 01:01:18 2026 -0700

    gen-luxe: add --variant=<A|B|C|D|E> flag to lock heritage aesthetic
    
    Composition gate stops cycling once any variant passes — so a "PASS" on
    variant A (de Gournay/Zuber chinoiserie) never gives us a shot at
    variant C (1838 flocked velvet) for the same source, even when Steve
    wanted to see the heritage-flock direction explicitly. The --variant
    flag locks to a single aesthetic and tries it up to 3 times, useful for
    A/B/C comparisons on the same source.
    
    Verified on frog #41554:
      C (1838 flocked velvet on navy silk Britton Midnight): clean 6-motif
        damask, emerald-flock silhouettes in laurel wreaths, no cartoon
        features possible — heritage standard.
      D (Cole & Son Whimsical on beige grasscloth): engraved naturalist
        energy, frogs with bottles among red wildflowers — better than A but
        has a visible horizontal seam where the ground tone shifts mid-tile.
---
 scripts/gen-luxe.js | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/scripts/gen-luxe.js b/scripts/gen-luxe.js
index ebef9f4..e022588 100644
--- a/scripts/gen-luxe.js
+++ b/scripts/gen-luxe.js
@@ -25,8 +25,12 @@ const { gateComposition } = require('../lib/composition-detector');
 const SRC_ID = parseInt(process.argv[2], 10);
 const MOTIF = process.argv[3];
 const TEXTURE_CAT = (process.argv.find(a => a.startsWith('--texture-cat=')) || '').split('=')[1] || '';
+// --variant=<A|B|C|D|E> forces a specific heritage-house aesthetic and
+// disables cycling — useful when you've already seen A pass and want to
+// compare against C (1838 flock) or D (Cole & Son) directly.
+const VARIANT = ((process.argv.find(a => a.startsWith('--variant=')) || '').split('=')[1] || '').toUpperCase();
 if (!Number.isFinite(SRC_ID) || !MOTIF) {
-  console.error('usage: <src_id> "<motif>" [--texture-cat=<grasscloth|linen|cork|silk|mica|...>]');
+  console.error('usage: <src_id> "<motif>" [--texture-cat=<grasscloth|linen|cork|silk|mica|...>] [--variant=<A|B|C|D|E>]');
   process.exit(2);
 }
 
@@ -151,10 +155,16 @@ function pickTextureBrief(category) {
   else              console.log(`[gen-luxe] ground texture: generic (PG pick returned nothing)`);
 
   let candidate = null, gate = null, attempt = 0;
-  const MAX = 5;
+  // If --variant=X is specified, lock to that variant and try it 3 times.
+  // Otherwise cycle A→B→C→D→E with one shot each.
+  const VARIANT_IDX = { A: 0, B: 1, C: 2, D: 3, E: 4 };
+  const startAttempt = VARIANT in VARIANT_IDX ? VARIANT_IDX[VARIANT] : 0;
+  const MAX = VARIANT ? 3 : 5;
   while (attempt < MAX) {
-    const prompt = buildLuxePrompt(MOTIF, attempt, textureBrief);
-    console.log(`\n[gen-luxe] attempt ${attempt} (variant ${'ABCDE'[attempt%5]})`);
+    // When locked to a variant, pass startAttempt every time (no cycling).
+    const variantIdx = VARIANT ? startAttempt : (startAttempt + attempt);
+    const prompt = buildLuxePrompt(MOTIF, variantIdx, textureBrief);
+    console.log(`\n[gen-luxe] attempt ${attempt} (variant ${'ABCDE'[variantIdx%5]}${VARIANT ? ' — LOCKED' : ''})`);
     const t0 = Date.now();
     const b64 = await geminiImage(prompt);
     console.log(`  gen: ${((Date.now()-t0)/1000).toFixed(1)}s`);
@@ -166,7 +176,7 @@ function pickTextureBrief(category) {
   }
   if (!candidate) {
     console.log(`[gen-luxe] gate failed all ${MAX}, accepting last`);
-    candidate = await geminiImage(buildLuxePrompt(MOTIF, MAX-1, textureBrief));
+    candidate = await geminiImage(buildLuxePrompt(MOTIF, VARIANT ? VARIANT_IDX[VARIANT] : MAX-1, textureBrief));
   }
 
   const newSeed = require('crypto').randomInt(1, 2 ** 31 - 1);

← 5d5b7c0 fix(edges-scan): move scanner from ~/.claude/skills into pro  ·  back to Wallco Ai  ·  design page: 3 admin accordions into admin sheet + ADMIN but 4399240 →