[object Object]

← back to Dw Yolo Loop

GMC feed-guard canary (c57): full-catalog recount PASS (0 still-on) + standing re-leak guard

edc90035b067024a783aba4ec2bb26fdecbe4cf2 · 2026-06-17 09:50:51 -0700 · Steve Abrams

Hardened the c55 recount (retry/backoff on non-JSON/429/5xx — fixes the crash that
stopped it at 36k). Full catalog now: 74,441 scanned, 0 $4.25-still-on-Google in 232s
→ COMPLETES the c55 verification (GMC exclusion confirmed catalog-wide, not half-scan).
Promoted as a daily standing GMC feed-guard via the c34 harness: FAILs if any $4.25
product reappears on the Google channel (catches re-leak from new imports). Package
PlistBuddy-validated (c56 lesson). Install Steve-gated.

Files touched

Diff

commit edc90035b067024a783aba4ec2bb26fdecbe4cf2
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Jun 17 09:50:51 2026 -0700

    GMC feed-guard canary (c57): full-catalog recount PASS (0 still-on) + standing re-leak guard
    
    Hardened the c55 recount (retry/backoff on non-JSON/429/5xx — fixes the crash that
    stopped it at 36k). Full catalog now: 74,441 scanned, 0 $4.25-still-on-Google in 232s
    → COMPLETES the c55 verification (GMC exclusion confirmed catalog-wide, not half-scan).
    Promoted as a daily standing GMC feed-guard via the c34 harness: FAILs if any $4.25
    product reappears on the Google channel (catches re-leak from new imports). Package
    PlistBuddy-validated (c56 lesson). Install Steve-gated.
---
 scripts/gmc-feed-guard/data/latest.json            |  9 +++++
 scripts/gmc-feed-guard/gmc-feed-guard.mjs          | 39 ++++++++++++++++++++++
 scripts/staged-launchd/gmc-feed-guard/INSTALL.txt  |  4 +++
 .../gmc-feed-guard/com.steve.gmc-feed-guard.plist  | 10 ++++++
 .../gmc-feed-guard/manifest-row.json               |  9 +++++
 .../gmc-feed-guard/run-gmc-feed-guard.sh           |  7 ++++
 6 files changed, 78 insertions(+)

diff --git a/scripts/gmc-feed-guard/data/latest.json b/scripts/gmc-feed-guard/data/latest.json
new file mode 100644
index 0000000..1515012
--- /dev/null
+++ b/scripts/gmc-feed-guard/data/latest.json
@@ -0,0 +1,9 @@
+{
+  "generated_at": "2026-06-17T16:49:45.672Z",
+  "status": "PASS",
+  "headline": "$4.25-still-on-Google=0 of 74441 active (target 0)",
+  "scanned": 74441,
+  "still_on_425": 0,
+  "offenders": [],
+  "elapsed_s": 232
+}
\ No newline at end of file
diff --git a/scripts/gmc-feed-guard/gmc-feed-guard.mjs b/scripts/gmc-feed-guard/gmc-feed-guard.mjs
new file mode 100644
index 0000000..ba24b7f
--- /dev/null
+++ b/scripts/gmc-feed-guard/gmc-feed-guard.mjs
@@ -0,0 +1,39 @@
+// gmc-feed-guard (c57) — READ-ONLY standing canary. Counts ACTIVE products whose
+// min-variant price <= $4.25 that are STILL published on the Google & YouTube
+// channel (pub 29646651457). After the c-GMC surgical exclusion this should be ~0;
+// any reappearance = a re-leak (new import re-published a $4.25 product to Google).
+// Hardened: retry/backoff on non-JSON/429/5xx (fixes the c55 crash). Writes
+// data/latest.json (c34 heartbeat). FAIL if still_on >0. $0.
+import fs from 'fs';
+const T=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^SHOPIFY_ADMIN_TOKEN=(.+)$/m)||[])[1];
+const API='https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/graphql.json';
+const GOOG='gid://shopify/Publication/29646651457';
+const DIR=process.env.HOME+'/Projects/dw-yolo-loop/scripts/gmc-feed-guard/data';
+const Q=process.env.HOME+'/.claude/yolo-queue';
+const sleep=ms=>new Promise(r=>setTimeout(r,ms));
+async function gql(q,v){
+  for(let a=0;a<7;a++){
+    try{ const r=await fetch(API,{method:'POST',headers:{'X-Shopify-Access-Token':T,'Content-Type':'application/json'},body:JSON.stringify({query:q,variables:v||{}}),signal:AbortSignal.timeout(20000)});
+      if(r.status===429||r.status>=500){await sleep(2500*(a+1));continue;}
+      const txt=await r.text(); let j; try{j=JSON.parse(txt);}catch(e){await sleep(2500*(a+1));continue;}  // non-JSON → retry (the c55 crash)
+      if(j.errors&&JSON.stringify(j.errors).match(/THROTTLED/)){await sleep(2500*(a+1));continue;}
+      return j;
+    }catch(e){ await sleep(2000*(a+1)); }
+  }
+  throw new Error('exhausted retries');
+}
+let cur=null,scanned=0,on425=0,pages=0,retries=0; const offenders=[]; const t0=Date.now();
+do{
+  const d=await gql(`query($c:String){products(first:150,after:$c,query:"status:active"){pageInfo{hasNextPage endCursor} nodes{handle vendor onGoogle:publishedOnPublication(publicationId:"${GOOG}") variants(first:60){nodes{price}}}}}`,{c:cur});
+  const pg=d.data.products;
+  for(const p of pg.nodes){ scanned++; const mn=Math.min(...p.variants.nodes.map(v=>parseFloat(v.price)).filter(x=>!isNaN(x))); if(mn<=4.25 && p.onGoogle){on425++; if(offenders.length<20)offenders.push(p.handle+' ['+p.vendor+']');} }
+  pages++; if(pages%80===0)process.stderr.write(`  ...${scanned} scanned, still-on=${on425}\n`);
+  cur=pg.pageInfo.hasNextPage?pg.pageInfo.endCursor:null;
+}while(cur);
+const verdict = on425>0 ? 'FAIL' : 'PASS';
+const out={generated_at:new Date().toISOString(), status:verdict, headline:`$4.25-still-on-Google=${on425} of ${scanned} active (target 0)`, scanned, still_on_425:on425, offenders, elapsed_s:((Date.now()-t0)/1000)|0};
+fs.mkdirSync(DIR,{recursive:true}); fs.writeFileSync(DIR+'/latest.json',JSON.stringify(out,null,2));
+fs.writeFileSync(Q+'/gmc-feed-guard-2026-06-17.json',JSON.stringify(out,null,2));
+console.log(`[gmc-feed-guard] ${verdict} — ${out.headline} (full catalog, ${out.elapsed_s}s)`);
+if(on425) offenders.forEach(o=>console.log('  ⚠️ re-leak: '+o));
+process.exit(verdict==='FAIL'?2:0);
diff --git a/scripts/staged-launchd/gmc-feed-guard/INSTALL.txt b/scripts/staged-launchd/gmc-feed-guard/INSTALL.txt
new file mode 100644
index 0000000..2c78bc7
--- /dev/null
+++ b/scripts/staged-launchd/gmc-feed-guard/INSTALL.txt
@@ -0,0 +1,4 @@
+# Steve-gated install for com.steve.gmc-feed-guard:
+cp "/Users/stevestudio2/Projects/dw-yolo-loop/scripts/staged-launchd/gmc-feed-guard/com.steve.gmc-feed-guard.plist" ~/Library/LaunchAgents/
+launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.steve.gmc-feed-guard.plist
+# then add manifest-row.json into ~/Projects/dw-canary-watchdog/manifest.json (canaries[])
diff --git a/scripts/staged-launchd/gmc-feed-guard/com.steve.gmc-feed-guard.plist b/scripts/staged-launchd/gmc-feed-guard/com.steve.gmc-feed-guard.plist
new file mode 100644
index 0000000..677ab58
--- /dev/null
+++ b/scripts/staged-launchd/gmc-feed-guard/com.steve.gmc-feed-guard.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0"><dict>
+  <key>Label</key><string>com.steve.gmc-feed-guard</string>
+  <key>ProgramArguments</key><array><string>/bin/sh</string><string>/Users/stevestudio2/Projects/dw-yolo-loop/scripts/staged-launchd/gmc-feed-guard/run-gmc-feed-guard.sh</string></array>
+  <key>StartInterval</key><integer>86400</integer>
+  <key>RunAtLoad</key><false/>
+  <key>StandardOutPath</key><string>/tmp/gmc-feed-guard.log</string>
+  <key>StandardErrorPath</key><string>/tmp/gmc-feed-guard.log</string>
+</dict></plist>
diff --git a/scripts/staged-launchd/gmc-feed-guard/manifest-row.json b/scripts/staged-launchd/gmc-feed-guard/manifest-row.json
new file mode 100644
index 0000000..45d9058
--- /dev/null
+++ b/scripts/staged-launchd/gmc-feed-guard/manifest-row.json
@@ -0,0 +1,9 @@
+{
+  "label": "gmc-feed-guard",
+  "cadence": "every 86400s (StartInterval)",
+  "stamp": "~/.claude/heartbeats/gmc-feed-guard.stamp",
+  "artifact": "~/.claude/heartbeats/gmc-feed-guard.stamp",
+  "launchd_log": "/tmp/gmc-feed-guard.log",
+  "warn_after": 100000,
+  "fail_after": 130000
+}
diff --git a/scripts/staged-launchd/gmc-feed-guard/run-gmc-feed-guard.sh b/scripts/staged-launchd/gmc-feed-guard/run-gmc-feed-guard.sh
new file mode 100755
index 0000000..b9e4f10
--- /dev/null
+++ b/scripts/staged-launchd/gmc-feed-guard/run-gmc-feed-guard.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# auto-generated by promote-canary.sh — runs gmc-feed-guard then writes its heartbeat stamp
+mkdir -p "$HOME/.claude/heartbeats"
+"/usr/local/bin/node" "/Users/stevestudio2/Projects/dw-yolo-loop/scripts/gmc-feed-guard/gmc-feed-guard.mjs"; rc=$?
+# rc 0=PASS, 2=FAIL-verdict — both mean the canary actually executed → stamp it
+if [ $rc -eq 0 ] || [ $rc -eq 2 ]; then date -u +%Y-%m-%dT%H:%M:%SZ > "$HOME/.claude/heartbeats/gmc-feed-guard.stamp"; fi
+exit $rc

← 780ef9c canary fleet REVISE (c56): fix corrupt metafield plist + sta  ·  back to Dw Yolo Loop  ·  gmc-feed-guard: tag FAIL offenders sample-leak vs real-$4.25 e88d630 →