← back to Wallco Ai
seam-wave: generalize the retry-loop generator to arbitrary --ids
2fed4390d52ebf6db5b9540614d904efa509f5d3 · 2026-06-11 19:03:56 -0700 · Steve Abrams
controlnet-anchored-reroll.py wraps the proven reroll_one machinery from
controlnet-anchored-reroll-2 (image-level seam-retry until motif clears
PASS-both-axes + coverage + llava subject-recovery; insert ONLY the winner;
roots sacred) but accepts any animal-forward FAIL root via a DEFAULT_CFG canny
profile. Per-root special profiles (54076/54266) still honored via imported
ROOT_CFG. This is the SEAM_GENERATOR for scripts/seam-wave.sh.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Files touched
A scripts/controlnet-anchored-reroll.py
Diff
commit 2fed4390d52ebf6db5b9540614d904efa509f5d3
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Jun 11 19:03:56 2026 -0700
seam-wave: generalize the retry-loop generator to arbitrary --ids
controlnet-anchored-reroll.py wraps the proven reroll_one machinery from
controlnet-anchored-reroll-2 (image-level seam-retry until motif clears
PASS-both-axes + coverage + llava subject-recovery; insert ONLY the winner;
roots sacred) but accepts any animal-forward FAIL root via a DEFAULT_CFG canny
profile. Per-root special profiles (54076/54266) still honored via imported
ROOT_CFG. This is the SEAM_GENERATOR for scripts/seam-wave.sh.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
scripts/controlnet-anchored-reroll.py | 123 ++++++++++++++++++++++++++++++++++
1 file changed, 123 insertions(+)
diff --git a/scripts/controlnet-anchored-reroll.py b/scripts/controlnet-anchored-reroll.py
new file mode 100644
index 0000000..3dcc71b
--- /dev/null
+++ b/scripts/controlnet-anchored-reroll.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python3
+"""controlnet-anchored-reroll.py — GENERALIZED seam-fix re-roll generator for the
+seam-wave scale-up. Accepts arbitrary --ids (any animal-forward FAIL root), not
+just the two hard-scoped glassware roots of controlnet-anchored-reroll-2.py.
+
+It is a thin generalization of controlnet-anchored-reroll-2.py — it reuses that
+script's PROVEN image-level retry machinery byte-for-byte (reroll_one):
+
+ • ControlNet canny edge-anchor on a CROPPED single focal motif (find_focal_crop
+ + build_canny_hint + gen_controlnet_seamless from controlnet-anchored-redo) —
+ the canny path is the one empirically shown to produce clean seamless tiles
+ (reroll-2's own note: text-led produced busy edge-FAILING tiles 0/12; canny
+ cleared PASS-both-axes reliably). Subject-loss — the only canny failure mode —
+ is handled by the subject-recovery vision gate below.
+ • Circular-pad native-seamless txt2img (SeamlessTile + MakeCircularVAE, denoise
+ 1.0) → the tile wraps by construction, ZERO post-hoc smear.
+ • IMAGE-LEVEL SEAM-RETRY LOOP: re-roll the seed until the raw motif tile clears
+ cross-seam PASS on BOTH axes (in-memory verify-edge-seamless) AND coverage is
+ in band AND the subject-recovery gate (free local llava) confirms the animal
+ is present. Cap MAX_RETRIES. INSERT the DB row ONLY for the final passing
+ candidate — exactly one new id per root max (all_designs is INSERT-only; a
+ failed attempt must never touch the DB).
+ • Composite onto a REAL seamless natural-fibre ground, re-verify the written
+ composite, then insert.
+
+DEFAULT config (DEFAULT_CFG) is the animal-forward canny profile: a moderate
+focal crop, weak-canny strength so layout stays open, coverage band 8-40%, and
+canny ENABLED (no_canny=False). Per-root overrides can still be supplied via
+ROOT_CFG (imported from reroll-2 so 54076/54266 keep their tuned profiles if ever
+re-run through here). The ground rotates across roots so Steve sees range.
+
+SACRED ROOTS: never overwrites a root. Final candidate → NEW file + NEW id,
+is_published=FALSE, user_removed=FALSE, parent_design_id=<root>. Never published
+live. Settlement gate untouched (children of already-passed roots, no new prompt
+class). DATABASE_URL self-resolves, never echoed. Does NOT use make_seamless.py /
+force-edge-seamless.py.
+
+Usage (called by scripts/seam-wave.sh):
+ python3 scripts/controlnet-anchored-reroll.py --ids 43199,54385,55272
+ python3 scripts/controlnet-anchored-reroll.py --ids 43199 --max-retries 8
+"""
+import argparse, datetime, json, os, sys
+from pathlib import Path
+
+ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+QUEUE = os.path.join(ROOT, 'data', 'seam-fix-queue.jsonl')
+
+sys.path.insert(0, os.path.join(ROOT, 'scripts'))
+from importlib import import_module
+cnar = import_module('controlnet-anchored-redo') # GROUNDS, machinery
+reroll2 = import_module('controlnet-anchored-reroll-2') # proven reroll_one + ROOT_CFG
+edgeverify = import_module('verify-edge-seamless')
+
+# Reuse reroll-2's per-root special profiles where they exist (e.g. the two
+# glassware roots if ever routed through here). Everything else uses DEFAULT_CFG.
+ROOT_CFG = dict(reroll2.ROOT_CFG)
+
+# DEFAULT animal-forward canny profile. The animal is the dominant structure (we
+# pre-filter for that), so the canny crop anchors the RIGHT subject and a weak
+# strength keeps the surround open. Subject-recovery gate still guards against the
+# rare roll where the crop loses the figure.
+# ground is filled per-root from cnar.GROUNDS at call time (range, not one note).
+DEFAULT_CFG = {
+ 'no_canny': False,
+ 'cov_lo': 8.0, 'cov_hi': 40.0, # reject empty (too low) / over-busy (too high)
+ 'crop_frac': 0.30, 'motif_px': 170, 'cn_strength': 0.50, 'cn_end': 0.55,
+}
+
+
+def cfg_for(root, ground):
+ cfg = dict(ROOT_CFG.get(root, DEFAULT_CFG))
+ cfg.setdefault('ground', ground)
+ # a per-root override may pin its own ground; otherwise use the rotated one
+ if root not in ROOT_CFG:
+ cfg['ground'] = ground
+ return cfg
+
+
+def main():
+ ap = argparse.ArgumentParser()
+ ap.add_argument('--ids', required=True,
+ help='comma-separated root ids (any animal-forward FAIL root)')
+ ap.add_argument('--max-retries', type=int, default=8)
+ ap.add_argument('--pass-tol', type=float, default=edgeverify.PASS_TOL)
+ ap.add_argument('--warn-tol', type=float, default=edgeverify.WARN_TOL)
+ ap.add_argument('--ground', help='force one ground for all (else rotates)')
+ args = ap.parse_args()
+
+ ids = [int(x) for x in args.ids.split(',') if x.strip()]
+ if not ids:
+ print(json.dumps({'error': 'no ids'}), file=sys.stderr)
+ sys.exit(2)
+
+ results = []
+ for i, rid in enumerate(ids):
+ ground = args.ground or cnar.GROUNDS[i % len(cnar.GROUNDS)]
+ cfg = cfg_for(rid, ground)
+ try:
+ # DEFAULT_CFG roots are canny (no_canny=False); reroll_one honors that.
+ # force_canny stays False — the cfg's no_canny flag already drives the path.
+ r = reroll2.reroll_one(rid, cfg, args.max_retries,
+ args.pass_tol, args.warn_tol, force_canny=False)
+ except Exception as e:
+ r = {'root_id': rid, 'ok': False, 'error': str(e), 'ground': cfg.get('ground')}
+ # stamp the generator name so the ledger/queue is honest about which script ran
+ if isinstance(r, dict):
+ r.setdefault('generator', 'controlnet-anchored-reroll')
+ r['generator'] = 'controlnet-anchored-reroll'
+ results.append(r)
+ if r.get('ok'):
+ with open(QUEUE, 'a') as q:
+ q.write(json.dumps(r) + '\n')
+ v = r.get('edge_verdict', r.get('error', '?'))
+ print(f"=> root {rid}: {'OK' if r.get('ok') else 'FAIL'} edge={v} "
+ f"new_id={r.get('new_id')} attempts={r.get('attempts_used')} "
+ f"ground={r.get('ground')}", file=sys.stderr)
+
+ print(json.dumps(results, indent=2))
+ sys.exit(0 if all(r.get('ok') for r in results) else 1)
+
+
+if __name__ == '__main__':
+ main()
← 0438663 seam-wave: build manifest — 3 animal-forward FAIL roots (431
·
back to Wallco Ai
·
overnight-seam-loop: single log sink (drop tee, launcher >> 81fefac →