← back to Wallco Ai
Task 31: circular-padding is now the DEFAULT for all seamless_tile gen
899e7fda663e255d19e482a052811c63fb5a87ad · 2026-05-27 14:40:50 -0700 · Steve Abrams
shouldCircularPad() returns true for every non-mural seamless_tile (no longer
gated on TILE_CATEGORIES); generate() force-routes those to the comfy backend
(only comfy patches UNet+VAE Conv2d to circular padding — replicate/flux/stub
ship padding=zeros = guaranteed edge-wrap FAIL). Prompt profile (silhouette vs
dense) stays keyed on TILE_CATEGORIES, decoupled from the padding decision.
Override knobs: WALLCO_NO_CIRCULAR=1 kill-switch, WALLCO_FORCE_TILEABLE=1 legacy
force (override design settled via /dtd -> verdict C).
Validated: damask #53712 + cactus #53716 both PASS edges-agent (all 6 lenses)
+ fuzzy_seam_scan, is_published=FALSE. All 4 edge-wrap lenses PASS across every
sampled comfy tile (vs Replicate tb=15-65 FAIL). The generator's own seam gate
still skipped 2/4 non-seamless attempts -> circular-pad raises the rate, the gate
stays essential. Internal h_mid can still WARN on some tiles (separate defect).
Files touched
M scripts/generate_designs.js
Diff
commit 899e7fda663e255d19e482a052811c63fb5a87ad
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed May 27 14:40:50 2026 -0700
Task 31: circular-padding is now the DEFAULT for all seamless_tile gen
shouldCircularPad() returns true for every non-mural seamless_tile (no longer
gated on TILE_CATEGORIES); generate() force-routes those to the comfy backend
(only comfy patches UNet+VAE Conv2d to circular padding — replicate/flux/stub
ship padding=zeros = guaranteed edge-wrap FAIL). Prompt profile (silhouette vs
dense) stays keyed on TILE_CATEGORIES, decoupled from the padding decision.
Override knobs: WALLCO_NO_CIRCULAR=1 kill-switch, WALLCO_FORCE_TILEABLE=1 legacy
force (override design settled via /dtd -> verdict C).
Validated: damask #53712 + cactus #53716 both PASS edges-agent (all 6 lenses)
+ fuzzy_seam_scan, is_published=FALSE. All 4 edge-wrap lenses PASS across every
sampled comfy tile (vs Replicate tb=15-65 FAIL). The generator's own seam gate
still skipped 2/4 non-seamless attempts -> circular-pad raises the rate, the gate
stays essential. Internal h_mid can still WARN on some tiles (separate defect).
---
scripts/generate_designs.js | 73 ++++++++++++++++++++++++++++++++-------------
1 file changed, 52 insertions(+), 21 deletions(-)
diff --git a/scripts/generate_designs.js b/scripts/generate_designs.js
index 2f882b1..d7ac6f7 100644
--- a/scripts/generate_designs.js
+++ b/scripts/generate_designs.js
@@ -74,6 +74,42 @@ function tileProfilePrompts(rawPrompt) {
return { positive, negative };
}
+// 2026-05-27 (Task 31) — Circular-padding (SeamlessTile + MakeCircularVAE) is
+// now the DEFAULT for EVERY seamless_tile generation, not just TILE_CATEGORIES.
+// Validated this session: ComfyUI circular-padding gives ~100% seam-PASS on a
+// fresh cactus sample (edge ΔE 1–3) vs Replicate's ~17% catalog-wide. Raw
+// Replicate is the seam-killer for tiles — padding='zeros' guarantees an
+// edge-wrap mismatch no prompt or post-heal fully fixes. Circular padding only
+// exists on the comfy backend, so generate() also force-routes tiles to comfy.
+//
+// SINGLE SOURCE OF TRUTH: both genComfy() (which workflow nodes) and generate()
+// (which backend) call this so the tileable flag and the comfy force can never
+// drift apart.
+//
+// Decoupled from PROMPT profile on purpose — the silhouette-vs-dense prompt is
+// still keyed off TILE_CATEGORIES (see generate path below). Figure-on-ground
+// silhouette categories (drunk-animals, designer-bugs, cactus) keep their
+// silhouette prompt but NOW also get circular padding: a true seamless repeat
+// wraps the subject across the boundary, and the sparse silhouette prompt keeps
+// figures centered with generous negative space so they rarely touch the seam
+// (the cactus validation is itself a single-subject silhouette).
+//
+// Murals (kind='mural' or a *mural* category) are a single non-repeating image
+// and must NEVER wrap — they are always excluded.
+//
+// Overrides (DTD verdict C, 2026-05-27 — Claude + Codex both C):
+// WALLCO_NO_CIRCULAR=1 — hard kill-switch; never circular-pad (escape
+// hatch if a future dense figure-on-ground category
+// genuinely bisects — preserves the old carve-out
+// without a code change / redeploy).
+// WALLCO_FORCE_TILEABLE=1 — legacy force-on; circular-pads even a mural.
+function shouldCircularPad(meta) {
+ if (process.env.WALLCO_NO_CIRCULAR === '1') return false;
+ if (process.env.WALLCO_FORCE_TILEABLE === '1') return true;
+ const isMural = !!meta && (meta.kind === 'mural' || /mural/i.test(meta.category || ''));
+ return !isMural;
+}
+
// Distribution of generation widths when --width is not explicitly passed.
// Override via env: GENERATE_WIDTH_POOL="24,24,36,36,52" (entries weight pick frequency).
const WIDTH_POOL = (process.env.GENERATE_WIDTH_POOL || '24,24,36,36,52')
@@ -318,16 +354,11 @@ function genComfy(prompt, seed, outPath, meta) {
// BOTH are required — patching just the UNet leaves seam-introducing decoder.
// First Fix-3 attempt shipped only SeamlessTile (commit d91f84ab); seam scores
// didn't improve because the VAE re-introduced seams. This adds the VAE patch.
- // Conditional on TILE_CATEGORIES because figure-on-ground categories
- // (drunk-animals, designer-bugs) shouldn't have the figure wrap around edges.
// Requires spinagon/ComfyUI-seamless-tiling on target ComfyUI (Mac1 9225ed5d).
- // WALLCO_FORCE_TILEABLE=1 opts a silhouette category (e.g. cactus) into the
- // circular-padding seamless workflow without adding it to TILE_CATEGORIES
- // (which would also swap its prompt to the dense tile profile). For a true
- // seamless wallpaper repeat the figure SHOULD wrap across the boundary —
- // 2026-05-27 cactus quality-redo. Default behavior unchanged when unset.
- const tileable = process.env.WALLCO_FORCE_TILEABLE === '1'
- || !!(meta && TILE_CATEGORIES.has(meta.category));
+ // 2026-05-27 (Task 31) — now DEFAULT for every non-mural seamless_tile, not
+ // just TILE_CATEGORIES. See shouldCircularPad() for the full rationale + the
+ // WALLCO_NO_CIRCULAR / WALLCO_FORCE_TILEABLE overrides.
+ const tileable = shouldCircularPad(meta);
const BASE_MODEL_REF = tileable ? ['1000', 0] : ['4', 0];
const REFINER_MODEL_REF = tileable ? ['1001', 0] : ['15', 0];
const BASE_VAE_REF = tileable ? ['2000', 0] : ['4', 2];
@@ -454,19 +485,19 @@ function genReplicateFlux(prompt, seed, outPath) {
}
function generate(prompt, seed, outPath, meta) {
- // 2026-05-26 — Dense edge-to-edge repeats (TILE_CATEGORIES) only render
- // seamlessly on the comfy backend, which patches the UNet+VAE Conv2d to
- // circular padding (SeamlessTile + MakeCircularVAE). replicate/flux/stub ship
- // padding='zeros' → guaranteed top-bottom edge-wrap FAIL that no prompt fixes.
- // Validated: replicate damask tb=15-65 ΔE FAIL vs comfy damask tb=2.14 PASS.
- // Force comfy for exactly TILE_CATEGORIES regardless of GEN_BACKEND so the
- // cron (which defaults to replicate) can't silently regenerate broken tile
- // inventory. This gate MUST mirror genComfy's `tileable` flag — figure-on-
- // ground categories (drunk-*, designer-bugs) are deliberately NOT here:
- // circular padding would wrap the figure around the seam (bisected monkey),
- // and comfy gives them no benefit, so they keep GEN_BACKEND.
+ // 2026-05-27 (Task 31) — Every seamless_tile renders seamlessly ONLY on the
+ // comfy backend, which patches the UNet+VAE Conv2d to circular padding
+ // (SeamlessTile + MakeCircularVAE). replicate/flux/stub ship padding='zeros'
+ // → guaranteed edge-wrap FAIL that no prompt or post-heal fully fixes.
+ // Validated: replicate damask tb=15-65 ΔE FAIL vs comfy damask tb=2.14 PASS;
+ // cactus comfy ~100% seam-PASS (edge ΔE 1–3) vs replicate ~17% catalog-wide.
+ // Force comfy for any design we're going to circular-pad, regardless of
+ // GEN_BACKEND, so the cron (which can default to replicate) can't silently
+ // regenerate broken tile inventory. This gate MUST mirror genComfy's
+ // `tileable` flag — both call shouldCircularPad() so they can't drift.
+ // Murals (never circular-padded) and WALLCO_NO_CIRCULAR=1 keep GEN_BACKEND.
let backend = BACKEND;
- if (meta && TILE_CATEGORIES.has(meta.category) && backend !== 'comfy') {
+ if (shouldCircularPad(meta) && backend !== 'comfy') {
backend = 'comfy';
}
switch (backend) {
← 8120fe7 drunk-curator: make Auto-ID opt-in via header toggle (off by
·
back to Wallco Ai
·
admin-card: add created date+time chip to dogs-curator + ret 08a8775 →