[object Object]

← back to Designer Wallcoverings

GMC re-gate: exclude Google & YouTube publication from all product-publish chokepoints (Steve policy 2026-07-08)

fd035f271ee8fbedfb6cdda33f138485bd22413e · 2026-07-08 15:55:59 -0700 · Steve

Stops the $4.25 sample-price re-leak at every daily/active publish path — not just
the 4 named go-live scripts. Excludes publication 29646651457 from cadence-import,
activate-gated, remediate-channels-inventory + 15 other publish vectors (wallquest
refresh, koroseal updaters, justindavid/command54 push, interior-design-tagger,
ImportNewSkufromURL, DW-Duplicate-Recolor, bulk-import route, ShopifyCalendarNext,
kravet25-reactivate, active-2026, vendor-command-center, twil staging). Google is fed
exclusively by the controlled TSV feed. All edits inline + reversible.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit fd035f271ee8fbedfb6cdda33f138485bd22413e
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Jul 8 15:55:59 2026 -0700

    GMC re-gate: exclude Google & YouTube publication from all product-publish chokepoints (Steve policy 2026-07-08)
    
    Stops the $4.25 sample-price re-leak at every daily/active publish path — not just
    the 4 named go-live scripts. Excludes publication 29646651457 from cadence-import,
    activate-gated, remediate-channels-inventory + 15 other publish vectors (wallquest
    refresh, koroseal updaters, justindavid/command54 push, interior-design-tagger,
    ImportNewSkufromURL, DW-Duplicate-Recolor, bulk-import route, ShopifyCalendarNext,
    kravet25-reactivate, active-2026, vendor-command-center, twil staging). Google is fed
    exclusively by the controlled TSV feed. All edits inline + reversible.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 DW-Agents/vendor-command-center/server.js              |  8 ++++++--
 .../DW-Duplicate-Recolor-v1.4/lib/shopifyClient.js     |  7 ++++++-
 DW-Programming/ImportNewSkufromURL/lib/shopify.ts      | 14 ++++++++++----
 .../ShopifyCalendarNext/scripts/activate-first-two.ts  |  8 ++++++--
 DW-Programming/ShopifyCalendarNext/src/lib/shopify.ts  |  8 ++++++--
 DW-Programming/command54-shopify-push.js               |  7 ++++++-
 DW-Programming/interior-design-tagger.js               |  6 +++++-
 DW-Programming/justindavid-shopify-push.js             |  7 ++++++-
 .../nextjs-liquid-app/app/api/bulk-import/route.ts     |  8 ++++++--
 pending-approval/burst_twil_naturals.py                |  7 ++++++-
 pending-approval/twil_golive2.py                       |  6 +++++-
 pending-approval/twil_price_update.py                  |  7 ++++++-
 scripts/activate-koroseal-product.js                   |  7 ++++++-
 scripts/wallquest-refresh/activate-publish-v2.cjs      |  7 ++++++-
 .../publish-channels-carl-robinson.cjs                 |  7 ++++++-
 scripts/wallquest-refresh/publish-grasscloth-pr.cjs    |  8 +++++++-
 shopify/scripts/active-2026-and-all-channels.js        |  6 +++++-
 shopify/scripts/cadence/activate-gated.js              | 16 +++++++++++++---
 shopify/scripts/cadence/cadence-import.js              | 18 +++++++++++++++---
 .../scripts/cadence/remediate-channels-inventory.js    |  7 ++++++-
 .../data/kravet-map-pricing/kravet25-reactivate.js     |  6 +++++-
 shopify/scripts/koroseal-complete-update.ts            |  7 ++++++-
 shopify/scripts/koroseal-update.js                     |  7 ++++++-
 23 files changed, 155 insertions(+), 34 deletions(-)

diff --git a/DW-Agents/vendor-command-center/server.js b/DW-Agents/vendor-command-center/server.js
index fd039183..dadfc980 100644
--- a/DW-Agents/vendor-command-center/server.js
+++ b/DW-Agents/vendor-command-center/server.js
@@ -1342,9 +1342,13 @@ app.post('/api/launch-test', async (req, res) => {
             }
             await new Promise(r => setTimeout(r, 600));
 
-            // Publish to all 14 channels
+            // Publish to all channels EXCEPT Google & YouTube.
+            // GMC source-fix (Steve policy, 2026-07-08): '29646651457' Google
+            // REMOVED. Shopify auto-syncs minVariantPrice ($4.25 sample) to
+            // Merchant Center -> price disapproval. Google is fed by the
+            // controlled TSV feed only. Rollback: re-add '29646651457' below.
             const PUBS = [
-              '22208643184','22497296496','29646651457','29739483201','29776969793',
+              '22208643184','22497296496',/* 29646651457 Google-REMOVED */'29739483201','29776969793',
               '37538791489','37904089153','43657658419','44234276915','44317474867',
               '44317507635','71898464307','115856375859','140027723827'
             ].map(id => ({ publicationId: `gid://shopify/Publication/${id}` }));
diff --git a/DW-Programming/DW-Duplicate-Recolor-v1.4/lib/shopifyClient.js b/DW-Programming/DW-Duplicate-Recolor-v1.4/lib/shopifyClient.js
index 96f21e66..550714b9 100644
--- a/DW-Programming/DW-Duplicate-Recolor-v1.4/lib/shopifyClient.js
+++ b/DW-Programming/DW-Duplicate-Recolor-v1.4/lib/shopifyClient.js
@@ -295,10 +295,15 @@ class ShopifyClient {
             // Convert REST API product ID to GraphQL ID
             const graphqlProductId = `gid://shopify/Product/${productId}`;
 
-            // Publish to each channel
+            // Publish to each channel EXCEPT Google & YouTube.
+            // GMC source-fix (Steve policy, 2026-07-08): skip publication
+            // 29646651457. Shopify auto-syncs minVariantPrice ($4.25 sample) to
+            // Merchant Center -> price disapproval. Google is fed by the
+            // controlled TSV feed only. Rollback: delete the continue below.
             for (const pub of publications) {
                 const publicationId = pub.node.id;
                 const publicationName = pub.node.name;
+                if (publicationId === 'gid://shopify/Publication/29646651457') continue; // GMC exclusion
 
                 const publishMutation = `
                     mutation {
diff --git a/DW-Programming/ImportNewSkufromURL/lib/shopify.ts b/DW-Programming/ImportNewSkufromURL/lib/shopify.ts
index cab83c3e..2dea802a 100644
--- a/DW-Programming/ImportNewSkufromURL/lib/shopify.ts
+++ b/DW-Programming/ImportNewSkufromURL/lib/shopify.ts
@@ -1230,10 +1230,16 @@ async function publishToAllChannels(productId: string): Promise<void> {
     // makes the whole mutation return ACCESS_DENIED even though the publish itself
     // succeeds. We only need userErrors to know if it worked. (2026-06-12)
 
-    // Create publication inputs for ALL channels
-    const productPublications = publications.map(pub => ({
-      publicationId: pub.id,
-    }));
+    // Create publication inputs for all channels EXCEPT Google & YouTube.
+    // GMC source-fix (Steve policy, 2026-07-08): exclude publication 29646651457.
+    // Shopify auto-syncs minVariantPrice ($4.25 sample) to Merchant Center ->
+    // price disapproval. Google is fed by the controlled TSV feed only.
+    // Rollback: delete the .filter() below.
+    const productPublications = publications
+      .filter(pub => pub.id !== 'gid://shopify/Publication/29646651457')
+      .map(pub => ({
+        publicationId: pub.id,
+      }));
 
     try {
       const data = await shopifyGraphQL<{
diff --git a/DW-Programming/ShopifyCalendarNext/scripts/activate-first-two.ts b/DW-Programming/ShopifyCalendarNext/scripts/activate-first-two.ts
index 77621870..dda9e5f8 100644
--- a/DW-Programming/ShopifyCalendarNext/scripts/activate-first-two.ts
+++ b/DW-Programming/ShopifyCalendarNext/scripts/activate-first-two.ts
@@ -7,11 +7,15 @@ const pool = new Pool({
   connectionString: (process.env.DATABASE_URL || 'postgresql://dw_admin@127.0.0.1:5432/dw_unified')
 });
 
-// All 14 sales channels
+// All sales channels EXCEPT Google & YouTube.
+// GMC source-fix (Steve policy, 2026-07-08): '29646651457' Google REMOVED.
+// Shopify auto-syncs minVariantPrice ($4.25 sample) to Merchant Center -> price
+// disapproval. Google is fed by the controlled TSV feed only.
+// Rollback: re-add the 29646651457 line below.
 const SALES_CHANNELS = [
   'gid://shopify/Publication/22208643184',  // Online Store
   'gid://shopify/Publication/22497296496',  // Buy Button
-  'gid://shopify/Publication/29646651457',  // Google & YouTube
+  // 'gid://shopify/Publication/29646651457',  // Google & YouTube — GMC-REMOVED 2026-07-08
   'gid://shopify/Publication/29739483201',  // Facebook & Instagram
   'gid://shopify/Publication/29776969793',  // Houzz
   'gid://shopify/Publication/37538791489',  // Carro
diff --git a/DW-Programming/ShopifyCalendarNext/src/lib/shopify.ts b/DW-Programming/ShopifyCalendarNext/src/lib/shopify.ts
index 89a6f89e..fa5c936d 100644
--- a/DW-Programming/ShopifyCalendarNext/src/lib/shopify.ts
+++ b/DW-Programming/ShopifyCalendarNext/src/lib/shopify.ts
@@ -45,11 +45,15 @@ export async function setProductStatus(productId: string, status: 'DRAFT' | 'ACT
   return result.data?.productUpdate?.product;
 }
 
-// All 14 sales channels
+// All sales channels EXCEPT Google & YouTube.
+// GMC source-fix (Steve policy, 2026-07-08): '29646651457' Google REMOVED.
+// Shopify auto-syncs minVariantPrice ($4.25 sample) to Merchant Center -> price
+// disapproval. Google is fed by the controlled TSV feed only.
+// Rollback: re-add the 29646651457 line below.
 export const SALES_CHANNELS = [
   'gid://shopify/Publication/22208643184',  // Online Store
   'gid://shopify/Publication/22497296496',  // Buy Button
-  'gid://shopify/Publication/29646651457',  // Google & YouTube
+  // 'gid://shopify/Publication/29646651457',  // Google & YouTube — GMC-REMOVED 2026-07-08
   'gid://shopify/Publication/29739483201',  // Facebook & Instagram
   'gid://shopify/Publication/29776969793',  // Houzz
   'gid://shopify/Publication/37538791489',  // Carro
diff --git a/DW-Programming/command54-shopify-push.js b/DW-Programming/command54-shopify-push.js
index 06927990..6b1ee129 100644
--- a/DW-Programming/command54-shopify-push.js
+++ b/DW-Programming/command54-shopify-push.js
@@ -55,7 +55,12 @@ let _PUBS = null;
 async function _loadPubs() {
   if (_PUBS) return _PUBS;
   const r = await shopifyGql(`{publications(first:50){edges{node{id name}}}}`, {});
-  _PUBS = (r?.data?.publications?.edges || []).map(e => e.node);
+  // GMC source-fix (Steve policy, 2026-07-08): exclude "Google & YouTube"
+  // (publication 29646651457). Shopify auto-syncs minVariantPrice ($4.25 sample)
+  // to Merchant Center → price disapproval. Google is fed by the controlled TSV
+  // feed only. Rollback: delete the .filter() below.
+  _PUBS = (r?.data?.publications?.edges || []).map(e => e.node)
+    .filter(p => p.id !== 'gid://shopify/Publication/29646651457');
   return _PUBS;
 }
 // Publish a product to ALL sales-channel publications (was: never published → only
diff --git a/DW-Programming/interior-design-tagger.js b/DW-Programming/interior-design-tagger.js
index 1752838b..befa8cdd 100644
--- a/DW-Programming/interior-design-tagger.js
+++ b/DW-Programming/interior-design-tagger.js
@@ -49,10 +49,14 @@ const RESET      = args.includes('--reset');
 
 // ─── Publication IDs (all 14 channels) ───────────────────────────────────────
 
+// GMC source-fix (Steve policy, 2026-07-08): 'Google & YouTube' (29646651457)
+// REMOVED. Shopify auto-syncs minVariantPrice ($4.25 sample) to Merchant Center
+// -> price disapproval. Google is fed by the controlled TSV feed only.
+// Rollback: re-add the 29646651457 line below.
 const PUBLICATION_IDS = [
   'gid://shopify/Publication/22208643184',   // Online Store
   'gid://shopify/Publication/22497296496',   // Buy Button
-  'gid://shopify/Publication/29646651457',   // Google & YouTube
+  // 'gid://shopify/Publication/29646651457',   // Google & YouTube — GMC-REMOVED 2026-07-08
   'gid://shopify/Publication/29739483201',   // Facebook & Instagram
   'gid://shopify/Publication/29776969793',   // Houzz
   'gid://shopify/Publication/37538791489',   // Carro
diff --git a/DW-Programming/justindavid-shopify-push.js b/DW-Programming/justindavid-shopify-push.js
index f235d4e5..eb75f63f 100644
--- a/DW-Programming/justindavid-shopify-push.js
+++ b/DW-Programming/justindavid-shopify-push.js
@@ -52,7 +52,12 @@ let _PUBS = null;
 async function _loadPubs() {
   if (_PUBS) return _PUBS;
   const r = await shopifyGql(`{publications(first:50){edges{node{id name}}}}`, {});
-  _PUBS = (r?.data?.publications?.edges || []).map(e => e.node);
+  // GMC source-fix (Steve policy, 2026-07-08): exclude "Google & YouTube"
+  // (publication 29646651457). Shopify auto-syncs minVariantPrice ($4.25 sample)
+  // to Merchant Center → price disapproval. Google is fed by the controlled TSV
+  // feed only. Rollback: delete the .filter() below.
+  _PUBS = (r?.data?.publications?.edges || []).map(e => e.node)
+    .filter(p => p.id !== 'gid://shopify/Publication/29646651457');
   return _PUBS;
 }
 async function publishToAllChannels(productGid) {
diff --git a/DW-Programming/nextjs-liquid-app/app/api/bulk-import/route.ts b/DW-Programming/nextjs-liquid-app/app/api/bulk-import/route.ts
index 772c8855..d7932a01 100644
--- a/DW-Programming/nextjs-liquid-app/app/api/bulk-import/route.ts
+++ b/DW-Programming/nextjs-liquid-app/app/api/bulk-import/route.ts
@@ -5,11 +5,15 @@ const SHOPIFY_STORE = 'designer-laboratory-sandbox.myshopify.com';
 const SHOPIFY_TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
 const GEMINI_API_KEY = '${GOOGLE_API_KEY}'; // Billed Tier 1 key
 
-// All 14 sales channels - publish to ALL on product creation
+// All sales channels EXCEPT Google & YouTube - publish to these on product creation.
+// GMC source-fix (Steve policy, 2026-07-08): '29646651457' Google REMOVED.
+// Shopify auto-syncs minVariantPrice ($4.25 sample) to Merchant Center -> price
+// disapproval. Google is fed by the controlled TSV feed only.
+// Rollback: re-add the 29646651457 line below.
 const ALL_PUBLICATION_IDS = [
   'gid://shopify/Publication/22208643184',  // Online Store
   'gid://shopify/Publication/22497296496',  // Buy Button
-  'gid://shopify/Publication/29646651457',  // Google & YouTube
+  // 'gid://shopify/Publication/29646651457',  // Google & YouTube — GMC-REMOVED 2026-07-08
   'gid://shopify/Publication/29739483201',  // Facebook & Instagram
   'gid://shopify/Publication/29776969793',  // Houzz
   'gid://shopify/Publication/37538791489',  // Carro
diff --git a/pending-approval/burst_twil_naturals.py b/pending-approval/burst_twil_naturals.py
index 866772ba..190d25b8 100644
--- a/pending-approval/burst_twil_naturals.py
+++ b/pending-approval/burst_twil_naturals.py
@@ -43,7 +43,12 @@ def all_publication_ids():
     global _PUBS
     if _PUBS is None:
         res=graphql("{ publications(first:50){edges{node{id name}}} }")
-        _PUBS=[e["node"]["id"] for e in res.get("data",{}).get("publications",{}).get("edges",[])]
+        # GMC source-fix (Steve policy, 2026-07-08): exclude "Google & YouTube"
+        # (publication 29646651457). Shopify auto-syncs minVariantPrice ($4.25
+        # sample) to Merchant Center -> price disapproval. Google is fed by the
+        # controlled TSV feed only. Rollback: delete the filter below.
+        _PUBS=[e["node"]["id"] for e in res.get("data",{}).get("publications",{}).get("edges",[])
+               if e["node"]["id"]!="gid://shopify/Publication/29646651457"]
     return _PUBS
 
 def publish_all_channels(product_id):
diff --git a/pending-approval/twil_golive2.py b/pending-approval/twil_golive2.py
index bb817527..258356c6 100644
--- a/pending-approval/twil_golive2.py
+++ b/pending-approval/twil_golive2.py
@@ -111,7 +111,11 @@ if DRY:
     print("\n[DRY] CONFIRM=1 to execute."); sys.exit()
 
 # ---- EXECUTE ----
-PUBS=[e["node"]["id"] for e in gql("{publications(first:50){edges{node{id name}}}}").get("data",{}).get("publications",{}).get("edges",[])]
+# GMC source-fix (Steve policy, 2026-07-08): exclude "Google & YouTube"
+# (publication 29646651457). Shopify auto-syncs minVariantPrice ($4.25 sample)
+# to Merchant Center -> price disapproval. Google is fed by the controlled TSV
+# feed only. Rollback: delete the filter below.
+PUBS=[e["node"]["id"] for e in gql("{publications(first:50){edges{node{id name}}}}").get("data",{}).get("publications",{}).get("edges",[]) if e["node"]["id"]!="gid://shopify/Publication/29646651457"]
 def publish(pid):
     return gql("""mutation($id:ID!,$in:[PublicationInput!]!){publishablePublish(id:$id,input:$in){userErrors{message}}}""",
        {"id":f"gid://shopify/Product/{pid}","in":[{"publicationId":x} for x in PUBS]}).get("data",{}).get("publishablePublish",{}).get("userErrors",[])
diff --git a/pending-approval/twil_price_update.py b/pending-approval/twil_price_update.py
index d9ccdd20..56507697 100644
--- a/pending-approval/twil_price_update.py
+++ b/pending-approval/twil_price_update.py
@@ -122,7 +122,12 @@ if DRY:
 print("\n=== APPLYING ===")
 def all_pubs():
     res=graphql("{ publications(first:50){edges{node{id name}}} }")
-    return [e["node"]["id"] for e in res.get("data",{}).get("publications",{}).get("edges",[])]
+    # GMC source-fix (Steve policy, 2026-07-08): exclude "Google & YouTube"
+    # (publication 29646651457). Shopify auto-syncs minVariantPrice ($4.25 sample)
+    # to Merchant Center -> price disapproval. Google is fed by the controlled TSV
+    # feed only. Rollback: delete the filter below.
+    return [e["node"]["id"] for e in res.get("data",{}).get("publications",{}).get("edges",[])
+            if e["node"]["id"]!="gid://shopify/Publication/29646651457"]
 PUBS=all_pubs()
 def publish(pid):
     gid=f"gid://shopify/Product/{pid}"
diff --git a/scripts/activate-koroseal-product.js b/scripts/activate-koroseal-product.js
index ea98a25b..9bbea724 100755
--- a/scripts/activate-koroseal-product.js
+++ b/scripts/activate-koroseal-product.js
@@ -77,7 +77,12 @@ async function publishToAllChannels(productId) {
   
   // Get all publications
   const pubsResult = await graphql(`{ publications(first: 50) { edges { node { id name } } } }`);
-  const publications = pubsResult.data?.publications?.edges?.map(e => e.node) || [];
+  // GMC source-fix (Steve policy, 2026-07-08): exclude "Google & YouTube"
+  // (publication 29646651457). Shopify auto-syncs minVariantPrice ($4.25 sample)
+  // to Merchant Center → price disapproval. Google is fed by the controlled TSV
+  // feed only. Rollback: delete the .filter() below.
+  const publications = (pubsResult.data?.publications?.edges?.map(e => e.node) || [])
+    .filter(p => p.id !== 'gid://shopify/Publication/29646651457');
   
   // Build mutation
   const pubInputs = publications.map(p => `{publicationId: "${p.id}"}`).join(', ');
diff --git a/scripts/wallquest-refresh/activate-publish-v2.cjs b/scripts/wallquest-refresh/activate-publish-v2.cjs
index d7f06229..fea27f7a 100644
--- a/scripts/wallquest-refresh/activate-publish-v2.cjs
+++ b/scripts/wallquest-refresh/activate-publish-v2.cjs
@@ -25,7 +25,12 @@ function gql(query, variables) {
 (async () => {
   const pubRes = await gql('{ publications(first:25){edges{node{id name}}} }');
   if (pubRes.errors) { console.error('publications error:', JSON.stringify(pubRes.errors).slice(0, 200)); process.exit(1); }
-  const pubs = pubRes.data.publications.edges.map(e => e.node);
+  // GMC source-fix (Steve policy, 2026-07-08): exclude "Google & YouTube"
+  // (publication 29646651457). Shopify auto-syncs minVariantPrice ($4.25 sample)
+  // to Merchant Center → price disapproval. Google is fed by the controlled TSV
+  // feed only. Rollback: delete the .filter() below.
+  const pubs = pubRes.data.publications.edges.map(e => e.node)
+    .filter(p => p.id !== 'gid://shopify/Publication/29646651457');
   const pubInput = pubs.map(p => ({ publicationId: p.id }));
   console.log('sales channels:', pubs.map(p => p.name).join(', '));
 
diff --git a/scripts/wallquest-refresh/publish-channels-carl-robinson.cjs b/scripts/wallquest-refresh/publish-channels-carl-robinson.cjs
index 7e32bf3a..8205300e 100644
--- a/scripts/wallquest-refresh/publish-channels-carl-robinson.cjs
+++ b/scripts/wallquest-refresh/publish-channels-carl-robinson.cjs
@@ -26,7 +26,12 @@ function gql(query, variables) {
   // 1) enumerate all sales channels (publications)
   const pubRes = await gql('{ publications(first:25){edges{node{id name}}} }');
   if (pubRes.errors) { console.error('publications error:', JSON.stringify(pubRes.errors).slice(0, 200)); process.exit(1); }
-  const pubs = pubRes.data.publications.edges.map(e => e.node);
+  // GMC source-fix (Steve policy, 2026-07-08): exclude "Google & YouTube"
+  // (publication 29646651457). Shopify auto-syncs minVariantPrice ($4.25 sample)
+  // to Merchant Center → price disapproval. Google is fed by the controlled TSV
+  // feed only. Rollback: delete the .filter() below.
+  const pubs = pubRes.data.publications.edges.map(e => e.node)
+    .filter(p => p.id !== 'gid://shopify/Publication/29646651457');
   console.log('sales channels:', pubs.map(p => p.name).join(', '));
   const pubInput = pubs.map(p => ({ publicationId: p.id }));
 
diff --git a/scripts/wallquest-refresh/publish-grasscloth-pr.cjs b/scripts/wallquest-refresh/publish-grasscloth-pr.cjs
index 4605d6d1..9309fc13 100644
--- a/scripts/wallquest-refresh/publish-grasscloth-pr.cjs
+++ b/scripts/wallquest-refresh/publish-grasscloth-pr.cjs
@@ -92,7 +92,13 @@ async function publishOne(row) {
   try {
     const gid = `gid://shopify/Product/${pid}`;
     const pubs = await gql(`{publications(first:30){edges{node{id name}}}}`);
-    const inputs = (pubs.data?.publications?.edges || []).map(e => ({ publicationId: e.node.id }));
+    // GMC source-fix (Steve policy, 2026-07-08): exclude "Google & YouTube"
+    // (publication 29646651457). Shopify auto-syncs minVariantPrice ($4.25 sample)
+    // to Merchant Center → price disapproval. Google is fed by the controlled TSV
+    // feed only. Rollback: delete the .filter() below.
+    const inputs = (pubs.data?.publications?.edges || [])
+      .filter(e => e.node.id !== 'gid://shopify/Publication/29646651457')
+      .map(e => ({ publicationId: e.node.id }));
     if (inputs.length) await gql(`mutation($id:ID!,$input:[PublicationInput!]!){publishablePublish(id:$id,input:$input){userErrors{field message}}}`, { id: gid, input: inputs });
   } catch (e) { console.error('  publish warn:', e.message); }
   // link shopify_product_id back into catalog
diff --git a/shopify/scripts/active-2026-and-all-channels.js b/shopify/scripts/active-2026-and-all-channels.js
index c1841f6b..5c6f2815 100644
--- a/shopify/scripts/active-2026-and-all-channels.js
+++ b/shopify/scripts/active-2026-and-all-channels.js
@@ -32,8 +32,12 @@ const TOKEN = (env.match(/^SHOPIFY_ADMIN_TOKEN=(.*)$/m) || [])[1].replace(/['"]/
 const STORE = 'designer-laboratory-sandbox.myshopify.com', API = '2024-10';
 const sleep = ms => new Promise(r => setTimeout(r, ms));
 
+// GMC source-fix (Steve policy, 2026-07-08): 'Google & YouTube' (29646651457)
+// REMOVED from the publish set. Shopify auto-syncs minVariantPrice ($4.25 sample)
+// to Merchant Center -> price disapproval. Google is fed by the controlled TSV
+// feed only. Rollback: re-add the ['Google & YouTube','29646651457'] entry below.
 const PUBS = [
-  ['Online Store', '22208643184'], ['Buy Button', '22497296496'], ['Google & YouTube', '29646651457'],
+  ['Online Store', '22208643184'], ['Buy Button', '22497296496'], /* Google-REMOVED 29646651457 */
   ['Facebook & Instagram', '29739483201'], ['Houzz', '29776969793'], ['Point of Sale', '37904089153'],
   ['Fabricut', '43657658419'], ['Pinterest', '44234276915'], ['Rakuten Ichiba (JP)', '44317474867'],
   ['Shop', '44317507635'], ['Inbox', '71898464307'], ['TikTok', '115856375859'], ['DWAutoPostBlog', '140027723827'],
diff --git a/shopify/scripts/cadence/activate-gated.js b/shopify/scripts/cadence/activate-gated.js
index bd1247d8..c3983abd 100644
--- a/shopify/scripts/cadence/activate-gated.js
+++ b/shopify/scripts/cadence/activate-gated.js
@@ -93,14 +93,24 @@ const M_PUBLISH = `mutation($id:ID!,$input:[PublicationInput!]!){
   publishablePublish(id:$id, input:$input){ userErrors{field message} }
 }`;
 let PUBLICATION_IDS = null;   // [{id,name}], loaded once per run
+// GMC source-fix (Steve policy, 2026-07-08): NEVER publish promoted SKUs to the
+// "Google & YouTube" channel (publication 29646651457). Shopify auto-syncs the
+// published product's minVariantPrice to Merchant Center; on DW that min is the
+// $4.25 "-Sample" variant → Google advertises $4.25 on a real roll → price
+// disapproval. Google is fed EXCLUSIVELY by the controlled TSV feed. This
+// DRAFT→ACTIVE promote path is a daily chokepoint, so the exclusion belongs here.
+// Rollback: delete the GOOGLE_PUBLICATION_ID filter line below.
+const GOOGLE_PUBLICATION_ID = 'gid://shopify/Publication/29646651457';
 async function loadPublications() {
   if (PUBLICATION_IDS) return PUBLICATION_IDS;
   const r = await gqlRetry(`{publications(first:50){edges{node{id name}}}}`, {});
-  PUBLICATION_IDS = (r.json?.data?.publications?.edges || []).map(e => e.node);
+  PUBLICATION_IDS = (r.json?.data?.publications?.edges || []).map(e => e.node)
+    .filter(p => p.id !== GOOGLE_PUBLICATION_ID); // GMC exclusion (2026-07-08)
   return PUBLICATION_IDS;
 }
-// Publish an ACTIVE product to ALL channel publications (Online Store first).
-// "already published" userErrors are benign (idempotent re-runs); real errors return.
+// Publish an ACTIVE product to ALL channel publications EXCEPT Google & YouTube
+// (Online Store first). "already published" userErrors are benign (idempotent
+// re-runs); real errors return.
 async function publishToChannels(productId) {
   const pubs = await loadPublications();
   if (!pubs.length) return { published: false, why: 'no-publications-scope' };
diff --git a/shopify/scripts/cadence/cadence-import.js b/shopify/scripts/cadence/cadence-import.js
index eeda4bb4..6fdb2193 100644
--- a/shopify/scripts/cadence/cadence-import.js
+++ b/shopify/scripts/cadence/cadence-import.js
@@ -704,14 +704,26 @@ const M_PUBLISH = `mutation($id:ID!,$input:[PublicationInput!]!){
   publishablePublish(id:$id, input:$input){ userErrors{field message} }
 }`;
 let PUBLICATION_IDS = null;   // [{id,name}], loaded once per run
+// GMC source-fix (Steve policy, 2026-07-08): NEVER publish new SKUs to the
+// "Google & YouTube" channel (publication 29646651457). Shopify auto-syncs a
+// published product's minVariantPrice to Merchant Center; on DW that min is the
+// $4.25 "-Sample" variant → Google advertises $4.25 on a real roll → price
+// disapproval. Google is fed EXCLUSIVELY by the controlled TSV feed
+// (build-google-feed.js), so channel membership on Google must stay empty.
+// This is the daily chokepoint — every vendor's newly-created/activated SKU
+// flows through publishToChannels() here, so the exclusion belongs here.
+// Rollback: delete the GOOGLE_PUBLICATION_ID filter line below.
+const GOOGLE_PUBLICATION_ID = 'gid://shopify/Publication/29646651457';
 async function loadPublications() {
   if (PUBLICATION_IDS) return PUBLICATION_IDS;
   const r = await gqlRetry(`{publications(first:50){edges{node{id name}}}}`, {});
-  PUBLICATION_IDS = (r.json?.data?.publications?.edges || []).map(e => e.node);
+  PUBLICATION_IDS = (r.json?.data?.publications?.edges || []).map(e => e.node)
+    .filter(p => p.id !== GOOGLE_PUBLICATION_ID); // GMC exclusion (2026-07-08)
   return PUBLICATION_IDS;
 }
-// Publish an ACTIVE product to ALL channel publications (Online Store first).
-// "already published" userErrors are benign (idempotent re-runs); real errors throw.
+// Publish an ACTIVE product to ALL channel publications EXCEPT Google & YouTube
+// (Online Store first). "already published" userErrors are benign (idempotent
+// re-runs); real errors throw.
 async function publishToChannels(productId) {
   const pubs = await loadPublications();
   if (!pubs.length) return { published: false, why: 'no-publications-scope' };
diff --git a/shopify/scripts/cadence/remediate-channels-inventory.js b/shopify/scripts/cadence/remediate-channels-inventory.js
index 25166a89..3b5c7de9 100644
--- a/shopify/scripts/cadence/remediate-channels-inventory.js
+++ b/shopify/scripts/cadence/remediate-channels-inventory.js
@@ -75,7 +75,12 @@ let PUBLICATION_IDS = null;
 async function loadPublications() {
   if (PUBLICATION_IDS) return PUBLICATION_IDS;
   const r = await gqlRetry(`{publications(first:50){edges{node{id name}}}}`, {});
-  PUBLICATION_IDS = (r.json?.data?.publications?.edges || []).map(e => e.node);
+  // GMC source-fix (Steve policy, 2026-07-08): exclude "Google & YouTube"
+  // (publication 29646651457). Shopify auto-syncs minVariantPrice ($4.25 sample)
+  // to Merchant Center → price disapproval. Google is fed by the controlled TSV
+  // feed only. Rollback: delete the .filter() below.
+  PUBLICATION_IDS = (r.json?.data?.publications?.edges || []).map(e => e.node)
+    .filter(p => p.id !== 'gid://shopify/Publication/29646651457');
   return PUBLICATION_IDS;
 }
 async function publishToChannels(productId) {
diff --git a/shopify/scripts/data/kravet-map-pricing/kravet25-reactivate.js b/shopify/scripts/data/kravet-map-pricing/kravet25-reactivate.js
index 3a23c2a7..cea1ed6a 100644
--- a/shopify/scripts/data/kravet-map-pricing/kravet25-reactivate.js
+++ b/shopify/scripts/data/kravet-map-pricing/kravet25-reactivate.js
@@ -33,8 +33,12 @@ const TOKEN = (env.match(/^SHOPIFY_ADMIN_TOKEN=(.*)$/m) || [])[1].replace(/['"]/
 const STORE = 'designer-laboratory-sandbox.myshopify.com', API = '2024-10';
 const sleep = ms => new Promise(r => setTimeout(r, ms));
 
+// GMC source-fix (Steve policy, 2026-07-08): 'Google & YouTube' (29646651457)
+// REMOVED from the publish set. Shopify auto-syncs minVariantPrice ($4.25 sample)
+// to Merchant Center -> price disapproval. Google is fed by the controlled TSV
+// feed only. Rollback: re-add the ['Google & YouTube','29646651457'] entry below.
 const PUBS = [
-  ['Online Store', '22208643184'], ['Buy Button', '22497296496'], ['Google & YouTube', '29646651457'],
+  ['Online Store', '22208643184'], ['Buy Button', '22497296496'], /* Google-REMOVED 29646651457 */
   ['Facebook & Instagram', '29739483201'], ['Houzz', '29776969793'], ['Point of Sale', '37904089153'],
   ['Fabricut', '43657658419'], ['Pinterest', '44234276915'], ['Rakuten Ichiba (JP)', '44317474867'],
   ['Shop', '44317507635'], ['Inbox', '71898464307'], ['TikTok', '115856375859'], ['DWAutoPostBlog', '140027723827'],
diff --git a/shopify/scripts/koroseal-complete-update.ts b/shopify/scripts/koroseal-complete-update.ts
index 769408bb..6ab4b711 100644
--- a/shopify/scripts/koroseal-complete-update.ts
+++ b/shopify/scripts/koroseal-complete-update.ts
@@ -105,7 +105,12 @@ async function getPublicationIds(): Promise<string[]> {
   const pubs = result.data?.publications?.edges || [];
   console.log(`📢 Found ${pubs.length} sales channels:`);
   pubs.forEach((p: any) => console.log(`   - ${p.node.name}`));
-  return pubs.map((p: any) => p.node.id);
+  // GMC source-fix (Steve policy, 2026-07-08): exclude "Google & YouTube"
+  // (publication 29646651457). Shopify auto-syncs minVariantPrice ($4.25 sample)
+  // to Merchant Center -> price disapproval. Google is fed by the controlled TSV
+  // feed only. Rollback: delete the .filter() below.
+  return pubs.map((p: any) => p.node.id)
+    .filter((id: string) => id !== 'gid://shopify/Publication/29646651457');
 }
 
 async function analyzeWithGemini(imageUrl: string, title: string): Promise<any> {
diff --git a/shopify/scripts/koroseal-update.js b/shopify/scripts/koroseal-update.js
index 58e5fa9e..65a7ad1f 100644
--- a/shopify/scripts/koroseal-update.js
+++ b/shopify/scripts/koroseal-update.js
@@ -116,7 +116,12 @@ async function getPublicationIds() {
   const result = await graphqlRequest(query);
   const pubs = result.data?.publications?.edges || [];
   console.log(`📢 Found ${pubs.length} sales channels`);
-  return pubs.map((p) => p.node.id);
+  // GMC source-fix (Steve policy, 2026-07-08): exclude "Google & YouTube"
+  // (publication 29646651457). Shopify auto-syncs minVariantPrice ($4.25 sample)
+  // to Merchant Center -> price disapproval. Google is fed by the controlled TSV
+  // feed only. Rollback: delete the .filter() below.
+  return pubs.map((p) => p.node.id)
+    .filter((id) => id !== 'gid://shopify/Publication/29646651457');
 }
 
 async function analyzeWithGemini(imageUrl, title) {

← 79f6183d auto-save: 2026-07-08T15:06:23 (8 files) — DW-Programming/Im  ·  back to Designer Wallcoverings  ·  auto-save: 2026-07-08T16:06:38 (5 files) — pending-approval/ c3e9a9f1 →