← back to Gmc Titlefix
TK-11898 Option B executor: productInputs.delete for the 30 dead-vid offers (canary --one / --all, requires --confirm, ledgers each, reads back). Not fired in this commit.
5ee7b7a5bef82e2e753791c3e46fc377979b02bc · 2026-09-18 11:02:15 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Xkg7MT5FYYmJF5ovKBsko
Files touched
A tk11898-delete-executor.cjs
Diff
commit 5ee7b7a5bef82e2e753791c3e46fc377979b02bc
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri Sep 18 11:02:15 2026 -0700
TK-11898 Option B executor: productInputs.delete for the 30 dead-vid offers (canary --one / --all, requires --confirm, ledgers each, reads back). Not fired in this commit.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Xkg7MT5FYYmJF5ovKBsko
---
tk11898-delete-executor.cjs | 76 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/tk11898-delete-executor.cjs b/tk11898-delete-executor.cjs
new file mode 100644
index 0000000..4315f8d
--- /dev/null
+++ b/tk11898-delete-executor.cjs
@@ -0,0 +1,76 @@
+// TK-11898 Option B (Steve-approved 2026-09-18) — DELETE the 30 dead-variant-id GMC offers.
+// Mechanism: Merchant API v1 productInputs.delete on dataSource 180695450 (Shopify-channel primary).
+// The offers embed a DEAD variantId (absent from the 320,038-variant store dump), so the Shopify
+// channel will NOT re-create them on sync (that vid no longer exists) => delete is effectively permanent.
+// Reversibility: NOT one-command (channel-managed feed). Audit preimage: data/tk11898-delete-preimages-*.json.
+// SAFETY: does NOTHING without --confirm. --one <offerId> = single canary. --all = the 30 from the target list.
+//
+// node tk11898-delete-executor.cjs --one shopify_US_1496058986608_17829266554945 --confirm # canary (Latigo)
+// node tk11898-delete-executor.cjs --all --confirm # the 30
+//
+// Cost: $0 (Merchant API; no per-call charge).
+const { token, MERCHANT } = require('./_auth.js');
+const mc = require('./_mc-read-v1.js');
+const fs = require('fs');
+
+const BASE = 'https://merchantapi.googleapis.com/products/v1';
+const DS = `accounts/${MERCHANT}/dataSources/180695450`;
+const TARGETS = JSON.parse(fs.readFileSync('/tmp/tk11898-delete-targets.json', 'utf8')).map(t => t.offer_id);
+const LEDGER = '/Users/macstudio3/.claude/yolo-queue/executed-reversible/ledger.jsonl';
+
+const args = process.argv.slice(2);
+const CONFIRM = args.includes('--confirm');
+const ALL = args.includes('--all');
+const ONE = args.includes('--one') ? args[args.indexOf('--one') + 1] : null;
+
+const sleep = ms => new Promise(r => setTimeout(r, ms));
+
+async function delOne(offerId, hdr) {
+ const name = `accounts/${MERCHANT}/productInputs/online~en~US~${offerId}`;
+ const url = `${BASE}/${name}?dataSource=${encodeURIComponent(DS)}`;
+ const r = await fetch(url, { method: 'DELETE', headers: hdr });
+ const body = r.ok ? '' : await r.text();
+ return { offerId, http: r.status, ok: r.ok, err: body.slice(0, 200) };
+}
+
+(async () => {
+ let list;
+ if (ONE) list = [ONE];
+ else if (ALL) list = TARGETS;
+ else { console.log('Refusing: pass --one <offerId> or --all'); process.exit(2); }
+
+ if (!CONFIRM) {
+ console.log(`DRY (no --confirm): would DELETE ${list.length} offer(s) from ${DS}:`);
+ list.forEach(o => console.log(' ', o));
+ console.log('Add --confirm to fire.');
+ process.exit(0);
+ }
+
+ const hdr = { Authorization: 'Bearer ' + (await token()) };
+ const results = [];
+ for (const o of list) {
+ const res = await delOne(o, hdr);
+ results.push(res);
+ console.log(`${res.ok ? 'OK ' : 'ERR'} ${res.http} ${o}${res.err ? ' | ' + res.err : ''}`);
+ // ledger each successful delete
+ if (res.ok) {
+ fs.appendFileSync(LEDGER, JSON.stringify({
+ ts: new Date().toISOString(), agent: 'night-TK-11898', ticket: 'TK-11898',
+ action: `GMC productInputs.delete ${o} from ds180695450 (Option B, Steve-approved)`,
+ blast_radius: 1,
+ undo: `NOT one-command reversible (channel-managed dead-vid offer); audit preimage in gmc-titlefix data/tk11898-delete-preimages-*.json`,
+ verify: `node -e "require('./_mc-read-v1.js').getProduct('${o}').then(p=>console.log(p.id)).catch(e=>console.log('GONE:',e.message))"`
+ }) + '\n');
+ }
+ await sleep(300);
+ }
+ const ok = results.filter(r => r.ok).length;
+ console.log(`\nDELETED ${ok}/${list.length}. Errors: ${list.length - ok}.`);
+ // readback verify
+ console.log('--- readback (expect GONE/404) ---');
+ for (const o of list) {
+ try { const p = await mc.getProduct(o); console.log('STILL PRESENT:', o, '| price', JSON.stringify(p.price)); }
+ catch (e) { console.log('gone:', o, '|', e.message.slice(0, 60)); }
+ await sleep(200);
+ }
+})();
← 3fc0eaa TK-11898 Option B (Steve-approved 2026-09-18): live preimage
·
back to Gmc Titlefix
·
TK-11898 Option B EXECUTED (Steve-approved): 30/30 dead-vid 10a3116 →