[object Object]

← back to Designerwallcoverings

TK-11076: Hollywood rollback artifact (no-op — batch judged unsafe, not run)

86ca8d49f05ef8256e5df3adbfe35845fe645cc7 · 2026-09-04 12:42:39 -0700 · Steve Abrams

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STupyqBoLfTPHaTr1Gi42b

Files touched

Diff

commit 86ca8d49f05ef8256e5df3adbfe35845fe645cc7
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Sep 4 12:42:39 2026 -0700

    TK-11076: Hollywood rollback artifact (no-op — batch judged unsafe, not run)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01STupyqBoLfTPHaTr1Gi42b
---
 scripts/hollywood-onboard/tk11076-rollback.mjs | 65 ++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/scripts/hollywood-onboard/tk11076-rollback.mjs b/scripts/hollywood-onboard/tk11076-rollback.mjs
new file mode 100644
index 0000000..d4f4903
--- /dev/null
+++ b/scripts/hollywood-onboard/tk11076-rollback.mjs
@@ -0,0 +1,65 @@
+#!/usr/bin/env node
+/**
+ * TK-11076 Hollywood Wallcoverings — per-handle rollback (--apply).
+ *
+ * STATUS: NO-OP. The TK-11076 canary for Hollywood was judged UNSAFE and the
+ * batch was NOT run — zero products were modified, so there is nothing to roll
+ * back. This script is emitted per the ticket's rollback-artifact requirement
+ * and will restore tags for any handle recorded in the rollback map IF a future
+ * run (with a proper colorway anchor) populates it.
+ *
+ * Anchor problem that triggered the stop: hollywood_catalog.color_name is
+ * blank / "AI-Analyzed-v2" / pattern-attribute garbage (Abstract, Type 2,
+ * Twisted Paper Weave, ACT Colorfastness, Panels…) for ~97% of the affected
+ * live products, so palette-noise could not be separated from legit color tags.
+ *
+ *   node tk11076-rollback.mjs                       # dry-run (lists recorded handles)
+ *   node tk11076-rollback.mjs --apply                # restore ALL recorded handles
+ *   node tk11076-rollback.mjs --only=h1,h2 --apply   # restore specific handles
+ */
+import fs from 'node:fs';
+import path from 'node:path';
+
+const STORE = process.env.SHOPIFY_STORE || 'designer-laboratory-sandbox.myshopify.com';
+const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
+const API = process.env.SHOPIFY_API_VERSION || '2024-10';
+const APPLY = process.argv.includes('--apply');
+const ONLY = ((process.argv.find(a => a.startsWith('--only=')) || '').split('=')[1] || '').split(',').filter(Boolean);
+const ROLLBACK = path.join(process.env.HOME, '.claude/yolo-queue/executed-reversible/TK-11076-Hollywood_Wallcoverings-rollback.json');
+const sleep = ms => new Promise(r => setTimeout(r, ms));
+
+async function gql(query, variables) {
+  for (let a = 0; a < 5; a++) {
+    const res = await fetch(`https://${STORE}/admin/api/${API}/graphql.json`, {
+      method: 'POST', headers: { 'X-Shopify-Access-Token': TOKEN, 'Content-Type': 'application/json' },
+      body: JSON.stringify({ query, variables }), signal: AbortSignal.timeout(45000) });
+    const j = await res.json().catch(() => ({}));
+    if (j.errors) { if (a === 4) return { errors: j.errors }; await sleep(1200 * (a + 1)); continue; }
+    await sleep(350); return j.data;
+  }
+}
+
+async function main() {
+  const map = fs.existsSync(ROLLBACK) ? JSON.parse(fs.readFileSync(ROLLBACK, 'utf8')) : { products: {} };
+  const products = map.products || {};
+  let handles = Object.keys(products);
+  if (ONLY.length) handles = handles.filter(h => ONLY.includes(h));
+  if (!handles.length) {
+    console.log(`No recorded handles to roll back (status=${map.status || 'unknown'}). NO-OP — the canary stopped before any write.`);
+    return;
+  }
+  if (!APPLY) { console.log(`DRY-RUN. Would restore ${handles.length} handles. Re-run with --apply.`); return; }
+  if (!TOKEN) { console.error('FATAL: set SHOPIFY_ADMIN_TOKEN'); process.exit(1); }
+  let done = 0;
+  for (const h of handles) {
+    const rec = products[h];
+    const d = await gql(`mutation($input:ProductInput!){ productUpdate(input:$input){ product{ id } userErrors{ field message } } }`,
+      { input: { id: rec.id, tags: rec.old_tags } });
+    const ue = d && d.productUpdate && d.productUpdate.userErrors;
+    if (ue && ue.length) { console.error(`  userErrors ${h}: ${JSON.stringify(ue)}`); continue; }
+    console.log(`[${++done}/${handles.length}] restored ${h}`);
+    await sleep(600);
+  }
+  console.log(`DONE: restored ${done} handles.`);
+}
+main();

← bfae207 TK-11076: colorway-title-anchor PL-exclusion + Malibu run sc  ·  back to Designerwallcoverings  ·  TK-10209: publish 435 O&L products missing from Google/YouTu c9a5901 →