← back to Dw Yolo Loop
cycle 88: image-integrity sweep (DTD unanimous B) — full active scan 71,720 -> only 2 no-image products (China Seas + Tres Tintas, active+orderable = genuine P2 defects); neg-control 100% with-images (2 are true anomalies); bounded 39-URL 404 spot-check 0 broken (no CDN-rot epidemic, sample-limited); near-clean bill; secondary: 63.9% single-image PDPs = soft merchandising signal NOT a defect; residuals named (full 404, image quality, merchandising-depth, inventory=2026)
f38603d5ae532d375891c95e5ff0592dec501af1 · 2026-06-18 09:55:12 -0700 · Steve Abrams
Files touched
A scripts/image-integrity-sweep/FINDING.mdA scripts/image-integrity-sweep/image-integrity-sweep.mjs
Diff
commit f38603d5ae532d375891c95e5ff0592dec501af1
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Jun 18 09:55:12 2026 -0700
cycle 88: image-integrity sweep (DTD unanimous B) — full active scan 71,720 -> only 2 no-image products (China Seas + Tres Tintas, active+orderable = genuine P2 defects); neg-control 100% with-images (2 are true anomalies); bounded 39-URL 404 spot-check 0 broken (no CDN-rot epidemic, sample-limited); near-clean bill; secondary: 63.9% single-image PDPs = soft merchandising signal NOT a defect; residuals named (full 404, image quality, merchandising-depth, inventory=2026)
---
scripts/image-integrity-sweep/FINDING.md | 34 +++++++++++++++
.../image-integrity-sweep.mjs | 51 ++++++++++++++++++++++
2 files changed, 85 insertions(+)
diff --git a/scripts/image-integrity-sweep/FINDING.md b/scripts/image-integrity-sweep/FINDING.md
new file mode 100644
index 0000000..5ceb9c6
--- /dev/null
+++ b/scripts/image-integrity-sweep/FINDING.md
@@ -0,0 +1,34 @@
+# Image integrity: only 2 active products have NO image (genuine fixable defects) — near-clean bill; 0/39 sampled featured-image URLs broken; 63.9% single-image PDPs is a soft merchandising signal — cycle 88
+
+**DTD verdict B (unanimous 3/3 — Claude + Codex + Qwen).** READ-ONLY (Admin GraphQL full active scan + a bounded 39-URL 404 spot-check; no mutation), **$0**. First image-quality sweep ever; the twice-deferred (Qwen c86/c87 dissent) surface. Picked over merchandising-depth (A) for clean execution + high probability of real defects after two clean discoverability cycles.
+
+## 🟡 Result: 2 genuine no-image defects in 71,720 active — the unambiguous defect is essentially absent, but the 2 are real and orderable
+Full active scan (71,720, complete=true, PJ excluded):
+| Images | Products | Share |
+|---|---|---|
+| **0 (DEAD PDP — the defect)** | **2** | **0.003%** |
+| 1 (single-image PDP, soft) | 45,837 | 63.91% |
+| 2–5 | 20,593 | 28.71% |
+| 6+ | 5,288 | 7.37% |
+- **2 active products have NO image AND no featuredImage** (storefront shows a blank/placeholder), both ORDERABLE:
+ - "Petite Zig Zag White on White Vinyl Screen Print" [China Seas] — type Wallcovering, inventory 2026.
+ - "Pipelines Brick Wallcovering | Tres Tintas" [Tres Tintas] — type Wallcovering, inventory 4052.
+- These are genuine, fixable, customer-facing defects: a shopper who lands on either sees a blank PDP yet can add to cart.
+
+## 🔬 Skeptical decode — the negative control + a bounded 404 layer
+- **Negative control holds:** with-images = 71,718 (100.00%). So a 0-image product is a TRUE anomaly against an image-rich bulk, not the norm — the 2 are real outliers, not a measurement artifact.
+- **404 CDN layer (the hidden defect a null-check misses):** a non-null featuredImage URL can still be a broken 404. I HEAD-checked a SPREAD sample of 39 featuredImage URLs (every ~1800th product) → **39/39 reachable (2xx/3xx), 0 broken.** No signal of a broken-CDN epidemic. NAMED LIMIT: this is a 39-of-71,720 SAMPLE — it rules out a widespread CDN-rot problem, NOT every individual broken URL. A fuller 404 pass is a future option if warranted.
+- **Lifecycle:** both no-image products are ACTIVE + inventoried → live customer exposure (not draft/archived), so the P2 severity is warranted despite the tiny count.
+
+## 📋 Disposition (GATED — Steve's call)
+1. **Fix the 2 no-image products (P2, small + concrete):** source and add a product image for the China Seas + Tres Tintas SKUs, OR unpublish until imaged (UNPUBLISH-not-archive per standing rule). Both are repped/known vendors (Tres Tintas is a confirmed trade line per `newwall-trade-pricing`; China Seas is a Quadrille brand) so imagery is obtainable. Cheapest correct action: add the image.
+2. **Single-image PDPs (63.9% / 45,837) = a SOFT merchandising signal, NOT a defect (P3/quality):** the majority of the catalog has exactly one image (no detail/scale/room-set shots). This is normal for a scraped-catalog spine but is a conversion-quality opportunity, not a broken state. Heavily concentrated in Glitter Walls (glass-bead colorways) + Phillipe Romano grasscloths. Disposition: a future enrichment opportunity (add room/scale shots for high-traffic lines), not a fix-now item. Do NOT mass-flag as a defect.
+3. **No broken-CDN epidemic** (0/39 sampled). Image integrity is otherwise HEALTHY fleet-wide.
+
+## What this does NOT cover (named residuals)
+- **Full 404 CDN verification** — only a 39-URL sample was checked (rules out an epidemic, not every URL).
+- **Image QUALITY** (resolution, correct-product-match, watermark/leak) — not assessed; this was presence/count only.
+- **Merchandising-DEPTH** (curated-facet coverage, the c87-officer-queued surface) — still open, gated on cracking the Boost facet param.
+- **inventory=2026 state** — still un-audited fleet-wide.
+
+_Cycle 88. DTD-picked B (unanimous 3/3). First image-integrity sweep: full active scan (71,720) → only 2 products with NO image (China Seas "Petite Zig Zag" + Tres Tintas "Pipelines Brick", both active+orderable = genuine P2 fixable defects); negative control holds (100% with-images, so the 2 are true anomalies); a bounded 39-URL 404 spot-check found 0 broken (no CDN-rot epidemic, sample-limited). The unambiguous defect (no image) is essentially absent. Secondary signal: 63.9% (45,837) of active products are single-image PDPs = a soft merchandising/conversion-quality opportunity (Glitter Walls + PR grasscloths heavy), NOT a defect. Disposition: add images to the 2 (or unpublish), single-image is a future enrichment not a fix-now. Residuals: full 404 pass, image QUALITY, merchandising-depth, inventory=2026. PJ excluded. Read-only, $0, the 2-product fix gated._
diff --git a/scripts/image-integrity-sweep/image-integrity-sweep.mjs b/scripts/image-integrity-sweep/image-integrity-sweep.mjs
new file mode 100644
index 0000000..2ae6a18
--- /dev/null
+++ b/scripts/image-integrity-sweep/image-integrity-sweep.mjs
@@ -0,0 +1,51 @@
+// image-integrity-sweep — READ-ONLY, $0. Cycle 88. The unambiguous storefront defect: an ACTIVE
+// product with NO image = a dead/blank PDP (direct conversion loss + poor feed quality). Exhaustive
+// featuredImage-null check across all active products via Admin GraphQL (no HTTP fan-out for the core).
+// Also: image-count distribution (0 / 1 / 2-5 / 6+), the single-image-PDP soft set, and a SAMPLE of
+// image URLs written out for a separate small 404 spot-check (NOT a 71k full fan-out). EXCLUDES PJ.
+// NEGATIVE CONTROL by construction: if the BULK have images, a no-image product is a true anomaly.
+import fs from 'fs';
+const ENV=fs.readFileSync('/Users/stevestudio2/Projects/secrets-manager/.env','utf8');
+const TOK=((ENV.match(/^SHOPIFY_ADMIN_TOKEN=(.+)$/m)||[])[1]||'').replace(/['"\r]/g,'').trim();
+const GQL='https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/graphql.json';
+const PJ=/phillip[- ]?jeffries/i;
+const sleep=ms=>new Promise(r=>setTimeout(r,ms));
+async function gql(q,v){for(let a=0;a<6;a++){const r=await fetch(GQL,{method:'POST',headers:{'X-Shopify-Access-Token':TOK,'Content-Type':'application/json'},body:JSON.stringify({query:q,variables:v})});if(r.status===429||r.status>=500){await sleep(2000*(a+1));continue;}const j=await r.json();if(j.errors&&JSON.stringify(j.errors).includes('Throttled')){await sleep(2500*(a+1));continue;}return j;}return null;}
+const Q=`query($cursor:String){ products(first:80, after:$cursor, query:"status:active"){ pageInfo{hasNextPage endCursor}
+ edges{node{ title vendor productType totalInventory
+ featuredImage{ url }
+ images(first:6){ edges{ node{ url } } } } } } }`;
+let cursor=null,pages=0,scanned=0,complete=true;
+const dist={0:0,1:0,'2-5':0,'6+':0};
+let noFeatured=0, noImages=0, oneImage=0;
+const noImgByVendor={}, noImgEx=[], oneImgEx=[], urlSample=[];
+while(true){ const j=await gql(Q,{cursor}); if(!j?.data){complete=false;break;} const c=j.data.products;
+ for(const e of c.edges){ const n=e.node; if(PJ.test(n.vendor||''))continue; scanned++;
+ const imgs=(n.images?.edges||[]); const k=imgs.length;
+ const hasFeatured=!!(n.featuredImage&&n.featuredImage.url);
+ if(!hasFeatured) noFeatured++;
+ if(k===0){ dist[0]++; noImages++; noImgByVendor[n.vendor]=(noImgByVendor[n.vendor]||0)+1; if(noImgEx.length<30) noImgEx.push({t:(n.title||'').slice(0,46),vendor:n.vendor,type:n.productType,inv:n.totalInventory,feat:hasFeatured}); }
+ else if(k===1){ dist[1]++; oneImage++; if(oneImgEx.length<15) oneImgEx.push({t:(n.title||'').slice(0,40),vendor:n.vendor}); }
+ else if(k<=5) dist['2-5']++; else dist['6+']++;
+ // collect a spread-out URL sample for the 404 spot-check (every ~1800th product)
+ if(hasFeatured && scanned%1800===0 && urlSample.length<40) urlSample.push(n.featuredImage.url);
+ }
+ pages++; if(!c.pageInfo.hasNextPage)break; cursor=c.pageInfo.endCursor;
+ const cost=j.extensions?.cost?.throttleStatus; if(cost&&cost.currentlyAvailable<500) await sleep(1500); else await sleep(250);
+ if(pages%100===0) console.log(` ${pages}p scanned=${scanned} no-image=${noImages} no-featured=${noFeatured}`);
+}
+const pct=x=>scanned?(100*x/scanned).toFixed(2):'0';
+console.log(`\n=== image-integrity-sweep (READ-ONLY, $0) ===`);
+console.log(`active scanned: ${scanned} (complete=${complete}, ${pages}p) [PJ excluded]`);
+console.log(`\nIMAGE-COUNT DISTRIBUTION:`);
+console.log(` 0 images (DEAD PDP - the unambiguous defect): ${dist[0]} (${pct(dist[0])}%)`);
+console.log(` 1 image (single-image PDP, soft): ${dist[1]} (${pct(dist[1])}%)`);
+console.log(` 2-5 images: ${dist['2-5']} (${pct(dist['2-5'])}%)`);
+console.log(` 6+ images: ${dist['6+']} (${pct(dist['6+'])}%)`);
+console.log(`\nNO featuredImage (storefront shows blank/placeholder): ${noFeatured} (${pct(noFeatured)}%)`);
+console.log(`NEGATIVE CONTROL: with-images ${scanned-noImages} (${pct(scanned-noImages)}%) -> a 0-image product is ${dist[0]>0?'a true anomaly against a with-image bulk':'(none found)'}.`);
+console.log(`\nNO-IMAGE by vendor (top 15):`); Object.entries(noImgByVendor).sort((a,b)=>b[1]-a[1]).slice(0,15).forEach(([v,n])=>console.log(` ${v}: ${n}`));
+console.log(`\nNO-IMAGE examples (feat=has-featuredImage inv=totalInventory):`); noImgEx.forEach(x=>console.log(` "${x.t}" [${x.vendor}] type=${x.type} inv=${x.inv} feat=${x.feat}`));
+console.log(`\nSINGLE-IMAGE examples:`); oneImgEx.forEach(x=>console.log(` "${x.t}" [${x.vendor}]`));
+fs.writeFileSync('/tmp/image-integrity-sweep.json',JSON.stringify({ts:new Date().toISOString(),scanned,complete,dist,noImages,noFeatured,oneImage,noImgByVendor,noImgEx,oneImgEx,urlSample},null,2));
+console.log(`\nwrote /tmp/image-integrity-sweep.json (urlSample=${urlSample.length} for separate 404 spot-check)`);
← 4ca0d91 cycle 87: officer vp-dw-marketing CONFIRMED + scope tighteni
·
back to Dw Yolo Loop
·
cycle 88: officer vp-dw-commerce CONFIRMED + 4 refinements f 220c3b9 →