[object Object]

← back to Wallco Ai

snapshot: backup runtime state (3 files)

1e5fc814d56b1d129d23e14a70d277e3a5fd8689 · 2026-05-13 12:16:01 -0700 · SteveStudio2

Files touched

Diff

commit 1e5fc814d56b1d129d23e14a70d277e3a5fd8689
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Wed May 13 12:16:01 2026 -0700

    snapshot: backup runtime state (3 files)
---
 data/designs.json                       | 341 ++++++++++++++++++++++++++++++++
 scripts/regen-bamboo-trellis-to-cane.js |   1 +
 scripts/settlement-gate.js              | 146 ++++++++++++++
 3 files changed, 488 insertions(+)

diff --git a/data/designs.json b/data/designs.json
index b70a230..5f0a813 100644
--- a/data/designs.json
+++ b/data/designs.json
@@ -71862,5 +71862,346 @@
     "user_scale_good": null,
     "user_stars": null,
     "room_mockups": []
+  },
+  {
+    "id": 3497,
+    "kind": "seamless_tile",
+    "category": "colorways-imperial-garden-barone",
+    "dominant_hex": "#2b3c2d",
+    "saturation": 0.165,
+    "title": "Sage Origin No.3497",
+    "handle": "wallco-3497",
+    "image_url": "/designs/img/dig1984_1778699657258_998252679.png",
+    "filename": "dig1984_1778699657258_998252679.png",
+    "generator": "wallco.ai",
+    "seed": 998252679,
+    "is_published": true,
+    "created_at": "2026-05-13T19:14:17.373303+00:00",
+    "motifs": [
+      "floral",
+      "garden",
+      "chinoiserie",
+      "traditional"
+    ],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3498,
+    "kind": "seamless_tile",
+    "category": "colorways-imperial-garden-barone",
+    "dominant_hex": "#aab083",
+    "saturation": 0.222,
+    "title": "Olive Folio No.3498",
+    "handle": "wallco-3498",
+    "image_url": "/designs/img/dig1984_1778699664718_784717064.png",
+    "filename": "dig1984_1778699664718_784717064.png",
+    "generator": "wallco.ai",
+    "seed": 784717064,
+    "is_published": true,
+    "created_at": "2026-05-13T19:14:24.851997+00:00",
+    "motifs": [
+      "floral",
+      "garden",
+      "chinoiserie",
+      "traditional"
+    ],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3499,
+    "kind": "seamless_tile",
+    "category": "colorways-imperial-garden-barone",
+    "dominant_hex": "#999354",
+    "saturation": 0.291,
+    "title": "Honey Reverie No.3499",
+    "handle": "wallco-3499",
+    "image_url": "/designs/img/dig1984_1778699674623_1900836927.png",
+    "filename": "dig1984_1778699674623_1900836927.png",
+    "generator": "wallco.ai",
+    "seed": 1900836927,
+    "is_published": true,
+    "created_at": "2026-05-13T19:14:34.749891+00:00",
+    "motifs": [
+      "floral",
+      "garden",
+      "chinoiserie",
+      "traditional"
+    ],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3500,
+    "kind": "seamless_tile",
+    "category": "colorways-imperial-garden-barone",
+    "dominant_hex": "#294b2f",
+    "saturation": 0.293,
+    "title": "Sage Atelier No.3500",
+    "handle": "wallco-3500",
+    "image_url": "/designs/img/dig1984_1778699682239_1550949847.png",
+    "filename": "dig1984_1778699682239_1550949847.png",
+    "generator": "wallco.ai",
+    "seed": 1550949847,
+    "is_published": true,
+    "created_at": "2026-05-13T19:14:42.359749+00:00",
+    "motifs": [
+      "floral",
+      "garden",
+      "chinoiserie",
+      "traditional"
+    ],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3501,
+    "kind": "seamless_tile",
+    "category": "colorways-imperial-garden-barone",
+    "dominant_hex": "#ddedde",
+    "saturation": 0.308,
+    "title": "Sage Studio No.3501",
+    "handle": "wallco-3501",
+    "image_url": "/designs/img/dig1984_1778699690522_130051995.png",
+    "filename": "dig1984_1778699690522_130051995.png",
+    "generator": "wallco.ai",
+    "seed": 130051995,
+    "is_published": true,
+    "created_at": "2026-05-13T19:14:51.524677+00:00",
+    "motifs": [
+      "floral",
+      "garden",
+      "chinoiserie",
+      "traditional"
+    ],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3502,
+    "kind": "seamless_tile",
+    "category": "colorways-imperial-garden-barone",
+    "dominant_hex": "#8f9d8e",
+    "saturation": 0.071,
+    "title": "Ash Origin No.3502",
+    "handle": "wallco-3502",
+    "image_url": "/designs/img/dig1984_1778699699762_2138836705.png",
+    "filename": "dig1984_1778699699762_2138836705.png",
+    "generator": "wallco.ai",
+    "seed": 2138836705,
+    "is_published": true,
+    "created_at": "2026-05-13T19:14:59.897359+00:00",
+    "motifs": [
+      "floral",
+      "garden",
+      "chinoiserie",
+      "traditional"
+    ],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3503,
+    "kind": "seamless_tile",
+    "category": "colorways-imperial-garden-barone",
+    "dominant_hex": "#c3d5e6",
+    "saturation": 0.412,
+    "title": "Sapphire Folio No.3503",
+    "handle": "wallco-3503",
+    "image_url": "/designs/img/dig1984_1778699707050_1568366990.png",
+    "filename": "dig1984_1778699707050_1568366990.png",
+    "generator": "wallco.ai",
+    "seed": 1568366990,
+    "is_published": true,
+    "created_at": "2026-05-13T19:15:07.174861+00:00",
+    "motifs": [
+      "floral",
+      "garden",
+      "chinoiserie",
+      "traditional"
+    ],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3504,
+    "kind": "seamless_tile",
+    "category": "colorways-imperial-garden-barone",
+    "dominant_hex": "#ddf0fc",
+    "saturation": 0.838,
+    "title": "Sapphire Reverie No.3504",
+    "handle": "wallco-3504",
+    "image_url": "/designs/img/dig1984_1778699715240_2116154951.png",
+    "filename": "dig1984_1778699715240_2116154951.png",
+    "generator": "wallco.ai",
+    "seed": 2116154951,
+    "is_published": true,
+    "created_at": "2026-05-13T19:15:15.367337+00:00",
+    "motifs": [
+      "floral",
+      "garden",
+      "chinoiserie",
+      "traditional"
+    ],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3505,
+    "kind": "seamless_tile",
+    "category": "colorways-imperial-garden-barone",
+    "dominant_hex": "#dcdaee",
+    "saturation": 0.37,
+    "title": "Sapphire Atelier No.3505",
+    "handle": "wallco-3505",
+    "image_url": "/designs/img/dig1984_1778699723292_657474069.png",
+    "filename": "dig1984_1778699723292_657474069.png",
+    "generator": "wallco.ai",
+    "seed": 657474069,
+    "is_published": true,
+    "created_at": "2026-05-13T19:15:23.424239+00:00",
+    "motifs": [
+      "floral",
+      "garden",
+      "chinoiserie",
+      "traditional"
+    ],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3506,
+    "kind": "seamless_tile",
+    "category": "colorways-imperial-garden-barone",
+    "dominant_hex": "#c7e7f7",
+    "saturation": 0.75,
+    "title": "Sapphire Studio No.3506",
+    "handle": "wallco-3506",
+    "image_url": "/designs/img/dig1984_1778699730782_1421708586.png",
+    "filename": "dig1984_1778699730782_1421708586.png",
+    "generator": "wallco.ai",
+    "seed": 1421708586,
+    "is_published": true,
+    "created_at": "2026-05-13T19:15:30.916211+00:00",
+    "motifs": [
+      "floral",
+      "garden",
+      "chinoiserie",
+      "traditional"
+    ],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3507,
+    "kind": "seamless_tile",
+    "category": "colorways-imperial-garden-barone",
+    "dominant_hex": "#617386",
+    "saturation": 0.16,
+    "title": "Sapphire Origin No.3507",
+    "handle": "wallco-3507",
+    "image_url": "/designs/img/dig1984_1778699739126_597530073.png",
+    "filename": "dig1984_1778699739126_597530073.png",
+    "generator": "wallco.ai",
+    "seed": 597530073,
+    "is_published": true,
+    "created_at": "2026-05-13T19:15:39.257374+00:00",
+    "motifs": [
+      "floral",
+      "garden",
+      "chinoiserie",
+      "traditional"
+    ],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3508,
+    "kind": "seamless_tile",
+    "category": "drunk-animals",
+    "dominant_hex": "#a54e7d",
+    "saturation": 0.358,
+    "title": "Plum Saunter No.3508",
+    "handle": "wallco-3508",
+    "image_url": "/designs/img/1778699731291_1338592738.png",
+    "filename": "1778699731291_1338592738.png",
+    "generator": "wallco.ai",
+    "seed": 1338592738,
+    "is_published": false,
+    "created_at": "2026-05-13T19:15:40.027593+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
+  },
+  {
+    "id": 3509,
+    "kind": "seamless_tile",
+    "category": "stoned-animals",
+    "dominant_hex": "#6d6b55",
+    "saturation": 0.124,
+    "title": "Olive Halcyon No.3509",
+    "handle": "wallco-3509",
+    "image_url": "/designs/img/1778699731480_243463689.png",
+    "filename": "1778699731480_243463689.png",
+    "generator": "wallco.ai",
+    "seed": 243463689,
+    "is_published": false,
+    "created_at": "2026-05-13T19:15:42.91227+00:00",
+    "motifs": [],
+    "user_removed": false,
+    "user_color_good": null,
+    "user_style_good": null,
+    "user_scale_good": null,
+    "user_stars": null,
+    "room_mockups": []
   }
 ]
\ No newline at end of file
diff --git a/scripts/regen-bamboo-trellis-to-cane.js b/scripts/regen-bamboo-trellis-to-cane.js
index bfc33a1..9393185 100644
--- a/scripts/regen-bamboo-trellis-to-cane.js
+++ b/scripts/regen-bamboo-trellis-to-cane.js
@@ -14,6 +14,7 @@ const fs = require('fs');
 const path = require('path');
 const crypto = require('crypto');
 const { execSync, spawnSync } = require('child_process');
+const { gateOrExit } = require('./settlement-gate');
 
 const KEY = process.env.GEMINI_API_KEY;
 if (!KEY) { console.error('GEMINI_API_KEY missing'); process.exit(1); }
diff --git a/scripts/settlement-gate.js b/scripts/settlement-gate.js
new file mode 100644
index 0000000..f541674
--- /dev/null
+++ b/scripts/settlement-gate.js
@@ -0,0 +1,146 @@
+/**
+ * Settlement pre-generation gate — call BEFORE running any Gemini batch.
+ * Mirrors the rules in ~/.claude/skills/settlement/SKILL.md. Returns
+ * { verdict, partA, partB, acceptable, reason, rewrite } where verdict is
+ * one of 'BLOCK' | 'NEEDS_REVIEW' | 'OK'.
+ *
+ * Hard rule from skill: Claude does not generate or publish a wallpaper
+ * pattern until this gate returns OK. Generators that import this should
+ * exit (or skip the variant) on BLOCK, and require explicit env-flag
+ * override on NEEDS_REVIEW.
+ *
+ * No external API calls. Pure text-pattern check against the proposed
+ * prompt — fast, free, deterministic. Post-generation image-vision check
+ * lives in lib/settlement-checker.ts on the DW side.
+ */
+'use strict';
+
+const PART_A_LEAVES = [
+  'palm', 'frond', 'banana leaf', 'monstera', 'leaves', 'leaf', 'foliage', 'jungle',
+];
+const PART_A_DIRECTIONAL = [
+  'directional', 'varied angle', 'tossed', 'scatter', 'rotated', 'multi-angle',
+  'overlapping', 'turning leaves', 'fanning',
+];
+const PART_A_OPEN_SPACE = [
+  'open space', 'breathing room', 'breathing space', 'scatter', 'tossed', 'sparse',
+];
+const PART_A_MULTICOLOR_NEG = [
+  'monochrome', 'single ink', 'one color', 'one-color', 'black ink', 'single-color',
+  'silhouette', 'tonal',
+];
+
+const PART_B = [
+  'banana', 'banana pod', 'grape', 'bird', 'birds', 'parrot', 'toucan',
+  'butterfly', 'butterflies', 'moth',
+];
+
+const ACCEPTABLE = [
+  'tree trunk', 'tree trunks', 'branch', 'branches', 'twig', 'bark',
+  'monkey', 'sloth', 'lemur', 'orangutan', 'gibbon', 'tarsier',
+  'fruit', 'cherry', 'apple', 'pear', 'pomegranate', 'fig', 'orange',
+  // NOTE: bananas/grapes excluded — those are Part B
+];
+
+const has = (text, list) => list.some(t => text.includes(t));
+
+function checkPrompt(prompt) {
+  const text = String(prompt || '').toLowerCase();
+
+  // Part A score
+  const a1 = has(text, PART_A_LEAVES) && has(text, PART_A_DIRECTIONAL);
+  const a2 = has(text, PART_A_OPEN_SPACE);
+  const a3Singlecolor = has(text, PART_A_MULTICOLOR_NEG);
+  // Multi-color is the default assumption unless the prompt explicitly says
+  // single-ink / monochrome / silhouette. "Palette: X + Y + Z" is multi-color.
+  const a3 = !a3Singlecolor && (text.includes('palette:') || text.match(/\b(red|blue|green|yellow|orange|pink|magenta|cyan|emerald|crimson|cobalt|amber)\b/) && !text.match(/\bblack and white\b/));
+
+  const partA = a1 && a2 && a3;
+
+  // Part B score
+  const partBFound = PART_B.filter(el => text.includes(el));
+  const partB = partBFound.length > 0;
+
+  // Acceptable cues
+  const acceptableFound = ACCEPTABLE.filter(el => text.includes(el));
+  const acceptable = acceptableFound.length > 0;
+
+  // Verdict
+  let verdict = 'OK';
+  let reason = '';
+  let rewrite = '';
+
+  if (partA && partB) {
+    verdict = 'BLOCK';
+    reason = `Settlement violation: Part A (directional ${PART_A_LEAVES.find(l => text.includes(l)) || 'leaves'} + open space + multi-color) AND Part B (${partBFound.join(', ')}) both present.`;
+    rewrite = `Drop one of:
+  - the directional-leaf scatter (render on cane lattice / trellis / geometric substrate instead), OR
+  - the open-space / tossed composition (use edge-to-edge coverage), OR
+  - the multi-color palette (go single-ink / silhouette / monochrome).
+Any one removal lands the prompt at OK while keeping the Part B element.`;
+  } else if (partA && !partB && !acceptable) {
+    verdict = 'NEEDS_REVIEW';
+    reason = `Part A satisfied (directional leaves + open space + multi-color) but no Acceptable element (tree trunk / branch / non-prohibited fruit or animal). Borderline — adding an Acceptable cue lands it at OK.`;
+    rewrite = `Add a tree-trunk or branch reference, or a non-prohibited animal (monkey/sloth/lemur) to make the design tropical-acceptable per the settlement.`;
+  }
+
+  return {
+    verdict,
+    partA: { satisfied: partA, a1, a2, a3 },
+    partB: { satisfied: partB, found: partBFound },
+    acceptable: { satisfied: acceptable, found: acceptableFound },
+    reason,
+    rewrite,
+  };
+}
+
+// Pretty-print the verdict in the format the skill prescribes.
+function format(prompt, result) {
+  const r = result;
+  let out = '';
+  out += `SETTLEMENT GATE — VERDICT\n`;
+  out += `=========================\n`;
+  out += `Prompt:        ${String(prompt).slice(0, 100)}${prompt.length > 100 ? '…' : ''}\n`;
+  out += `Part A score:  A1=${r.partA.a1} A2=${r.partA.a2} A3=${r.partA.a3}  →  ${r.partA.satisfied ? 'satisfied' : 'not satisfied'}\n`;
+  out += `Part B score:  ${r.partB.found.length ? r.partB.found.join(', ') : 'none'}\n`;
+  out += `Acceptable:    ${r.acceptable.found.length ? r.acceptable.found.join(', ') : 'none'}\n\n`;
+  out += `VERDICT:  ${r.verdict}\n`;
+  if (r.reason) out += `\nREASON:  ${r.reason}\n`;
+  if (r.rewrite) out += `\nREWRITE SUGGESTION:\n${r.rewrite}\n`;
+  return out;
+}
+
+// gateOrExit: convenience for batch generators — calls process.exit(2) on
+// BLOCK, prints a warning on NEEDS_REVIEW (but allows continue if env
+// SETTLEMENT_ALLOW_REVIEW=1), returns silently on OK.
+function gateOrExit(prompt, opts = {}) {
+  const r = checkPrompt(prompt);
+  if (r.verdict === 'BLOCK') {
+    console.error(format(prompt, r));
+    console.error('\nBlocked by settlement gate. Rewrite the prompt or set SETTLEMENT_OVERRIDE=1 (logs to design.notes).');
+    if (!process.env.SETTLEMENT_OVERRIDE) process.exit(2);
+    console.error('SETTLEMENT_OVERRIDE=1 — proceeding under explicit operator override.');
+    return { ...r, overridden: true };
+  }
+  if (r.verdict === 'NEEDS_REVIEW') {
+    console.error(format(prompt, r));
+    if (!process.env.SETTLEMENT_ALLOW_REVIEW) {
+      console.error('Needs review. Add SETTLEMENT_ALLOW_REVIEW=1 to proceed; new rows will be is_published=FALSE.');
+      process.exit(3);
+    }
+  }
+  return r;
+}
+
+module.exports = { checkPrompt, format, gateOrExit };
+
+if (require.main === module) {
+  const prompt = process.argv.slice(2).join(' ');
+  if (!prompt) {
+    console.error('Usage: node settlement-gate.js "<prompt text to check>"');
+    process.exit(1);
+  }
+  const r = checkPrompt(prompt);
+  console.log(format(prompt, r));
+  process.exit(r.verdict === 'BLOCK' ? 2 : r.verdict === 'NEEDS_REVIEW' ? 3 : 0);
+}

← 5c53e57 snapshot: backup uncommitted work (6 files)  ·  back to Wallco Ai  ·  settlement: pre-generation legal gate + wallco-ai/scripts/se bbf4173 →