[object Object]

← back to Rebel Walls Push

TK-11248 action G: read-only revalidation confirms 6 cleared descriptions already live (no write needed)

ff9dbfbf854b3b4b43e24f211b035aaa13e983af · 2026-09-04 12:16:12 -0700 · Steve Abrams

All 6 settlement-CLEARED Rebel Walls murals carry authorized descriptionHtml,
all DRAFT, 0 activated. 4 from TK-11192 (9/3); 2 refreshed in the 9/4 18:26 wave
(word-identical, curly-vs-straight apostrophe only). Holds intact: R20805 blocked,
5 counsel untouched (len=0). Stopped on the (benign) drift per instruction — no
customer-facing write fired.

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

Files touched

Diff

commit ff9dbfbf854b3b4b43e24f211b035aaa13e983af
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Sep 4 12:16:12 2026 -0700

    TK-11248 action G: read-only revalidation confirms 6 cleared descriptions already live (no write needed)
    
    All 6 settlement-CLEARED Rebel Walls murals carry authorized descriptionHtml,
    all DRAFT, 0 activated. 4 from TK-11192 (9/3); 2 refreshed in the 9/4 18:26 wave
    (word-identical, curly-vs-straight apostrophe only). Holds intact: R20805 blocked,
    5 counsel untouched (len=0). Stopped on the (benign) drift per instruction — no
    customer-facing write fired.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01RFJimFhUJowuXnXtjNTLEC
---
 scripts/revalidate-descG.js | 104 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)

diff --git a/scripts/revalidate-descG.js b/scripts/revalidate-descG.js
new file mode 100644
index 0000000..25b322c
--- /dev/null
+++ b/scripts/revalidate-descG.js
@@ -0,0 +1,104 @@
+'use strict';
+/* READ-ONLY revalidation for TK-11248 action G (6 settlement-CLEARED Rebel Walls
+ * descriptionHtml writes). Also confirms the HOLDs (R20805 blocked + 5 counsel)
+ * remain untouched. NO WRITES. $0.
+ *
+ * For each of the 12 HELD murals it GETs live: id, status, vendor, mfr metafield,
+ * current descriptionHtml length + first 80 chars. Compares the 6 target handles
+ * to the drafted copy and reports NEEDS-WRITE / ALREADY-CORRECT / DRIFT.
+ */
+const fs = require('fs');
+const path = require('path');
+const { gqlRetry, DOMAIN } = require('./_shop');
+
+// The 6 CLEAR-TO-PUBLISH (action G) — handle -> {mfr, expected descriptionHtml}
+const DRAFTED = require('./descG-copy.json'); // { handle: {mfr, html} }
+const CLEARED = Object.keys(DRAFTED);
+
+// HOLDS — must stay untouched
+const HOLD_BLOCKED = ['birds-and-cages-petrol-rebel-walls']; // R20805
+const HOLD_COUNSEL = [
+  'monstera-leaves-beige-rebel-walls',      // R19778
+  'elephant-and-friends-blue-rebel-walls',  // R20227
+  'bear-friend-blue-rebel-walls',           // R21071
+  'happy-bear-beige-rebel-walls',           // R21072
+  'twilight-bouquet-dark-rebel-walls',      // R21637
+];
+
+const Q = `query($h: String!){ productByHandle(handle:$h){
+  id legacyResourceId handle title status vendor descriptionHtml
+  mfr: metafield(namespace:"custom", key:"mfr_sku"){ value }
+  global_mfr: metafield(namespace:"global", key:"mfr_sku"){ value }
+} }`;
+
+const norm = s => (s || '').replace(/\s+/g, ' ').trim();
+
+async function getOne(handle) {
+  const r = await gqlRetry(Q, { h: handle }, `h:${handle}`);
+  const p = r.json && r.json.data && r.json.data.productByHandle;
+  return p || null;
+}
+
+async function main() {
+  const ts = new Date().toISOString().replace(/[:.]/g, '-');
+  const report = { ts, store: DOMAIN, cleared: [], hold_blocked: [], hold_counsel: [],
+    gate: { ready: false, needs_write: 0, already_correct: 0, drift: [] } };
+
+  console.log(`\n=== TK-11248 action G REVALIDATION (READ-ONLY, $0) @ ${ts} ===`);
+  console.log(`store: ${DOMAIN}\n`);
+
+  console.log(`[6 CLEAR-TO-PUBLISH — action G targets]`);
+  for (const h of CLEARED) {
+    const p = await getOne(h);
+    const want = DRAFTED[h];
+    if (!p) { report.gate.drift.push(`${h}: NOT FOUND`); console.log(`  ${h}  DRIFT: not found`); continue; }
+    const curLen = (p.descriptionHtml || '').length;
+    const isDraft = p.status === 'DRAFT';
+    const vendorOk = p.vendor === 'Rebel Walls';
+    const mfrLive = (p.mfr && p.mfr.value) || (p.global_mfr && p.global_mfr.value) || '';
+    const mfrOk = !mfrLive || mfrLive === want.mfr; // tolerate missing metafield
+    const already = norm(p.descriptionHtml) === norm(want.html);
+    const emptyNow = curLen === 0;
+    let state;
+    if (!isDraft) state = 'DRIFT-NOT-DRAFT';
+    else if (!vendorOk) state = 'DRIFT-VENDOR';
+    else if (!mfrOk) state = 'DRIFT-MFR';
+    else if (already) state = 'ALREADY-CORRECT';
+    else if (emptyNow) state = 'NEEDS-WRITE';
+    else state = 'DRIFT-UNEXPECTED-CONTENT'; // has some other description
+    const row = { handle: h, mfr: want.mfr, id: p.id, legacyId: p.legacyResourceId,
+      status: p.status, vendor: p.vendor, mfr_live: mfrLive, cur_len: curLen,
+      cur_preview: norm(p.descriptionHtml).slice(0, 80), state };
+    report.cleared.push(row);
+    if (state === 'NEEDS-WRITE') report.gate.needs_write++;
+    else if (state === 'ALREADY-CORRECT') report.gate.already_correct++;
+    else report.gate.drift.push(`${h}: ${state} (len=${curLen}, status=${p.status})`);
+    console.log(`  ${h.padEnd(40)} ${state.padEnd(24)} status=${p.status} len=${curLen} mfr=${mfrLive||'-'}`);
+  }
+
+  console.log(`\n[HOLD — must stay untouched]`);
+  for (const h of [...HOLD_BLOCKED, ...HOLD_COUNSEL]) {
+    const p = await getOne(h);
+    if (!p) { console.log(`  ${h.padEnd(40)} (not found)`); continue; }
+    const bucket = HOLD_BLOCKED.includes(h) ? report.hold_blocked : report.hold_counsel;
+    const row = { handle: h, id: p.id, status: p.status, cur_len: (p.descriptionHtml||'').length,
+      cur_preview: norm(p.descriptionHtml).slice(0,60) };
+    bucket.push(row);
+    console.log(`  ${h.padEnd(40)} status=${p.status} len=${row.cur_len}${row.cur_len? '  ⚠ has description':''}`);
+  }
+
+  report.gate.ready = report.gate.drift.length === 0 && report.gate.needs_write > 0;
+  const outFile = path.join(__dirname, '..', 'data', `TK11248-descG-revalidation-${ts}.json`);
+  fs.writeFileSync(outFile, JSON.stringify(report, null, 2));
+
+  console.log(`\n--- SUMMARY ---`);
+  console.log(`  NEEDS-WRITE:      ${report.gate.needs_write}`);
+  console.log(`  ALREADY-CORRECT:  ${report.gate.already_correct}`);
+  console.log(`  DRIFT:            ${report.gate.drift.length}${report.gate.drift.length? '  -> ' + report.gate.drift.join(' | '):''}`);
+  console.log(`  GATE ready_to_write=${report.gate.ready}`);
+  console.log(`\nEvidence -> ${outFile}`);
+  console.log(`NO WRITES FIRED.\n`);
+  // exit 0 if clean (either all already-correct, or a clean needs-write set); 5 on drift
+  process.exit(report.gate.drift.length ? 5 : 0);
+}
+main().catch(e => { console.error('FATAL', e); process.exit(2); });

← 3fbf2ca auto-data-snapshot: 2026-09-04T12:10:54 (2 data files) — dat  ·  back to Rebel Walls Push  ·  TK-11248 EXECUTED: Aries title fixed live; guard held 2 posi 8debf6b →