[object Object]

← back to Designer Wallcoverings

auto-save: 2026-07-02T09:46:55 (9 files) — pending-approval/boost-filter-consolidation-2026-06-25 shopify/scripts/cadence/data/cadence-cursor.json shopify/scripts/cadence/data/cadence-plan-am-2026-07-02.json shopify/scripts/cadence/data/upload-restore-2026-07-02.jsonl vendor-scrapers/china-seas-refresh

d10d9eba92d8dca243bad1eb66d3bb6da585a8c2 · 2026-07-02 09:47:06 -0700 · Steve Abrams

Files touched

Diff

commit d10d9eba92d8dca243bad1eb66d3bb6da585a8c2
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Jul 2 09:47:06 2026 -0700

    auto-save: 2026-07-02T09:46:55 (9 files) — pending-approval/boost-filter-consolidation-2026-06-25 shopify/scripts/cadence/data/cadence-cursor.json shopify/scripts/cadence/data/cadence-plan-am-2026-07-02.json shopify/scripts/cadence/data/upload-restore-2026-07-02.jsonl vendor-scrapers/china-seas-refresh
---
 .../scripts/sangetsu-width-recover.py              | 102 ++++++++++
 scripts/discontinued-sweep/build-verify-lists.sh   |  66 +++++++
 .../audits/thibaut-backfill-exceptions.jsonl       |  11 ++
 .../scripts/audits/thibaut-backfill-summary.json   |  12 ++
 shopify/scripts/cadence/data/cadence-cursor.json   |   2 +-
 .../cadence/data/cadence-plan-am-2026-07-02.json   | 214 +++++++++------------
 .../cadence/data/upload-restore-2026-07-02.jsonl   |  15 ++
 7 files changed, 298 insertions(+), 124 deletions(-)

diff --git a/onboarding/sangetsu-lilycolor/scripts/sangetsu-width-recover.py b/onboarding/sangetsu-lilycolor/scripts/sangetsu-width-recover.py
new file mode 100644
index 00000000..0830e5b3
--- /dev/null
+++ b/onboarding/sangetsu-lilycolor/scripts/sangetsu-width-recover.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python3
+"""sangetsu-width-recover.py — recover missing width/spec from the free Store API.
+
+The existing storeapi-enrich left 545/623 patterns with NO width. Diagnosis showed
+the width is OFTEN present in the product `description` but in prose forms the
+japan-enrich parse_spec() misses (e.g. `Width 52" / 132 cm`, `Width ... 91 cm`).
+Some patterns genuinely have NO width in the source (e.g. "Acappella") — those stay
+missing and are reported, never fabricated.
+
+CONSERVATIVE extraction — only accept a width when it's unambiguously labelled:
+  1. `<in>" / <cm> cm`     (the canonical Sangetsu spec form)  -> "<cm> cm"
+  2. `Width ...<cm> cm`     (Width-labelled cm, one number)     -> "<cm> cm"
+  3. `Width ...<in>"`       (Width-labelled inches, one number) -> "<in> Inches"
+Multiple conflicting numbers with no clear label -> SKIP (flag), never guess.
+
+Reversible: read-only fetch + atomic rewrite of spec.width only when currently
+empty (never overwrites an existing width). $0. No dw_unified/Shopify write.
+"""
+import sys, os, json, re, time
+
+HERE = os.path.dirname(os.path.abspath(__file__))
+STAGING = os.path.join(os.path.dirname(HERE), "staging", "sangetsu-staging.jsonl")
+sys.path.insert(0, os.path.expanduser("~/Projects/japan-enrich"))
+from scrape_sangetsu_specs import get, slug_of  # noqa: E402
+
+# canonical: 52" / 132 cm   (accept curly quotes)
+RE_IN_CM = re.compile(r'(\d{2,3})\s*["”″]\s*/\s*(\d{2,3})\s*cm', re.I)
+# Width-labelled single cm within 30 chars
+RE_W_CM = re.compile(r'\bwidth\b[^0-9]{0,30}?(\d{2,3})\s*cm', re.I)
+# Width-labelled single inch within 30 chars
+RE_W_IN = re.compile(r'\bwidth\b[^0-9]{0,30}?(\d{2,3})\s*["”″]', re.I)
+
+
+def extract_width(desc_html):
+    txt = re.sub(r"<[^>]+>", " ", desc_html or "")
+    txt = re.sub(r"\s+", " ", txt)
+    m = RE_IN_CM.search(txt)
+    if m:
+        return f"{m.group(2)} cm", "in/cm"
+    # count distinct cm numbers near a Width label; if exactly one, trust it
+    cms = RE_W_CM.findall(txt)
+    if cms and len(set(cms)) == 1:
+        return f"{cms[0]} cm", "width-cm"
+    ins = RE_W_IN.findall(txt)
+    if ins and len(set(ins)) == 1:
+        return f'{ins[0]} Inches', "width-in"
+    return None, ("ambiguous" if cms or ins else "absent")
+
+
+def main():
+    dry = "--apply" not in sys.argv
+    rows = [json.loads(l) for l in open(STAGING) if l.strip()]
+    before = sum(1 for p in rows if str((p.get("spec") or {}).get("width") or "").strip())
+    recovered = 0
+    reasons = {"in/cm": 0, "width-cm": 0, "width-in": 0, "ambiguous": 0, "absent": 0, "miss": 0}
+    residual = []
+    for i, p in enumerate(rows):
+        if str((p.get("spec") or {}).get("width") or "").strip():
+            continue
+        d = get(f"/products?slug={slug_of(p['source_url'])}")
+        if not d:
+            reasons["miss"] += 1
+            residual.append((p["pattern"], "no-api"))
+            continue
+        w, why = extract_width(d[0].get("description", ""))
+        if w:
+            reasons[why] += 1
+            recovered += 1
+            if not dry:
+                p.setdefault("spec", {})["width"] = w
+                p["spec"]["_width_src"] = f"storeapi:{why}"
+        else:
+            reasons[why] += 1
+            residual.append((p["pattern"], why))
+        if i % 60 == 0:
+            print(f"[{i+1}/{len(rows)}] recovered={recovered}", flush=True)
+        time.sleep(0.12)
+
+    if not dry:
+        tmp = STAGING + ".tmp"
+        with open(tmp, "w") as f:
+            for p in rows:
+                f.write(json.dumps(p, ensure_ascii=False) + "\n")
+        os.replace(tmp, STAGING)
+        after = sum(1 for p in rows if str((p.get("spec") or {}).get("width") or "").strip())
+    else:
+        after = before + recovered
+
+    print(json.dumps({
+        "mode": "DRY-RUN" if dry else "APPLIED",
+        "width_before": before, "width_after_est": after,
+        "recovered": recovered, "by_reason": reasons,
+        "residual_no_width": len(residual),
+    }, indent=2))
+    # write the residual list (genuinely-absent widths) for the record
+    with open(os.path.join(os.path.dirname(STAGING), "sangetsu-width-residual.txt"), "w") as f:
+        for name, why in residual:
+            f.write(f"{name}\t{why}\n")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/discontinued-sweep/build-verify-lists.sh b/scripts/discontinued-sweep/build-verify-lists.sh
new file mode 100755
index 00000000..24ffdc2c
--- /dev/null
+++ b/scripts/discontinued-sweep/build-verify-lists.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+# Build the per-vendor verification lists for the discontinued sweep
+# (York = targeted per-SKU verification; Thibaut+Anna French = catalog-URL revalidation).
+#
+# Reads the LOCAL dw_unified mirror only (read-only). Outputs CSVs under data/.
+# Safety: York-sourced membership is join-based (mfr_sku) with a COLLISION GUARD —
+# short numeric mfr_skus collide across vendors (proven: Phillip Jeffries 5251 vs
+# York 5251 are different products), so inclusion requires either a York-family
+# house-line vendor, a DWJS prefix, or a title<->pattern_name match. Low-confidence
+# matches are excluded from probing and listed in york-excluded-ambiguous.csv.
+set -euo pipefail
+cd "$(dirname "$0")"
+DB='postgresql:///dw_unified?host=/tmp'
+mkdir -p data
+
+# ---------- York: authoritative York-sourced ACTIVE list ----------
+psql "$DB" -v ON_ERROR_STOP=1 <<'SQL'
+DROP TABLE IF EXISTS tmp_york_sourced;
+CREATE TEMP TABLE tmp_york_sourced AS
+WITH act AS (
+  SELECT DISTINCT ON (shopify_id) shopify_id, dw_sku, mfr_sku, vendor, title, handle
+  FROM shopify_products WHERE status ILIKE 'active'
+),
+hits AS (
+  SELECT a.*,
+    y.product_url  AS yc_url,
+    y.pattern_name AS yc_pattern,
+    (y.mfr_sku IS NOT NULL)  AS in_yc,
+    EXISTS (SELECT 1 FROM brewster_york_master m  WHERE upper(m.mfr_sku)=upper(a.mfr_sku)) AS in_bym,
+    EXISTS (SELECT 1 FROM york_contract_catalog c WHERE upper(c.mfr_sku)=upper(a.mfr_sku)) AS in_ycc
+  FROM act a
+  LEFT JOIN LATERAL (
+    SELECT mfr_sku, product_url, pattern_name FROM york_catalog y
+    WHERE upper(y.mfr_sku)=upper(a.mfr_sku) LIMIT 1
+  ) y ON true
+)
+SELECT *,
+  CASE
+    WHEN vendor IN ('Jeffrey Stevens','Ronald Redding','Missoni Wallpaper','Apartment Wallpaper',
+                    'Brewster & York','Wallpaper NYC','LA Walls','Hollywood Wallcoverings')
+      OR dw_sku LIKE 'DWJS%' THEN 'high'
+    WHEN yc_pattern IS NOT NULL AND length(yc_pattern) > 3
+      AND position(lower(yc_pattern) IN lower(coalesce(title,''))) > 0 THEN 'medium'
+    ELSE 'low'
+  END AS match_confidence
+FROM hits
+WHERE in_yc OR in_bym OR in_ycc OR dw_sku LIKE 'DWJS%';
+
+\copy (SELECT dw_sku, mfr_sku, vendor, title, yc_url AS evidence_url, match_confidence, in_yc, in_bym, in_ycc FROM tmp_york_sourced ORDER BY match_confidence, vendor, dw_sku) TO 'data/york-sourced-actives-full.csv' CSV HEADER
+
+\copy (SELECT dw_sku, mfr_sku, 'york' AS vendor, title, yc_url AS evidence_url, match_confidence FROM tmp_york_sourced WHERE match_confidence IN ('high','medium') AND yc_url IS NOT NULL AND yc_url LIKE 'https://www.yorkwallcoverings.com%' ORDER BY match_confidence, dw_sku) TO 'data/york-verify-list.csv' CSV HEADER
+
+\copy (SELECT dw_sku, mfr_sku, vendor, title, match_confidence, in_yc, in_bym, in_ycc, yc_url FROM tmp_york_sourced WHERE match_confidence='low' OR yc_url IS NULL OR yc_url NOT LIKE 'https://www.yorkwallcoverings.com%' ORDER BY vendor, dw_sku) TO 'data/york-excluded-ambiguous.csv' CSV HEADER
+SQL
+
+# ---------- Thibaut + Anna French: ACTIVE products with vendor URLs ----------
+psql "$DB" -v ON_ERROR_STOP=1 <<'SQL'
+\copy (WITH act AS (SELECT DISTINCT ON (shopify_id) shopify_id, dw_sku, mfr_sku, vendor, title FROM shopify_products WHERE status ILIKE 'active' AND vendor IN ('Thibaut','Anna French')) SELECT a.dw_sku, a.mfr_sku, 'thibaut' AS vendor, a.title, coalesce(t.product_url, af.product_url) AS evidence_url, 'high' AS match_confidence FROM act a LEFT JOIN LATERAL (SELECT product_url FROM thibaut_catalog t WHERE upper(t.mfr_sku)=upper(a.mfr_sku) AND t.product_url IS NOT NULL LIMIT 1) t ON true LEFT JOIN LATERAL (SELECT product_url FROM anna_french_catalog f WHERE upper(f.mfr_sku)=upper(a.mfr_sku) AND f.product_url IS NOT NULL LIMIT 1) af ON true WHERE coalesce(t.product_url, af.product_url) IS NOT NULL ORDER BY a.vendor, a.dw_sku) TO 'data/thibaut-verify-list.csv' CSV HEADER
+
+\copy (WITH act AS (SELECT DISTINCT ON (shopify_id) shopify_id, dw_sku, mfr_sku, vendor, title FROM shopify_products WHERE status ILIKE 'active' AND vendor IN ('Thibaut','Anna French')) SELECT a.dw_sku, a.mfr_sku, a.vendor, a.title, CASE WHEN a.mfr_sku IS NULL OR a.mfr_sku='' THEN 'no_mfr_sku' ELSE 'no_vendor_url' END AS reason FROM act a WHERE NOT EXISTS (SELECT 1 FROM thibaut_catalog t WHERE upper(t.mfr_sku)=upper(a.mfr_sku) AND t.product_url IS NOT NULL) AND NOT EXISTS (SELECT 1 FROM anna_french_catalog f WHERE upper(f.mfr_sku)=upper(a.mfr_sku) AND f.product_url IS NOT NULL) ORDER BY a.vendor, a.dw_sku) TO 'data/thibaut-unprobeable.csv' CSV HEADER
+SQL
+
+echo "--- list sizes ---"
+for f in data/york-sourced-actives-full.csv data/york-verify-list.csv data/york-excluded-ambiguous.csv data/thibaut-verify-list.csv data/thibaut-unprobeable.csv; do
+  echo "$f: $(( $(wc -l < "$f") - 1 )) rows"
+done
diff --git a/shopify/scripts/audits/thibaut-backfill-exceptions.jsonl b/shopify/scripts/audits/thibaut-backfill-exceptions.jsonl
new file mode 100644
index 00000000..863b71b0
--- /dev/null
+++ b/shopify/scripts/audits/thibaut-backfill-exceptions.jsonl
@@ -0,0 +1,11 @@
+{"ts":"2026-07-02T16:43:29.514Z","mfr":"T10825","table":"thibaut","reason":"discontinued_redirect","redirectedTo":"https://www.thibautdesign.com/category/wallcoverings","note":"archive decision is GATED — review"}
+{"ts":"2026-07-02T16:44:00.502Z","mfr":"T10825","table":"thibaut","reason":"discontinued_redirect","redirectedTo":"https://www.thibautdesign.com/category/wallcoverings","note":"archive decision is GATED — review"}
+{"ts":"2026-07-02T16:44:00.568Z","mfr":"T10829","table":"thibaut","reason":"discontinued_redirect","redirectedTo":"https://www.thibautdesign.com/category/wallcoverings","note":"archive decision is GATED — review"}
+{"ts":"2026-07-02T16:45:45.454Z","mfr":"T14363","table":"thibaut","reason":"discontinued_redirect","redirectedTo":"https://www.thibautdesign.com/category/wallcoverings","note":"archive decision is GATED — review"}
+{"ts":"2026-07-02T16:45:48.603Z","mfr":"T14313","table":"thibaut","reason":"discontinued_redirect","redirectedTo":"https://www.thibautdesign.com/category/wallcoverings","note":"archive decision is GATED — review"}
+{"ts":"2026-07-02T16:45:54.456Z","mfr":"T10869","table":"thibaut","reason":"discontinued_redirect","redirectedTo":"https://www.thibautdesign.com/category/wallcoverings","note":"archive decision is GATED — review"}
+{"ts":"2026-07-02T16:46:05.195Z","mfr":"T27015","table":"thibaut","reason":"discontinued_redirect","redirectedTo":"https://www.thibautdesign.com/category/wallcoverings","note":"archive decision is GATED — review"}
+{"ts":"2026-07-02T16:46:23.471Z","mfr":"T10408","table":"thibaut","reason":"discontinued_redirect","redirectedTo":"https://www.thibautdesign.com/category/wallcoverings","note":"archive decision is GATED — review"}
+{"ts":"2026-07-02T16:46:23.490Z","mfr":"T10455","table":"thibaut","reason":"discontinued_redirect","redirectedTo":"https://www.thibautdesign.com/category/wallcoverings","note":"archive decision is GATED — review"}
+{"ts":"2026-07-02T16:46:28.883Z","mfr":"T10446","table":"thibaut","reason":"discontinued_redirect","redirectedTo":"https://www.thibautdesign.com/category/wallcoverings","note":"archive decision is GATED — review"}
+{"ts":"2026-07-02T16:46:34.398Z","mfr":"T10418","table":"thibaut","reason":"discontinued_redirect","redirectedTo":"https://www.thibautdesign.com/category/wallcoverings","note":"archive decision is GATED — review"}
diff --git a/shopify/scripts/audits/thibaut-backfill-summary.json b/shopify/scripts/audits/thibaut-backfill-summary.json
new file mode 100644
index 00000000..de10c1a1
--- /dev/null
+++ b/shopify/scripts/audits/thibaut-backfill-summary.json
@@ -0,0 +1,12 @@
+{
+ "finished_at": "2026-07-02T16:43:32.339Z",
+ "dry_run": false,
+ "queue": 15,
+ "scraped": 14,
+ "updated": 14,
+ "wouldWrite": 0,
+ "redirected": 1,
+ "fetchErr": 0,
+ "noLength": 0,
+ "conflict": 0
+}
\ No newline at end of file
diff --git a/shopify/scripts/cadence/data/cadence-cursor.json b/shopify/scripts/cadence/data/cadence-cursor.json
index 42528841..5c8771a6 100644
--- a/shopify/scripts/cadence/data/cadence-cursor.json
+++ b/shopify/scripts/cadence/data/cadence-cursor.json
@@ -1,5 +1,5 @@
 {
- "idx": 7,
+ "idx": 0,
  "lastSlot": "am",
  "lastRun": "2026-07-02"
 }
\ No newline at end of file
diff --git a/shopify/scripts/cadence/data/cadence-plan-am-2026-07-02.json b/shopify/scripts/cadence/data/cadence-plan-am-2026-07-02.json
index bbfd7f2e..4a2c2a8f 100644
--- a/shopify/scripts/cadence/data/cadence-plan-am-2026-07-02.json
+++ b/shopify/scripts/cadence/data/cadence-plan-am-2026-07-02.json
@@ -1,184 +1,152 @@
 [
  {
-  "vendor": "Thibaut",
-  "dw_sku": "DWTT-73656",
-  "cost": 165.6,
-  "retail": 299.73,
+  "vendor": "Quadrille",
+  "dw_sku": "DWQC-600198",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Hampton, Sky Blue Wallcoverings | Thibaut",
+  "sampleOnly": true,
+  "title": "Shanghai, Navy / Windsor on White Wallcoverings | Quadrille",
   "willActivate": true
  },
  {
-  "vendor": "Thibaut",
-  "dw_sku": "DWTT-73657",
-  "cost": 165.6,
-  "retail": 299.73,
+  "vendor": "Quadrille",
+  "dw_sku": "DWQC-600199",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Hampton, Navy Wallcoverings | Thibaut",
+  "sampleOnly": true,
+  "title": "Shanghai, Turquoise on White Wallcoverings | Quadrille",
   "willActivate": true
  },
  {
-  "vendor": "Thibaut",
-  "dw_sku": "DWTT-73658",
-  "cost": 165.6,
-  "retail": 299.73,
+  "vendor": "Quadrille",
+  "dw_sku": "DWQC-600200",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Hampton, White Wallcoverings | Thibaut",
+  "sampleOnly": true,
+  "title": "Shanghai, Pistachios on White Wallcoverings | Quadrille",
   "willActivate": true
  },
  {
-  "vendor": "Designtex",
-  "dw_sku": "DWDX-220516",
-  "cost": 58,
-  "retail": 104.98,
+  "vendor": "Alan Campbell",
+  "dw_sku": "DWAK-700199",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Fragments, New York Wallcoverings | Designtex",
-  "willActivate": true,
-  "held": true,
-  "heldReason": "\"York Wallcoverings\" is a banned front-facing trade-parent name"
- },
- {
-  "vendor": "Designtex",
-  "dw_sku": "DWDX-220519",
-  "cost": 58,
-  "retail": 104.98,
-  "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Fragments, Tucson Wallcoverings | Designtex",
+  "sampleOnly": true,
+  "title": "Terracotta Purple Yellow Lime on Tint Wallcoverings | Alan Campbell",
   "willActivate": true
  },
  {
-  "vendor": "Designtex",
-  "dw_sku": "DWDX-220520",
-  "cost": 58,
-  "retail": 104.98,
+  "vendor": "Alan Campbell",
+  "dw_sku": "DWAK-700200",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Resurfacing, Plaster Wallcoverings | Designtex",
+  "sampleOnly": true,
+  "title": "Navy Blues Yellow Lime on White Wallcoverings | Alan Campbell",
   "willActivate": true
  },
  {
-  "vendor": "Newwall",
-  "dw_sku": "DWXW-1005718",
-  "cost": 88,
-  "retail": 159.28,
-  "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Woods Summer Path 6500208, Made to Measure Mural Vinyl Wallcoverings | Newwall",
-  "willActivate": false
- },
- {
-  "vendor": "Newwall",
-  "dw_sku": "DWXW-1005719",
-  "cost": 88,
-  "retail": 159.28,
+  "vendor": "Alan Campbell",
+  "dw_sku": "DWAK-700201",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Japanese Window, Made to Measure Mural Vinyl Wallcoverings | Newwall",
-  "willActivate": false
- },
- {
-  "vendor": "Newwall",
-  "dw_sku": "DWXW-1005720",
-  "cost": 88,
-  "retail": 159.28,
-  "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Sea Window, Made to Measure Mural Vinyl Wallcoverings | Newwall",
-  "willActivate": false
+  "sampleOnly": true,
+  "title": "Brown Blues Yellow Lime on White Wallcoverings | Alan Campbell",
+  "willActivate": true
  },
  {
-  "vendor": "Brewster & York",
-  "dw_sku": "DWBR-170876",
-  "cost": 90,
-  "retail": 162.9,
+  "vendor": "Home Couture",
+  "dw_sku": "DWHJ-900194",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Mara, Green Wallcoverings | Malibu Wallcovering",
+  "sampleOnly": true,
+  "title": "Vapors on White Wallcoverings | Home Couture",
   "willActivate": true
  },
  {
-  "vendor": "Brewster & York",
-  "dw_sku": "DWBR-170877",
-  "cost": 90,
-  "retail": 162.9,
+  "vendor": "Home Couture",
+  "dw_sku": "DWHJ-900195",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Mara, Grey Wallcoverings | Malibu Wallcovering",
+  "sampleOnly": true,
+  "title": "Beige on Tint Wallcoverings | Home Couture",
   "willActivate": true
  },
  {
-  "vendor": "Brewster & York",
-  "dw_sku": "DWBR-170878",
-  "cost": 90,
-  "retail": 162.9,
+  "vendor": "Home Couture",
+  "dw_sku": "DWHJ-900196",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Lindlöv, Grey Wallcoverings | Malibu Wallcovering",
+  "sampleOnly": true,
+  "title": "Medium Blue on Tint Wallcoverings | Home Couture",
   "willActivate": true
  },
  {
-  "vendor": "Kravet",
-  "dw_sku": "DWKK-102916",
-  "cost": 59.95,
-  "retail": 89.93,
+  "vendor": "Suncloth",
+  "dw_sku": "DWUX-800200",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Poet Plain, Gray Wallcoverings | Kravet",
+  "sampleOnly": true,
+  "title": "Drizzle Slate Wallcoverings | Suncloth",
   "willActivate": true
  },
  {
-  "vendor": "Kravet",
-  "dw_sku": "DWKK-102917",
-  "cost": 59.95,
-  "retail": 89.93,
+  "vendor": "Suncloth",
+  "dw_sku": "DWUX-800201",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Poet Plain, Beige Wallcoverings | Kravet",
+  "sampleOnly": true,
+  "title": "Apricot Brown Wallcoverings | Suncloth",
   "willActivate": true
  },
  {
-  "vendor": "Kravet",
-  "dw_sku": "DWKK-102918",
-  "cost": 59.95,
-  "retail": 89.93,
+  "vendor": "Suncloth",
+  "dw_sku": "DWUX-800202",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Poet Plain, Beige Wallcoverings | Kravet",
+  "sampleOnly": true,
+  "title": "Sage Green Brown Wallcoverings | Suncloth",
   "willActivate": true
  },
  {
-  "vendor": "Schumacher",
-  "dw_sku": "DWLK-807210",
-  "cost": 34,
-  "retail": 61.54,
+  "vendor": "Plains",
+  "dw_sku": "DWYP-1000197",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Burnell Butterfly, Cobalt Blue Wallcoverings | Schumacher",
+  "sampleOnly": true,
+  "title": "Cloud Wallcoverings | Plains",
   "willActivate": true
  },
  {
-  "vendor": "Schumacher",
-  "dw_sku": "DWLK-807220",
-  "cost": 34,
-  "retail": 61.54,
+  "vendor": "Plains",
+  "dw_sku": "DWYP-1000198",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Burnell Butterfly, Black Wallcoverings | Schumacher",
+  "sampleOnly": true,
+  "title": "Pale Lilac Wallcoverings | Plains",
   "willActivate": true
  },
  {
-  "vendor": "Schumacher",
-  "dw_sku": "DWLK-807230",
-  "cost": 38,
-  "retail": 68.78,
+  "vendor": "Plains",
+  "dw_sku": "DWYP-1000199",
+  "cost": 0,
+  "retail": 0,
   "sample": "4.25",
-  "sampleOnly": false,
-  "title": "Villandry Damask Print, Blue Wallcoverings | Schumacher",
+  "sampleOnly": true,
+  "title": "Heather Wallcoverings | Plains",
   "willActivate": true
  }
 ]
\ No newline at end of file
diff --git a/shopify/scripts/cadence/data/upload-restore-2026-07-02.jsonl b/shopify/scripts/cadence/data/upload-restore-2026-07-02.jsonl
index 2e173732..d41dd0d8 100644
--- a/shopify/scripts/cadence/data/upload-restore-2026-07-02.jsonl
+++ b/shopify/scripts/cadence/data/upload-restore-2026-07-02.jsonl
@@ -252,3 +252,18 @@
 {"table":"schumacher_catalog","mfr_sku":"5011741","dw_sku":"DWLK-807210","shopify_product_id":"7874146598963","action":"created","activated":true,"published":true,"sampleOnly":false,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T15-40-00-914Z","ts":"2026-07-02T15:40:53.402Z"}
 {"table":"schumacher_catalog","mfr_sku":"5011742","dw_sku":"DWLK-807220","shopify_product_id":"7874146664499","action":"created","activated":true,"published":true,"sampleOnly":false,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T15-40-00-914Z","ts":"2026-07-02T15:40:57.004Z"}
 {"table":"schumacher_catalog","mfr_sku":"5011750","dw_sku":"DWLK-807230","shopify_product_id":"7874146697267","action":"created","activated":true,"published":true,"sampleOnly":false,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T15-40-00-914Z","ts":"2026-07-02T15:41:00.611Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"JF01000-11","dw_sku":"DWQC-600198","shopify_product_id":"7874169307187","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:06.830Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"JF01000-08","dw_sku":"DWQC-600199","shopify_product_id":"7874169339955","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:10.066Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"JF01000-07","dw_sku":"DWQC-600200","shopify_product_id":"7874169372723","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:13.934Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"AC117-03","dw_sku":"DWAK-700199","shopify_product_id":"7874169471027","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:17.318Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"AC117-04W","dw_sku":"DWAK-700200","shopify_product_id":"7874169700403","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:20.633Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"AC117-05W","dw_sku":"DWAK-700201","shopify_product_id":"7874169962547","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:25.230Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"HC1900-02","dw_sku":"DWHJ-900194","shopify_product_id":"7874170159155","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:28.626Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"HC1860-01","dw_sku":"DWHJ-900195","shopify_product_id":"7874170224691","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:32.046Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"HC1860-03","dw_sku":"DWHJ-900196","shopify_product_id":"7874170257459","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:35.330Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"149-47SUN","dw_sku":"DWUX-800200","shopify_product_id":"7874170355763","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:38.621Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"149-42SUN","dw_sku":"DWUX-800201","shopify_product_id":"7874170421299","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:41.828Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"149-40SUN","dw_sku":"DWUX-800202","shopify_product_id":"7874170486835","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:44.996Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"HC1420-03","dw_sku":"DWYP-1000197","shopify_product_id":"7874170552371","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:48.472Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"HC1420-07","dw_sku":"DWYP-1000198","shopify_product_id":"7874170585139","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:51.921Z"}
+{"table":"quadrille_house_catalog","mfr_sku":"HC1420-09","dw_sku":"DWYP-1000199","shopify_product_id":"7874170650675","action":"created","activated":true,"published":true,"sampleOnly":true,"status":"ACTIVE","batch_id":"upload-am-2026-07-02T16-40-00-967Z","ts":"2026-07-02T16:40:55.138Z"}

← 1fc5c567 Thibaut/AF wave-2 scrape backfill: PDP SingleRollLength -> l  ·  back to Designer Wallcoverings  ·  discontinued-sweep: verify-list builder + positive-signal pr 3f3883ed →