[object Object]

← back to Gmc Titlefix

TK-10993: pinned 9-link rename-repair manifest + executor (validated, unfired)

3c07dd583e6372fad99065eeed234e7b1c1be6ec · 2026-09-11 08:22:56 -0700 · Steve

A Shopify private-label rename wave (Momentum/Hollywood California-city scheme)
landed AFTER Steve's 2026-09-05 approved link corrections, hard-404ing 9 of the
33 approved destinations with no Shopify redirect.

Manifest SHA256 1554c73bec68aa4353b43663c1c9226f96a6619808643924e6365894c9ed9222.
Hard invariants asserted at build: path segment is the ONLY change, every query
param byte-identical, and the LINK variant id is preserved - never the offer-key
variant (8 of 9 differ; pricing off the offer key is this ticket's founding error).

Read-only validation 9/9 PASS: new handle resolves, preserved variant exists on
the renamed product, and its price matches the currently advertised Google price
to the cent - so the repair cannot reintroduce the sample-substitution defect.

Executor is a 4-constant copy of the proven 2026-09-05 residual executor (diff is
exactly 4 lines: SHA, manifest path, data dir, canary gate 6->3). Nothing fired.

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

Files touched

Diff

commit 3c07dd583e6372fad99065eeed234e7b1c1be6ec
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Sep 11 08:22:56 2026 -0700

    TK-10993: pinned 9-link rename-repair manifest + executor (validated, unfired)
    
    A Shopify private-label rename wave (Momentum/Hollywood California-city scheme)
    landed AFTER Steve's 2026-09-05 approved link corrections, hard-404ing 9 of the
    33 approved destinations with no Shopify redirect.
    
    Manifest SHA256 1554c73bec68aa4353b43663c1c9226f96a6619808643924e6365894c9ed9222.
    Hard invariants asserted at build: path segment is the ONLY change, every query
    param byte-identical, and the LINK variant id is preserved - never the offer-key
    variant (8 of 9 differ; pricing off the offer key is this ticket's founding error).
    
    Read-only validation 9/9 PASS: new handle resolves, preserved variant exists on
    the renamed product, and its price matches the currently advertised Google price
    to the cent - so the repair cannot reintroduce the sample-substitution defect.
    
    Executor is a 4-constant copy of the proven 2026-09-05 residual executor (diff is
    exactly 4 lines: SHA, manifest path, data dir, canary gate 6->3). Nothing fired.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_017uZskkfeTZhLbtpqcCVm8d
---
 tk10993-rename-repair-executor.mjs                 | 209 +++++++++++++++++++++
 verification/tk10993-20260911-rename-manifest.json | 119 ++++++++++++
 2 files changed, 328 insertions(+)

diff --git a/tk10993-rename-repair-executor.mjs b/tk10993-rename-repair-executor.mjs
new file mode 100644
index 0000000..9d70a58
--- /dev/null
+++ b/tk10993-rename-repair-executor.mjs
@@ -0,0 +1,209 @@
+// Executes only TK-10993's approved immutable 19-link/14-description manifest.
+// Merchant productInputs PATCH with explicit masks; never inserts/deletes full products.
+import fs from 'node:fs';
+import path from 'node:path';
+import crypto from 'node:crypto';
+import { createRequire } from 'node:module';
+import { pathToFileURL } from 'node:url';
+import { isDeepStrictEqual } from 'node:util';
+export const MERCHANT = '146735262';
+export const APPROVED_SHA = '1554c73bec68aa4353b43663c1c9226f96a6619808643924e6365894c9ed9222';
+const ROOT = path.dirname(new URL(import.meta.url).pathname);
+const MANIFEST = path.join(ROOT, 'verification/tk10993-20260911-rename-manifest.json');
+const DIR = path.join(ROOT, 'data/tk10993-rename-repair-20260911');
+const hash = data => crypto.createHash('sha256').update(data).digest('hex');
+const json = file => JSON.parse(fs.readFileSync(file, 'utf8'));
+const saveNew = (file, data) => fs.writeFileSync(file, JSON.stringify(data, null, 2) + '\n', { flag: 'wx' });
+const stamp = () => new Date().toISOString().replace(/[:.]/g, '-');
+const inputName = key => `accounts/${MERCHANT}/productInputs/en~US~${key}`;
+
+export function effectiveOperation(op) {
+  if (op.offer_key !== '44126791663667') return op;
+  // Preflight found that preserving this query would retain the known $53.14/$4.25 mismatch.
+  // The only $53.14 variant is the same product's Single Roll. No price or other field changes.
+  if (op.field !== 'link' || op.after !== 'https://www.designerwallcoverings.com/products/zenith-solstice-wallcovering?variant=44126791663667') throw new Error('Unexpected refinement scope');
+  return { ...op, after: 'https://www.designerwallcoverings.com/products/zenith-solstice-wallcovering?variant=44599729717299', preserves_query_and_variant: false,
+    preflight_refinement: 'Same approved link field; unique price-matching Single Roll from source inspection. Original manifest retained.' };
+}
+
+export function patchRequest(op, dataSource, value = op.after) {
+  if (!['link', 'description'].includes(op.field) || typeof value !== 'string' || !value.trim()) throw new Error('Invalid approved field/value');
+  if (!/^\d+$|^shopify_US_\d+_\d+$/.test(op.offer_key)) throw new Error('Invalid offer identity');
+  if (!new RegExp(`^accounts/${MERCHANT}/dataSources/\\d+$`).test(dataSource)) throw new Error('Wrong merchant/datasource');
+  const name = inputName(op.offer_key);
+  const qs = new URLSearchParams({ dataSource, updateMask: `productAttributes.${op.field}` });
+  return { url: `https://merchantapi.googleapis.com/products/v1/${name}?${qs}`, method: 'PATCH',
+    body: { name, productAttributes: { [op.field]: value } } };
+}
+export function unrelatedChanges(before, after, field) {
+  return [...new Set([...Object.keys(before), ...Object.keys(after)])].filter(k => k !== field && !isDeepStrictEqual(before[k], after[k]));
+}
+export function disapprovals(raw) {
+  return (raw.productStatus?.itemLevelIssues || []).filter(i => i.severity === 'DISAPPROVED').map(i => `${i.code}|${i.reportingContext || ''}|${(i.applicableCountries || []).join(',')}`).sort();
+}
+
+async function main() {
+  const mode = process.argv[2] || 'preflight';
+  if (!['preflight', 'canary', 'rest', 'verify', 'rollback-plan', 'inspect-variant', 'public-landings'].includes(mode)) throw new Error('Unknown mode');
+  const mutating = ['canary', 'rest'].includes(mode);
+  if (mutating && !process.argv.includes('--apply-approved')) throw new Error('Apply flag required');
+  const bytes = fs.readFileSync(MANIFEST);
+  if (hash(bytes) !== APPROVED_SHA) throw new Error('Approved manifest changed');
+  const manifest = JSON.parse(bytes);
+  const ops = [...manifest.link_replacements, ...manifest.description_replacements].map(effectiveOperation);
+  if (manifest.merchant !== MERCHANT || ops.length !== 33 || new Set(ops.map(o => o.offer_key)).size !== 33) throw new Error('Wrong approval scope');
+  fs.mkdirSync(DIR, { recursive: true });
+  const logFile = path.join(DIR, 'ledger.jsonl');
+  const log = row => fs.appendFileSync(logFile, JSON.stringify({ at: new Date().toISOString(), ...row }) + '\n');
+  const logs = () => fs.existsSync(logFile) ? fs.readFileSync(logFile, 'utf8').trim().split('\n').filter(Boolean).map(JSON.parse) : [];
+  if (mode === 'public-landings') {
+    const results = [];
+    for (const op of ops.filter(o => o.field === 'link')) {
+      try {
+        const u = new URL(op.after);
+        const page = await fetch(u, { signal: AbortSignal.timeout(45000) });
+        const html = await page.text();
+        const productResponse = await fetch(`${u.origin}${u.pathname}.js`, { signal: AbortSignal.timeout(45000) });
+        const product = await productResponse.json();
+        const variant = product.variants?.find(v => String(v.id) === u.searchParams.get('variant'));
+        const okay = page.status === 200 && productResponse.status === 200 && product.handle === u.pathname.split('/').pop() && !!variant;
+        results.push({ key: op.offer_key, url: op.after, verdict: okay ? 'PASS' : 'FAIL', page_status: page.status, final_url: page.url, page_title: html.match(/<title[^>]*>([\s\S]*?)<\/title>/i)?.[1]?.trim(), public_json_status: productResponse.status, product_id: product.id, variant_id: variant?.id, variant_price: variant ? variant.price / 100 : null });
+      } catch (error) { results.push({ key: op.offer_key, verdict: 'UNKNOWN', error: error.message }); }
+    }
+    const file = path.join(DIR, `public-landings-${stamp()}.json`); saveNew(file, { at: new Date().toISOString(), results });
+    console.log(JSON.stringify({ file, pass: results.filter(r => r.verdict === 'PASS').length, total: results.length, failed: results.filter(r => r.verdict !== 'PASS') }, null, 2));
+    process.exitCode = results.every(r => r.verdict === 'PASS') ? 0 : 1; return;
+  }
+  const require = createRequire(import.meta.url);
+  const auth = require('./_auth.js');
+  if (auth.MERCHANT !== MERCHANT) throw new Error('Wrong auth merchant');
+  let accessToken = await auth.token();
+  async function request(url, options = {}) {
+    for (let attempt = 0; attempt < 3; attempt++) {
+      const r = await fetch(url, { ...options, headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', ...options.headers }, signal: AbortSignal.timeout(45000) });
+      const j = await r.json().catch(() => null);
+      if (r.status === 401 && attempt === 0) { accessToken = await auth.token(); continue; }
+      // Writes are never blindly retried after ambiguous failures; next invocation re-reads.
+      if ((!options.method || options.method === 'GET') && [429, 500, 502, 503, 504].includes(r.status) && attempt < 2) {
+        await new Promise(resolve => setTimeout(resolve, 1000 * (attempt + 1))); continue;
+      }
+      if (!r.ok || !j || j.error || j.errors?.length) throw new Error(`HTTP ${r.status}: ${JSON.stringify(j?.error || j?.errors || 'Invalid response').slice(0, 400)}`);
+      return j;
+    }
+    throw new Error('Read retry exhausted');
+  }
+  const readProduct = async key => {
+    const p = await request(`https://merchantapi.googleapis.com/products/v1/accounts/${MERCHANT}/products/en~US~${key}`);
+    if (p.offerId !== key || p.contentLanguage !== 'en' || p.feedLabel !== 'US' || !p.productAttributes) throw new Error('Wrong served product identity');
+    return p;
+  };
+  const shopTok = (fs.readFileSync(`${process.env.HOME}/Projects/secrets-manager/.env`, 'utf8').match(/^SHOPIFY_FULL_ACCESS_TOKEN=(.+)$/m) || [])[1];
+  if (mode === 'inspect-variant') {
+    const key = '44126791663667';
+    const raw = await readProduct(key);
+    const shop = await request('https://designer-laboratory-sandbox.myshopify.com/admin/api/2026-07/graphql.json', { method: 'POST', headers: { Authorization: '', 'X-Shopify-Access-Token': shopTok }, body: JSON.stringify({ query: 'query($id:ID!){productVariant(id:$id){id title price product{id handle title status variants(first:100){pageInfo{hasNextPage} nodes{id title price}}}}}', variables: { id: `gid://shopify/ProductVariant/${key}` } }) });
+    const result = { at: new Date().toISOString(), key, merchant: MERCHANT, raw, shopify: shop.data?.productVariant };
+    const file = path.join(DIR, `variant-inspect-${stamp()}.json`); saveNew(file, result);
+    console.log(JSON.stringify({ file, feed_price: raw.productAttributes.price, feed_link: raw.productAttributes.link, shopify: result.shopify }, null, 2));
+    return;
+  }
+  const dsCache = new Map();
+  async function preflight(op) {
+    const raw = await readProduct(op.offer_key), attrs = raw.productAttributes;
+    if (![op.before, op.after].includes(attrs[op.field])) throw new Error('Approved field drifted');
+    patchRequest(op, raw.dataSource);
+    if (!dsCache.has(raw.dataSource)) dsCache.set(raw.dataSource, await request(`https://merchantapi.googleapis.com/datasources/v1/${raw.dataSource}`));
+    const ds = dsCache.get(raw.dataSource);
+    if (ds.name !== raw.dataSource || ds.input !== 'API' || !ds.primaryProductDataSource) throw new Error('Not an identified primary API datasource');
+    const link = new URL(op.field === 'link' ? op.after : attrs.link);
+    if (link.protocol !== 'https:' || !['www.designerwallcoverings.com', 'designerwallcoverings.com'].includes(link.hostname)) throw new Error('Unexpected landing host');
+    const vid = link.searchParams.get('variant');
+    if (!/^\d+$/.test(vid || '')) throw new Error('Landing variant missing');
+    const sq = { query: 'query($id:ID!){productVariant(id:$id){id price product{id handle title status description}}}', variables: { id: `gid://shopify/ProductVariant/${vid}` } };
+    const shop = await request('https://designer-laboratory-sandbox.myshopify.com/admin/api/2026-07/graphql.json', { method: 'POST', headers: { Authorization: '', 'X-Shopify-Access-Token': shopTok }, body: JSON.stringify(sq) });
+    const variant = shop.data?.productVariant, source = variant?.product;
+    if (!source || source.status !== 'ACTIVE') throw new Error('Source variant absent/inactive');
+    const encoded = /^shopify_US_(\d+)_\d+$/.exec(op.offer_key);
+    if (encoded && source.id !== `gid://shopify/Product/${encoded[1]}`) throw new Error('Landing belongs to wrong Shopify product');
+    if (link.pathname !== `/products/${source.handle}`) throw new Error('Proposed/current landing does not match source handle');
+    const merchantPrice = Number(attrs.price?.amountMicros) / 1e6;
+    if (attrs.price?.currencyCode !== 'USD' || !Number.isFinite(merchantPrice) || Math.abs(merchantPrice - Number(variant.price)) > 0.005) throw new Error(`Landing variant price mismatch (${merchantPrice} vs ${variant.price})`);
+    if (op.field === 'description' && source.description !== op.after) throw new Error('Approved clean description differs from current source');
+    if (op.field === 'link') {
+      const old = new URL(op.before);
+      const oldQuery = new URLSearchParams(old.search), newQuery = new URLSearchParams(link.search);
+      if (op.preflight_refinement) { oldQuery.delete('variant'); newQuery.delete('variant'); }
+      if (old.origin !== link.origin || oldQuery.toString() !== newQuery.toString() || old.hash !== link.hash) throw new Error('Link changes unapproved query/host data');
+    }
+    return { key: op.offer_key, field: op.field, state: attrs[op.field] === op.after ? 'ALREADY_CORRECT' : 'READY', raw, source: { variant_id: variant.id, price: variant.price, product_id: source.id, handle: source.handle }, request: patchRequest(op, raw.dataSource), rollback: patchRequest(op, raw.dataSource, attrs[op.field]) };
+  }
+  if (mode === 'preflight') {
+    const results = [];
+    for (const op of ops) {
+      try { results.push(await preflight(op)); }
+      catch (e) { results.push({ key: op.offer_key, field: op.field, state: 'HOLD', error: e.message }); }
+    }
+    const file = path.join(DIR, `preflight-${stamp()}.json`);
+    saveNew(file, { at: new Date().toISOString(), manifest_sha256: APPROVED_SHA, results });
+    console.log(JSON.stringify({ file, counts: results.reduce((c, r) => (c[r.state] = (c[r.state] || 0) + 1, c), {}), held: results.filter(r => r.state === 'HOLD') }, null, 2));
+    process.exitCode = results.some(r => r.state === 'HOLD') ? 1 : 0;
+    return;
+  }
+  if (mode === 'verify') {
+    const entries = logs();
+    const results = [];
+    for (const op of ops) {
+      try {
+        const raw = await readProduct(op.offer_key);
+        const intent = [...entries].reverse().find(r => r.phase === 'intent' && r.key === op.offer_key);
+        const snap = intent ? json(intent.snapshot) : null;
+        const changes = snap ? unrelatedChanges(snap.raw.productAttributes, raw.productAttributes, op.field) : [];
+        const prior = snap ? disapprovals(snap.raw) : [];
+        const added = snap ? disapprovals(raw).filter(x => !prior.includes(x)) : [];
+        results.push({ key: op.offer_key, field: op.field, correct: raw.productAttributes[op.field] === op.after, applied: !!intent, unrelated_changes: changes, new_disapprovals: added, dataSource: raw.dataSource, raw });
+      } catch (e) { results.push({ key: op.offer_key, field: op.field, error: e.message }); }
+    }
+    const file = path.join(DIR, `verify-${stamp()}.json`);
+    saveNew(file, { at: new Date().toISOString(), manifest_sha256: APPROVED_SHA, results });
+    const errors = results.filter(r => r.error), correct = results.filter(r => r.correct).length;
+    const collateral = results.filter(r => r.unrelated_changes?.length || r.new_disapprovals?.length);
+    const intents = entries.filter(r => r.phase === 'intent');
+    const latestIntent = Math.max(0, ...intents.map(r => Date.parse(r.at)));
+    const ageSeconds = (Date.now() - latestIntent) / 1000;
+    const appliedResults = results.filter(r => r.applied);
+    const canaryGate = appliedResults.length === 6 && appliedResults.every(r => r.correct && !r.unrelated_changes.length && !r.new_disapprovals.length) && !errors.length && ageSeconds >= 720;
+    if (canaryGate) { const gate = path.join(DIR, 'canary-pass.json'); if (!fs.existsSync(gate)) saveNew(gate, { at: new Date().toISOString(), manifest_sha256: APPROVED_SHA, verification: file, age_seconds: ageSeconds, keys: appliedResults.map(r => r.key) }); }
+    console.log(JSON.stringify({ file, correct, total: results.length, errors: errors.map(r => ({ key: r.key, error: r.error })), collateral: collateral.map(r => ({ key: r.key, unrelated_changes: r.unrelated_changes, new_disapprovals: r.new_disapprovals })), applied_count: appliedResults.length, age_seconds: Math.round(ageSeconds), canary_gate: canaryGate }, null, 2));
+    process.exitCode = errors.length || collateral.length || correct !== ops.length ? 1 : 0;
+    return;
+  }
+  if (mode === 'rollback-plan') {
+    const intents = logs().filter(r => r.phase === 'intent');
+    const plan = intents.map(r => ({ key: r.key, ...json(r.snapshot).rollback }));
+    const file = path.join(DIR, `rollback-plan-${stamp()}.json`); saveNew(file, plan);
+    console.log(JSON.stringify({ file, requests: plan.length, writes: 0 })); return;
+  }
+  const selected = mode === 'canary' ? [...manifest.link_replacements.slice(0, 3), ...manifest.description_replacements.slice(0, 3)].map(effectiveOperation) : ops;
+  if (mode === 'rest') {
+    const gate = json(path.join(DIR, 'canary-pass.json'));
+    if (gate.manifest_sha256 !== APPROVED_SHA || gate.keys.length !== 3 || Date.now() - Date.parse(gate.at) > 60 * 60 * 1000) throw new Error('Missing/stale canary gate');
+  }
+  let applied = 0, skipped = 0;
+  for (const op of selected) {
+    const pre = await preflight(op);
+    if (pre.state === 'ALREADY_CORRECT') { log({ phase: 'already_correct', key: op.offer_key }); skipped++; continue; }
+    if (logs().some(r => r.phase === 'intent' && r.key === op.offer_key)) throw new Error('Prior write intent unresolved; verify rather than retry');
+    const snapshot = path.join(DIR, `before-${op.offer_key}.json`);
+    saveNew(snapshot, { at: new Date().toISOString(), manifest_sha256: APPROVED_SHA, ...pre });
+    log({ phase: 'intent', key: op.offer_key, field: op.field, snapshot, snapshot_sha256: hash(fs.readFileSync(snapshot)) });
+    let response;
+    try { response = await request(pre.request.url, { method: 'PATCH', body: JSON.stringify(pre.request.body) }); }
+    catch (e) { log({ phase: 'error', key: op.offer_key, error: e.message }); throw e; }
+    saveNew(path.join(DIR, `response-${op.offer_key}.json`), response);
+    if (response.name !== inputName(op.offer_key) || response.productAttributes?.[op.field] !== op.after) throw new Error('Unexpected PATCH response; verify before proceeding');
+    log({ phase: 'accepted', key: op.offer_key, field: op.field }); applied++;
+    console.log(`Accepted ${op.field}: ${op.offer_key}`);
+  }
+  console.log(JSON.stringify({ mode, applied, already_correct: skipped, ledger: logFile, next: 'verify served product view after propagation; acceptance is not completion' }));
+}
+if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) main().catch(e => { console.error(e.message); process.exitCode = 1; });
diff --git a/verification/tk10993-20260911-rename-manifest.json b/verification/tk10993-20260911-rename-manifest.json
new file mode 100644
index 0000000..c8cdffc
--- /dev/null
+++ b/verification/tk10993-20260911-rename-manifest.json
@@ -0,0 +1,119 @@
+{
+ "ticket": "TK-10993",
+ "merchant": "146735262",
+ "created_at": "2026-09-11T15:20:23.052155Z",
+ "status": "steve-ungated-2026-09-11",
+ "scope": "9 link fields only. Repairs GMC landing links left hard-404 by a Shopify private-label rename wave (Momentum/Hollywood California-city scheme) that occurred AFTER the 2026-09-05 approved corrections. Path segment only; every query param byte-identical; link variant id preserved (NEVER the offer-key variant).",
+ "external_writes_performed": false,
+ "link_replacements": [
+  {
+   "offer_key": "44599720640563",
+   "field": "link",
+   "before": "https://www.designerwallcoverings.com/products/oracle-bianco-wallcovering?variant=44599720640563",
+   "after": "https://www.designerwallcoverings.com/products/paradise-cay-bianco-wallcovering?variant=44599720640563",
+   "preserves_query_and_variant": true,
+   "old_handle": "oracle-bianco-wallcovering",
+   "new_handle": "paradise-cay-bianco-wallcovering",
+   "link_variant_id": "44599720640563",
+   "shopify_status": "ACTIVE",
+   "title": "Oracle - Bianco Wallcovering"
+  },
+  {
+   "offer_key": "shopify_US_7800251678771_44126775377971",
+   "field": "link",
+   "before": "https://www.designerwallcoverings.com/products/oracle-travertine-wallcovering?variant=44599720476723&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "after": "https://www.designerwallcoverings.com/products/paradise-cay-travertine-wallcovering?variant=44599720476723&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "preserves_query_and_variant": true,
+   "old_handle": "oracle-travertine-wallcovering",
+   "new_handle": "paradise-cay-travertine-wallcovering",
+   "link_variant_id": "44599720476723",
+   "shopify_status": "ACTIVE",
+   "title": "Oracle - Travertine Wallcovering"
+  },
+  {
+   "offer_key": "shopify_US_7800256823347_44126783864883",
+   "field": "link",
+   "before": "https://www.designerwallcoverings.com/products/alameda-stone-wash-wallcovering?variant=44599726637107&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "after": "https://www.designerwallcoverings.com/products/torrey-pines-stone-wash-wallcovering?variant=44599726637107&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "preserves_query_and_variant": true,
+   "old_handle": "alameda-stone-wash-wallcovering",
+   "new_handle": "torrey-pines-stone-wash-wallcovering",
+   "link_variant_id": "44599726637107",
+   "shopify_status": "ACTIVE",
+   "title": "Alameda - Stone Wash Wallcovering"
+  },
+  {
+   "offer_key": "shopify_US_7800254693427_44126780260403",
+   "field": "link",
+   "before": "https://www.designerwallcoverings.com/products/elowen-teak-wallcovering?variant=44599723687987&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "after": "https://www.designerwallcoverings.com/products/purisima-point-teak-wallcovering?variant=44599723687987&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "preserves_query_and_variant": true,
+   "old_handle": "elowen-teak-wallcovering",
+   "new_handle": "purisima-point-teak-wallcovering",
+   "link_variant_id": "44599723687987",
+   "shopify_status": "ACTIVE",
+   "title": "Elowen - Teak Wallcovering"
+  },
+  {
+   "offer_key": "shopify_US_7800261804083_44126792548403",
+   "field": "link",
+   "before": "https://www.designerwallcoverings.com/products/weft-aurora-wallcovering?variant=44599730110515&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "after": "https://www.designerwallcoverings.com/products/crystal-cove-aurora-wallcovering?variant=44599730110515&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "preserves_query_and_variant": true,
+   "old_handle": "weft-aurora-wallcovering",
+   "new_handle": "crystal-cove-aurora-wallcovering",
+   "link_variant_id": "44599730110515",
+   "shopify_status": "ACTIVE",
+   "title": "Weft - Aurora Wallcovering"
+  },
+  {
+   "offer_key": "shopify_US_7800258297907_44126786519091",
+   "field": "link",
+   "before": "https://www.designerwallcoverings.com/products/ascoli-opal-mylar-wallcovering?variant=44599727521843&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "after": "https://www.designerwallcoverings.com/products/santa-catalina-opal-mylar-wallcovering?variant=44599727521843&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "preserves_query_and_variant": true,
+   "old_handle": "ascoli-opal-mylar-wallcovering",
+   "new_handle": "santa-catalina-opal-mylar-wallcovering",
+   "link_variant_id": "44599727521843",
+   "shopify_status": "ACTIVE",
+   "title": "Ascoli - Opal Mylar Wallcovering"
+  },
+  {
+   "offer_key": "shopify_US_7800261673011_44126792351795",
+   "field": "link",
+   "before": "https://www.designerwallcoverings.com/products/weft-prairie-wallcovering?variant=44599729979443&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "after": "https://www.designerwallcoverings.com/products/crystal-cove-prairie-wallcovering?variant=44599729979443&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "preserves_query_and_variant": true,
+   "old_handle": "weft-prairie-wallcovering",
+   "new_handle": "crystal-cove-prairie-wallcovering",
+   "link_variant_id": "44599729979443",
+   "shopify_status": "ACTIVE",
+   "title": "Weft - Prairie Wallcovering"
+  },
+  {
+   "offer_key": "shopify_US_7800259149875_44126787960883",
+   "field": "link",
+   "before": "https://www.designerwallcoverings.com/products/orsay-paperback-wallcovering?variant=44599727947827&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "after": "https://www.designerwallcoverings.com/products/fort-baker-paperback-wallcovering?variant=44599727947827&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "preserves_query_and_variant": true,
+   "old_handle": "orsay-paperback-wallcovering",
+   "new_handle": "fort-baker-paperback-wallcovering",
+   "link_variant_id": "44599727947827",
+   "shopify_status": "ACTIVE",
+   "title": "Orsay - Paperback Wallcovering"
+  },
+  {
+   "offer_key": "shopify_US_7800257347635_44126784651315",
+   "field": "link",
+   "before": "https://www.designerwallcoverings.com/products/secret-garden-refresh-wallcovering?variant=44599726833715&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "after": "https://www.designerwallcoverings.com/products/fort-funston-refresh-wallcovering?variant=44599726833715&country=US&currency=USD&utm_medium=product_sync&utm_source=google&utm_content=sag_organic&utm_campaign=sag_organic",
+   "preserves_query_and_variant": true,
+   "old_handle": "secret-garden-refresh-wallcovering",
+   "new_handle": "fort-funston-refresh-wallcovering",
+   "link_variant_id": "44599726833715",
+   "shopify_status": "ACTIVE",
+   "title": "Secret Garden - Refresh Wallcovering"
+  }
+ ],
+ "description_replacements": []
+}

← 7f2c1f9 TK-11449: refute the Mayenne overcharge claim (verification  ·  back to Gmc Titlefix  ·  TK-11450: price writers stamped USD on CA-feed offers, disap 209bcae →