← 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
M DW-Agents/vendor-command-center/server.jsM DW-Programming/DW-Duplicate-Recolor-v1.4/lib/shopifyClient.jsM DW-Programming/ImportNewSkufromURL/lib/shopify.tsM DW-Programming/ShopifyCalendarNext/scripts/activate-first-two.tsM DW-Programming/ShopifyCalendarNext/src/lib/shopify.tsM DW-Programming/command54-shopify-push.jsM DW-Programming/interior-design-tagger.jsM DW-Programming/justindavid-shopify-push.jsM DW-Programming/nextjs-liquid-app/app/api/bulk-import/route.tsM pending-approval/burst_twil_naturals.pyM pending-approval/twil_golive2.pyM pending-approval/twil_price_update.pyM scripts/activate-koroseal-product.jsM scripts/wallquest-refresh/activate-publish-v2.cjsM scripts/wallquest-refresh/publish-channels-carl-robinson.cjsM scripts/wallquest-refresh/publish-grasscloth-pr.cjsM shopify/scripts/active-2026-and-all-channels.jsM shopify/scripts/cadence/activate-gated.jsM shopify/scripts/cadence/cadence-import.jsM shopify/scripts/cadence/remediate-channels-inventory.jsM shopify/scripts/data/kravet-map-pricing/kravet25-reactivate.jsM shopify/scripts/koroseal-complete-update.tsM shopify/scripts/koroseal-update.js
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 →