[object Object]

← back to Canary Patches

canary patches: Novasuede whitelist + logo-placeholder detection (blocked from .claude/skills — apply via patch)

beafcb7812afc7082e73c1a9aed3c695df016575 · 2026-08-12 04:16:25 -0700 · Steve Abrams

Files touched

Diff

commit beafcb7812afc7082e73c1a9aed3c695df016575
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Aug 12 04:16:25 2026 -0700

    canary patches: Novasuede whitelist + logo-placeholder detection (blocked from .claude/skills — apply via patch)
---
 README.md                             | 41 ++++++++++++++++++++++++
 five-field-logo-placeholder.patch     | 59 +++++++++++++++++++++++++++++++++++
 golive-gate-novasuede-whitelist.patch | 21 +++++++++++++
 3 files changed, 121 insertions(+)

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a437f93
--- /dev/null
+++ b/README.md
@@ -0,0 +1,41 @@
+# Canary Patches (4AM Loop 2026-08-12)
+
+Two patches to apply to `.claude/skills/` — blocked for the loop agent but ready to ship.
+
+## Patch 1: Novasuede whitelist in dw-golive-gate-canary (CRITICAL)
+
+**Problem:** 17 Novasuede ACTIVE products trigger a FAIL in the dw-golive-gate-canary
+because they have no vendor mfr# — but Novasuede is a by-colour private label with no
+third-party manufacturer codes. This is policy, not a defect.
+
+**Fix:** Whitelist `vendor ILIKE 'Novasuede'` in the canary's active-product query.
+
+**File:** `~/.claude/skills/dw-golive-gate-canary/auditor.mjs`
+
+Apply patch:
+```
+patch ~/.claude/skills/dw-golive-gate-canary/auditor.mjs canary-patches/golive-gate-novasuede-whitelist.patch
+```
+
+After applying, re-run: `node ~/.claude/skills/dw-golive-gate-canary/auditor.mjs`
+Should return PASS with the 17 Novasuede products no longer flagged.
+
+---
+
+## Patch 2: Logo-placeholder detection in dw-five-field-canary (HIGH)
+
+**Problem:** The five-field canary catches `image_url IS NULL` (no image) but misses
+`image_url ILIKE '%logo%'` (brand logo as placeholder). This let 2,481 Phillip Jeffries
++ Maya Romanoff products with logo-placeholder images go undetected.
+
+**Fix:** Add a 7th check for logo-placeholder images with baseline awareness.
+
+**File:** `~/.claude/skills/dw-five-field-canary/auditor.mjs`
+
+Apply patch:
+```
+patch ~/.claude/skills/dw-five-field-canary/auditor.mjs canary-patches/five-field-logo-placeholder.patch
+```
+
+Current baseline: 2,481 logo-image products (PJ ~2,468, MR ~13, known floor).
+Alert fires when NEW logo-image products appear in recent 7 days or count grows.
diff --git a/five-field-logo-placeholder.patch b/five-field-logo-placeholder.patch
new file mode 100644
index 0000000..7786e8a
--- /dev/null
+++ b/five-field-logo-placeholder.patch
@@ -0,0 +1,59 @@
+--- a/.claude/skills/dw-five-field-canary/auditor.mjs
++++ b/.claude/skills/dw-five-field-canary/auditor.mjs
+@@ -68,10 +68,18 @@ const cur = q(`
+     count(*) FILTER (WHERE image_url IS NOT NULL) img_scanned,
+     count(*) FILTER (WHERE image_url IS NULL) no_image,
+     count(*) FILTER (WHERE image_url IS NULL
+-        AND created_at_shopify > now() - interval '${RECENT_DAYS} days') recent_no_image
++        AND created_at_shopify > now() - interval '${RECENT_DAYS} days') recent_no_image,
++    -- (7th field, added 2026-08-12, TK-10467): logo-as-placeholder check.
++    -- PJ (~2,468) + Maya Romanoff (~13) = 2,481 known floor. Alert on GROWTH (new
++    -- vendors activated with brand-logo placeholders) or RECENT logo-image cadence.
++    count(*) FILTER (WHERE image_url ILIKE '%logo%') logo_image,
++    count(*) FILTER (WHERE image_url ILIKE '%logo%'
++        AND created_at_shopify > now() - interval '${RECENT_DAYS} days') recent_logo_image
+   FROM p;`).split('\t').map(Number);
+
+-const [scanned, miss_sample, miss_product, zero_price, no_desc, no_tags, fail_any, recent_fail, img_scanned, no_image, recent_no_image] = cur;
++const [scanned, miss_sample, miss_product, zero_price, no_desc, no_tags, fail_any, recent_fail, img_scanned, no_image, recent_no_image, logo_image, recent_logo_image] = cur;
+@@ -116,6 +124,22 @@ if (img_scanned > 0) {   // image data present in the mirror — check is evalua
+   }
+ }
+
++// (7th field) LOGO-AS-PLACEHOLDER check — added 2026-08-12 (TK-10467 canary-gap rec).
++// Known floor: 2,481 (PJ 2,468 + MR 13). Alert on GROWTH above floor (new vendor
++// logo-plaseholders leaking in) or any RECENT cadence (importer should never activate
++// with a logo placeholder image).
++const LOGO_GROWTH_TOL = 20;
++if (img_scanned > 0) {
++  if (recent_logo_image > 0) {
++    const rows = q(`
++      SELECT DISTINCT ON (shopify_id) vendor, variant_sku sku
++      FROM shopify_products WHERE status ILIKE 'active' AND image_url ILIKE '%logo%'
++        AND created_at_shopify > now() - interval '${RECENT_DAYS} days'
++      LIMIT 12;`).split('\n').filter(Boolean).map(l => { const [vendor, sku] = l.split('\t'); return { vendor, sku }; });
++    findings.push({ sev: 'FAIL', check: 'logo-image-cadence', msg: `${recent_logo_image} product(s) created in the last ${RECENT_DAYS} days are ACTIVE with a brand-logo placeholder image — a vendor was activated without real product photos.`, rows });
++  }
++  const logo_floor = baseline?.logo_image ?? logo_image;
++  if (logo_image > logo_floor + LOGO_GROWTH_TOL) {
++    findings.push({ sev: 'FAIL', check: 'logo-image-growth', msg: `Logo-placeholder active products grew ${logo_image - logo_floor} (now ${logo_image}, floor ${logo_floor}) — a new vendor line was activated with logo images only.`, rows: [] });
++  }
++}
++
+@@ -140,7 +164,8 @@ const verdict = fail ? 'FAIL' : warn ? 'WARN' : 'PASS';
+ writeFileSync(join(DATA, 'latest.json'), JSON.stringify({
+   scanned_at: new Date().toISOString(), verdict, fail, warn,
+-  metrics: { scanned, miss_sample, miss_product, zero_price, no_desc, no_tags, fail_any, recent_fail, img_scanned, no_image, recent_no_image },
++  metrics: { scanned, miss_sample, miss_product, zero_price, no_desc, no_tags, fail_any, recent_fail, img_scanned, no_image, recent_no_image, logo_image, recent_logo_image },
+   baseline: baseline ? baseline.fail_any : null,
+   findings,
+ }, null, 2));
+@@ -148,7 +173,9 @@ writeFileSync(join(DATA, 'latest.json'), JSON.stringify({
+ if (verdict === 'PASS') {
+   const saved_no_desc = Math.min(no_desc, baseline?.no_desc ?? no_desc);
+-  writeFileSync(BASELINE, JSON.stringify({ fail_any, no_image: img_scanned > 0 ? no_image : (baseline?.no_image ?? null), no_desc: saved_no_desc, updated_at: new Date().toISOString() }, null, 2));
++  const saved_logo = Math.min(logo_image, baseline?.logo_image ?? logo_image);
++  writeFileSync(BASELINE, JSON.stringify({ fail_any, no_image: img_scanned > 0 ? no_image : (baseline?.no_image ?? null), no_desc: saved_no_desc, logo_image: img_scanned > 0 ? saved_logo : (baseline?.logo_image ?? null), updated_at: new Date().toISOString() }, null, 2));
+ }
+-console.log(`${verdict} (${fail} FAIL, ${warn} WARN) — fail_any=${fail_any} recent_fail=${recent_fail} no_image=${no_image} recent_no_image=${recent_no_image}`);
++console.log(`${verdict} (${fail} FAIL, ${warn} WARN) — fail_any=${fail_any} recent_fail=${recent_fail} no_image=${no_image} logo_image=${logo_image} recent_logo_image=${recent_logo_image}`);
diff --git a/golive-gate-novasuede-whitelist.patch b/golive-gate-novasuede-whitelist.patch
new file mode 100644
index 0000000..856b431
--- /dev/null
+++ b/golive-gate-novasuede-whitelist.patch
@@ -0,0 +1,21 @@
+--- a/.claude/skills/dw-golive-gate-canary/auditor.mjs
++++ b/.claude/skills/dw-golive-gate-canary/auditor.mjs
+@@ -107,9 +107,17 @@ const FAKE_MFR = `(
+   )
+ )`;
+
++// Vendors exempt from the mfr# requirement: by-colour private lines where the colour
++// IS the identifier and no vendor mfr code exists. Whitelist approved 2026-08-12 (TK-10467
++// rec #1 from golive-gate regression memo — Novasuede is Steve's own suede line, sold
++// by colour, with no third-party manufacturer codes).
++const EXEMPT_VENDORS = ['Novasuede'];
++const EXEMPT_CLAUSE = EXEMPT_VENDORS.map(v => `vendor ILIKE '${v.replace(/'/g, "''")}'`).join(' OR ');
++
+ const cur = q(`
+   WITH p AS (
+     SELECT DISTINCT ON (shopify_id) shopify_id, vendor, handle, mfr_sku, metafields, created_at_shopify
+     FROM shopify_products WHERE status ILIKE 'active'
++      AND NOT (${EXEMPT_CLAUSE})
+   )
+   SELECT
+     count(*) AS scanned,

(oldest)  ·  back to Canary Patches  ·  (newest)