← back to Wallco Ai
revert luxe-c blanket rollout + add curator-mode 4-up picker
45dcfb753c664666b83f3c82fd3f26a72af26c75 · 2026-05-25 01:31:35 -0700 · Steve Abrams
WHAT WENT WRONG:
roll-luxe-c.js ran to completion (261/263 succeeded, $10.44 burned)
before I noticed Steve flagging quality on the gallery. Variant C
(1838 flocked velvet) collapsed beautiful painterly tropical roots
(giraffe-in-orange-flowers, frog-with-butterflies, macaw-in-orchids)
into monotonous 2-color silhouette damasks — some lost the subject
entirely (parrots → bottles). Single elephant sample I previewed
before kicking off was a poor proxy: simple iconic motifs translate
to flocked silhouette, painterly multi-element comps don't.
REVERT:
SQL transaction re-published 791 originals + unpublished all 261
luxe-v2 rows (kept in DB for forensics). Old ledger archived to
data/luxe-c-rollout.REVERTED-2026-05-25.jsonl. /designs back to
pre-rollout state.
NEW CURATOR PATH (DTD vote: option 3 — 3-variant hot-or-not):
- gen-luxe.js: --curator-mode lands variants as is_published=FALSE
without touching source. Lets the picker decide publish state per row.
- scripts/queue-luxe-curator.js: for each unluxed root in <category>,
fan out 3 variants in parallel — A (de Gournay chinoiserie/raffia),
C (1838 flocked velvet/silk), E (Brunschwig archive/grasscloth).
Ground choice is canonical-per-house, not arbitrary rotation.
Idempotent against roots that already have luxe children.
- /api/luxe-curator: groups queue rows by root, hides decided ones
via the new luxe_curator_choices table.
- /api/luxe-curator/pick: records the choice (A/C/E/NONE). On a
variant pick: publishes that luxe + unpublishes all non-luxe
descendants of root. On NONE: leaves publish state alone (root
stays). Idempotent on root_id via ON CONFLICT.
- public/luxe-curator.html: 4-up rows (root | A | C | E), click any
variant to pick or "keep root" to reject all. Keyboard nav (1=root,
2/3/4=variants, K=keep root, J/K=next/prev row).
SANITY BATCH: 3 untouched drunk-animals roots queued ($0.36, 25.8s).
3 panda + 3 peacock + 3 giraffe variants live for Steve to test the
picker UX before scaling to the remaining 45 untouched roots.
KEY LESSON CODIFIED: validation-loop applies to bulk transformations
too. "Sample 1 worked" is not "all 263 will work" — heterogeneous
inputs need a heterogeneous sanity batch (or a human picker) before
any bulk publish.
Files touched
A data/luxe-c-rollout.REVERTED-2026-05-25.jsonlA public/luxe-curator.htmlM scripts/gen-luxe.jsA scripts/queue-luxe-curator.js
Diff
commit 45dcfb753c664666b83f3c82fd3f26a72af26c75
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon May 25 01:31:35 2026 -0700
revert luxe-c blanket rollout + add curator-mode 4-up picker
WHAT WENT WRONG:
roll-luxe-c.js ran to completion (261/263 succeeded, $10.44 burned)
before I noticed Steve flagging quality on the gallery. Variant C
(1838 flocked velvet) collapsed beautiful painterly tropical roots
(giraffe-in-orange-flowers, frog-with-butterflies, macaw-in-orchids)
into monotonous 2-color silhouette damasks — some lost the subject
entirely (parrots → bottles). Single elephant sample I previewed
before kicking off was a poor proxy: simple iconic motifs translate
to flocked silhouette, painterly multi-element comps don't.
REVERT:
SQL transaction re-published 791 originals + unpublished all 261
luxe-v2 rows (kept in DB for forensics). Old ledger archived to
data/luxe-c-rollout.REVERTED-2026-05-25.jsonl. /designs back to
pre-rollout state.
NEW CURATOR PATH (DTD vote: option 3 — 3-variant hot-or-not):
- gen-luxe.js: --curator-mode lands variants as is_published=FALSE
without touching source. Lets the picker decide publish state per row.
- scripts/queue-luxe-curator.js: for each unluxed root in <category>,
fan out 3 variants in parallel — A (de Gournay chinoiserie/raffia),
C (1838 flocked velvet/silk), E (Brunschwig archive/grasscloth).
Ground choice is canonical-per-house, not arbitrary rotation.
Idempotent against roots that already have luxe children.
- /api/luxe-curator: groups queue rows by root, hides decided ones
via the new luxe_curator_choices table.
- /api/luxe-curator/pick: records the choice (A/C/E/NONE). On a
variant pick: publishes that luxe + unpublishes all non-luxe
descendants of root. On NONE: leaves publish state alone (root
stays). Idempotent on root_id via ON CONFLICT.
- public/luxe-curator.html: 4-up rows (root | A | C | E), click any
variant to pick or "keep root" to reject all. Keyboard nav (1=root,
2/3/4=variants, K=keep root, J/K=next/prev row).
SANITY BATCH: 3 untouched drunk-animals roots queued ($0.36, 25.8s).
3 panda + 3 peacock + 3 giraffe variants live for Steve to test the
picker UX before scaling to the remaining 45 untouched roots.
KEY LESSON CODIFIED: validation-loop applies to bulk transformations
too. "Sample 1 worked" is not "all 263 will work" — heterogeneous
inputs need a heterogeneous sanity batch (or a human picker) before
any bulk publish.
---
data/luxe-c-rollout.REVERTED-2026-05-25.jsonl | 263 ++++++++++++++++++++++++++
public/luxe-curator.html | 240 +++++++++++++++++++++++
scripts/gen-luxe.js | 17 +-
scripts/queue-luxe-curator.js | 186 ++++++++++++++++++
4 files changed, 700 insertions(+), 6 deletions(-)
diff --git a/data/luxe-c-rollout.REVERTED-2026-05-25.jsonl b/data/luxe-c-rollout.REVERTED-2026-05-25.jsonl
new file mode 100644
index 0000000..925adae
--- /dev/null
+++ b/data/luxe-c-rollout.REVERTED-2026-05-25.jsonl
@@ -0,0 +1,263 @@
+{"ts":"2026-05-25T08:09:04.472Z","worker":1,"idx":1,"total":263,"root_id":10354,"ground":"raffia","motif":"wobbly pink champagne elephant, mid-toast with a champagne flute, golden bubbles spilling, head tilted, set among sun-bleached field of sunflowers, golden disc faces packed edge-to-edge, palette: tiff","ok":true,"new_id":41563,"duration_ms":8352,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:05.960Z","worker":2,"idx":2,"total":263,"root_id":10417,"ground":"grasscloth","motif":"sloshed scarlet macaw, clutching a long-stemmed red wine glass, deep burgundy sloshing over the rim, set among cascading wisteria racemes, mauve and lilac, climbing trellis behind, palette: baroque je","ok":true,"new_id":41564,"duration_ms":9837,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:06.452Z","worker":3,"idx":3,"total":263,"root_id":15399,"ground":"raffia","motif":"starry-eyed sloth holding a wine glass, cradling an emerald-green beer bottle, foam crowning the lip, content sigh, set among Lady's Slipper Orchid (Cypripedium), translucent pouches of pink and ivory","ok":true,"new_id":41565,"duration_ms":10329,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:06.920Z","worker":4,"idx":4,"total":263,"root_id":16576,"ground":"cork","motif":"sloshed scarlet macaw, two paws on a hand-blown wine bottle, burgundy splashing onto a flower, set among Passion Flower (Passiflora incarnata), filament-haloed indigo discs, palette: parakeet kelly gr","ok":true,"new_id":41566,"duration_ms":10796,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:12.919Z","worker":1,"idx":5,"total":263,"root_id":17024,"ground":"raffia","motif":"inebriated lemur swinging from a vine, cradling an emerald-green beer bottle, foam crowning the lip, content sigh, set among meadow of California poppies and lupine, deep orange and indigo, palette: D","ok":true,"new_id":41567,"duration_ms":8428,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:14.739Z","worker":3,"idx":7,"total":263,"root_id":28991,"ground":"cork","motif":"starry-eyed sloth holding a wine glass, martini glass in mid-spin, two olives skewered, vodka splashing, set among Passion Flower (Passiflora incarnata), filament-haloed indigo discs, palette: neon co","ok":true,"new_id":41568,"duration_ms":8270,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:14.985Z","worker":2,"idx":6,"total":263,"root_id":23401,"ground":"cork","motif":"pink-cheeked drunken bullfrog, gripping a pale-gold pilsner glass in one paw, amber bottle in the other, set among Passion Flower (Passiflora incarnata), filament-haloed indigo discs, palette: Warhol ","ok":true,"new_id":41569,"duration_ms":9007,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:15.806Z","worker":4,"idx":8,"total":263,"root_id":35679,"ground":"raffia","motif":"sloshed scarlet macaw, mug of pilsner the size of its head, foam dripping down its chin, set among Naked Man Orchid (Orchis italica), pink figurine-shaped blooms in spike, palette: neon coral + spearm","ok":true,"new_id":41570,"duration_ms":8869,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:21.654Z","worker":1,"idx":9,"total":263,"root_id":36234,"ground":"raffia","motif":"long-lashed Maasai giraffe sipping a daiquiri, holding a frosted clear vodka bottle aloft, condensation beads, cheeks flushed, set among Parrot Tulips, frilled edges in flame red, viridian, and aprico","ok":true,"new_id":41571,"duration_ms":8718,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:23.506Z","worker":3,"idx":10,"total":263,"root_id":36837,"ground":"grasscloth","motif":"plastered red panda, mid-pour from a cobalt-blue vodka bottle into a shot glass, eyes crossed, set among crimson bougainvillea spilling over a stucco wall, papery bracts, palette: rosso red #bc0030 + ","ok":true,"new_id":41572,"duration_ms":8750,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:24.955Z","worker":2,"idx":11,"total":263,"root_id":37049,"ground":"raffia","motif":"shaggy orange orangutan clutching a banana cocktail, cradling a deep-purple velvet-bag whiskey decanter, label edge peeking, set among Ghost Orchid (Dendrophylax lindenii) suspended midair, white peta","ok":true,"new_id":41573,"duration_ms":9954,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:25.379Z","worker":4,"idx":12,"total":263,"root_id":37280,"ground":"silk","motif":"tipsy emerald glass frog, champagne magnum bottle wedged under one arm, flute in the other paw, set among magenta hibiscus, hot-pink dahlias, fuchsia peonies — saturated cottage garden, palette: vinta","ok":true,"new_id":41574,"duration_ms":9557,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:29.964Z","worker":1,"idx":13,"total":263,"root_id":37761,"ground":"cork","motif":"pink-cheeked drunken bullfrog, holding a frosted clear vodka bottle aloft, condensation beads, cheeks flushed, set among Foxglove (Digitalis purpurea) spires, freckled magenta throats, palette: campbe","ok":true,"new_id":41575,"duration_ms":8293,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:32.187Z","worker":3,"idx":14,"total":263,"root_id":37961,"ground":"cork","motif":"inebriated lemur swinging from a vine, clutching a long-stemmed red wine glass, deep burgundy sloshing over the rim, set among Beehive Ginger (Zingiber spectabile), torch-shaped scarlet cones, palette","ok":true,"new_id":41576,"duration_ms":8667,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:32.932Z","worker":2,"idx":15,"total":263,"root_id":37975,"ground":"silk","motif":"jolly grey African elephant calf, long-neck amber beer bottle on its head like a hat, grin lopsided, set among Indian Paintbrush wildflower (Castilleja), vermillion bracts in a prairie, palette: shock","ok":true,"new_id":41577,"duration_ms":7959,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:33.973Z","worker":4,"idx":16,"total":263,"root_id":37987,"ground":"grasscloth","motif":"sleepy Bornean orangutan slumped against a fern, frosted vodka decanter etched with silhouettes, cradled to its chest, set among meadow of California poppies and lupine, deep orange and indigo, palett","ok":true,"new_id":41578,"duration_ms":8580,"unpublished_descendants":226}
+{"ts":"2026-05-25T08:09:38.866Z","worker":1,"idx":17,"total":263,"root_id":38001,"ground":"cork","motif":"plastered red panda, cradling an emerald-green beer bottle, foam crowning the lip, content sigh, set among Bleeding Heart (Lamprocapnos), strings of rose-pink hearts dangling, palette: silkscreen hot ","ok":true,"new_id":41579,"duration_ms":8886,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:40.656Z","worker":3,"idx":18,"total":263,"root_id":38219,"ground":"raffia","motif":"tipsy emerald glass frog, mid-pour from a cobalt-blue vodka bottle into a shot glass, eyes crossed, set among magenta hibiscus, hot-pink dahlias, fuchsia peonies — saturated cottage garden, palette: d","ok":true,"new_id":41580,"duration_ms":8453,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:41.632Z","worker":2,"idx":19,"total":263,"root_id":38220,"ground":"silk","motif":"auto-variation hue+60 of design #38219","ok":true,"new_id":41581,"duration_ms":8685,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:42.661Z","worker":4,"idx":20,"total":263,"root_id":38221,"ground":"cork","motif":"auto-variation hue+120 of design #38219","ok":true,"new_id":41582,"duration_ms":8666,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:47.988Z","worker":1,"idx":21,"total":263,"root_id":38318,"ground":"linen","motif":"jolly grey African elephant calf, two paws on a hand-blown wine bottle, burgundy splashing onto a flower, set among Black Bat Flower (Tacca chantrieri), inky violet with cascading whiskers, palette: M","ok":true,"new_id":41583,"duration_ms":9106,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:49.293Z","worker":3,"idx":22,"total":263,"root_id":38355,"ground":"silk","motif":"tipsy capybara holding a mint julep, clutching a long-stemmed red wine glass, deep burgundy sloshing over the rim, set among Indian Paintbrush wildflower (Castilleja), vermillion bracts in a prairie, ","ok":true,"new_id":41584,"duration_ms":8623,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:50.600Z","worker":2,"idx":23,"total":263,"root_id":38358,"ground":"linen","motif":"sleepy Bornean orangutan slumped against a fern, sipping from a coupe glass of rosé, eyes half-closed, pink liquid sloshing, set among Black Bat Flower (Tacca chantrieri), inky violet with cascading w","ok":true,"new_id":41585,"duration_ms":8953,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:53.261Z","worker":4,"idx":24,"total":263,"root_id":38403,"ground":"linen","motif":"starry-eyed sloth holding a wine glass, long-neck amber beer bottle on its head like a hat, grin lopsided, set among crimson bougainvillea spilling over a stucco wall, papery bracts, palette: saddle-l","ok":true,"new_id":41586,"duration_ms":10584,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:56.490Z","worker":1,"idx":25,"total":263,"root_id":38405,"ground":"silk","motif":"auto-variation hue-60 of design #38403","ok":true,"new_id":41587,"duration_ms":8487,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:57.486Z","worker":3,"idx":26,"total":263,"root_id":38406,"ground":"cork","motif":"auto-variation hue+60 of design #38404","ok":true,"new_id":41588,"duration_ms":8177,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:09:59.650Z","worker":2,"idx":27,"total":263,"root_id":38407,"ground":"grasscloth","motif":"auto-variation mono of design #38403","ok":true,"new_id":41589,"duration_ms":9034,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:02.832Z","worker":4,"idx":28,"total":263,"root_id":38408,"ground":"linen","motif":"auto-variation hue+120 of design #38404","ok":true,"new_id":41590,"duration_ms":9554,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:04.676Z","worker":1,"idx":29,"total":263,"root_id":38409,"ground":"raffia","motif":"auto-variation hue+180 of design #38404","ok":true,"new_id":41591,"duration_ms":8169,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:06.664Z","worker":3,"idx":30,"total":263,"root_id":38410,"ground":"silk","motif":"auto-variation hue-60 of design #38404","ok":true,"new_id":41592,"duration_ms":9164,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:08.274Z","worker":2,"idx":31,"total":263,"root_id":38411,"ground":"cork","motif":"auto-variation mono of design #38404","ok":true,"new_id":41593,"duration_ms":8608,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:11.846Z","worker":4,"idx":32,"total":263,"root_id":38412,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38411","ok":true,"new_id":41594,"duration_ms":8998,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:14.088Z","worker":1,"idx":33,"total":263,"root_id":38413,"ground":"linen","motif":"auto-variation hue+120 of design #38411","ok":true,"new_id":41595,"duration_ms":9397,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:15.252Z","worker":3,"idx":34,"total":263,"root_id":38414,"ground":"raffia","motif":"auto-variation hue+180 of design #38411","ok":true,"new_id":41596,"duration_ms":8571,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:17.195Z","worker":2,"idx":35,"total":263,"root_id":38415,"ground":"silk","motif":"auto-variation hue-60 of design #38411","ok":true,"new_id":41597,"duration_ms":8905,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:20.205Z","worker":4,"idx":36,"total":263,"root_id":38416,"ground":"cork","motif":"auto-variation mono of design #38411","ok":true,"new_id":41598,"duration_ms":8344,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:22.660Z","worker":1,"idx":37,"total":263,"root_id":38417,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38416","ok":true,"new_id":41599,"duration_ms":8556,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:23.884Z","worker":3,"idx":38,"total":263,"root_id":38418,"ground":"linen","motif":"auto-variation hue+120 of design #38416","ok":true,"new_id":41600,"duration_ms":8616,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:25.529Z","worker":2,"idx":39,"total":263,"root_id":38419,"ground":"raffia","motif":"auto-variation hue+180 of design #38416","ok":true,"new_id":41601,"duration_ms":8320,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:29.894Z","worker":4,"idx":40,"total":263,"root_id":38420,"ground":"silk","motif":"auto-variation hue-60 of design #38416","ok":true,"new_id":41602,"duration_ms":9675,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:31.452Z","worker":1,"idx":41,"total":263,"root_id":38421,"ground":"cork","motif":"auto-variation mono of design #38416","ok":true,"new_id":41603,"duration_ms":8776,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:33.295Z","worker":3,"idx":42,"total":263,"root_id":38422,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38421","ok":true,"new_id":41604,"duration_ms":9396,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:34.811Z","worker":2,"idx":43,"total":263,"root_id":38423,"ground":"linen","motif":"auto-variation hue+120 of design #38421","ok":true,"new_id":41605,"duration_ms":9265,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:38.376Z","worker":4,"idx":44,"total":263,"root_id":38424,"ground":"raffia","motif":"auto-variation hue+180 of design #38421","ok":true,"new_id":41606,"duration_ms":8465,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:39.420Z","worker":1,"idx":45,"total":263,"root_id":38425,"ground":"silk","motif":"auto-variation hue-60 of design #38421","ok":true,"new_id":41607,"duration_ms":7952,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:41.703Z","worker":3,"idx":46,"total":263,"root_id":38426,"ground":"cork","motif":"auto-variation mono of design #38421","ok":true,"new_id":41608,"duration_ms":8393,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:44.138Z","worker":2,"idx":47,"total":263,"root_id":38427,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38426","ok":true,"new_id":41609,"duration_ms":9311,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:47.566Z","worker":4,"idx":48,"total":263,"root_id":38428,"ground":"linen","motif":"auto-variation hue+120 of design #38426","ok":true,"new_id":41610,"duration_ms":9176,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:48.395Z","worker":1,"idx":49,"total":263,"root_id":38429,"ground":"raffia","motif":"auto-variation hue+180 of design #38426","ok":true,"new_id":41611,"duration_ms":8959,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:50.505Z","worker":3,"idx":50,"total":263,"root_id":38430,"ground":"silk","motif":"auto-variation hue-60 of design #38426","ok":true,"new_id":41612,"duration_ms":8786,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:52.464Z","worker":2,"idx":51,"total":263,"root_id":38431,"ground":"cork","motif":"auto-variation mono of design #38426","ok":true,"new_id":41613,"duration_ms":8311,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:56.544Z","worker":4,"idx":52,"total":263,"root_id":38432,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38431","ok":true,"new_id":41614,"duration_ms":8962,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:57.541Z","worker":1,"idx":53,"total":263,"root_id":38433,"ground":"linen","motif":"auto-variation hue+120 of design #38431","ok":true,"new_id":41615,"duration_ms":9132,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:10:59.608Z","worker":3,"idx":54,"total":263,"root_id":38434,"ground":"raffia","motif":"auto-variation hue+180 of design #38431","ok":true,"new_id":41616,"duration_ms":9076,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:00.879Z","worker":2,"idx":55,"total":263,"root_id":38435,"ground":"silk","motif":"auto-variation hue-60 of design #38431","ok":true,"new_id":41617,"duration_ms":8395,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:05.362Z","worker":4,"idx":56,"total":263,"root_id":38436,"ground":"cork","motif":"auto-variation mono of design #38431","ok":true,"new_id":41618,"duration_ms":8799,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:05.864Z","worker":1,"idx":57,"total":263,"root_id":38437,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38436","ok":true,"new_id":41619,"duration_ms":8308,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:07.609Z","worker":3,"idx":58,"total":263,"root_id":38438,"ground":"linen","motif":"auto-variation hue+120 of design #38436","ok":true,"new_id":41620,"duration_ms":7985,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:08.897Z","worker":2,"idx":59,"total":263,"root_id":38439,"ground":"raffia","motif":"auto-variation hue+180 of design #38436","ok":true,"new_id":41621,"duration_ms":8003,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:13.548Z","worker":4,"idx":60,"total":263,"root_id":38440,"ground":"silk","motif":"auto-variation hue-60 of design #38436","ok":true,"new_id":41622,"duration_ms":8171,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:14.412Z","worker":1,"idx":61,"total":263,"root_id":38441,"ground":"cork","motif":"auto-variation mono of design #38436","ok":true,"new_id":41623,"duration_ms":8534,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:15.989Z","worker":3,"idx":62,"total":263,"root_id":38442,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38441","ok":true,"new_id":41624,"duration_ms":8363,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:17.772Z","worker":2,"idx":63,"total":263,"root_id":38443,"ground":"linen","motif":"auto-variation hue+120 of design #38441","ok":true,"new_id":41625,"duration_ms":8859,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:22.361Z","worker":4,"idx":64,"total":263,"root_id":38444,"ground":"raffia","motif":"auto-variation hue+180 of design #38441","ok":true,"new_id":41626,"duration_ms":8797,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:22.996Z","worker":1,"idx":65,"total":263,"root_id":38445,"ground":"silk","motif":"auto-variation hue-60 of design #38441","ok":true,"new_id":41627,"duration_ms":8570,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:25.155Z","worker":3,"idx":66,"total":263,"root_id":38446,"ground":"cork","motif":"auto-variation mono of design #38441","ok":true,"new_id":41628,"duration_ms":9150,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:26.363Z","worker":2,"idx":67,"total":263,"root_id":38447,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38446","ok":true,"new_id":41629,"duration_ms":8576,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:31.457Z","worker":4,"idx":68,"total":263,"root_id":38448,"ground":"linen","motif":"auto-variation hue+120 of design #38446","ok":true,"new_id":41630,"duration_ms":9080,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:32.166Z","worker":1,"idx":69,"total":263,"root_id":38449,"ground":"raffia","motif":"auto-variation hue+180 of design #38446","ok":true,"new_id":41631,"duration_ms":9154,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:33.221Z","worker":3,"idx":70,"total":263,"root_id":38450,"ground":"silk","motif":"auto-variation hue-60 of design #38446","ok":true,"new_id":41632,"duration_ms":8052,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:36.803Z","worker":2,"idx":71,"total":263,"root_id":38451,"ground":"cork","motif":"auto-variation mono of design #38446","ok":true,"new_id":41633,"duration_ms":10424,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:37.667Z","worker":2,"idx":75,"total":263,"root_id":38455,"ground":"silk","motif":"auto-variation hue-60 of design #38451","ok":false,"new_id":null,"duration_ms":849,"code":1,"stderr":"FATAL gemini returned no image\n"}
+{"ts":"2026-05-25T08:11:39.990Z","worker":1,"idx":73,"total":263,"root_id":38453,"ground":"linen","motif":"auto-variation hue+120 of design #38451","ok":true,"new_id":41634,"duration_ms":7810,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:41.099Z","worker":4,"idx":72,"total":263,"root_id":38452,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38451","ok":true,"new_id":41635,"duration_ms":9627,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:42.795Z","worker":3,"idx":74,"total":263,"root_id":38454,"ground":"raffia","motif":"auto-variation hue+180 of design #38451","ok":true,"new_id":41636,"duration_ms":9559,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:46.333Z","worker":2,"idx":76,"total":263,"root_id":38456,"ground":"cork","motif":"auto-variation mono of design #38451","ok":true,"new_id":41637,"duration_ms":8666,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:48.667Z","worker":1,"idx":77,"total":263,"root_id":38457,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38456","ok":true,"new_id":41638,"duration_ms":8661,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:49.965Z","worker":4,"idx":78,"total":263,"root_id":38458,"ground":"linen","motif":"auto-variation hue+120 of design #38456","ok":true,"new_id":41639,"duration_ms":8851,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:51.668Z","worker":3,"idx":79,"total":263,"root_id":38459,"ground":"raffia","motif":"auto-variation hue+180 of design #38456","ok":true,"new_id":41640,"duration_ms":8858,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:55.161Z","worker":2,"idx":80,"total":263,"root_id":38460,"ground":"silk","motif":"auto-variation hue-60 of design #38456","ok":true,"new_id":41641,"duration_ms":8813,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:57.457Z","worker":1,"idx":81,"total":263,"root_id":38461,"ground":"cork","motif":"auto-variation mono of design #38456","ok":true,"new_id":41642,"duration_ms":8773,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:11:58.679Z","worker":4,"idx":82,"total":263,"root_id":38462,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38461","ok":true,"new_id":41643,"duration_ms":8699,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:00.236Z","worker":3,"idx":83,"total":263,"root_id":38463,"ground":"linen","motif":"auto-variation hue+120 of design #38461","ok":true,"new_id":41644,"duration_ms":8553,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:03.429Z","worker":2,"idx":84,"total":263,"root_id":38464,"ground":"raffia","motif":"auto-variation hue+180 of design #38461","ok":true,"new_id":41645,"duration_ms":8253,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:04.422Z","worker":2,"idx":88,"total":263,"root_id":38468,"ground":"linen","motif":"auto-variation hue+120 of design #38466","ok":false,"new_id":null,"duration_ms":978,"code":1,"stderr":"FATAL gemini returned no image\n"}
+{"ts":"2026-05-25T08:12:05.425Z","worker":1,"idx":85,"total":263,"root_id":38465,"ground":"silk","motif":"auto-variation hue-60 of design #38461","ok":true,"new_id":41646,"duration_ms":7951,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:07.225Z","worker":4,"idx":86,"total":263,"root_id":38466,"ground":"cork","motif":"auto-variation mono of design #38461","ok":true,"new_id":41647,"duration_ms":8531,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:09.018Z","worker":3,"idx":87,"total":263,"root_id":38467,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38466","ok":true,"new_id":41648,"duration_ms":8767,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:13.576Z","worker":1,"idx":90,"total":263,"root_id":38470,"ground":"silk","motif":"auto-variation hue-60 of design #38466","ok":true,"new_id":41649,"duration_ms":8136,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:14.841Z","worker":2,"idx":89,"total":263,"root_id":38469,"ground":"raffia","motif":"auto-variation hue+180 of design #38466","ok":true,"new_id":41650,"duration_ms":10419,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:15.714Z","worker":4,"idx":91,"total":263,"root_id":38471,"ground":"cork","motif":"auto-variation mono of design #38466","ok":true,"new_id":41651,"duration_ms":8473,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:17.686Z","worker":3,"idx":92,"total":263,"root_id":38472,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38471","ok":true,"new_id":41652,"duration_ms":8637,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:22.570Z","worker":1,"idx":93,"total":263,"root_id":38473,"ground":"linen","motif":"auto-variation hue+120 of design #38471","ok":true,"new_id":41653,"duration_ms":8971,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:23.415Z","worker":2,"idx":94,"total":263,"root_id":38474,"ground":"raffia","motif":"auto-variation hue+180 of design #38471","ok":true,"new_id":41654,"duration_ms":8556,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:24.965Z","worker":4,"idx":95,"total":263,"root_id":38475,"ground":"silk","motif":"auto-variation hue-60 of design #38471","ok":true,"new_id":41655,"duration_ms":9235,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:25.943Z","worker":3,"idx":96,"total":263,"root_id":38476,"ground":"cork","motif":"auto-variation mono of design #38471","ok":true,"new_id":41656,"duration_ms":8241,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:30.461Z","worker":1,"idx":97,"total":263,"root_id":38477,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38476","ok":true,"new_id":41657,"duration_ms":7877,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:32.248Z","worker":2,"idx":98,"total":263,"root_id":38478,"ground":"linen","motif":"auto-variation hue+120 of design #38476","ok":true,"new_id":41658,"duration_ms":8815,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:33.747Z","worker":4,"idx":99,"total":263,"root_id":38479,"ground":"raffia","motif":"auto-variation hue+180 of design #38476","ok":true,"new_id":41659,"duration_ms":8767,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:33.816Z","worker":3,"idx":100,"total":263,"root_id":38480,"ground":"silk","motif":"auto-variation hue-60 of design #38476","ok":true,"new_id":41660,"duration_ms":7858,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:38.991Z","worker":1,"idx":101,"total":263,"root_id":38481,"ground":"cork","motif":"auto-variation mono of design #38476","ok":true,"new_id":41661,"duration_ms":8515,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:40.484Z","worker":2,"idx":102,"total":263,"root_id":38482,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38481","ok":true,"new_id":41662,"duration_ms":8219,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:42.390Z","worker":3,"idx":104,"total":263,"root_id":38484,"ground":"raffia","motif":"auto-variation hue+180 of design #38481","ok":true,"new_id":41663,"duration_ms":8558,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:42.996Z","worker":4,"idx":103,"total":263,"root_id":38483,"ground":"linen","motif":"auto-variation hue+120 of design #38481","ok":true,"new_id":41664,"duration_ms":9233,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:48.910Z","worker":1,"idx":105,"total":263,"root_id":38485,"ground":"silk","motif":"auto-variation hue-60 of design #38481","ok":true,"new_id":41665,"duration_ms":9903,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:49.388Z","worker":2,"idx":106,"total":263,"root_id":38486,"ground":"cork","motif":"auto-variation mono of design #38481","ok":true,"new_id":41666,"duration_ms":8889,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:51.255Z","worker":4,"idx":108,"total":263,"root_id":38488,"ground":"linen","motif":"auto-variation hue+120 of design #38486","ok":true,"new_id":41667,"duration_ms":8244,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:51.695Z","worker":3,"idx":107,"total":263,"root_id":38487,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38486","ok":true,"new_id":41668,"duration_ms":9287,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:57.567Z","worker":1,"idx":109,"total":263,"root_id":38489,"ground":"raffia","motif":"auto-variation hue+180 of design #38486","ok":true,"new_id":41669,"duration_ms":8641,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:58.225Z","worker":2,"idx":110,"total":263,"root_id":38490,"ground":"silk","motif":"auto-variation hue-60 of design #38486","ok":true,"new_id":41670,"duration_ms":8823,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:59.877Z","worker":3,"idx":112,"total":263,"root_id":38492,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38491","ok":true,"new_id":41671,"duration_ms":8168,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:12:59.987Z","worker":4,"idx":111,"total":263,"root_id":38491,"ground":"cork","motif":"auto-variation mono of design #38486","ok":true,"new_id":41672,"duration_ms":8717,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:06.670Z","worker":2,"idx":114,"total":263,"root_id":38494,"ground":"raffia","motif":"auto-variation hue+180 of design #38491","ok":true,"new_id":41673,"duration_ms":8430,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:06.945Z","worker":1,"idx":113,"total":263,"root_id":38493,"ground":"linen","motif":"auto-variation hue+120 of design #38491","ok":true,"new_id":41674,"duration_ms":9361,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:08.342Z","worker":4,"idx":116,"total":263,"root_id":38496,"ground":"cork","motif":"auto-variation mono of design #38491","ok":true,"new_id":41675,"duration_ms":8340,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:08.984Z","worker":3,"idx":115,"total":263,"root_id":38495,"ground":"silk","motif":"auto-variation hue-60 of design #38491","ok":true,"new_id":41676,"duration_ms":9090,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:15.012Z","worker":1,"idx":118,"total":263,"root_id":38498,"ground":"linen","motif":"auto-variation hue+120 of design #38496","ok":true,"new_id":41677,"duration_ms":8050,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:16.190Z","worker":2,"idx":117,"total":263,"root_id":38497,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38496","ok":true,"new_id":41678,"duration_ms":9504,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:16.610Z","worker":4,"idx":119,"total":263,"root_id":38499,"ground":"raffia","motif":"auto-variation hue+180 of design #38496","ok":true,"new_id":41679,"duration_ms":8252,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:18.282Z","worker":3,"idx":120,"total":263,"root_id":38500,"ground":"silk","motif":"auto-variation hue-60 of design #38496","ok":true,"new_id":41680,"duration_ms":9283,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:24.184Z","worker":1,"idx":121,"total":263,"root_id":38501,"ground":"cork","motif":"auto-variation mono of design #38496","ok":true,"new_id":41681,"duration_ms":9155,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:24.872Z","worker":4,"idx":123,"total":263,"root_id":38503,"ground":"linen","motif":"auto-variation hue+120 of design #38501","ok":true,"new_id":41682,"duration_ms":8247,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:25.559Z","worker":2,"idx":122,"total":263,"root_id":38502,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38501","ok":true,"new_id":41683,"duration_ms":9353,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:27.677Z","worker":3,"idx":124,"total":263,"root_id":38504,"ground":"raffia","motif":"auto-variation hue+180 of design #38501","ok":true,"new_id":41684,"duration_ms":9380,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:33.347Z","worker":1,"idx":125,"total":263,"root_id":38505,"ground":"silk","motif":"auto-variation hue-60 of design #38501","ok":true,"new_id":41685,"duration_ms":9148,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:33.937Z","worker":4,"idx":126,"total":263,"root_id":38506,"ground":"cork","motif":"auto-variation mono of design #38501","ok":true,"new_id":41686,"duration_ms":9049,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:34.148Z","worker":2,"idx":127,"total":263,"root_id":38507,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38506","ok":true,"new_id":41687,"duration_ms":8573,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:36.518Z","worker":3,"idx":128,"total":263,"root_id":38508,"ground":"linen","motif":"auto-variation hue+120 of design #38506","ok":true,"new_id":41688,"duration_ms":8825,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:42.706Z","worker":2,"idx":131,"total":263,"root_id":38511,"ground":"cork","motif":"auto-variation mono of design #38506","ok":true,"new_id":41689,"duration_ms":8540,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:42.824Z","worker":1,"idx":129,"total":263,"root_id":38509,"ground":"raffia","motif":"auto-variation hue+180 of design #38506","ok":true,"new_id":41690,"duration_ms":9461,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:43.091Z","worker":4,"idx":130,"total":263,"root_id":38510,"ground":"silk","motif":"auto-variation hue-60 of design #38506","ok":true,"new_id":41691,"duration_ms":9135,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:45.049Z","worker":3,"idx":132,"total":263,"root_id":38512,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38511","ok":true,"new_id":41692,"duration_ms":8513,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:51.770Z","worker":4,"idx":135,"total":263,"root_id":38515,"ground":"silk","motif":"auto-variation hue-60 of design #38511","ok":true,"new_id":41693,"duration_ms":8663,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:52.451Z","worker":2,"idx":133,"total":263,"root_id":38513,"ground":"linen","motif":"auto-variation hue+120 of design #38511","ok":true,"new_id":41694,"duration_ms":9726,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:52.467Z","worker":1,"idx":134,"total":263,"root_id":38514,"ground":"raffia","motif":"auto-variation hue+180 of design #38511","ok":true,"new_id":41695,"duration_ms":9625,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:13:54.278Z","worker":3,"idx":136,"total":263,"root_id":38516,"ground":"cork","motif":"auto-variation mono of design #38511","ok":true,"new_id":41696,"duration_ms":9211,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:00.516Z","worker":1,"idx":139,"total":263,"root_id":38519,"ground":"raffia","motif":"auto-variation hue+180 of design #38516","ok":true,"new_id":41697,"duration_ms":8033,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:01.115Z","worker":2,"idx":138,"total":263,"root_id":38518,"ground":"linen","motif":"auto-variation hue+120 of design #38516","ok":true,"new_id":41698,"duration_ms":8649,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:01.868Z","worker":4,"idx":137,"total":263,"root_id":38517,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38516","ok":true,"new_id":41699,"duration_ms":10082,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:02.527Z","worker":3,"idx":140,"total":263,"root_id":38520,"ground":"silk","motif":"auto-variation hue-60 of design #38516","ok":true,"new_id":41700,"duration_ms":8234,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:09.509Z","worker":1,"idx":141,"total":263,"root_id":38521,"ground":"cork","motif":"auto-variation mono of design #38516","ok":true,"new_id":41701,"duration_ms":8977,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:10.652Z","worker":2,"idx":142,"total":263,"root_id":38522,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38521","ok":true,"new_id":41702,"duration_ms":9521,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:11.140Z","worker":4,"idx":143,"total":263,"root_id":38523,"ground":"linen","motif":"auto-variation hue+120 of design #38521","ok":true,"new_id":41703,"duration_ms":9257,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:11.790Z","worker":3,"idx":144,"total":263,"root_id":38524,"ground":"raffia","motif":"auto-variation hue+180 of design #38521","ok":true,"new_id":41704,"duration_ms":9249,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:17.892Z","worker":1,"idx":145,"total":263,"root_id":38525,"ground":"silk","motif":"auto-variation hue-60 of design #38521","ok":true,"new_id":41705,"duration_ms":8367,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:19.312Z","worker":2,"idx":146,"total":263,"root_id":38526,"ground":"cork","motif":"auto-variation mono of design #38521","ok":true,"new_id":41706,"duration_ms":8644,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:19.959Z","worker":4,"idx":147,"total":263,"root_id":38527,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38526","ok":true,"new_id":41707,"duration_ms":8803,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:20.681Z","worker":3,"idx":148,"total":263,"root_id":38528,"ground":"linen","motif":"auto-variation hue+120 of design #38526","ok":true,"new_id":41708,"duration_ms":8875,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:26.233Z","worker":1,"idx":149,"total":263,"root_id":38529,"ground":"raffia","motif":"auto-variation hue+180 of design #38526","ok":true,"new_id":41709,"duration_ms":8325,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:28.547Z","worker":2,"idx":150,"total":263,"root_id":38530,"ground":"silk","motif":"auto-variation hue-60 of design #38526","ok":true,"new_id":41710,"duration_ms":9217,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:29.193Z","worker":4,"idx":151,"total":263,"root_id":38531,"ground":"cork","motif":"auto-variation mono of design #38526","ok":true,"new_id":41711,"duration_ms":9218,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:29.418Z","worker":3,"idx":152,"total":263,"root_id":38532,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38531","ok":true,"new_id":41712,"duration_ms":8720,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:37.003Z","worker":1,"idx":153,"total":263,"root_id":38533,"ground":"linen","motif":"auto-variation hue+120 of design #38531","ok":true,"new_id":41713,"duration_ms":10750,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:37.324Z","worker":4,"idx":155,"total":263,"root_id":38535,"ground":"silk","motif":"auto-variation hue-60 of design #38531","ok":true,"new_id":41714,"duration_ms":8112,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:38.494Z","worker":2,"idx":154,"total":263,"root_id":38534,"ground":"raffia","motif":"auto-variation hue+180 of design #38531","ok":true,"new_id":41715,"duration_ms":9931,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:39.480Z","worker":3,"idx":156,"total":263,"root_id":38536,"ground":"cork","motif":"auto-variation mono of design #38531","ok":true,"new_id":41716,"duration_ms":10046,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:45.525Z","worker":1,"idx":157,"total":263,"root_id":38537,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38536","ok":true,"new_id":41717,"duration_ms":8507,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:45.672Z","worker":4,"idx":158,"total":263,"root_id":38538,"ground":"linen","motif":"auto-variation hue+120 of design #38536","ok":true,"new_id":41718,"duration_ms":8334,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:46.584Z","worker":4,"idx":162,"total":263,"root_id":38542,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38541","ok":false,"new_id":null,"duration_ms":894,"code":1,"stderr":"FATAL gemini returned no image\n"}
+{"ts":"2026-05-25T08:14:47.156Z","worker":2,"idx":159,"total":263,"root_id":38539,"ground":"raffia","motif":"auto-variation hue+180 of design #38536","ok":true,"new_id":41719,"duration_ms":8638,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:47.313Z","worker":3,"idx":160,"total":263,"root_id":38540,"ground":"silk","motif":"auto-variation hue-60 of design #38536","ok":true,"new_id":41720,"duration_ms":7816,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:54.194Z","worker":1,"idx":161,"total":263,"root_id":38541,"ground":"cork","motif":"auto-variation mono of design #38536","ok":true,"new_id":41721,"duration_ms":8639,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:55.544Z","worker":4,"idx":163,"total":263,"root_id":38543,"ground":"linen","motif":"auto-variation hue+120 of design #38541","ok":true,"new_id":41722,"duration_ms":8959,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:55.561Z","worker":3,"idx":165,"total":263,"root_id":38545,"ground":"silk","motif":"auto-variation hue-60 of design #38541","ok":true,"new_id":41723,"duration_ms":8230,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:14:57.001Z","worker":2,"idx":164,"total":263,"root_id":38544,"ground":"raffia","motif":"auto-variation hue+180 of design #38541","ok":true,"new_id":41724,"duration_ms":9828,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:03.317Z","worker":1,"idx":166,"total":263,"root_id":38546,"ground":"cork","motif":"auto-variation mono of design #38541","ok":true,"new_id":41725,"duration_ms":9109,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:04.580Z","worker":4,"idx":167,"total":263,"root_id":38547,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38546","ok":true,"new_id":41726,"duration_ms":9020,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:04.909Z","worker":3,"idx":168,"total":263,"root_id":38548,"ground":"linen","motif":"auto-variation hue+120 of design #38546","ok":true,"new_id":41727,"duration_ms":9334,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:06.069Z","worker":2,"idx":169,"total":263,"root_id":38549,"ground":"raffia","motif":"auto-variation hue+180 of design #38546","ok":true,"new_id":41728,"duration_ms":9053,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:12.234Z","worker":1,"idx":170,"total":263,"root_id":38550,"ground":"silk","motif":"auto-variation hue-60 of design #38546","ok":true,"new_id":41729,"duration_ms":8901,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:12.758Z","worker":4,"idx":171,"total":263,"root_id":38551,"ground":"cork","motif":"auto-variation mono of design #38546","ok":true,"new_id":41730,"duration_ms":8162,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:13.846Z","worker":3,"idx":172,"total":263,"root_id":38552,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38551","ok":true,"new_id":41731,"duration_ms":8921,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:14.398Z","worker":2,"idx":173,"total":263,"root_id":38553,"ground":"linen","motif":"auto-variation hue+120 of design #38551","ok":true,"new_id":41732,"duration_ms":8314,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:21.088Z","worker":4,"idx":175,"total":263,"root_id":38555,"ground":"silk","motif":"auto-variation hue-60 of design #38551","ok":true,"new_id":41733,"duration_ms":8314,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:23.353Z","worker":1,"idx":174,"total":263,"root_id":38554,"ground":"raffia","motif":"auto-variation hue+180 of design #38551","ok":true,"new_id":41734,"duration_ms":11099,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:23.492Z","worker":3,"idx":176,"total":263,"root_id":38556,"ground":"cork","motif":"auto-variation mono of design #38551","ok":true,"new_id":41735,"duration_ms":9631,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:24.310Z","worker":2,"idx":177,"total":263,"root_id":38557,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38556","ok":true,"new_id":41736,"duration_ms":9895,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:31.209Z","worker":1,"idx":179,"total":263,"root_id":38559,"ground":"raffia","motif":"auto-variation hue+180 of design #38556","ok":true,"new_id":41737,"duration_ms":7841,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:31.537Z","worker":3,"idx":180,"total":263,"root_id":38560,"ground":"silk","motif":"auto-variation hue-60 of design #38556","ok":true,"new_id":41738,"duration_ms":8030,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:32.649Z","worker":2,"idx":181,"total":263,"root_id":38561,"ground":"cork","motif":"auto-variation mono of design #38556","ok":true,"new_id":41739,"duration_ms":8322,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:38.464Z","worker":4,"idx":178,"total":263,"root_id":38558,"ground":"linen","motif":"auto-variation hue+120 of design #38556","ok":true,"new_id":41740,"duration_ms":17361,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:40.231Z","worker":1,"idx":182,"total":263,"root_id":38562,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38561","ok":true,"new_id":41741,"duration_ms":9005,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:41.357Z","worker":2,"idx":184,"total":263,"root_id":38564,"ground":"raffia","motif":"auto-variation hue+180 of design #38561","ok":true,"new_id":41742,"duration_ms":8692,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:41.452Z","worker":3,"idx":183,"total":263,"root_id":38563,"ground":"linen","motif":"auto-variation hue+120 of design #38561","ok":true,"new_id":41743,"duration_ms":9899,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:46.422Z","worker":4,"idx":185,"total":263,"root_id":38565,"ground":"silk","motif":"auto-variation hue-60 of design #38561","ok":true,"new_id":41744,"duration_ms":7940,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:49.851Z","worker":2,"idx":187,"total":263,"root_id":38567,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38566","ok":true,"new_id":41745,"duration_ms":8478,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:50.433Z","worker":3,"idx":188,"total":263,"root_id":38568,"ground":"linen","motif":"auto-variation hue+120 of design #38566","ok":true,"new_id":41746,"duration_ms":8966,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:52.051Z","worker":1,"idx":186,"total":263,"root_id":38566,"ground":"cork","motif":"auto-variation mono of design #38561","ok":true,"new_id":41747,"duration_ms":11802,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:55.620Z","worker":4,"idx":189,"total":263,"root_id":38569,"ground":"raffia","motif":"auto-variation hue+180 of design #38566","ok":true,"new_id":41748,"duration_ms":9179,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:58.297Z","worker":3,"idx":191,"total":263,"root_id":38571,"ground":"cork","motif":"auto-variation mono of design #38566","ok":true,"new_id":41749,"duration_ms":7848,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:15:58.864Z","worker":2,"idx":190,"total":263,"root_id":38570,"ground":"silk","motif":"auto-variation hue-60 of design #38566","ok":true,"new_id":41750,"duration_ms":8997,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:00.210Z","worker":1,"idx":192,"total":263,"root_id":38572,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38571","ok":true,"new_id":41751,"duration_ms":8144,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:04.056Z","worker":4,"idx":193,"total":263,"root_id":38573,"ground":"linen","motif":"auto-variation hue+120 of design #38571","ok":true,"new_id":41752,"duration_ms":8421,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:07.378Z","worker":3,"idx":194,"total":263,"root_id":38574,"ground":"raffia","motif":"auto-variation hue+180 of design #38571","ok":true,"new_id":41753,"duration_ms":9065,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:08.232Z","worker":1,"idx":196,"total":263,"root_id":38576,"ground":"cork","motif":"auto-variation mono of design #38571","ok":true,"new_id":41754,"duration_ms":8006,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:09.595Z","worker":2,"idx":195,"total":263,"root_id":38575,"ground":"silk","motif":"auto-variation hue-60 of design #38571","ok":true,"new_id":41755,"duration_ms":10716,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:12.408Z","worker":4,"idx":197,"total":263,"root_id":38577,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38576","ok":true,"new_id":41756,"duration_ms":8335,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:15.205Z","worker":3,"idx":198,"total":263,"root_id":38578,"ground":"linen","motif":"auto-variation hue+120 of design #38576","ok":true,"new_id":41757,"duration_ms":7811,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:16.938Z","worker":1,"idx":199,"total":263,"root_id":38579,"ground":"raffia","motif":"auto-variation hue+180 of design #38576","ok":true,"new_id":41758,"duration_ms":8689,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:17.669Z","worker":1,"idx":203,"total":263,"root_id":38584,"ground":"raffia","motif":"auto-variation hue+180 of design #38581","ok":false,"new_id":null,"duration_ms":714,"code":1,"stderr":"FATAL gemini returned no image\n"}
+{"ts":"2026-05-25T08:16:18.378Z","worker":2,"idx":200,"total":263,"root_id":38580,"ground":"silk","motif":"auto-variation hue-60 of design #38576","ok":true,"new_id":41759,"duration_ms":8767,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:21.039Z","worker":4,"idx":201,"total":263,"root_id":38582,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38581","ok":true,"new_id":41760,"duration_ms":8617,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:23.972Z","worker":3,"idx":202,"total":263,"root_id":38583,"ground":"linen","motif":"auto-variation hue+120 of design #38581","ok":true,"new_id":41761,"duration_ms":8747,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:25.577Z","worker":1,"idx":204,"total":263,"root_id":38585,"ground":"silk","motif":"auto-variation hue-60 of design #38581","ok":true,"new_id":41762,"duration_ms":7907,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:26.626Z","worker":2,"idx":205,"total":263,"root_id":38586,"ground":"cork","motif":"auto-variation mono of design #38581","ok":true,"new_id":41763,"duration_ms":8233,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:29.435Z","worker":4,"idx":206,"total":263,"root_id":38588,"ground":"linen","motif":"auto-variation hue+120 of design #38586","ok":true,"new_id":41764,"duration_ms":8381,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:32.562Z","worker":3,"idx":207,"total":263,"root_id":38589,"ground":"raffia","motif":"auto-variation hue+180 of design #38586","ok":true,"new_id":41765,"duration_ms":8567,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:33.248Z","worker":1,"idx":208,"total":263,"root_id":38590,"ground":"silk","motif":"auto-variation hue-60 of design #38586","ok":true,"new_id":41766,"duration_ms":7651,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:35.059Z","worker":2,"idx":209,"total":263,"root_id":38591,"ground":"cork","motif":"auto-variation mono of design #38586","ok":true,"new_id":41767,"duration_ms":8417,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:38.472Z","worker":4,"idx":210,"total":263,"root_id":38592,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38591","ok":true,"new_id":41768,"duration_ms":9021,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:41.015Z","worker":1,"idx":212,"total":263,"root_id":38595,"ground":"silk","motif":"auto-variation hue-60 of design #38591","ok":true,"new_id":41769,"duration_ms":7751,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:42.021Z","worker":3,"idx":211,"total":263,"root_id":38594,"ground":"raffia","motif":"auto-variation hue+180 of design #38591","ok":true,"new_id":41770,"duration_ms":9439,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:43.276Z","worker":2,"idx":213,"total":263,"root_id":38596,"ground":"cork","motif":"auto-variation mono of design #38591","ok":true,"new_id":41771,"duration_ms":8202,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:45.943Z","worker":4,"idx":214,"total":263,"root_id":38597,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38596","ok":true,"new_id":41772,"duration_ms":7456,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:49.494Z","worker":1,"idx":215,"total":263,"root_id":38598,"ground":"linen","motif":"auto-variation hue+120 of design #38596","ok":true,"new_id":41773,"duration_ms":8464,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:50.465Z","worker":3,"idx":216,"total":263,"root_id":38599,"ground":"raffia","motif":"auto-variation hue+180 of design #38596","ok":true,"new_id":41774,"duration_ms":8428,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:51.547Z","worker":2,"idx":217,"total":263,"root_id":38603,"ground":"linen","motif":"auto-variation hue+120 of design #38601","ok":true,"new_id":41775,"duration_ms":8255,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:54.655Z","worker":4,"idx":218,"total":263,"root_id":38605,"ground":"silk","motif":"auto-variation hue-60 of design #38601","ok":true,"new_id":41776,"duration_ms":8697,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:57.754Z","worker":1,"idx":219,"total":263,"root_id":38606,"ground":"cork","motif":"auto-variation mono of design #38601","ok":true,"new_id":41777,"duration_ms":8245,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:16:58.884Z","worker":3,"idx":220,"total":263,"root_id":38607,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38606","ok":true,"new_id":41778,"duration_ms":8402,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:00.102Z","worker":2,"idx":221,"total":263,"root_id":38608,"ground":"linen","motif":"auto-variation hue+120 of design #38606","ok":true,"new_id":41779,"duration_ms":8541,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:03.654Z","worker":4,"idx":222,"total":263,"root_id":38609,"ground":"raffia","motif":"auto-variation hue+180 of design #38606","ok":true,"new_id":41780,"duration_ms":8985,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:05.986Z","worker":1,"idx":223,"total":263,"root_id":38610,"ground":"silk","motif":"auto-variation hue-60 of design #38606","ok":true,"new_id":41781,"duration_ms":8217,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:07.503Z","worker":3,"idx":224,"total":263,"root_id":38611,"ground":"cork","motif":"auto-variation mono of design #38606","ok":true,"new_id":41782,"duration_ms":8604,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:08.929Z","worker":2,"idx":225,"total":263,"root_id":38612,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38611","ok":true,"new_id":41783,"duration_ms":8811,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:11.962Z","worker":4,"idx":226,"total":263,"root_id":38613,"ground":"linen","motif":"auto-variation hue+120 of design #38611","ok":true,"new_id":41784,"duration_ms":8292,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:14.064Z","worker":1,"idx":227,"total":263,"root_id":38614,"ground":"raffia","motif":"auto-variation hue+180 of design #38611","ok":true,"new_id":41785,"duration_ms":8055,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:15.812Z","worker":3,"idx":228,"total":263,"root_id":38615,"ground":"silk","motif":"auto-variation hue-60 of design #38611","ok":true,"new_id":41786,"duration_ms":8294,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:16.899Z","worker":2,"idx":229,"total":263,"root_id":38616,"ground":"cork","motif":"auto-variation mono of design #38611","ok":true,"new_id":41787,"duration_ms":7955,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:20.999Z","worker":4,"idx":230,"total":263,"root_id":38617,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38616","ok":true,"new_id":41788,"duration_ms":9022,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:22.482Z","worker":1,"idx":231,"total":263,"root_id":38619,"ground":"raffia","motif":"auto-variation hue+180 of design #38616","ok":true,"new_id":41789,"duration_ms":8401,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:23.593Z","worker":3,"idx":232,"total":263,"root_id":38622,"ground":"grasscloth","motif":"auto-variation hue+60 of design #38621","ok":true,"new_id":41790,"duration_ms":7763,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:25.161Z","worker":2,"idx":233,"total":263,"root_id":38623,"ground":"linen","motif":"auto-variation hue+120 of design #38621","ok":true,"new_id":41791,"duration_ms":8245,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:29.785Z","worker":4,"idx":234,"total":263,"root_id":38624,"ground":"raffia","motif":"auto-variation hue+180 of design #38621","ok":true,"new_id":41792,"duration_ms":8765,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:31.344Z","worker":1,"idx":235,"total":263,"root_id":38627,"ground":"grasscloth","motif":"pink-cheeked drunken bullfrog, champagne magnum bottle wedged under one arm, flute in the other paw, set among Bleeding Heart (Lamprocapnos), strings of rose-pink hearts dangling, palette: tiffany rob","ok":true,"new_id":41793,"duration_ms":8846,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:32.154Z","worker":3,"idx":236,"total":263,"root_id":38640,"ground":"silk","motif":"shaggy orange orangutan clutching a banana cocktail, gold-labeled cognac snifter cradled in both paws, swirling deliberately, set among Beehive Ginger (Zingiber spectabile), torch-shaped scarlet cones","ok":true,"new_id":41794,"duration_ms":8541,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:33.514Z","worker":2,"idx":237,"total":263,"root_id":38653,"ground":"linen","motif":"drunken peacock with feathers half-fanned, one paw around a jet-black stout pint, cream head, eyelids drooping, set among Parrot Tulips, frilled edges in flame red, viridian, and apricot, palette: ros","ok":true,"new_id":41795,"duration_ms":8336,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:39.373Z","worker":4,"idx":238,"total":263,"root_id":38672,"ground":"grasscloth","motif":"sloshed scarlet macaw, one paw around a jet-black stout pint, cream head, eyelids drooping, set among antique heirloom rose garden — David Austin pinks, butter creams, burgundies, palette: Warhol elec","ok":true,"new_id":41796,"duration_ms":9572,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:40.054Z","worker":1,"idx":239,"total":263,"root_id":38679,"ground":"raffia","motif":"long-lashed Maasai giraffe sipping a daiquiri, martini glass in mid-spin, two olives skewered, vodka splashing, set among crimson bougainvillea spilling over a stucco wall, papery bracts, palette: dar","ok":true,"new_id":41797,"duration_ms":8691,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:41.779Z","worker":3,"idx":240,"total":263,"root_id":38687,"ground":"grasscloth","motif":"sleepy Bornean orangutan slumped against a fern, cradling a deep-purple velvet-bag whiskey decanter, label edge peeking, set among Foxglove (Digitalis purpurea) spires, freckled magenta throats, palet","ok":true,"new_id":41798,"duration_ms":9607,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:42.383Z","worker":2,"idx":241,"total":263,"root_id":38694,"ground":"raffia","motif":"tipsy capybara holding a mint julep, gripping a pale-gold pilsner glass in one paw, amber bottle in the other, set among antique heirloom rose garden — David Austin pinks, butter creams, burgundies, p","ok":true,"new_id":41799,"duration_ms":8851,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:48.959Z","worker":4,"idx":242,"total":263,"root_id":38701,"ground":"cork","motif":"inebriated lemur swinging from a vine, two paws on a hand-blown wine bottle, burgundy splashing onto a flower, set among Naked Man Orchid (Orchis italica), pink figurine-shaped blooms in spike, palett","ok":true,"new_id":41800,"duration_ms":9558,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:49.016Z","worker":1,"idx":243,"total":263,"root_id":38714,"ground":"raffia","motif":"wobbly pink champagne elephant, mid-toast with a champagne flute, golden bubbles spilling, head tilted, set among Black Bat Flower (Tacca chantrieri), inky violet with cascading whiskers, palette: tif","ok":true,"new_id":41801,"duration_ms":8946,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:51.054Z","worker":2,"idx":245,"total":263,"root_id":38752,"ground":"grasscloth","motif":"wide-eyed Amazonian tree frog, frosted vodka decanter etched with silhouettes, cradled to its chest, set among Globe Amaranth (Gomphrena globosa), magenta button-flowers, papery and dense, palette: Ma","ok":true,"new_id":41802,"duration_ms":8650,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:51.230Z","worker":3,"idx":244,"total":263,"root_id":38745,"ground":"silk","motif":"starry-eyed sloth holding a wine glass, mid-pour from a cobalt-blue vodka bottle into a shot glass, eyes crossed, set among Foxglove (Digitalis purpurea) spires, freckled magenta throats, palette: ros","ok":true,"new_id":41803,"duration_ms":9430,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:57.826Z","worker":4,"idx":246,"total":263,"root_id":38755,"ground":"silk","motif":"pink-cheeked drunken bullfrog, one paw around a jet-black stout pint, cream head, eyelids drooping, set among sun-bleached field of sunflowers, golden disc faces packed edge-to-edge, palette: equestri","ok":true,"new_id":41804,"duration_ms":8851,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:58.404Z","worker":1,"idx":247,"total":263,"root_id":38762,"ground":"grasscloth","motif":"tipsy emerald glass frog, gold-labeled cognac snifter cradled in both paws, swirling deliberately, set among antique heirloom rose garden — David Austin pinks, butter creams, burgundies, palette: silk","ok":true,"new_id":41805,"duration_ms":9369,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:17:59.428Z","worker":2,"idx":248,"total":263,"root_id":38769,"ground":"raffia","motif":"sloshed scarlet macaw, cradling an emerald-green beer bottle, foam crowning the lip, content sigh, set among Naked Man Orchid (Orchis italica), pink figurine-shaped blooms in spike, palette: tiffany r","ok":true,"new_id":41806,"duration_ms":8354,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:18:00.237Z","worker":3,"idx":249,"total":263,"root_id":38777,"ground":"grasscloth","motif":"sleepy Bornean orangutan slumped against a fern, sipping from a coupe glass of rosé, eyes half-closed, pink liquid sloshing, set among Snake's Head Fritillary (Fritillaria meleagris), checkered purple","ok":true,"new_id":41807,"duration_ms":8991,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:18:06.711Z","worker":4,"idx":250,"total":263,"root_id":38784,"ground":"raffia","motif":"long-lashed Maasai giraffe sipping a daiquiri, clutching a long-stemmed red wine glass, deep burgundy sloshing over the rim, set among Snake's Head Fritillary (Fritillaria meleagris), checkered purple","ok":true,"new_id":41808,"duration_ms":8869,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:18:07.092Z","worker":1,"idx":251,"total":263,"root_id":38791,"ground":"cork","motif":"inebriated lemur swinging from a vine, mid-pour from a cobalt-blue vodka bottle into a shot glass, eyes crossed, set among crimson bougainvillea spilling over a stucco wall, papery bracts, palette: Wa","ok":true,"new_id":41809,"duration_ms":8673,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:18:07.542Z","worker":2,"idx":252,"total":263,"root_id":38804,"ground":"raffia","motif":"jolly grey African elephant calf, clear pale lager bottle with a lime wedge stuffed in its neck, set among Bleeding Heart (Lamprocapnos), strings of rose-pink hearts dangling, palette: Brillo-box red,","ok":true,"new_id":41810,"duration_ms":8098,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:18:08.326Z","worker":3,"idx":253,"total":263,"root_id":38829,"ground":"raffia","motif":"plastered red panda, tequila shot in one paw, lime wedge in the other, salt rim on the glass, set among Love-in-a-Mist (Nigella damascena), cobalt stars in feathery haze, palette: Day-Glo orange + ult","ok":true,"new_id":41811,"duration_ms":8074,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:18:14.942Z","worker":1,"idx":255,"total":263,"root_id":41092,"ground":"grasscloth","motif":"Sage Caprice (Charcoal tonal) — Recolor everything into the CHARCOAL family ONLY","ok":true,"new_id":41812,"duration_ms":7833,"unpublished_descendants":1}
+{"ts":"2026-05-25T08:18:15.558Z","worker":4,"idx":254,"total":263,"root_id":38836,"ground":"cork","motif":"reticulated giraffe with crooked smile, holding a frosted clear vodka bottle aloft, condensation beads, cheeks flushed, set among Naked Man Orchid (Orchis italica), pink figurine-shaped blooms in spik","ok":true,"new_id":41813,"duration_ms":8831,"unpublished_descendants":2}
+{"ts":"2026-05-25T08:18:16.737Z","worker":3,"idx":257,"total":263,"root_id":41094,"ground":"raffia","motif":"Sage Caprice (Pink tonal) — Recolor everything into the PINK family ONLY","ok":true,"new_id":41814,"duration_ms":8397,"unpublished_descendants":1}
+{"ts":"2026-05-25T08:18:16.771Z","worker":2,"idx":256,"total":263,"root_id":41093,"ground":"linen","motif":"Sage Caprice (Magenta tonal) — Recolor everything into the MAGENTA family ONLY","ok":true,"new_id":41815,"duration_ms":9214,"unpublished_descendants":1}
+{"ts":"2026-05-25T08:18:24.407Z","worker":1,"idx":258,"total":263,"root_id":41097,"ground":"grasscloth","motif":"Sage Caprice (Neutral tonal) — Recolor everything into the NEUTRAL family ONLY","ok":true,"new_id":41816,"duration_ms":9449,"unpublished_descendants":1}
+{"ts":"2026-05-25T08:18:24.954Z","worker":4,"idx":259,"total":263,"root_id":41099,"ground":"raffia","motif":"Sage Caprice (Cyan tonal) — Recolor everything into the CYAN family ONLY","ok":true,"new_id":41817,"duration_ms":9380,"unpublished_descendants":1}
+{"ts":"2026-05-25T08:18:25.109Z","worker":2,"idx":261,"total":263,"root_id":41105,"ground":"silk","motif":"Sage Caprice (Magenta tonal) — Recolor everything into the MAGENTA family ONLY","ok":true,"new_id":41818,"duration_ms":8322,"unpublished_descendants":1}
+{"ts":"2026-05-25T08:18:25.613Z","worker":3,"idx":260,"total":263,"root_id":41100,"ground":"silk","motif":"Sage Caprice (Blue tonal) — Recolor everything into the BLUE family ONLY","ok":true,"new_id":41819,"duration_ms":8861,"unpublished_descendants":1}
+{"ts":"2026-05-25T08:18:25.871Z","worker":4,"idx":263,"total":263,"root_id":41545,"ground":"silk","motif":"Sapphire Folly (Valentino tonal) — Recolor everything into the VALENTINO fashion-house palette ONLY: #D70000, #FFFFFF, #000000 (saturated romantic red, classical drama)","ok":false,"new_id":null,"duration_ms":900,"code":1,"stderr":"FATAL gemini returned no image\n"}
+{"ts":"2026-05-25T08:18:32.761Z","worker":1,"idx":262,"total":263,"root_id":41107,"ground":"grasscloth","motif":"Sage Caprice (Indigo tonal) — Recolor everything into the INDIGO family ONLY","ok":true,"new_id":41820,"duration_ms":8338,"unpublished_descendants":1}
diff --git a/public/luxe-curator.html b/public/luxe-curator.html
new file mode 100644
index 0000000..41a74b0
--- /dev/null
+++ b/public/luxe-curator.html
@@ -0,0 +1,240 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Luxe Curator — hot-or-not picker</title>
+<style>
+ :root {
+ --bg:#fafaf8; --fg:#1a1a1a; --muted:#6a6a6a; --card:#fff;
+ --border:#e8e6e1; --accent:#8b1f1f; --gold:#c9a14b;
+ --pick:#1d6b3a; --reject:#7a7a7a; --root:#2a4d6e;
+ }
+ * { box-sizing: border-box; }
+ body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.5 -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif; }
+ header { padding:18px 28px 14px; border-bottom:1px solid var(--border); background:var(--card); position:sticky; top:0; z-index:10; }
+ header h1 { margin:0 0 4px; font-size:18px; font-weight:600; letter-spacing:-0.01em; }
+ header h1 .badge { display:inline-block; padding:2px 8px; font-size:11px; font-weight:600; border-radius:10px; background:#1a1a1a; color:#fff; margin-left:8px; vertical-align:middle; }
+ header .stats { color:var(--muted); font-size:12.5px; }
+ header .stats b { color:var(--fg); }
+ header .keyhelp { font-size:11px; color:var(--muted); margin-top:6px; }
+ header .keyhelp kbd { display:inline-block; padding:1px 5px; font-size:10px; background:#f1efe9; border:1px solid var(--border); border-radius:3px; font-family:ui-monospace,Menlo,monospace; margin:0 2px; }
+ main { padding:22px 28px 80px; }
+ .row {
+ display:grid; grid-template-columns:repeat(4, 1fr); gap:12px;
+ margin-bottom:18px; background:var(--card); border:1px solid var(--border);
+ border-radius:10px; padding:12px; transition:opacity .25s;
+ }
+ .row.decided { opacity:0.4; pointer-events:none; }
+ .row .tile { position:relative; aspect-ratio:1; background:#f0eee8; overflow:hidden; border-radius:6px; cursor:pointer; transition:transform .12s, box-shadow .12s; border:3px solid transparent; }
+ .row .tile:hover { transform:scale(1.02); box-shadow:0 4px 14px rgba(0,0,0,0.08); }
+ .row .tile.picked { border-color:var(--pick); box-shadow:0 0 0 2px rgba(29,107,58,0.18); }
+ .row .tile img { width:100%; height:100%; object-fit:cover; display:block; }
+ .row .tile .label {
+ position:absolute; top:6px; left:6px; padding:2px 8px; font-size:10px;
+ letter-spacing:0.08em; text-transform:uppercase; border-radius:2px;
+ background:rgba(0,0,0,0.78); color:#fff; font-weight:600;
+ }
+ .row .tile .label.root { background:var(--root); }
+ .row .tile .label.A { background:#9b6b3f; }
+ .row .tile .label.B { background:#7b3b8e; }
+ .row .tile .label.C { background:#8c283c; }
+ .row .tile .label.D { background:#3f6b9b; }
+ .row .tile .label.E { background:#5a7a3a; }
+ .row .tile .ground {
+ position:absolute; bottom:6px; right:6px; padding:2px 6px; font-size:9.5px;
+ letter-spacing:0.05em; background:rgba(255,255,255,0.92); color:#1a1a1a;
+ border-radius:2px; font-weight:600;
+ }
+ .row .meta {
+ grid-column:1/-1; display:flex; justify-content:space-between; align-items:center;
+ font-size:11.5px; color:var(--muted); padding:4px 4px 0;
+ }
+ .row .meta .motif { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; padding-right:8px; }
+ .row .meta .pick-status { font-weight:600; }
+ .row .meta button.keep-root {
+ padding:5px 12px; border:1px solid var(--border); background:var(--card);
+ border-radius:14px; font:11px var(--sans); cursor:pointer; color:var(--reject);
+ text-transform:uppercase; letter-spacing:.06em; font-weight:600;
+ }
+ .row .meta button.keep-root:hover { background:#f1efe9; border-color:var(--reject); }
+ .row .meta button.keep-root.picked { background:#f1efe9; color:var(--fg); }
+ .empty { padding:60px; text-align:center; color:var(--muted); font-size:14px; }
+ .toast { position:fixed; bottom:20px; left:50%; transform:translateX(-50%); padding:8px 16px; background:#1a1a1a; color:#fff; border-radius:20px; font-size:12.5px; opacity:0; transition:opacity .2s; pointer-events:none; z-index:99; }
+ .toast.show { opacity:1; }
+</style>
+</head>
+<body>
+<header>
+ <h1>Luxe Curator <span class="badge" id="count">…</span></h1>
+ <div class="stats">
+ <b id="pendingCount">…</b> roots pending · <b id="decidedCount">…</b> decided.
+ Click <b>any variant</b> to pick → publishes that luxe + unpublishes the root family.
+ Click <b>"keep root"</b> to reject all 3 variants and keep the original.
+ </div>
+ <div class="keyhelp">
+ <kbd>1</kbd> root <kbd>2</kbd> variant A <kbd>3</kbd> variant C <kbd>4</kbd> variant E
+ · <kbd>K</kbd> keep root · <kbd>↓</kbd>/<kbd>j</kbd> next row · <kbd>↑</kbd>/<kbd>k</kbd> prev row
+ </div>
+</header>
+<main>
+ <div id="rows"><div class="empty">Loading…</div></div>
+</main>
+<div class="toast" id="toast"></div>
+<script>
+let DATA = [];
+let FOCUS = 0;
+
+async function loadData() {
+ const r = await fetch('/api/luxe-curator');
+ if (!r.ok) throw new Error('fetch failed: ' + r.status);
+ return r.json();
+}
+
+function toast(msg) {
+ const t = document.getElementById('toast');
+ t.textContent = msg;
+ t.classList.add('show');
+ clearTimeout(t._tm);
+ t._tm = setTimeout(() => t.classList.remove('show'), 1600);
+}
+
+function render() {
+ const main = document.getElementById('rows');
+ document.getElementById('count').textContent = DATA.length;
+ document.getElementById('pendingCount').textContent = DATA.length;
+ if (!DATA.length) {
+ main.innerHTML = '<div class="empty">No pending roots. Queue some with <code>node scripts/queue-luxe-curator.js --limit=10</code></div>';
+ return;
+ }
+ main.innerHTML = DATA.map((p, i) => {
+ const variantTiles = p.variants.map(v => `
+ <div class="tile" data-pick="variant" data-luxe-id="${v.new_id}" data-variant="${v.variant}" data-row="${i}" title="Pick variant ${v.variant} (${v.ground})">
+ <img loading="lazy" src="/designs/img/by-id/${v.new_id}" alt="${v.variant}">
+ <span class="label ${v.variant}">Variant ${v.variant}</span>
+ <span class="ground">${v.ground}</span>
+ </div>
+ `).join('');
+ return `
+ <div class="row" data-row="${i}" data-root="${p.root_id}" id="row-${i}">
+ <div class="tile" data-pick="root" data-row="${i}" title="Keep root (don't publish any variant)">
+ <img loading="lazy" src="/designs/img/by-id/${p.root_id}?asis=1" alt="root ${p.root_id}">
+ <span class="label root">Root #${p.root_id}</span>
+ </div>
+ ${variantTiles}
+ <div class="meta">
+ <span class="motif" title="${p.motif||''}">${p.motif || ''}</span>
+ <span class="pick-status" id="status-${i}"></span>
+ <button class="keep-root" data-pick="keep" data-row="${i}">Keep root — reject all 3</button>
+ </div>
+ </div>
+ `;
+ }).join('');
+ // Wire clicks
+ main.querySelectorAll('[data-pick]').forEach(el => {
+ el.addEventListener('click', (e) => {
+ const kind = el.dataset.pick;
+ const row = parseInt(el.dataset.row, 10);
+ if (kind === 'variant') {
+ pickVariant(row, parseInt(el.dataset.luxeId, 10), el.dataset.variant);
+ } else if (kind === 'keep' || kind === 'root') {
+ keepRoot(row);
+ }
+ });
+ });
+}
+
+async function pickVariant(rowIdx, luxeId, variant) {
+ const p = DATA[rowIdx];
+ if (!p) return;
+ try {
+ const r = await fetch('/api/luxe-curator/pick', {
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ root_id: p.root_id, picked_variant: variant, picked_luxe_id: luxeId }),
+ });
+ const j = await r.json();
+ if (!j.ok) throw new Error(j.error || 'pick failed');
+ // Mark UI
+ const row = document.getElementById('row-' + rowIdx);
+ row.querySelectorAll('.tile').forEach(t => t.classList.remove('picked'));
+ row.querySelector(`[data-luxe-id="${luxeId}"]`)?.classList.add('picked');
+ document.getElementById('status-' + rowIdx).textContent = `✓ Variant ${variant} published · ${j.unpublished_descendants} descendants unpublished`;
+ row.classList.add('decided');
+ toast(`Variant ${variant} picked for root #${p.root_id}`);
+ advance(rowIdx);
+ } catch (e) { toast('ERR: ' + e.message); }
+}
+
+async function keepRoot(rowIdx) {
+ const p = DATA[rowIdx];
+ if (!p) return;
+ try {
+ const r = await fetch('/api/luxe-curator/pick', {
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ root_id: p.root_id, picked_variant: 'NONE' }),
+ });
+ const j = await r.json();
+ if (!j.ok) throw new Error(j.error || 'keep failed');
+ const row = document.getElementById('row-' + rowIdx);
+ document.getElementById('status-' + rowIdx).textContent = '✗ All variants rejected — root kept';
+ row.classList.add('decided');
+ toast(`Root #${p.root_id} kept (all 3 rejected)`);
+ advance(rowIdx);
+ } catch (e) { toast('ERR: ' + e.message); }
+}
+
+function advance(rowIdx) {
+ // Scroll to next undecided row
+ for (let i = rowIdx + 1; i < DATA.length; i++) {
+ const row = document.getElementById('row-' + i);
+ if (row && !row.classList.contains('decided')) {
+ row.scrollIntoView({ behavior: 'smooth', block: 'start' });
+ FOCUS = i;
+ return;
+ }
+ }
+}
+
+document.addEventListener('keydown', (e) => {
+ if (e.target.matches('input,textarea')) return;
+ const p = DATA[FOCUS];
+ if (!p) return;
+ const key = e.key.toLowerCase();
+ // 1=root, 2=A, 3=C, 4=E (or whichever variants exist in that order)
+ if (key === '1') { keepRoot(FOCUS); e.preventDefault(); }
+ else if (key === 'k') { keepRoot(FOCUS); e.preventDefault(); }
+ else if (key === '2' || key === '3' || key === '4') {
+ const idx = parseInt(key, 10) - 2; // 2→0, 3→1, 4→2
+ const v = p.variants[idx];
+ if (v) { pickVariant(FOCUS, v.new_id, v.variant); e.preventDefault(); }
+ }
+ else if (key === 'j' || key === 'arrowdown') {
+ for (let i = FOCUS + 1; i < DATA.length; i++) {
+ if (!document.getElementById('row-' + i).classList.contains('decided')) {
+ document.getElementById('row-' + i).scrollIntoView({ behavior: 'smooth', block: 'start' });
+ FOCUS = i; break;
+ }
+ }
+ e.preventDefault();
+ }
+ else if (key === 'k' && e.shiftKey || key === 'arrowup') {
+ for (let i = FOCUS - 1; i >= 0; i--) {
+ if (!document.getElementById('row-' + i).classList.contains('decided')) {
+ document.getElementById('row-' + i).scrollIntoView({ behavior: 'smooth', block: 'start' });
+ FOCUS = i; break;
+ }
+ }
+ e.preventDefault();
+ }
+});
+
+loadData().then(d => {
+ DATA = d.items || [];
+ document.getElementById('decidedCount').textContent = d.decided || 0;
+ render();
+}).catch(e => {
+ document.getElementById('rows').innerHTML = '<div class="empty">Failed to load: ' + e.message + '</div>';
+});
+</script>
+</body>
+</html>
diff --git a/scripts/gen-luxe.js b/scripts/gen-luxe.js
index e022588..5d09bc2 100644
--- a/scripts/gen-luxe.js
+++ b/scripts/gen-luxe.js
@@ -25,12 +25,14 @@ 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.
+// --variant=<A|B|C|D|E> forces a specific heritage-house aesthetic.
const VARIANT = ((process.argv.find(a => a.startsWith('--variant=')) || '').split('=')[1] || '').toUpperCase();
+// --curator-mode lands variants as is_published=FALSE without touching
+// the source. For the hot-or-not curator workflow where Steve picks the
+// keeper from a 4-up before anything ships.
+const CURATOR = process.argv.includes('--curator-mode');
if (!Number.isFinite(SRC_ID) || !MOTIF) {
- console.error('usage: <src_id> "<motif>" [--texture-cat=<grasscloth|linen|cork|silk|mica|...>] [--variant=<A|B|C|D|E>]');
+ console.error('usage: <src_id> "<motif>" [--texture-cat=<grasscloth|linen|cork|silk|mica|...>] [--variant=<A|B|C|D|E>] [--curator-mode]');
process.exit(2);
}
@@ -198,13 +200,16 @@ VALUES
${esc(outPath)},
${esc(d.dominant_hex)},
${esc(d.category)},
- TRUE,
+ ${CURATOR ? 'FALSE' : 'TRUE'},
${SRC_ID})
RETURNING id;`;
const newId = parseInt(psql(insertSQL), 10);
if (!newId) throw new Error('insert failed');
psql(`UPDATE spoon_all_designs SET image_url='/designs/img/by-id/${newId}' WHERE id=${newId}`);
- psql(`UPDATE spoon_all_designs SET is_published=FALSE WHERE id=${SRC_ID}`);
+ // In curator mode we DO NOT touch the source — Steve hasn't picked yet.
+ if (!CURATOR) {
+ psql(`UPDATE spoon_all_designs SET is_published=FALSE WHERE id=${SRC_ID}`);
+ }
console.log(`[gen-luxe] PG id: ${newId}`);
console.log(`[gen-luxe] view: http://127.0.0.1:9877/design/${newId}`);
})().catch(e => { console.error('FATAL', e.message); process.exit(1); });
diff --git a/scripts/queue-luxe-curator.js b/scripts/queue-luxe-curator.js
new file mode 100644
index 0000000..313109f
--- /dev/null
+++ b/scripts/queue-luxe-curator.js
@@ -0,0 +1,186 @@
+#!/usr/bin/env node
+// queue-luxe-curator — for each root in <category>, generate 3 heritage
+// variants (A=de Gournay chinoiserie, C=1838 flocked velvet, E=Brunschwig
+// & Fils archive) into the curator queue. Variants land as
+// is_published=FALSE — Steve picks the keeper per row via the
+// /luxe-curator.html hot-or-not gallery, which flips publish state on
+// chosen variant + unpublishes root descendants.
+//
+// Skips:
+// - any root that already has a luxe-v2 child in the queue
+// - rotates --texture-cat per variant within a root so the 3 options
+// also vary on ground (silk for C/flock, raffia for A/chinoiserie,
+// grasscloth for E/archive) — gives Steve real range, not 3
+// near-duplicates.
+//
+// Usage:
+// node scripts/queue-luxe-curator.js [--category=drunk-animals]
+// [--limit=N] [--concurrency=4]
+// [--variants=A,C,E] [--dry-run]
+//
+// Output: data/luxe-curator-queue.jsonl (append-only, one row per gen)
+
+const fs = require('fs');
+const path = require('path');
+const { spawn, spawnSync } = require('child_process');
+
+const ARG = (k, dflt) => {
+ const a = process.argv.find(x => x.startsWith(`--${k}=`));
+ return a ? a.split('=')[1] : dflt;
+};
+const FLAG = (k) => process.argv.includes(`--${k}`);
+
+const CATEGORY = ARG('category', 'drunk-animals');
+const LIMIT = parseInt(ARG('limit', '0'), 10);
+const CONCURRENCY = parseInt(ARG('concurrency', '4'), 10);
+const VARIANTS = ARG('variants', 'A,C,E').toUpperCase().split(',').filter(v => 'ABCDE'.includes(v));
+const DRY = FLAG('dry-run');
+
+const ROOT_DIR = path.join(__dirname, '..');
+const LOG = path.join(ROOT_DIR, 'data', 'luxe-curator-queue.jsonl');
+
+// Ground pairings per variant — picked to match each heritage house's
+// own canonical material rather than rotating arbitrarily.
+const VARIANT_GROUND = {
+ A: 'raffia', // de Gournay hand-painted chinoiserie on raffia/silk
+ B: 'silk',
+ C: 'silk', // 1838 flocked velvet always on silk for the flock pop
+ D: 'grasscloth', // Cole & Son Whimsical on grasscloth
+ E: 'grasscloth', // Brunschwig & Fils archive on linen/grasscloth
+};
+
+function psql(sql) {
+ const r = spawnSync('psql', ['dw_unified', '-At', '-q', '-F|'], { input: sql, encoding: 'utf8' });
+ if (r.status !== 0) throw new Error(r.stderr || 'psql failed');
+ return r.stdout.trim();
+}
+
+function pickRoots() {
+ // Same recursive parent-walk as roll-luxe-c, but skip roots that already
+ // have any luxe-v2 child (curator-mode rows count too — they're in the queue).
+ const sql = `
+ WITH RECURSIVE chain AS (
+ SELECT id, parent_design_id, prompt, generator, id AS leaf_id, 0 AS depth
+ FROM spoon_all_designs
+ WHERE category = '${CATEGORY.replace(/'/g, "''")}'
+ AND brand = 'wallco.ai'
+ AND is_published = TRUE
+ AND local_path IS NOT NULL
+ AND generator NOT LIKE '%luxe%'
+ UNION ALL
+ SELECT s.id, s.parent_design_id, s.prompt, s.generator, c.leaf_id, c.depth + 1
+ FROM spoon_all_designs s
+ JOIN chain c ON s.id = c.parent_design_id
+ WHERE c.depth < 10
+ ),
+ roots AS (
+ SELECT DISTINCT ON (leaf_id) leaf_id, id AS root_id, prompt AS root_prompt
+ FROM chain
+ ORDER BY leaf_id, depth DESC
+ ),
+ deduped AS (
+ SELECT DISTINCT root_id, root_prompt FROM roots
+ )
+ SELECT d.root_id, regexp_replace(d.root_prompt, E'\\n|\\r', ' ', 'g')
+ FROM deduped d
+ LEFT JOIN spoon_all_designs lux
+ ON lux.parent_design_id = d.root_id
+ AND lux.generator LIKE '%luxe%'
+ WHERE lux.id IS NULL
+ ORDER BY d.root_id
+ ${LIMIT > 0 ? `LIMIT ${LIMIT}` : ''}
+ `;
+ const raw = psql(sql);
+ if (!raw) return [];
+ return raw.split('\n').map(line => {
+ const [rootId, ...promptParts] = line.split('|');
+ return { rootId: parseInt(rootId, 10), prompt: promptParts.join('|') };
+ }).filter(r => Number.isFinite(r.rootId));
+}
+
+function extractMotif(rootPrompt, len = 300) {
+ let m = rootPrompt.trim().slice(0, len);
+ const dot = m.indexOf('. ');
+ if (dot > 60 && dot < m.length - 1) m = m.slice(0, dot);
+ return m.trim();
+}
+
+function runGenLuxe(rootId, motif, variant, ground) {
+ return new Promise((resolve) => {
+ const args = [
+ path.join(__dirname, 'gen-luxe.js'),
+ String(rootId), motif,
+ `--variant=${variant}`,
+ `--texture-cat=${ground}`,
+ `--curator-mode`,
+ ];
+ const t0 = Date.now();
+ const child = spawn('node', args, { cwd: ROOT_DIR, env: process.env });
+ let stdout = '', stderr = '';
+ child.stdout.on('data', d => { stdout += d; });
+ child.stderr.on('data', d => { stderr += d; });
+ child.on('close', (code) => {
+ const durationMs = Date.now() - t0;
+ const m = stdout.match(/\[gen-luxe\] PG id: (\d+)/);
+ const newId = m ? parseInt(m[1], 10) : null;
+ resolve({ ok: code === 0 && newId !== null, code, newId, durationMs, stderr: stderr.slice(-300) });
+ });
+ });
+}
+
+function logResult(entry) {
+ fs.appendFileSync(LOG, JSON.stringify(entry) + '\n');
+}
+
+(async () => {
+ const roots = pickRoots();
+ const totalCalls = roots.length * VARIANTS.length;
+ const estCost = (totalCalls * 0.04).toFixed(2);
+ console.log(`[queue-luxe-curator] category=${CATEGORY} candidates=${roots.length} variants=${VARIANTS.join('+')} total_calls=${totalCalls} est_cost=$${estCost} ${DRY ? '(DRY RUN)' : ''}`);
+ if (DRY) {
+ for (const r of roots.slice(0, 4)) {
+ const motif = extractMotif(r.prompt, 100);
+ console.log(` root #${r.rootId} → variants ${VARIANTS.map(v => `${v}(${VARIANT_GROUND[v]})`).join(', ')} · "${motif}…"`);
+ }
+ if (roots.length > 4) console.log(` … and ${roots.length - 4} more`);
+ return;
+ }
+ if (!roots.length) { console.log('[queue-luxe-curator] no candidates'); return; }
+
+ // Build the work queue: one job per (root, variant)
+ const jobs = [];
+ for (const r of roots) {
+ const motif = extractMotif(r.prompt);
+ for (const v of VARIANTS) {
+ jobs.push({ rootId: r.rootId, motif, variant: v, ground: VARIANT_GROUND[v] });
+ }
+ }
+
+ const startedAt = Date.now();
+ let okCount = 0, errCount = 0, i = 0;
+
+ async function worker(wid) {
+ while (jobs.length) {
+ const j = jobs.shift();
+ if (!j) return;
+ const idx = ++i;
+ const res = await runGenLuxe(j.rootId, j.motif, j.variant, j.ground);
+ const entry = {
+ ts: new Date().toISOString(),
+ worker: wid, idx, total: jobs.length + idx,
+ root_id: j.rootId, variant: j.variant, ground: j.ground,
+ motif: j.motif.slice(0, 200),
+ ok: res.ok, new_id: res.newId, duration_ms: res.durationMs,
+ ...(res.ok ? {} : { code: res.code, stderr: res.stderr }),
+ };
+ if (res.ok) okCount++; else errCount++;
+ logResult(entry);
+ const elapsed = ((Date.now() - startedAt) / 1000).toFixed(1);
+ console.log(`[w${wid}] ${idx} root=${j.rootId} ${j.variant} (${j.ground}) → ${res.ok ? '✓ #' + res.newId : '✗ code=' + res.code} (${(res.durationMs/1000).toFixed(1)}s) · totals: ok=${okCount} err=${errCount} · ${elapsed}s wall`);
+ }
+ }
+
+ await Promise.all(Array.from({ length: CONCURRENCY }, (_, k) => worker(k + 1)));
+ const totalSec = ((Date.now() - startedAt) / 1000).toFixed(1);
+ console.log(`\n[queue-luxe-curator] done · ok=${okCount} err=${errCount} actual_cost≈$${(okCount * 0.04).toFixed(2)} · ${totalSec}s wall · queue=${LOG}`);
+})().catch(e => { console.error('FATAL', e.stack || e.message); process.exit(1); });
← f34f3f9 feat(design page): tag remaining buyer blocks for drawer rel
·
back to Wallco Ai
·
lib/subject-detector — Gemini vision gate for "is the prompt caabe86 →