[object Object]

← back to Dw Validator Debug TK11314

governance(TK-11370): make live-by-default Shopify writers dry-run by default

278d8a494ab0733b10e29ce464c2d71155fc7396 · 2026-09-10 17:52:30 -0700 · Steve

Flip `DRY = argv.includes('--dry')` -> `DRY = !argv.includes('--apply')` so a
zero-argument run no longer fires customer-facing Shopify writes.

Backward compatible: `--dry` still means dry; `--apply` now required to write.
Only zero-arg invocations change behaviour, and every candidate was checked
against its launchd/cron/pm2/wrapper invocation sites first (4 scripts that a
cadence job runs flagless were EXCLUDED so this cannot silently disable them).

Verified: node --check/py_compile 87/87 with a positive control proving the
checker rejects an injected fault; argv truth-table negative test 5/5.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L53y4oP2itY3qeJ8WQgMzc

Files touched

Diff

commit 278d8a494ab0733b10e29ce464c2d71155fc7396
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu Sep 10 17:52:30 2026 -0700

    governance(TK-11370): make live-by-default Shopify writers dry-run by default
    
    Flip `DRY = argv.includes('--dry')` -> `DRY = !argv.includes('--apply')` so a
    zero-argument run no longer fires customer-facing Shopify writes.
    
    Backward compatible: `--dry` still means dry; `--apply` now required to write.
    Only zero-arg invocations change behaviour, and every candidate was checked
    against its launchd/cron/pm2/wrapper invocation sites first (4 scripts that a
    cadence job runs flagless were EXCLUDED so this cannot silently disable them).
    
    Verified: node --check/py_compile 87/87 with a positive control proving the
    checker rejects an injected fault; argv truth-table negative test 5/5.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01L53y4oP2itY3qeJ8WQgMzc
---
 shopify/scripts/add-missing-samples-v2.js             | 2 +-
 shopify/scripts/create-missing-sample-variants.js     | 2 +-
 shopify/scripts/dwvs-reconcile-mfr.js                 | 2 +-
 shopify/scripts/innovations-pattern-sweep.js          | 2 +-
 shopify/scripts/innovations-sitemap-sweep.js          | 2 +-
 shopify/scripts/inventory-set-2026.js                 | 2 +-
 shopify/scripts/sandberg-add-bolt-variants.js         | 2 +-
 shopify/scripts/sandberg-add-mural-variants.js        | 2 +-
 shopify/scripts/sandberg-william-morris-weight-4lb.js | 2 +-
 shopify/scripts/sandberg-wm-add-wallcovering-title.js | 2 +-
 shopify/scripts/set-active-zero-to-2026.js            | 2 +-
 shopify/scripts/thibaut-disco-draft.js                | 2 +-
 shopify/scripts/thibaut-photo-fix.js                  | 2 +-
 shopify/scripts/thibaut-spec-backfill.js              | 2 +-
 shopify/scripts/vendor-disco-draft.js                 | 2 +-
 shopify/scripts/wm-add-bolt-variants.js               | 2 +-
 16 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/shopify/scripts/add-missing-samples-v2.js b/shopify/scripts/add-missing-samples-v2.js
index 60d28ec1..56a4a368 100644
--- a/shopify/scripts/add-missing-samples-v2.js
+++ b/shopify/scripts/add-missing-samples-v2.js
@@ -358,7 +358,7 @@ async function createMissingVariants(progress) {
 // ─── Main ──────────────────────────────────────────────────────────────
 async function main() {
   const args = process.argv.slice(2);
-  const dryRun = args.includes('--dry-run');
+  const dryRun = !args.includes('--apply');
   const scanOnly = args.includes('--scan-only');
   const fresh = args.includes('--fresh');
 
diff --git a/shopify/scripts/create-missing-sample-variants.js b/shopify/scripts/create-missing-sample-variants.js
index 6918f906..9f8e3a11 100644
--- a/shopify/scripts/create-missing-sample-variants.js
+++ b/shopify/scripts/create-missing-sample-variants.js
@@ -124,7 +124,7 @@ async function setInventory(inventoryItemId, qty = 2026) {
 
 async function main() {
   const args = process.argv.slice(2);
-  const dryRun = args.includes('--dry-run');
+  const dryRun = !args.includes('--apply');
   const fresh = args.includes('--fresh');
 
   console.log(`\n${'═'.repeat(60)}`);
diff --git a/shopify/scripts/dwvs-reconcile-mfr.js b/shopify/scripts/dwvs-reconcile-mfr.js
index 3f2c010e..fa308ec7 100644
--- a/shopify/scripts/dwvs-reconcile-mfr.js
+++ b/shopify/scripts/dwvs-reconcile-mfr.js
@@ -15,7 +15,7 @@ const fs = require('fs');
 const path = require('path');
 const { execSync } = require('child_process');
 
-const DRY_RUN = process.argv.includes('--dry-run');
+const DRY_RUN = !process.argv.includes('--apply');
 
 async function gql(q, v = {}) {
   const r = await fetch(ENDPOINT, {
diff --git a/shopify/scripts/innovations-pattern-sweep.js b/shopify/scripts/innovations-pattern-sweep.js
index 9a40be67..6bdfb16f 100644
--- a/shopify/scripts/innovations-pattern-sweep.js
+++ b/shopify/scripts/innovations-pattern-sweep.js
@@ -15,7 +15,7 @@ const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
 const ENDPOINT = `https://${SHOP}/admin/api/2024-10/graphql.json`;
 if (!TOKEN) { console.error('Missing SHOPIFY_ADMIN_TOKEN'); process.exit(1); }
 const sleep = ms => new Promise(r => setTimeout(r, ms));
-const DRY = process.argv.includes('--dry-run');
+const DRY = !process.argv.includes('--apply');
 
 async function gql(q, v = {}) {
   for (let a = 0; a < 6; a++) {
diff --git a/shopify/scripts/innovations-sitemap-sweep.js b/shopify/scripts/innovations-sitemap-sweep.js
index 58b63a55..f799ebec 100644
--- a/shopify/scripts/innovations-sitemap-sweep.js
+++ b/shopify/scripts/innovations-sitemap-sweep.js
@@ -14,7 +14,7 @@ const ENDPOINT = `https://${SHOP}/admin/api/2024-10/graphql.json`;
 const SITEMAP = 'https://www.innovationsusa.com/sitemap.xml';
 if (!TOKEN) { console.error('Missing SHOPIFY_ADMIN_TOKEN'); process.exit(1); }
 const sleep = ms => new Promise(r => setTimeout(r, ms));
-const DRY = process.argv.includes('--dry-run');
+const DRY = !process.argv.includes('--apply');
 
 async function gql(q, v = {}) {
   for (let a = 0; a < 6; a++) {
diff --git a/shopify/scripts/inventory-set-2026.js b/shopify/scripts/inventory-set-2026.js
index c7560c39..1a009a7e 100644
--- a/shopify/scripts/inventory-set-2026.js
+++ b/shopify/scripts/inventory-set-2026.js
@@ -108,7 +108,7 @@ async function applyQuantities(map, dry) {
 }
 
 async function run() {
-  const dry = process.argv.includes('--dry-run');
+  const dry = !process.argv.includes('--apply');
   console.log(`${dry ? '[DRY] ' : ''}inventory set on_hand=${TARGET_QTY} for ${SKUS.length} SKUs at location ${LOCATION_ID}`);
 
   console.log('\nStep 1: build SKU → inventoryItemId map');
diff --git a/shopify/scripts/sandberg-add-bolt-variants.js b/shopify/scripts/sandberg-add-bolt-variants.js
index ed1ceca1..2c2b6591 100644
--- a/shopify/scripts/sandberg-add-bolt-variants.js
+++ b/shopify/scripts/sandberg-add-bolt-variants.js
@@ -99,7 +99,7 @@ async function processOne(row, dry) {
 }
 
 async function run() {
-  const dry = process.argv.includes('--dry-run');
+  const dry = !process.argv.includes('--apply');
   console.log(`${dry ? '[DRY RUN] ' : ''}Adding bolt variants to ${ROLLS.length} Sandberg products.`);
   console.log(`  option: "${OPTION_NAME}" = "${BOLT_OPTION_VALUE}"`);
   console.log(`  weight: ${TARGET_WEIGHT_LB} lb`);
diff --git a/shopify/scripts/sandberg-add-mural-variants.js b/shopify/scripts/sandberg-add-mural-variants.js
index 9fffef3b..b52883e0 100644
--- a/shopify/scripts/sandberg-add-mural-variants.js
+++ b/shopify/scripts/sandberg-add-mural-variants.js
@@ -70,7 +70,7 @@ async function processOne(row, dry) {
 }
 
 async function run() {
-  const dry = process.argv.includes('--dry-run');
+  const dry = !process.argv.includes('--apply');
   console.log(`${dry ? '[DRY RUN] ' : ''}Adding m² variants to ${ITEMS.length} Sandberg murals.`);
 
   const results = [];
diff --git a/shopify/scripts/sandberg-william-morris-weight-4lb.js b/shopify/scripts/sandberg-william-morris-weight-4lb.js
index b2e09201..b01c66ed 100644
--- a/shopify/scripts/sandberg-william-morris-weight-4lb.js
+++ b/shopify/scripts/sandberg-william-morris-weight-4lb.js
@@ -116,7 +116,7 @@ async function run() {
 
   fs.writeFileSync(path.join(outDir, `sandberg-wm-plan-${stamp}.json`), JSON.stringify({ bolts, sampleOnly }, null, 2));
 
-  if (process.argv.includes('--dry-run')) {
+  if (!process.argv.includes('--apply')) {
     console.log('Dry run — no updates made. Plan written.');
     return;
   }
diff --git a/shopify/scripts/sandberg-wm-add-wallcovering-title.js b/shopify/scripts/sandberg-wm-add-wallcovering-title.js
index 3591fba2..79c6f113 100644
--- a/shopify/scripts/sandberg-wm-add-wallcovering-title.js
+++ b/shopify/scripts/sandberg-wm-add-wallcovering-title.js
@@ -89,7 +89,7 @@ async function run() {
 
   fs.writeFileSync(path.join(outDir, `sandberg-wm-title-plan-${stamp}.json`), JSON.stringify({ plan, skipped }, null, 2));
 
-  if (process.argv.includes('--dry-run')) {
+  if (!process.argv.includes('--apply')) {
     console.log('[title] Dry run — no updates made.');
     if (plan.length) console.log('[title] Sample:', plan.slice(0, 5));
     return;
diff --git a/shopify/scripts/set-active-zero-to-2026.js b/shopify/scripts/set-active-zero-to-2026.js
index 0c353c59..7881042b 100644
--- a/shopify/scripts/set-active-zero-to-2026.js
+++ b/shopify/scripts/set-active-zero-to-2026.js
@@ -59,7 +59,7 @@ const SET_QTY = `
   }`;
 
 (async () => {
-  const dry = process.argv.includes('--dry-run');
+  const dry = !process.argv.includes('--apply');
   const scanPath = latestScan();
   const scan = JSON.parse(fs.readFileSync(scanPath, 'utf8'));
   // newest→oldest (scan already sorted CREATED_AT desc).
diff --git a/shopify/scripts/thibaut-disco-draft.js b/shopify/scripts/thibaut-disco-draft.js
index 5729a6e9..2a545a80 100644
--- a/shopify/scripts/thibaut-disco-draft.js
+++ b/shopify/scripts/thibaut-disco-draft.js
@@ -16,7 +16,7 @@ const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
 const ENDPOINT = `https://${SHOP}/admin/api/2024-10/graphql.json`;
 if (!TOKEN) { console.error('Missing SHOPIFY_ADMIN_TOKEN'); process.exit(1); }
 const sleep = ms => new Promise(r => setTimeout(r, ms));
-const DRY = process.argv.includes('--dry-run');
+const DRY = !process.argv.includes('--apply');
 const LIM = parseInt((process.argv.find(a=>a.startsWith('--limit='))||'--limit=0').split('=')[1]) || 0;
 
 async function gql(q, v = {}) {
diff --git a/shopify/scripts/thibaut-photo-fix.js b/shopify/scripts/thibaut-photo-fix.js
index 5fc71dff..3ecf657a 100644
--- a/shopify/scripts/thibaut-photo-fix.js
+++ b/shopify/scripts/thibaut-photo-fix.js
@@ -129,7 +129,7 @@ async function doPrune(dry) {
 }
 
 (async () => {
-  const dry = process.argv.includes('--dry-run');
+  const dry = !process.argv.includes('--apply');
   if (process.argv.includes('--prune')) await doPrune(dry);
   else await doAdd(dry); // default = add
 })().catch(e => { console.error('\nFATAL', e); process.exit(1); });
diff --git a/shopify/scripts/thibaut-spec-backfill.js b/shopify/scripts/thibaut-spec-backfill.js
index dc69e0f8..001acfd5 100644
--- a/shopify/scripts/thibaut-spec-backfill.js
+++ b/shopify/scripts/thibaut-spec-backfill.js
@@ -12,7 +12,7 @@ const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
 const ENDPOINT = `https://${SHOP}/admin/api/2024-10/graphql.json`;
 if (!TOKEN) { console.error('Missing SHOPIFY_ADMIN_TOKEN'); process.exit(1); }
 const sleep = ms => new Promise(r => setTimeout(r, ms));
-const DRY = process.argv.includes('--dry-run');
+const DRY = !process.argv.includes('--apply');
 
 async function gql(q, v = {}) {
   for (let a = 0; a < 6; a++) {
diff --git a/shopify/scripts/vendor-disco-draft.js b/shopify/scripts/vendor-disco-draft.js
index d567a6fa..c92007cc 100644
--- a/shopify/scripts/vendor-disco-draft.js
+++ b/shopify/scripts/vendor-disco-draft.js
@@ -15,7 +15,7 @@ const ENDPOINT = `https://${SHOP}/admin/api/2024-10/graphql.json`;
 if (!TOKEN) { console.error('Missing SHOPIFY_ADMIN_TOKEN'); process.exit(1); }
 const sleep = ms => new Promise(r => setTimeout(r, ms));
 const arg = k => (process.argv.find(a => a.startsWith(`--${k}=`)) || '').split('=').slice(1).join('=');
-const VENDOR = arg('vendor'), TABLE = arg('table'), DRY = process.argv.includes('--dry-run');
+const VENDOR = arg('vendor'), TABLE = arg('table'), DRY = !process.argv.includes('--apply');
 if (!VENDOR || !TABLE) { console.error('need --vendor and --table'); process.exit(1); }
 
 async function gql(q, v = {}) {
diff --git a/shopify/scripts/wm-add-bolt-variants.js b/shopify/scripts/wm-add-bolt-variants.js
index 7d9c954d..83a98214 100644
--- a/shopify/scripts/wm-add-bolt-variants.js
+++ b/shopify/scripts/wm-add-bolt-variants.js
@@ -60,7 +60,7 @@ async function processOne(row, dry) {
 }
 
 async function run() {
-  const dry = process.argv.includes('--dry-run');
+  const dry = !process.argv.includes('--apply');
   console.log(`${dry ? '[DRY] ' : ''}Adding Bolt variants to ${TARGETS.length} William Morris products at $${PRICE_USD}`);
   const results = [];
   for (const row of TARGETS) {

← 1f69e597 TK-11357 action A: hard-abort guard on 5 debug-clone store-w  ·  back to Dw Validator Debug TK11314  ·  (newest)