← back to Designer Wallcoverings
harden: fail loud on bare run across dry-by-default scripts (TK-11503 F2)
995a82ea22fb18c3f15ad761debebd9761702d7a · 2026-09-15 11:50:02 -0700 · Steve
The dry-by-default flip (DRY = !includes('--apply')) makes a bare invocation a
silent no-op — it runs dry, writes nothing, and exits 0, so a stale cron/wrapper
caller silently does nothing with no signal. This adds an explicit-mode guard to
every dry-by-default script that lacked one: a bare run (no --apply and no
--dry-run) now prints a message and exits 2 instead of silently no-op'ing.
Idempotent (skips scripts already guarded), node --check verified per file, and
skips importable scripts (module.exports/export) where a top-level guard would
break an importer — those are left for a human main-check.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M DW-Programming/PhillipeRomanoTagger/consolidate-pr-vendors.jsM DW-Programming/backfill-canonical-colors.jsM DW-Programming/cleanup-all-body-html.jsM DW-Programming/cleanup-body-html-all-vendors.jsM DW-Programming/cleanup-pr-body-html-bulk.jsM DW-Programming/color-collection-cleaner.jsM DW-Programming/fabricut-activate.jsM DW-Programming/fix-phillipe-romano-vendors.jsM DW-Programming/fix-product-type-by-width.jsM DW-Programming/fix-single-variant-pricing.jsM DW-Programming/sweep-to-100.jsM DW-Programming/tag-designer-colors.jsM scripts/dwtt-body-to-metafields.jsM scripts/interior-design-tags.jsM scripts/populate-mfr-sku-metafield.jsM scripts/rw-upload-room-settings.jsM scripts/standardize-product-types-bulk.jsM scripts/standardize-product-types.jsM scripts/wallquest-refresh/publish-grasscloth-pr.cjsM shopify/scripts/add-missing-samples-v2.jsM shopify/scripts/cadence/kravet-3b-pricefix.mjsM shopify/scripts/create-missing-sample-variants.jsM shopify/scripts/dwvs-reconcile-mfr.jsM shopify/scripts/innovations-pattern-sweep.jsM shopify/scripts/innovations-sitemap-sweep.jsM shopify/scripts/inventory-set-2026.jsM shopify/scripts/reconcile/fix-live-shopify-product-type.jsM shopify/scripts/sandberg-add-bolt-variants.jsM shopify/scripts/sandberg-add-mural-variants.jsM shopify/scripts/sandberg-william-morris-weight-4lb.jsM shopify/scripts/sandberg-wm-add-wallcovering-title.jsM shopify/scripts/set-active-zero-to-2026.jsM shopify/scripts/thibaut-disco-draft.jsM shopify/scripts/thibaut-photo-fix.jsM shopify/scripts/thibaut-spec-backfill.jsM shopify/scripts/vendor-disco-draft.jsM shopify/scripts/wm-add-bolt-variants.js
Diff
commit 995a82ea22fb18c3f15ad761debebd9761702d7a
Author: Steve <steve@designerwallcoverings.com>
Date: Tue Sep 15 11:50:02 2026 -0700
harden: fail loud on bare run across dry-by-default scripts (TK-11503 F2)
The dry-by-default flip (DRY = !includes('--apply')) makes a bare invocation a
silent no-op — it runs dry, writes nothing, and exits 0, so a stale cron/wrapper
caller silently does nothing with no signal. This adds an explicit-mode guard to
every dry-by-default script that lacked one: a bare run (no --apply and no
--dry-run) now prints a message and exits 2 instead of silently no-op'ing.
Idempotent (skips scripts already guarded), node --check verified per file, and
skips importable scripts (module.exports/export) where a top-level guard would
break an importer — those are left for a human main-check.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
DW-Programming/PhillipeRomanoTagger/consolidate-pr-vendors.js | 5 +++++
DW-Programming/backfill-canonical-colors.js | 5 +++++
DW-Programming/cleanup-all-body-html.js | 5 +++++
DW-Programming/cleanup-body-html-all-vendors.js | 5 +++++
DW-Programming/cleanup-pr-body-html-bulk.js | 5 +++++
DW-Programming/color-collection-cleaner.js | 5 +++++
DW-Programming/fabricut-activate.js | 5 +++++
DW-Programming/fix-phillipe-romano-vendors.js | 5 +++++
DW-Programming/fix-product-type-by-width.js | 5 +++++
DW-Programming/fix-single-variant-pricing.js | 5 +++++
DW-Programming/sweep-to-100.js | 5 +++++
DW-Programming/tag-designer-colors.js | 5 +++++
scripts/dwtt-body-to-metafields.js | 5 +++++
scripts/interior-design-tags.js | 5 +++++
scripts/populate-mfr-sku-metafield.js | 5 +++++
scripts/rw-upload-room-settings.js | 5 +++++
scripts/standardize-product-types-bulk.js | 5 +++++
scripts/standardize-product-types.js | 5 +++++
scripts/wallquest-refresh/publish-grasscloth-pr.cjs | 5 +++++
shopify/scripts/add-missing-samples-v2.js | 5 +++++
shopify/scripts/cadence/kravet-3b-pricefix.mjs | 5 +++++
shopify/scripts/create-missing-sample-variants.js | 5 +++++
shopify/scripts/dwvs-reconcile-mfr.js | 5 +++++
shopify/scripts/innovations-pattern-sweep.js | 5 +++++
shopify/scripts/innovations-sitemap-sweep.js | 5 +++++
shopify/scripts/inventory-set-2026.js | 5 +++++
shopify/scripts/reconcile/fix-live-shopify-product-type.js | 5 +++++
shopify/scripts/sandberg-add-bolt-variants.js | 5 +++++
shopify/scripts/sandberg-add-mural-variants.js | 5 +++++
shopify/scripts/sandberg-william-morris-weight-4lb.js | 5 +++++
shopify/scripts/sandberg-wm-add-wallcovering-title.js | 5 +++++
shopify/scripts/set-active-zero-to-2026.js | 5 +++++
shopify/scripts/thibaut-disco-draft.js | 5 +++++
shopify/scripts/thibaut-photo-fix.js | 5 +++++
shopify/scripts/thibaut-spec-backfill.js | 5 +++++
shopify/scripts/vendor-disco-draft.js | 5 +++++
shopify/scripts/wm-add-bolt-variants.js | 5 +++++
37 files changed, 185 insertions(+)
diff --git a/DW-Programming/PhillipeRomanoTagger/consolidate-pr-vendors.js b/DW-Programming/PhillipeRomanoTagger/consolidate-pr-vendors.js
index 3ba27981..037f2a75 100644
--- a/DW-Programming/PhillipeRomanoTagger/consolidate-pr-vendors.js
+++ b/DW-Programming/PhillipeRomanoTagger/consolidate-pr-vendors.js
@@ -28,6 +28,11 @@ const VARIANT_VENDORS = [
'Phillipe Romano Vinyls',
];
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY_RUN = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
const BATCH_DELAY_MS = 300; // ms between mutations
const CONCURRENT_MUTATIONS = 4; // parallel mutations
diff --git a/DW-Programming/backfill-canonical-colors.js b/DW-Programming/backfill-canonical-colors.js
index 4bffe6dc..c8674e30 100644
--- a/DW-Programming/backfill-canonical-colors.js
+++ b/DW-Programming/backfill-canonical-colors.js
@@ -15,6 +15,11 @@ const API_VERSION = '2024-01';
const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
const DB_URL = process.env.TODO_DB_URL || 'postgres://stevestudio2@/dw_unified?host=/tmp';
const args = process.argv.slice(2);
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY = (args.includes('--dry-run') || !args.includes('--apply'));
const LIMIT = parseInt(args.find((_, i, a) => a[i-1] === '--limit') || '0', 10) || 0;
const CONC = parseInt(args.find((_, i, a) => a[i-1] === '--conc') || '8', 10) || 8;
diff --git a/DW-Programming/cleanup-all-body-html.js b/DW-Programming/cleanup-all-body-html.js
index 82448c0e..cb5a5918 100644
--- a/DW-Programming/cleanup-all-body-html.js
+++ b/DW-Programming/cleanup-all-body-html.js
@@ -14,6 +14,11 @@ const https = require('https');
const STORE = 'designer-laboratory-sandbox.myshopify.com';
const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
const API_VERSION = '2024-10';
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY_RUN = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
const LIMIT = (() => { const i = process.argv.indexOf('--limit'); return i >= 0 ? parseInt(process.argv[i + 1]) : 500; })();
const LOG_FILE = '/root/DW-Agents/logs/body-html-cleanup.log';
diff --git a/DW-Programming/cleanup-body-html-all-vendors.js b/DW-Programming/cleanup-body-html-all-vendors.js
index 6474b660..3a641ea8 100644
--- a/DW-Programming/cleanup-body-html-all-vendors.js
+++ b/DW-Programming/cleanup-body-html-all-vendors.js
@@ -15,6 +15,11 @@ const STORE = 'designer-laboratory-sandbox.myshopify.com';
const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
const API_VERSION = '2024-10';
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY_RUN = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
const LIMIT_ARG = process.argv.find((a, i) => process.argv[i - 1] === '--limit');
const LIMIT = LIMIT_ARG ? parseInt(LIMIT_ARG) : 500;
diff --git a/DW-Programming/cleanup-pr-body-html-bulk.js b/DW-Programming/cleanup-pr-body-html-bulk.js
index 4f0c4d4e..18a3c3ef 100644
--- a/DW-Programming/cleanup-pr-body-html-bulk.js
+++ b/DW-Programming/cleanup-pr-body-html-bulk.js
@@ -15,6 +15,11 @@ const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
const API_VERSION = '2024-10';
const VENDOR = 'Phillipe Romano';
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY_RUN = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
const SLACK_WEBHOOK_PATH = '/services/T03U65C1G7J/B09RCFHS7PW/7Izxc7OGsDWKPdRALLOocO6O';
diff --git a/DW-Programming/color-collection-cleaner.js b/DW-Programming/color-collection-cleaner.js
index 3d0e80fe..b9bcb26b 100644
--- a/DW-Programming/color-collection-cleaner.js
+++ b/DW-Programming/color-collection-cleaner.js
@@ -15,6 +15,11 @@ const API_VERSION = '2024-01';
const GEMINI_KEY = '${GOOGLE_API_KEY}'; // billed key - free tier quota exceeded
const args = process.argv.slice(2);
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY_RUN = (args.includes('--dry-run') || !args.includes('--apply'));
const TARGET_COLOR = args.find((_, i, a) => a[i - 1] === '--color') || null;
const ALL_COLORS = args.includes('--all');
diff --git a/DW-Programming/fabricut-activate.js b/DW-Programming/fabricut-activate.js
index ebd4ba5b..c2580813 100644
--- a/DW-Programming/fabricut-activate.js
+++ b/DW-Programming/fabricut-activate.js
@@ -81,6 +81,11 @@ async function activate(row,dry){
}
async function main(){
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
const args=process.argv.slice(2),dry=(args.includes('--dry-run') || !args.includes('--apply'));
let limit=null;const li=args.indexOf('--limit');if(li>=0&&args[li+1])limit=parseInt(args[li+1]);
if(!TOKEN){console.error('no SHOPIFY_ADMIN_TOKEN');process.exit(1);}
diff --git a/DW-Programming/fix-phillipe-romano-vendors.js b/DW-Programming/fix-phillipe-romano-vendors.js
index 785c7e57..82d2b14f 100644
--- a/DW-Programming/fix-phillipe-romano-vendors.js
+++ b/DW-Programming/fix-phillipe-romano-vendors.js
@@ -18,6 +18,11 @@ const GQL = `https://${SHOP}/admin/api/${API_VERSION}/graphql.json`;
const CANONICAL_VENDOR = 'Phillipe Romano';
// DRY_RUN=true means no mutations, just report what would happen
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY_RUN = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
const VERBOSE = process.argv.includes('--verbose');
diff --git a/DW-Programming/fix-product-type-by-width.js b/DW-Programming/fix-product-type-by-width.js
index 10bb3968..cd7482ce 100644
--- a/DW-Programming/fix-product-type-by-width.js
+++ b/DW-Programming/fix-product-type-by-width.js
@@ -31,6 +31,11 @@ const SLACK_WEBHOOK_PATH = '/services/T03U65C1G7J/B09RCFHS7PW/7Izxc7OGsDWKPdRALL
const args = process.argv.slice(2);
const DB_ONLY = args.includes('--db-only');
const PUSH_ONLY = args.includes('--push-only');
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY_RUN = (args.includes('--dry-run') || !args.includes('--apply'));
// ═══════════════════════════════════════════════
diff --git a/DW-Programming/fix-single-variant-pricing.js b/DW-Programming/fix-single-variant-pricing.js
index 67d82679..ef0eaf9a 100644
--- a/DW-Programming/fix-single-variant-pricing.js
+++ b/DW-Programming/fix-single-variant-pricing.js
@@ -385,6 +385,11 @@ async function addPricingVariant(productId, dwSku, retailPrice, compareAtPrice)
// ─── Main ───────────────────────────────────────────────────
async function main() {
const args = process.argv.slice(2);
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
const DRY_RUN = !args.includes('--apply');
const LIMIT = args.find(a => a.startsWith('--limit='));
const maxProducts = LIMIT ? parseInt(LIMIT.split('=')[1]) : Infinity;
diff --git a/DW-Programming/sweep-to-100.js b/DW-Programming/sweep-to-100.js
index 5b065e99..27b9d9f7 100644
--- a/DW-Programming/sweep-to-100.js
+++ b/DW-Programming/sweep-to-100.js
@@ -16,6 +16,11 @@ const SHOPIFY_DOMAIN = 'designer-laboratory-sandbox.myshopify.com';
const API_VERSION = '2024-01';
const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
const args = process.argv.slice(2);
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY = (args.includes('--dry-run') || !args.includes('--apply'));
const CONC = parseInt(args.find((_, i, a) => a[i-1] === '--conc') || '6', 10) || 6;
diff --git a/DW-Programming/tag-designer-colors.js b/DW-Programming/tag-designer-colors.js
index afbc1219..bdc59038 100644
--- a/DW-Programming/tag-designer-colors.js
+++ b/DW-Programming/tag-designer-colors.js
@@ -17,6 +17,11 @@ const args = process.argv.slice(2);
const SHOPIFY_DOMAIN = 'designer-laboratory-sandbox.myshopify.com';
const API_VERSION = '2024-01';
const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY = (args.includes('--dry-run') || !args.includes('--apply'));
const TOP2 = args.includes('--top2');
const PREFIX = args.find((_, i, a) => a[i-1] === '--prefix') || 'color:';
diff --git a/scripts/dwtt-body-to-metafields.js b/scripts/dwtt-body-to-metafields.js
index 8046b751..dd6beeef 100644
--- a/scripts/dwtt-body-to-metafields.js
+++ b/scripts/dwtt-body-to-metafields.js
@@ -10,6 +10,11 @@ const STORE = 'designer-laboratory-sandbox.myshopify.com';
const API = `https://${STORE}/admin/api/2024-01`;
const args = process.argv.slice(2);
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY_RUN = (args.includes('--dry-run') || !args.includes('--apply'));
const BATCH = parseInt(args[args.indexOf('--batch') + 1]) || 250;
const AFTER_CURSOR = args.includes('--after') ? args[args.indexOf('--after') + 1] : null;
diff --git a/scripts/interior-design-tags.js b/scripts/interior-design-tags.js
index bd643732..25c7bf67 100644
--- a/scripts/interior-design-tags.js
+++ b/scripts/interior-design-tags.js
@@ -504,6 +504,11 @@ async function processTable(tableName, limit, dryRun, shopifyOnly) {
async function main() {
const args = process.argv.slice(2);
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
const dryRun = (args.includes('--dry-run') || !args.includes('--apply'));
const shopifyOnly = args.includes('--shopify-only');
const tableFilter = args.find((a, i) => args[i - 1] === '--table');
diff --git a/scripts/populate-mfr-sku-metafield.js b/scripts/populate-mfr-sku-metafield.js
index a5ef3f7d..251f495b 100644
--- a/scripts/populate-mfr-sku-metafield.js
+++ b/scripts/populate-mfr-sku-metafield.js
@@ -185,6 +185,11 @@ function determineMfrSku(product) {
async function main() {
const args = process.argv.slice(2);
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
const dryRun = (args.includes('--dry-run') || !args.includes('--apply'));
const vendorArg = args.find(a => a.startsWith('--vendor='));
const vendorFilter = vendorArg ? vendorArg.split('=')[1] : null;
diff --git a/scripts/rw-upload-room-settings.js b/scripts/rw-upload-room-settings.js
index a4d606bc..687586b2 100644
--- a/scripts/rw-upload-room-settings.js
+++ b/scripts/rw-upload-room-settings.js
@@ -32,6 +32,11 @@ const pool = new Pool({
const args = process.argv.slice(2);
const batchSize = parseInt(args.find((a,i) => args[i-1] === '--batch') || '50');
const startId = parseInt(args.find((a,i) => args[i-1] === '--start-id') || '0');
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const dryRun = (args.includes('--dry-run') || !args.includes('--apply'));
/**
diff --git a/scripts/standardize-product-types-bulk.js b/scripts/standardize-product-types-bulk.js
index 61114b19..a1f5f527 100644
--- a/scripts/standardize-product-types-bulk.js
+++ b/scripts/standardize-product-types-bulk.js
@@ -14,6 +14,11 @@ const API_VERSION = '2024-10';
const GQL_URL = `https://${SHOPIFY_DOMAIN}/admin/api/${API_VERSION}/graphql.json`;
const SLACK_WEBHOOK = process.env.SLACK_WEBHOOK_URL || '';
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY_RUN = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
const fs = require('fs');
const path = require('path');
diff --git a/scripts/standardize-product-types.js b/scripts/standardize-product-types.js
index 27d84e1c..a06dbea1 100644
--- a/scripts/standardize-product-types.js
+++ b/scripts/standardize-product-types.js
@@ -14,6 +14,11 @@ const API_VERSION = '2024-10';
const GQL_URL = `https://${SHOPIFY_DOMAIN}/admin/api/${API_VERSION}/graphql.json`;
const SLACK_WEBHOOK = process.env.SLACK_WEBHOOK_URL || '';
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY_RUN = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
const BATCH_FILTER = process.argv.find(a => a.startsWith('--batch='))?.split('=')[1] || null;
diff --git a/scripts/wallquest-refresh/publish-grasscloth-pr.cjs b/scripts/wallquest-refresh/publish-grasscloth-pr.cjs
index 421d3bb1..fa573312 100644
--- a/scripts/wallquest-refresh/publish-grasscloth-pr.cjs
+++ b/scripts/wallquest-refresh/publish-grasscloth-pr.cjs
@@ -14,6 +14,11 @@ const PSQL = '/opt/homebrew/opt/postgresql@14/bin/psql';
const q = sql => execSync(`PGPASSWORD='${PGPW}' ${PSQL} -h localhost -U dw_admin -d dw_unified -tAc "${sql.replace(/"/g, '\\"')}"`, { encoding: 'utf8', maxBuffer: 1e8 });
const args = process.argv.slice(2);
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY = (args.includes('--dry-run') || !args.includes('--apply'));
const PILOT = args.includes('--pilot');
const ONE = (args[args.indexOf('--sku') + 1] && args.includes('--sku')) ? args[args.indexOf('--sku') + 1] : null;
diff --git a/shopify/scripts/add-missing-samples-v2.js b/shopify/scripts/add-missing-samples-v2.js
index 8962c0c3..85b675dc 100644
--- a/shopify/scripts/add-missing-samples-v2.js
+++ b/shopify/scripts/add-missing-samples-v2.js
@@ -359,6 +359,11 @@ async function createMissingVariants(progress) {
// ─── Main ──────────────────────────────────────────────────────────────
async function main() {
const args = process.argv.slice(2);
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
const dryRun = (args.includes('--dry-run') || !args.includes('--apply'));
const scanOnly = args.includes('--scan-only');
const fresh = args.includes('--fresh');
diff --git a/shopify/scripts/cadence/kravet-3b-pricefix.mjs b/shopify/scripts/cadence/kravet-3b-pricefix.mjs
index 90717142..9226e647 100644
--- a/shopify/scripts/cadence/kravet-3b-pricefix.mjs
+++ b/shopify/scripts/cadence/kravet-3b-pricefix.mjs
@@ -59,6 +59,11 @@ for (const t of targets) {
}
console.log(`Undo CSV written: ${UNDO}`);
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
if (DRY) { console.log('DRY RUN — no writes'); process.exit(0); }
diff --git a/shopify/scripts/create-missing-sample-variants.js b/shopify/scripts/create-missing-sample-variants.js
index bf402f37..2b216a06 100644
--- a/shopify/scripts/create-missing-sample-variants.js
+++ b/shopify/scripts/create-missing-sample-variants.js
@@ -125,6 +125,11 @@ async function setInventory(inventoryItemId, qty = 2026) {
async function main() {
const args = process.argv.slice(2);
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
const dryRun = (args.includes('--dry-run') || !args.includes('--apply'));
const fresh = args.includes('--fresh');
diff --git a/shopify/scripts/dwvs-reconcile-mfr.js b/shopify/scripts/dwvs-reconcile-mfr.js
index bd4bc4a9..df116230 100644
--- a/shopify/scripts/dwvs-reconcile-mfr.js
+++ b/shopify/scripts/dwvs-reconcile-mfr.js
@@ -15,6 +15,11 @@ const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY_RUN = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
async function gql(q, v = {}) {
diff --git a/shopify/scripts/innovations-pattern-sweep.js b/shopify/scripts/innovations-pattern-sweep.js
index 1cbb3e15..f17c99f9 100644
--- a/shopify/scripts/innovations-pattern-sweep.js
+++ b/shopify/scripts/innovations-pattern-sweep.js
@@ -15,6 +15,11 @@ 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));
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
async function gql(q, v = {}) {
diff --git a/shopify/scripts/innovations-sitemap-sweep.js b/shopify/scripts/innovations-sitemap-sweep.js
index 26a3274b..91ba5be0 100644
--- a/shopify/scripts/innovations-sitemap-sweep.js
+++ b/shopify/scripts/innovations-sitemap-sweep.js
@@ -14,6 +14,11 @@ 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));
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
async function gql(q, v = {}) {
diff --git a/shopify/scripts/inventory-set-2026.js b/shopify/scripts/inventory-set-2026.js
index db23a0ee..758386b4 100644
--- a/shopify/scripts/inventory-set-2026.js
+++ b/shopify/scripts/inventory-set-2026.js
@@ -138,6 +138,11 @@ async function applyQuantities(map, dry) {
}
async function run() {
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
const dry = !process.argv.includes('--apply');
console.log(`${dry ? '[DRY] ' : ''}inventory set on_hand=${TARGET_QTY} for ${SKUS.length} SKUs at location ${LOCATION_ID}`);
diff --git a/shopify/scripts/reconcile/fix-live-shopify-product-type.js b/shopify/scripts/reconcile/fix-live-shopify-product-type.js
index 0cb9c932..a9110612 100644
--- a/shopify/scripts/reconcile/fix-live-shopify-product-type.js
+++ b/shopify/scripts/reconcile/fix-live-shopify-product-type.js
@@ -27,6 +27,11 @@
const fs = require('fs');
const path = require('path');
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
const DOMAIN = 'designer-laboratory-sandbox.myshopify.com';
const API = '2024-10';
diff --git a/shopify/scripts/sandberg-add-bolt-variants.js b/shopify/scripts/sandberg-add-bolt-variants.js
index 7aaad952..3f9dccb6 100644
--- a/shopify/scripts/sandberg-add-bolt-variants.js
+++ b/shopify/scripts/sandberg-add-bolt-variants.js
@@ -99,6 +99,11 @@ async function processOne(row, dry) {
}
async function run() {
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
const dry = (process.argv.includes('--dry-run') || !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}"`);
diff --git a/shopify/scripts/sandberg-add-mural-variants.js b/shopify/scripts/sandberg-add-mural-variants.js
index 2f02d8ec..eb4fc1f2 100644
--- a/shopify/scripts/sandberg-add-mural-variants.js
+++ b/shopify/scripts/sandberg-add-mural-variants.js
@@ -70,6 +70,11 @@ async function processOne(row, dry) {
}
async function run() {
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
const dry = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
console.log(`${dry ? '[DRY RUN] ' : ''}Adding m² variants to ${ITEMS.length} Sandberg murals.`);
diff --git a/shopify/scripts/sandberg-william-morris-weight-4lb.js b/shopify/scripts/sandberg-william-morris-weight-4lb.js
index 8d15329c..fbab3455 100644
--- a/shopify/scripts/sandberg-william-morris-weight-4lb.js
+++ b/shopify/scripts/sandberg-william-morris-weight-4lb.js
@@ -116,6 +116,11 @@ async function run() {
fs.writeFileSync(path.join(outDir, `sandberg-wm-plan-${stamp}.json`), JSON.stringify({ bolts, sampleOnly }, null, 2));
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
if ((process.argv.includes('--dry-run') || !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 9efd531f..ed633009 100644
--- a/shopify/scripts/sandberg-wm-add-wallcovering-title.js
+++ b/shopify/scripts/sandberg-wm-add-wallcovering-title.js
@@ -89,6 +89,11 @@ async function run() {
fs.writeFileSync(path.join(outDir, `sandberg-wm-title-plan-${stamp}.json`), JSON.stringify({ plan, skipped }, null, 2));
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
if ((process.argv.includes('--dry-run') || !process.argv.includes('--apply'))) {
console.log('[title] Dry run — no updates made.');
if (plan.length) console.log('[title] Sample:', plan.slice(0, 5));
diff --git a/shopify/scripts/set-active-zero-to-2026.js b/shopify/scripts/set-active-zero-to-2026.js
index 68d00420..067c9d57 100644
--- a/shopify/scripts/set-active-zero-to-2026.js
+++ b/shopify/scripts/set-active-zero-to-2026.js
@@ -81,6 +81,11 @@ const SET_QTY = `
}`;
(async () => {
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
const dry = !process.argv.includes('--apply');
const scanPath = latestScan();
const scan = JSON.parse(fs.readFileSync(scanPath, 'utf8'));
diff --git a/shopify/scripts/thibaut-disco-draft.js b/shopify/scripts/thibaut-disco-draft.js
index 2b8c8a53..aa7e232c 100644
--- a/shopify/scripts/thibaut-disco-draft.js
+++ b/shopify/scripts/thibaut-disco-draft.js
@@ -16,6 +16,11 @@ 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));
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
const LIM = parseInt((process.argv.find(a=>a.startsWith('--limit='))||'--limit=0').split('=')[1]) || 0;
diff --git a/shopify/scripts/thibaut-photo-fix.js b/shopify/scripts/thibaut-photo-fix.js
index 1baca67c..08c573b2 100644
--- a/shopify/scripts/thibaut-photo-fix.js
+++ b/shopify/scripts/thibaut-photo-fix.js
@@ -130,6 +130,11 @@ async function doPrune(dry) {
}
(async () => {
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
const dry = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
if (process.argv.includes('--prune')) await doPrune(dry);
else await doAdd(dry); // default = add
diff --git a/shopify/scripts/thibaut-spec-backfill.js b/shopify/scripts/thibaut-spec-backfill.js
index d1ea730d..0fcb9631 100644
--- a/shopify/scripts/thibaut-spec-backfill.js
+++ b/shopify/scripts/thibaut-spec-backfill.js
@@ -12,6 +12,11 @@ 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));
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const DRY = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
async function gql(q, v = {}) {
diff --git a/shopify/scripts/vendor-disco-draft.js b/shopify/scripts/vendor-disco-draft.js
index 9bac3045..6cc938d1 100644
--- a/shopify/scripts/vendor-disco-draft.js
+++ b/shopify/scripts/vendor-disco-draft.js
@@ -15,6 +15,11 @@ 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('=');
+// TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+}
const VENDOR = arg('vendor'), TABLE = arg('table'), DRY = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
if (!VENDOR || !TABLE) { console.error('need --vendor and --table'); process.exit(1); }
diff --git a/shopify/scripts/wm-add-bolt-variants.js b/shopify/scripts/wm-add-bolt-variants.js
index f1221106..5eb5045b 100644
--- a/shopify/scripts/wm-add-bolt-variants.js
+++ b/shopify/scripts/wm-add-bolt-variants.js
@@ -60,6 +60,11 @@ async function processOne(row, dry) {
}
async function run() {
+ // TK-11503 F2: refuse to run without an explicit mode — fail loud, never a silent dry no-op.
+ if (!process.argv.includes('--apply') && !process.argv.includes('--dry-run')) {
+ console.error('Refusing to run: pass --apply to WRITE or --dry-run to preview.');
+ process.exit(2);
+ }
const dry = (process.argv.includes('--dry-run') || !process.argv.includes('--apply'));
console.log(`${dry ? '[DRY] ' : ''}Adding Bolt variants to ${TARGETS.length} William Morris products at $${PRICE_USD}`);
const results = [];
← fce6b836 vcc: add /programs 'All DW Programs' hub (TK-11765)
·
back to Designer Wallcoverings
·
vcc: add deploy-programs-hub.sh — drift-safe Kamatera deploy 95aca976 →