[object Object]

← back to Designerwallcoverings

guard TK-11357 Fix D: never stock a $0/quote-only variant in the 9 go-live activators

fab7c61945ddd358be8d78b141f56bfe717af15a · 2026-09-10 09:25:42 -0700 · Steve

The $0-orderable defect (lineage TK-10825/10965/11140/11299/11301/11357) recurs because
activators stamp qty=2026 on EVERY variant of a product and apply any price check only at
the PRODUCT level (or, in these 9, nowhere at all). Positive stock is what flips
availableForSale=true, so a $0 variant riding alongside a priced one becomes orderable at $0.

PRE-EXISTING GUARD STATE, verified per file before patching (not assumed):
  maharam/knoll/osborne/artmura/fallingstar/tres-tintas — NO price gate anywhere on the write
    path (only heldNoMfr + heldNoDesc holds, which are metafield/description checks).
  muralsource/stout/stroheim — call validateBeforeActivate upstream, but that validator has NO
    price check (it checks specs/description/images/sample-variant presence), and it reads the
    original draft-mint PAYLOAD, not the live product. So: no price gate either.
  maharam-onboard/go-live.mjs is the highest priority of the set: com.steve.dw-maharam-daily is
    LOADED in launchd and runs `go-live.mjs --apply` daily with NO --limit, on a QUOTE-ONLY line.

$0 is the LIVE theme's deliberate quote-only sentinel (snippets/product-form-content.liquid
renders the "Contact Us" button iff variant.price == 0), so the remedy is NEVER a placeholder
price — it is "do not stock it". Steve's 2026-06-20 "active products are never out of stock"
rule is preserved for PRICED goods: a priced variant still gets TARGET_QTY.

Adopts the shared guard lib/inventory-stamp-guard.mjs (safeStampQuantity) rather than
reinventing it — vendored into this repo (not cross-repo-imported) so a moved tree cannot
hard-crash the scheduled maharam cadence; the proof harness hashes all copies and fails on
drift. Adds one strictly-safer rule on top: price <= 0 / NaN is ALWAYS 0, even on a variant
labelled "Sample", because a $0 "sample" is the same $0-orderable defect (the shared guard
alone exempts samples). The real $4.25 memo sample keeps its existing 2026 — deliberately
unchanged, out of scope.

Also adds `title price` to each variant selection and `vendor tags` to the product selection,
which these queries did not fetch — without them the filter is structurally impossible.

Proven by shopify/scripts/tk11357-source-fix-proof/predicate-proof.mjs in the sibling
Designer-Wallcoverings repo: 4/4 required + 3/3 regression on all 9, against the predicate
EXTRACTED from each file (not hand-copied).

SOURCE-ONLY: no script was run with --apply, no Shopify write, no dw_unified write.
Reversible: git revert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Files touched

Diff

commit fab7c61945ddd358be8d78b141f56bfe717af15a
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu Sep 10 09:25:42 2026 -0700

    guard TK-11357 Fix D: never stock a $0/quote-only variant in the 9 go-live activators
    
    The $0-orderable defect (lineage TK-10825/10965/11140/11299/11301/11357) recurs because
    activators stamp qty=2026 on EVERY variant of a product and apply any price check only at
    the PRODUCT level (or, in these 9, nowhere at all). Positive stock is what flips
    availableForSale=true, so a $0 variant riding alongside a priced one becomes orderable at $0.
    
    PRE-EXISTING GUARD STATE, verified per file before patching (not assumed):
      maharam/knoll/osborne/artmura/fallingstar/tres-tintas — NO price gate anywhere on the write
        path (only heldNoMfr + heldNoDesc holds, which are metafield/description checks).
      muralsource/stout/stroheim — call validateBeforeActivate upstream, but that validator has NO
        price check (it checks specs/description/images/sample-variant presence), and it reads the
        original draft-mint PAYLOAD, not the live product. So: no price gate either.
      maharam-onboard/go-live.mjs is the highest priority of the set: com.steve.dw-maharam-daily is
        LOADED in launchd and runs `go-live.mjs --apply` daily with NO --limit, on a QUOTE-ONLY line.
    
    $0 is the LIVE theme's deliberate quote-only sentinel (snippets/product-form-content.liquid
    renders the "Contact Us" button iff variant.price == 0), so the remedy is NEVER a placeholder
    price — it is "do not stock it". Steve's 2026-06-20 "active products are never out of stock"
    rule is preserved for PRICED goods: a priced variant still gets TARGET_QTY.
    
    Adopts the shared guard lib/inventory-stamp-guard.mjs (safeStampQuantity) rather than
    reinventing it — vendored into this repo (not cross-repo-imported) so a moved tree cannot
    hard-crash the scheduled maharam cadence; the proof harness hashes all copies and fails on
    drift. Adds one strictly-safer rule on top: price <= 0 / NaN is ALWAYS 0, even on a variant
    labelled "Sample", because a $0 "sample" is the same $0-orderable defect (the shared guard
    alone exempts samples). The real $4.25 memo sample keeps its existing 2026 — deliberately
    unchanged, out of scope.
    
    Also adds `title price` to each variant selection and `vendor tags` to the product selection,
    which these queries did not fetch — without them the filter is structurally impossible.
    
    Proven by shopify/scripts/tk11357-source-fix-proof/predicate-proof.mjs in the sibling
    Designer-Wallcoverings repo: 4/4 required + 3/3 regression on all 9, against the predicate
    EXTRACTED from each file (not hand-copied).
    
    SOURCE-ONLY: no script was run with --apply, no Shopify write, no dw_unified write.
    Reversible: git revert.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---
 scripts/artmura-onboard/go-live-artmura.js         | 31 ++++++++-
 scripts/fallingstar-onboard/go-live-fallingstar.js | 31 ++++++++-
 scripts/knoll-onboard/go-live.mjs                  | 31 ++++++++-
 scripts/lib/inventory-stamp-guard.mjs              | 80 ++++++++++++++++++++++
 scripts/maharam-onboard/go-live.mjs                | 31 ++++++++-
 scripts/muralsource-onboard/go-live.mjs            | 31 ++++++++-
 scripts/osborne-onboard/go-live.mjs                | 31 ++++++++-
 scripts/stout-onboard/go-live.mjs                  | 31 ++++++++-
 scripts/stroheim-onboard/go-live.mjs               | 31 ++++++++-
 scripts/tres-tintas-onboard/go-live-tres-tintas.js | 31 ++++++++-
 10 files changed, 332 insertions(+), 27 deletions(-)

diff --git a/scripts/artmura-onboard/go-live-artmura.js b/scripts/artmura-onboard/go-live-artmura.js
index 51111c3..ad007fe 100644
--- a/scripts/artmura-onboard/go-live-artmura.js
+++ b/scripts/artmura-onboard/go-live-artmura.js
@@ -62,7 +62,30 @@ async function gql(query, variables = {}) {
   }
 }
 
-const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status variants(first:10){edges{node{id sku inventoryItem{id}}}}}}`;
+const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status vendor tags variants(first:10){edges{node{id sku title price inventoryItem{id}}}}}}`;
+const { safeStampQuantity } = require('../lib/inventory-stamp-guard.mjs');  // GUARD TK-11357 (shared guard)
+// ── GUARD TK-11357 BEGIN ─ do not edit without re-running the fixture proof ──────────
+// A $0 / quote-only sellable variant must NEVER receive positive stock: positive stock is what
+// flips availableForSale=true, making it checkout-orderable at $0 (lineage TK-10825 -> 10965 ->
+// 11140 -> 11299 -> 11301 -> 11357). $0 is the LIVE theme's deliberate quote-only SENTINEL
+// (snippets/product-form-content.liquid renders the "Contact Us" button iff variant.price == 0),
+// so the remedy is NEVER to write a placeholder price - it is "do not stock it".
+// Steve's 2026-06-20 "active products are never out of stock" rule is PRESERVED for PRICED goods:
+// a priced variant still gets `desired`. The quote-only tag/vendor decision is delegated to the
+// shared guard (lib/inventory-stamp-guard.mjs); this adds one strictly-safer rule of its own -
+// price <= 0 / NaN is ALWAYS 0, even on a variant labelled "Sample" (a $0 "sample" is the same
+// $0-orderable defect). The real $4.25 memo sample is unaffected and keeps its existing quantity.
+function safeQuantities(product, variants, locationId, desired) {
+  return (variants || []).map(v => ({
+    inventoryItemId: v.inventoryItem.id,
+    locationId,
+    quantity: Number(v.price) > 0
+      ? safeStampQuantity({ title: v.title, price: v.price }, product, desired)
+      : 0,
+  }));
+}
+// ── GUARD TK-11357 END ────────────────────────────────────────────
+
 const M_TRACK = `mutation($id:ID!){ inventoryItemUpdate(id:$id, input:{tracked:true}){ userErrors{message} } }`;
 const M_ACTIVATE = `mutation($iid:ID!,$loc:ID!){ inventoryActivate(inventoryItemId:$iid, locationId:$loc){ userErrors{message} } }`;
 const M_SETQTY = `mutation($input:InventorySetQuantitiesInput!){ inventorySetQuantities(input:$input){ userErrors{field message code} } }`;
@@ -74,7 +97,9 @@ async function goLive(pid) {
   const errs = [];
   const d = await gql(Q_VARIANTS, { id: gidP });
   if (d.product?.status === 'ACTIVE') return { skipped: true };
-  const items = d.product.variants.edges.map(e => e.node.inventoryItem.id);
+  const vnodes = d.product.variants.edges.map(e => e.node);
+  const items = vnodes.map(v => v.inventoryItem.id);              // track+activate: unchanged
+  const quantities = safeQuantities(d.product, vnodes, LOCATION_ID, TARGET_QTY);  // GUARD TK-11357
   // 1+2: track, activate, set 2026 per item
   for (const iid of items) {
     let r = await gql(M_TRACK, { id: iid }); (r.inventoryItemUpdate?.userErrors || []).forEach(e => errs.push('track:' + e.message));
@@ -83,7 +108,7 @@ async function goLive(pid) {
     ae.forEach(e => errs.push('activate:' + e.message));
   }
   const r2 = await gql(M_SETQTY, { input: { name: 'on_hand', reason: 'correction', ignoreCompareQuantity: true,
-    quantities: items.map(iid => ({ inventoryItemId: iid, locationId: LOCATION_ID, quantity: TARGET_QTY })) } });
+    quantities } });                                               // GUARD TK-11357
   (r2.inventorySetQuantities?.userErrors || []).forEach(e => errs.push('setqty:' + e.message));
   // 3: publish to all channels
   const r3 = await gql(M_PUBLISH, { id: gidP, pubs: PUBLICATIONS.filter(_pid => _pid !== 29646651457 || !_isShowroomGuard("Artmura")).map(p => ({ publicationId: p })) });
diff --git a/scripts/fallingstar-onboard/go-live-fallingstar.js b/scripts/fallingstar-onboard/go-live-fallingstar.js
index fff00c7..aae60e3 100644
--- a/scripts/fallingstar-onboard/go-live-fallingstar.js
+++ b/scripts/fallingstar-onboard/go-live-fallingstar.js
@@ -56,7 +56,30 @@ async function gql(query, variables = {}) {
     } catch (e) { if (a === 3) throw e; await sleep(900 * (a + 1)); }
   }
 }
-const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status variants(first:10){edges{node{id sku inventoryItem{id}}}}}}`;
+const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status vendor tags variants(first:10){edges{node{id sku title price inventoryItem{id}}}}}}`;
+const { safeStampQuantity } = require('../lib/inventory-stamp-guard.mjs');  // GUARD TK-11357 (shared guard)
+// ── GUARD TK-11357 BEGIN ─ do not edit without re-running the fixture proof ──────────
+// A $0 / quote-only sellable variant must NEVER receive positive stock: positive stock is what
+// flips availableForSale=true, making it checkout-orderable at $0 (lineage TK-10825 -> 10965 ->
+// 11140 -> 11299 -> 11301 -> 11357). $0 is the LIVE theme's deliberate quote-only SENTINEL
+// (snippets/product-form-content.liquid renders the "Contact Us" button iff variant.price == 0),
+// so the remedy is NEVER to write a placeholder price - it is "do not stock it".
+// Steve's 2026-06-20 "active products are never out of stock" rule is PRESERVED for PRICED goods:
+// a priced variant still gets `desired`. The quote-only tag/vendor decision is delegated to the
+// shared guard (lib/inventory-stamp-guard.mjs); this adds one strictly-safer rule of its own -
+// price <= 0 / NaN is ALWAYS 0, even on a variant labelled "Sample" (a $0 "sample" is the same
+// $0-orderable defect). The real $4.25 memo sample is unaffected and keeps its existing quantity.
+function safeQuantities(product, variants, locationId, desired) {
+  return (variants || []).map(v => ({
+    inventoryItemId: v.inventoryItem.id,
+    locationId,
+    quantity: Number(v.price) > 0
+      ? safeStampQuantity({ title: v.title, price: v.price }, product, desired)
+      : 0,
+  }));
+}
+// ── GUARD TK-11357 END ────────────────────────────────────────────
+
 const M_TRACK = `mutation($id:ID!){ inventoryItemUpdate(id:$id, input:{tracked:true}){ userErrors{message} } }`;
 const M_ACTIVATE = `mutation($iid:ID!,$loc:ID!){ inventoryActivate(inventoryItemId:$iid, locationId:$loc){ userErrors{message} } }`;
 const M_SETQTY = `mutation($input:InventorySetQuantitiesInput!){ inventorySetQuantities(input:$input){ userErrors{field message code} } }`;
@@ -68,14 +91,16 @@ async function goLive(pid) {
   const errs = [];
   const d = await gql(Q_VARIANTS, { id: gidP });
   if (!d?.product) return ['product not found'];
-  const items = d.product.variants.edges.map(e => e.node.inventoryItem.id);
+  const vnodes = d.product.variants.edges.map(e => e.node);
+  const items = vnodes.map(v => v.inventoryItem.id);              // track+activate: unchanged
+  const quantities = safeQuantities(d.product, vnodes, LOCATION_ID, TARGET_QTY);  // GUARD TK-11357
   for (const iid of items) {
     let r = await gql(M_TRACK, { id: iid }); (r.inventoryItemUpdate?.userErrors || []).forEach(e => errs.push('track:' + e.message));
     r = await gql(M_ACTIVATE, { iid, loc: LOCATION_ID });
     (r.inventoryActivate?.userErrors || []).filter(e => !/already/i.test(e.message)).forEach(e => errs.push('activate:' + e.message));
   }
   const r2 = await gql(M_SETQTY, { input: { name: 'available', reason: 'correction', ignoreCompareQuantity: true,
-    quantities: items.map(iid => ({ inventoryItemId: iid, locationId: LOCATION_ID, quantity: TARGET_QTY })) } });
+    quantities } });                                               // GUARD TK-11357
   (r2.inventorySetQuantities?.userErrors || []).forEach(e => errs.push('setqty:' + e.message));
   const r3 = await gql(M_PUBLISH, { id: gidP, pubs: PUBLICATIONS.filter(_pid => _pid !== 29646651457 || !_isShowroomGuard("Falling Star")).map(p => ({ publicationId: p })) });
   (r3.publishablePublish?.userErrors || []).forEach(e => errs.push('publish:' + e.message));
diff --git a/scripts/knoll-onboard/go-live.mjs b/scripts/knoll-onboard/go-live.mjs
index a5e9be8..aac6e05 100644
--- a/scripts/knoll-onboard/go-live.mjs
+++ b/scripts/knoll-onboard/go-live.mjs
@@ -37,7 +37,30 @@ const PUBLICATIONS = [
 ].map(n => `gid://shopify/Publication/${n}`);
 const sleep = ms => new Promise(r => setTimeout(r, ms));
 
-const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status handle variants(first:10){edges{node{inventoryItem{id}}}}}}`;
+const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status handle vendor tags variants(first:10){edges{node{title price inventoryItem{id}}}}}}`;
+import { safeStampQuantity } from '../lib/inventory-stamp-guard.mjs';  // GUARD TK-11357 (shared guard)
+// ── GUARD TK-11357 BEGIN ─ do not edit without re-running the fixture proof ──────────
+// A $0 / quote-only sellable variant must NEVER receive positive stock: positive stock is what
+// flips availableForSale=true, making it checkout-orderable at $0 (lineage TK-10825 -> 10965 ->
+// 11140 -> 11299 -> 11301 -> 11357). $0 is the LIVE theme's deliberate quote-only SENTINEL
+// (snippets/product-form-content.liquid renders the "Contact Us" button iff variant.price == 0),
+// so the remedy is NEVER to write a placeholder price - it is "do not stock it".
+// Steve's 2026-06-20 "active products are never out of stock" rule is PRESERVED for PRICED goods:
+// a priced variant still gets `desired`. The quote-only tag/vendor decision is delegated to the
+// shared guard (lib/inventory-stamp-guard.mjs); this adds one strictly-safer rule of its own -
+// price <= 0 / NaN is ALWAYS 0, even on a variant labelled "Sample" (a $0 "sample" is the same
+// $0-orderable defect). The real $4.25 memo sample is unaffected and keeps its existing quantity.
+function safeQuantities(product, variants, locationId, desired) {
+  return (variants || []).map(v => ({
+    inventoryItemId: v.inventoryItem.id,
+    locationId,
+    quantity: Number(v.price) > 0
+      ? safeStampQuantity({ title: v.title, price: v.price }, product, desired)
+      : 0,
+  }));
+}
+// ── GUARD TK-11357 END ────────────────────────────────────────────
+
 const M_TRACK = `mutation($id:ID!){ inventoryItemUpdate(id:$id, input:{tracked:true}){ userErrors{message} } }`;
 const M_ACTIVATE = `mutation($iid:ID!,$loc:ID!){ inventoryActivate(inventoryItemId:$iid, locationId:$loc){ userErrors{message} } }`;
 const M_SETQTY = `mutation($input:InventorySetQuantitiesInput!){ inventorySetQuantities(input:$input){ userErrors{message code} } }`;
@@ -66,14 +89,16 @@ async function goLive(pid, sku) {
   const d = await gql(Q_VARIANTS, { id: gidP });
   if (!d?.product) return { missing: true };
   if (d.product.status === 'ACTIVE') { dbWriteBack(sku, pid, d.product.handle); return { skipped: true }; }
-  const items = d.product.variants.edges.map(e => e.node.inventoryItem.id);
+  const vnodes = d.product.variants.edges.map(e => e.node);
+  const items = vnodes.map(v => v.inventoryItem.id);              // track+activate: unchanged
+  const quantities = safeQuantities(d.product, vnodes, LOCATION_ID, TARGET_QTY);  // GUARD TK-11357
   for (const iid of items) {
     let r = await gql(M_TRACK, { id: iid }); (r.inventoryItemUpdate?.userErrors || []).forEach(e => errs.push('track:' + e.message));
     r = await gql(M_ACTIVATE, { iid, loc: LOCATION_ID });
     (r.inventoryActivate?.userErrors || []).filter(e => !/already/i.test(e.message)).forEach(e => errs.push('activate:' + e.message));
   }
   const r2 = await gql(M_SETQTY, { input: { name: 'on_hand', reason: 'correction', ignoreCompareQuantity: true,
-    quantities: items.map(iid => ({ inventoryItemId: iid, locationId: LOCATION_ID, quantity: TARGET_QTY })) } });
+    quantities } });                                               // GUARD TK-11357
   (r2.inventorySetQuantities?.userErrors || []).forEach(e => errs.push('setqty:' + e.message));
   const r3 = await gql(M_PUBLISH, { id: gidP, pubs: PUBLICATIONS.filter(_pid => _pid !== 29646651457 || !_isShowroomGuard("Knoll")).map(p => ({ publicationId: p })) });
   (r3.publishablePublish?.userErrors || []).forEach(e => errs.push('publish:' + e.message));
diff --git a/scripts/lib/inventory-stamp-guard.mjs b/scripts/lib/inventory-stamp-guard.mjs
new file mode 100644
index 0000000..29d1810
--- /dev/null
+++ b/scripts/lib/inventory-stamp-guard.mjs
@@ -0,0 +1,80 @@
+// VENDORED COPY — canonical source: Designer-Wallcoverings/shopify/scripts/lib/inventory-stamp-guard.mjs
+// Vendored (not cross-repo-imported) on purpose: this repo ships and runs independently, and a
+// cross-repo relative import would hard-crash the scheduled cadence if either tree moved.
+// KEEP IN SYNC — the TK-11357 fixture harness hashes both copies and FAILS on drift.
+// TK-11357 (lineage TK-10825/10965/11140/11299/11301/11357).
+// TK-10965 — Fix B (prevention): the inventory-stamp invariant, as a pure guard.
+//
+// ROOT CAUSE (see ../FINDINGS.md): importers stamp a positive "cap-free" stock
+// number (the year literal 2026) on the SELLABLE non-Sample variant of every
+// activated product — both in the product-create payload (`inventory_quantity: 2026`)
+// and on reconcile (`setInventory2026()`). When that sellable variant is ALSO
+// priced $0 (quote-only / contact-for-price lines like Phillipe Romano, Fentucci
+// Naturals), positive stock makes it `availableForSale` → checkout-orderable for $0.
+//
+// THE INVARIANT this module enforces (one place, both call sites):
+//   A sellable variant that is priced $0 OR belongs to a quote-only / price-
+//   suppressed line must NEVER receive positive inventory. It gets 0 → not orderable.
+//   (The $4.25 Sample variant is unaffected — it is not the sellable variant and is
+//    already qty=0/non-orderable by design.)
+//
+// PURE + dependency-free on purpose: no network, no env, no Shopify client, so it
+// unit-tests offline and drops into any importer runtime unchanged. $0 (local).
+
+// Tag family that means "this line has no public retail price" — a superset of the
+// single `quote-only` tag the standing canary keyed on (which is why Fentucci, tagged
+// `quotes`/`Needs-Price`, was the canary's 462-product blind spot).
+export const PRICE_SUPPRESSED_TAGS = new Set([
+  'quote-only', 'quote only', 'quote_only',
+  'quotes', 'contact-for-price', 'contact for price', 'needs-price', 'needs price',
+]);
+
+const norm = t => String(t).trim().toLowerCase();
+
+/**
+ * Is this product a quote-only / price-suppressed line?
+ * @param {{tags?: string[]|string, vendor?: string}} product
+ */
+export function isPriceSuppressed(product = {}) {
+  const tags = Array.isArray(product.tags)
+    ? product.tags
+    : String(product.tags || '').split(',');
+  if (tags.some(t => PRICE_SUPPRESSED_TAGS.has(norm(t)))) return true;
+  // Vendor fallback for untagged cohorts (Fentucci Naturals ships quote-only with
+  // zero quote-only tags). Extend as new price-on-request lines are onboarded.
+  return norm(product.vendor) === 'fentucci naturals';
+}
+
+/**
+ * A variant is the "sellable" one iff it is NOT the Sample variant.
+ * (Importers create exactly two variants: `Sample` @ $4.25 and the real unit @ price.)
+ * @param {{title?: string, option1?: string}} variant
+ */
+export function isSellableVariant(variant = {}) {
+  const label = variant.title ?? variant.option1 ?? '';
+  return !/sample/i.test(label);
+}
+
+/**
+ * Would giving this sellable variant positive stock make it a $0-orderable defect?
+ * True iff it's the sellable variant AND (price is 0 OR the line is price-suppressed).
+ * @param {object} variant  the variant about to be stamped
+ * @param {object} product  its parent (for tags/vendor)
+ */
+export function isZeroPriceOrderableRisk(variant = {}, product = {}) {
+  if (!isSellableVariant(variant)) return false;
+  const price = Number(variant.price);
+  return price === 0 || Number.isNaN(price) || isPriceSuppressed(product);
+}
+
+/**
+ * THE GUARD. Return the inventory quantity that is SAFE to stamp on this variant.
+ * Drop-in replacement for the literal `2026` at both call sites:
+ *   - create payload:  inventory_quantity: safeStampQuantity(variant, product)
+ *   - setInventory2026: quantity:        safeStampQuantity(variant, product)
+ * Returns `desired` (2026) for normal priced variants; 0 for the defect class.
+ * @returns {number} 0 for a zero-price-orderable risk, else `desired`
+ */
+export function safeStampQuantity(variant, product, desired = 2026) {
+  return isZeroPriceOrderableRisk(variant, product) ? 0 : desired;
+}
diff --git a/scripts/maharam-onboard/go-live.mjs b/scripts/maharam-onboard/go-live.mjs
index e66b1cc..dd989c7 100644
--- a/scripts/maharam-onboard/go-live.mjs
+++ b/scripts/maharam-onboard/go-live.mjs
@@ -40,7 +40,30 @@ const PUBLICATIONS = [
 ].map(n => `gid://shopify/Publication/${n}`);
 const sleep = ms => new Promise(r => setTimeout(r, ms));
 
-const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status handle variants(first:10){edges{node{inventoryItem{id}}}}}}`;
+const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status handle vendor tags variants(first:10){edges{node{title price inventoryItem{id}}}}}}`;
+import { safeStampQuantity } from '../lib/inventory-stamp-guard.mjs';  // GUARD TK-11357 (shared guard)
+// ── GUARD TK-11357 BEGIN ─ do not edit without re-running the fixture proof ──────────
+// A $0 / quote-only sellable variant must NEVER receive positive stock: positive stock is what
+// flips availableForSale=true, making it checkout-orderable at $0 (lineage TK-10825 -> 10965 ->
+// 11140 -> 11299 -> 11301 -> 11357). $0 is the LIVE theme's deliberate quote-only SENTINEL
+// (snippets/product-form-content.liquid renders the "Contact Us" button iff variant.price == 0),
+// so the remedy is NEVER to write a placeholder price - it is "do not stock it".
+// Steve's 2026-06-20 "active products are never out of stock" rule is PRESERVED for PRICED goods:
+// a priced variant still gets `desired`. The quote-only tag/vendor decision is delegated to the
+// shared guard (lib/inventory-stamp-guard.mjs); this adds one strictly-safer rule of its own -
+// price <= 0 / NaN is ALWAYS 0, even on a variant labelled "Sample" (a $0 "sample" is the same
+// $0-orderable defect). The real $4.25 memo sample is unaffected and keeps its existing quantity.
+function safeQuantities(product, variants, locationId, desired) {
+  return (variants || []).map(v => ({
+    inventoryItemId: v.inventoryItem.id,
+    locationId,
+    quantity: Number(v.price) > 0
+      ? safeStampQuantity({ title: v.title, price: v.price }, product, desired)
+      : 0,
+  }));
+}
+// ── GUARD TK-11357 END ────────────────────────────────────────────
+
 const M_TRACK = `mutation($id:ID!){ inventoryItemUpdate(id:$id, input:{tracked:true}){ userErrors{message} } }`;
 const M_ACTIVATE = `mutation($iid:ID!,$loc:ID!){ inventoryActivate(inventoryItemId:$iid, locationId:$loc){ userErrors{message} } }`;
 const M_SETQTY = `mutation($input:InventorySetQuantitiesInput!){ inventorySetQuantities(input:$input){ userErrors{message code} } }`;
@@ -71,14 +94,16 @@ async function goLive(pid, sku, mfrSku) {
   const d = await gql(Q_VARIANTS, { id: gidP });
   if (!d?.product) return { missing: true };
   if (d.product.status === 'ACTIVE') { dbWriteBack(sku, pid, d.product.handle, mfrSku); return { skipped: true }; }
-  const items = d.product.variants.edges.map(e => e.node.inventoryItem.id);
+  const vnodes = d.product.variants.edges.map(e => e.node);
+  const items = vnodes.map(v => v.inventoryItem.id);              // track+activate: unchanged
+  const quantities = safeQuantities(d.product, vnodes, LOCATION_ID, TARGET_QTY);  // GUARD TK-11357
   for (const iid of items) {
     let r = await gql(M_TRACK, { id: iid }); (r.inventoryItemUpdate?.userErrors || []).forEach(e => errs.push('track:' + e.message));
     r = await gql(M_ACTIVATE, { iid, loc: LOCATION_ID });
     (r.inventoryActivate?.userErrors || []).filter(e => !/already/i.test(e.message)).forEach(e => errs.push('activate:' + e.message));
   }
   const r2 = await gql(M_SETQTY, { input: { name: 'on_hand', reason: 'correction', ignoreCompareQuantity: true,
-    quantities: items.map(iid => ({ inventoryItemId: iid, locationId: LOCATION_ID, quantity: TARGET_QTY })) } });
+    quantities } });                                               // GUARD TK-11357
   (r2.inventorySetQuantities?.userErrors || []).forEach(e => errs.push('setqty:' + e.message));
   const r3 = await gql(M_PUBLISH, { id: gidP, pubs: PUBLICATIONS.filter(_pid => _pid !== 29646651457 || !_isShowroomGuard("Maharam")).map(p => ({ publicationId: p })) });
   (r3.publishablePublish?.userErrors || []).forEach(e => errs.push('publish:' + e.message));
diff --git a/scripts/muralsource-onboard/go-live.mjs b/scripts/muralsource-onboard/go-live.mjs
index 04fce25..3753c22 100644
--- a/scripts/muralsource-onboard/go-live.mjs
+++ b/scripts/muralsource-onboard/go-live.mjs
@@ -45,7 +45,30 @@ const PUBLICATIONS = [
 ].map(n => `gid://shopify/Publication/${n}`);
 const sleep = ms => new Promise(r => setTimeout(r, ms));
 
-const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status handle variants(first:10){edges{node{inventoryItem{id}}}}}}`;
+const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status handle vendor tags variants(first:10){edges{node{title price inventoryItem{id}}}}}}`;
+import { safeStampQuantity } from '../lib/inventory-stamp-guard.mjs';  // GUARD TK-11357 (shared guard)
+// ── GUARD TK-11357 BEGIN ─ do not edit without re-running the fixture proof ──────────
+// A $0 / quote-only sellable variant must NEVER receive positive stock: positive stock is what
+// flips availableForSale=true, making it checkout-orderable at $0 (lineage TK-10825 -> 10965 ->
+// 11140 -> 11299 -> 11301 -> 11357). $0 is the LIVE theme's deliberate quote-only SENTINEL
+// (snippets/product-form-content.liquid renders the "Contact Us" button iff variant.price == 0),
+// so the remedy is NEVER to write a placeholder price - it is "do not stock it".
+// Steve's 2026-06-20 "active products are never out of stock" rule is PRESERVED for PRICED goods:
+// a priced variant still gets `desired`. The quote-only tag/vendor decision is delegated to the
+// shared guard (lib/inventory-stamp-guard.mjs); this adds one strictly-safer rule of its own -
+// price <= 0 / NaN is ALWAYS 0, even on a variant labelled "Sample" (a $0 "sample" is the same
+// $0-orderable defect). The real $4.25 memo sample is unaffected and keeps its existing quantity.
+function safeQuantities(product, variants, locationId, desired) {
+  return (variants || []).map(v => ({
+    inventoryItemId: v.inventoryItem.id,
+    locationId,
+    quantity: Number(v.price) > 0
+      ? safeStampQuantity({ title: v.title, price: v.price }, product, desired)
+      : 0,
+  }));
+}
+// ── GUARD TK-11357 END ────────────────────────────────────────────
+
 const M_TRACK = `mutation($id:ID!){ inventoryItemUpdate(id:$id, input:{tracked:true}){ userErrors{message} } }`;
 const M_ACTIVATE = `mutation($iid:ID!,$loc:ID!){ inventoryActivate(inventoryItemId:$iid, locationId:$loc){ userErrors{message} } }`;
 const M_SETQTY = `mutation($input:InventorySetQuantitiesInput!){ inventorySetQuantities(input:$input){ userErrors{message code} } }`;
@@ -91,14 +114,16 @@ async function goLive(pid, sku, mfrSku) {
   const d = await gql(Q_VARIANTS, { id: gidP });
   if (!d?.product) return { missing: true };
   if (d.product.status === 'ACTIVE') { dbWriteBack(sku, mfrSku, pid, d.product.handle); return { skipped: true }; }
-  const items = d.product.variants.edges.map(e => e.node.inventoryItem.id);
+  const vnodes = d.product.variants.edges.map(e => e.node);
+  const items = vnodes.map(v => v.inventoryItem.id);              // track+activate: unchanged
+  const quantities = safeQuantities(d.product, vnodes, LOCATION_ID, TARGET_QTY);  // GUARD TK-11357
   for (const iid of items) {
     let r = await gql(M_TRACK, { id: iid }); (r.inventoryItemUpdate?.userErrors || []).forEach(e => errs.push('track:' + e.message));
     r = await gql(M_ACTIVATE, { iid, loc: LOCATION_ID });
     (r.inventoryActivate?.userErrors || []).filter(e => !/already/i.test(e.message)).forEach(e => errs.push('activate:' + e.message));
   }
   const r2 = await gql(M_SETQTY, { input: { name: 'on_hand', reason: 'correction', ignoreCompareQuantity: true,
-    quantities: items.map(iid => ({ inventoryItemId: iid, locationId: LOCATION_ID, quantity: TARGET_QTY })) } });
+    quantities } });                                               // GUARD TK-11357
   (r2.inventorySetQuantities?.userErrors || []).forEach(e => errs.push('setqty:' + e.message));
   const r3 = await gql(M_PUBLISH, { id: gidP, pubs: PUBLICATIONS.filter(_pid => _pid !== 29646651457 || !_isShowroomGuard("Mural Source")).map(p => ({ publicationId: p })) });
   (r3.publishablePublish?.userErrors || []).forEach(e => errs.push('publish:' + e.message));
diff --git a/scripts/osborne-onboard/go-live.mjs b/scripts/osborne-onboard/go-live.mjs
index a98d77c..6608384 100644
--- a/scripts/osborne-onboard/go-live.mjs
+++ b/scripts/osborne-onboard/go-live.mjs
@@ -51,7 +51,30 @@ async function gql(query, variables = {}) {
     } catch (e) { if (a === 3) throw e; await sleep(900 * (a + 1)); }
   }
 }
-const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status variants(first:10){edges{node{inventoryItem{id}}}}}}`;
+const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status vendor tags variants(first:10){edges{node{title price inventoryItem{id}}}}}}`;
+import { safeStampQuantity } from '../lib/inventory-stamp-guard.mjs';  // GUARD TK-11357 (shared guard)
+// ── GUARD TK-11357 BEGIN ─ do not edit without re-running the fixture proof ──────────
+// A $0 / quote-only sellable variant must NEVER receive positive stock: positive stock is what
+// flips availableForSale=true, making it checkout-orderable at $0 (lineage TK-10825 -> 10965 ->
+// 11140 -> 11299 -> 11301 -> 11357). $0 is the LIVE theme's deliberate quote-only SENTINEL
+// (snippets/product-form-content.liquid renders the "Contact Us" button iff variant.price == 0),
+// so the remedy is NEVER to write a placeholder price - it is "do not stock it".
+// Steve's 2026-06-20 "active products are never out of stock" rule is PRESERVED for PRICED goods:
+// a priced variant still gets `desired`. The quote-only tag/vendor decision is delegated to the
+// shared guard (lib/inventory-stamp-guard.mjs); this adds one strictly-safer rule of its own -
+// price <= 0 / NaN is ALWAYS 0, even on a variant labelled "Sample" (a $0 "sample" is the same
+// $0-orderable defect). The real $4.25 memo sample is unaffected and keeps its existing quantity.
+function safeQuantities(product, variants, locationId, desired) {
+  return (variants || []).map(v => ({
+    inventoryItemId: v.inventoryItem.id,
+    locationId,
+    quantity: Number(v.price) > 0
+      ? safeStampQuantity({ title: v.title, price: v.price }, product, desired)
+      : 0,
+  }));
+}
+// ── GUARD TK-11357 END ────────────────────────────────────────────
+
 const M_TRACK = `mutation($id:ID!){ inventoryItemUpdate(id:$id, input:{tracked:true}){ userErrors{message} } }`;
 const M_ACTIVATE = `mutation($iid:ID!,$loc:ID!){ inventoryActivate(inventoryItemId:$iid, locationId:$loc){ userErrors{message} } }`;
 const M_SETQTY = `mutation($input:InventorySetQuantitiesInput!){ inventorySetQuantities(input:$input){ userErrors{message code} } }`;
@@ -64,14 +87,16 @@ async function goLive(pid) {
   const d = await gql(Q_VARIANTS, { id: gidP });
   if (!d?.product) return { missing: true };
   if (d.product.status === 'ACTIVE') return { skipped: true };
-  const items = d.product.variants.edges.map(e => e.node.inventoryItem.id);
+  const vnodes = d.product.variants.edges.map(e => e.node);
+  const items = vnodes.map(v => v.inventoryItem.id);              // track+activate: unchanged
+  const quantities = safeQuantities(d.product, vnodes, LOCATION_ID, TARGET_QTY);  // GUARD TK-11357
   for (const iid of items) {
     let r = await gql(M_TRACK, { id: iid }); (r.inventoryItemUpdate?.userErrors || []).forEach(e => errs.push('track:' + e.message));
     r = await gql(M_ACTIVATE, { iid, loc: LOCATION_ID });
     (r.inventoryActivate?.userErrors || []).filter(e => !/already/i.test(e.message)).forEach(e => errs.push('activate:' + e.message));
   }
   const r2 = await gql(M_SETQTY, { input: { name: 'on_hand', reason: 'correction', ignoreCompareQuantity: true,
-    quantities: items.map(iid => ({ inventoryItemId: iid, locationId: LOCATION_ID, quantity: TARGET_QTY })) } });
+    quantities } });                                               // GUARD TK-11357
   (r2.inventorySetQuantities?.userErrors || []).forEach(e => errs.push('setqty:' + e.message));
   const r3 = await gql(M_PUBLISH, { id: gidP, pubs: PUBLICATIONS.filter(_pid => _pid !== 29646651457 || !_isShowroomGuard("Osborne & Little")).map(p => ({ publicationId: p })) });
   (r3.publishablePublish?.userErrors || []).forEach(e => errs.push('publish:' + e.message));
diff --git a/scripts/stout-onboard/go-live.mjs b/scripts/stout-onboard/go-live.mjs
index 89c606d..f429d8d 100644
--- a/scripts/stout-onboard/go-live.mjs
+++ b/scripts/stout-onboard/go-live.mjs
@@ -48,7 +48,30 @@ const PUBLICATIONS = [
 ].map(n => `gid://shopify/Publication/${n}`);
 const sleep = ms => new Promise(r => setTimeout(r, ms));
 
-const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status handle variants(first:10){edges{node{inventoryItem{id}}}}}}`;
+const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status handle vendor tags variants(first:10){edges{node{title price inventoryItem{id}}}}}}`;
+import { safeStampQuantity } from '../lib/inventory-stamp-guard.mjs';  // GUARD TK-11357 (shared guard)
+// ── GUARD TK-11357 BEGIN ─ do not edit without re-running the fixture proof ──────────
+// A $0 / quote-only sellable variant must NEVER receive positive stock: positive stock is what
+// flips availableForSale=true, making it checkout-orderable at $0 (lineage TK-10825 -> 10965 ->
+// 11140 -> 11299 -> 11301 -> 11357). $0 is the LIVE theme's deliberate quote-only SENTINEL
+// (snippets/product-form-content.liquid renders the "Contact Us" button iff variant.price == 0),
+// so the remedy is NEVER to write a placeholder price - it is "do not stock it".
+// Steve's 2026-06-20 "active products are never out of stock" rule is PRESERVED for PRICED goods:
+// a priced variant still gets `desired`. The quote-only tag/vendor decision is delegated to the
+// shared guard (lib/inventory-stamp-guard.mjs); this adds one strictly-safer rule of its own -
+// price <= 0 / NaN is ALWAYS 0, even on a variant labelled "Sample" (a $0 "sample" is the same
+// $0-orderable defect). The real $4.25 memo sample is unaffected and keeps its existing quantity.
+function safeQuantities(product, variants, locationId, desired) {
+  return (variants || []).map(v => ({
+    inventoryItemId: v.inventoryItem.id,
+    locationId,
+    quantity: Number(v.price) > 0
+      ? safeStampQuantity({ title: v.title, price: v.price }, product, desired)
+      : 0,
+  }));
+}
+// ── GUARD TK-11357 END ────────────────────────────────────────────
+
 const M_TRACK = `mutation($id:ID!){ inventoryItemUpdate(id:$id, input:{tracked:true}){ userErrors{message} } }`;
 const M_ACTIVATE = `mutation($iid:ID!,$loc:ID!){ inventoryActivate(inventoryItemId:$iid, locationId:$loc){ userErrors{message} } }`;
 const M_SETQTY = `mutation($input:InventorySetQuantitiesInput!){ inventorySetQuantities(input:$input){ userErrors{message code} } }`;
@@ -94,14 +117,16 @@ async function goLive(pid, sku, mfrSku) {
   const d = await gql(Q_VARIANTS, { id: gidP });
   if (!d?.product) return { missing: true };
   if (d.product.status === 'ACTIVE') { dbWriteBack(sku, mfrSku, pid, d.product.handle); return { skipped: true }; }
-  const items = d.product.variants.edges.map(e => e.node.inventoryItem.id);
+  const vnodes = d.product.variants.edges.map(e => e.node);
+  const items = vnodes.map(v => v.inventoryItem.id);              // track+activate: unchanged
+  const quantities = safeQuantities(d.product, vnodes, LOCATION_ID, TARGET_QTY);  // GUARD TK-11357
   for (const iid of items) {
     let r = await gql(M_TRACK, { id: iid }); (r.inventoryItemUpdate?.userErrors || []).forEach(e => errs.push('track:' + e.message));
     r = await gql(M_ACTIVATE, { iid, loc: LOCATION_ID });
     (r.inventoryActivate?.userErrors || []).filter(e => !/already/i.test(e.message)).forEach(e => errs.push('activate:' + e.message));
   }
   const r2 = await gql(M_SETQTY, { input: { name: 'on_hand', reason: 'correction', ignoreCompareQuantity: true,
-    quantities: items.map(iid => ({ inventoryItemId: iid, locationId: LOCATION_ID, quantity: TARGET_QTY })) } });
+    quantities } });                                               // GUARD TK-11357
   (r2.inventorySetQuantities?.userErrors || []).forEach(e => errs.push('setqty:' + e.message));
   const r3 = await gql(M_PUBLISH, { id: gidP, pubs: PUBLICATIONS.filter(_pid => _pid !== 29646651457 || !_isShowroomGuard("Stout")).map(p => ({ publicationId: p })) });
   (r3.publishablePublish?.userErrors || []).forEach(e => errs.push('publish:' + e.message));
diff --git a/scripts/stroheim-onboard/go-live.mjs b/scripts/stroheim-onboard/go-live.mjs
index fcb3a62..9985a26 100644
--- a/scripts/stroheim-onboard/go-live.mjs
+++ b/scripts/stroheim-onboard/go-live.mjs
@@ -50,7 +50,30 @@ const PUBLICATIONS = [
 ].map(n => `gid://shopify/Publication/${n}`);
 const sleep = ms => new Promise(r => setTimeout(r, ms));
 
-const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status handle variants(first:10){edges{node{inventoryItem{id}}}}}}`;
+const Q_VARIANTS = `query($id:ID!){ product(id:$id){ status handle vendor tags variants(first:10){edges{node{title price inventoryItem{id}}}}}}`;
+import { safeStampQuantity } from '../lib/inventory-stamp-guard.mjs';  // GUARD TK-11357 (shared guard)
+// ── GUARD TK-11357 BEGIN ─ do not edit without re-running the fixture proof ──────────
+// A $0 / quote-only sellable variant must NEVER receive positive stock: positive stock is what
+// flips availableForSale=true, making it checkout-orderable at $0 (lineage TK-10825 -> 10965 ->
+// 11140 -> 11299 -> 11301 -> 11357). $0 is the LIVE theme's deliberate quote-only SENTINEL
+// (snippets/product-form-content.liquid renders the "Contact Us" button iff variant.price == 0),
+// so the remedy is NEVER to write a placeholder price - it is "do not stock it".
+// Steve's 2026-06-20 "active products are never out of stock" rule is PRESERVED for PRICED goods:
+// a priced variant still gets `desired`. The quote-only tag/vendor decision is delegated to the
+// shared guard (lib/inventory-stamp-guard.mjs); this adds one strictly-safer rule of its own -
+// price <= 0 / NaN is ALWAYS 0, even on a variant labelled "Sample" (a $0 "sample" is the same
+// $0-orderable defect). The real $4.25 memo sample is unaffected and keeps its existing quantity.
+function safeQuantities(product, variants, locationId, desired) {
+  return (variants || []).map(v => ({
+    inventoryItemId: v.inventoryItem.id,
+    locationId,
+    quantity: Number(v.price) > 0
+      ? safeStampQuantity({ title: v.title, price: v.price }, product, desired)
+      : 0,
+  }));
+}
+// ── GUARD TK-11357 END ────────────────────────────────────────────
+
 const M_TRACK = `mutation($id:ID!){ inventoryItemUpdate(id:$id, input:{tracked:true}){ userErrors{message} } }`;
 const M_ACTIVATE = `mutation($iid:ID!,$loc:ID!){ inventoryActivate(inventoryItemId:$iid, locationId:$loc){ userErrors{message} } }`;
 const M_SETQTY = `mutation($input:InventorySetQuantitiesInput!){ inventorySetQuantities(input:$input){ userErrors{message code} } }`;
@@ -95,14 +118,16 @@ async function goLive(pid, sku, mfrSku) {
   const d = await gql(Q_VARIANTS, { id: gidP });
   if (!d?.product) return { missing: true };
   if (d.product.status === 'ACTIVE') { dbWriteBack(sku, mfrSku, pid, d.product.handle); return { skipped: true }; }
-  const items = d.product.variants.edges.map(e => e.node.inventoryItem.id);
+  const vnodes = d.product.variants.edges.map(e => e.node);
+  const items = vnodes.map(v => v.inventoryItem.id);              // track+activate: unchanged
+  const quantities = safeQuantities(d.product, vnodes, LOCATION_ID, TARGET_QTY);  // GUARD TK-11357
   for (const iid of items) {
     let r = await gql(M_TRACK, { id: iid }); (r.inventoryItemUpdate?.userErrors || []).forEach(e => errs.push('track:' + e.message));
     r = await gql(M_ACTIVATE, { iid, loc: LOCATION_ID });
     (r.inventoryActivate?.userErrors || []).filter(e => !/already/i.test(e.message)).forEach(e => errs.push('activate:' + e.message));
   }
   const r2 = await gql(M_SETQTY, { input: { name: 'on_hand', reason: 'correction', ignoreCompareQuantity: true,
-    quantities: items.map(iid => ({ inventoryItemId: iid, locationId: LOCATION_ID, quantity: TARGET_QTY })) } });
+    quantities } });                                               // GUARD TK-11357
   (r2.inventorySetQuantities?.userErrors || []).forEach(e => errs.push('setqty:' + e.message));
   const r3 = await gql(M_PUBLISH, { id: gidP, pubs: PUBLICATIONS.filter(_pid => _pid !== 29646651457 || !_isShowroomGuard("Stroheim")).map(p => ({ publicationId: p })) });
   (r3.publishablePublish?.userErrors || []).forEach(e => errs.push('publish:' + e.message));
diff --git a/scripts/tres-tintas-onboard/go-live-tres-tintas.js b/scripts/tres-tintas-onboard/go-live-tres-tintas.js
index a277757..2be4bb8 100644
--- a/scripts/tres-tintas-onboard/go-live-tres-tintas.js
+++ b/scripts/tres-tintas-onboard/go-live-tres-tintas.js
@@ -58,7 +58,30 @@ async function gql(query, variables = {}) {
     } catch (e) { if (a === 3) throw e; await sleep(900 * (a + 1)); }
   }
 }
-const Q_V = `query($id:ID!){ product(id:$id){ status variants(first:10){edges{node{id inventoryItem{id}}}} } }`;
+const Q_V = `query($id:ID!){ product(id:$id){ status vendor tags variants(first:10){edges{node{id title price inventoryItem{id}}}} } }`;
+const { safeStampQuantity } = require('../lib/inventory-stamp-guard.mjs');  // GUARD TK-11357 (shared guard)
+// ── GUARD TK-11357 BEGIN ─ do not edit without re-running the fixture proof ──────────
+// A $0 / quote-only sellable variant must NEVER receive positive stock: positive stock is what
+// flips availableForSale=true, making it checkout-orderable at $0 (lineage TK-10825 -> 10965 ->
+// 11140 -> 11299 -> 11301 -> 11357). $0 is the LIVE theme's deliberate quote-only SENTINEL
+// (snippets/product-form-content.liquid renders the "Contact Us" button iff variant.price == 0),
+// so the remedy is NEVER to write a placeholder price - it is "do not stock it".
+// Steve's 2026-06-20 "active products are never out of stock" rule is PRESERVED for PRICED goods:
+// a priced variant still gets `desired`. The quote-only tag/vendor decision is delegated to the
+// shared guard (lib/inventory-stamp-guard.mjs); this adds one strictly-safer rule of its own -
+// price <= 0 / NaN is ALWAYS 0, even on a variant labelled "Sample" (a $0 "sample" is the same
+// $0-orderable defect). The real $4.25 memo sample is unaffected and keeps its existing quantity.
+function safeQuantities(product, variants, locationId, desired) {
+  return (variants || []).map(v => ({
+    inventoryItemId: v.inventoryItem.id,
+    locationId,
+    quantity: Number(v.price) > 0
+      ? safeStampQuantity({ title: v.title, price: v.price }, product, desired)
+      : 0,
+  }));
+}
+// ── GUARD TK-11357 END ────────────────────────────────────────────
+
 const M_TRACK = `mutation($id:ID!){ inventoryItemUpdate(id:$id, input:{tracked:true}){ userErrors{message} } }`;
 const M_ACT = `mutation($iid:ID!,$loc:ID!){ inventoryActivate(inventoryItemId:$iid, locationId:$loc){ userErrors{message} } }`;
 const M_QTY = `mutation($input:InventorySetQuantitiesInput!){ inventorySetQuantities(input:$input){ userErrors{message code} } }`;
@@ -71,14 +94,16 @@ async function goLive(pid) {
   const d = await gql(Q_V, { id: gid });
   if (!d.product) return { errs: ['not found'] };
   if (d.product.status === 'ACTIVE') return { skipped: true };
-  const items = d.product.variants.edges.map(e => e.node.inventoryItem.id);
+  const vnodes = d.product.variants.edges.map(e => e.node);
+  const items = vnodes.map(v => v.inventoryItem.id);              // track+activate: unchanged
+  const quantities = safeQuantities(d.product, vnodes, LOCATION_ID, TARGET_QTY);  // GUARD TK-11357
   for (const iid of items) {
     let r = await gql(M_TRACK, { id: iid }); (r.inventoryItemUpdate?.userErrors || []).forEach(e => errs.push('track:' + e.message));
     r = await gql(M_ACT, { iid, loc: LOCATION_ID });
     (r.inventoryActivate?.userErrors || []).filter(e => !/already/i.test(e.message)).forEach(e => errs.push('act:' + e.message));
   }
   const rq = await gql(M_QTY, { input: { name: 'on_hand', reason: 'correction', ignoreCompareQuantity: true,
-    quantities: items.map(iid => ({ inventoryItemId: iid, locationId: LOCATION_ID, quantity: TARGET_QTY })) } });
+    quantities } });                                               // GUARD TK-11357
   (rq.inventorySetQuantities?.userErrors || []).forEach(e => errs.push('qty:' + e.message));
   const rp = await gql(M_PUB, { id: gid, pubs: PUBLICATIONS.filter(_pid => _pid !== 29646651457 || !_isShowroomGuard("Tres Tintas")).map(p => ({ publicationId: p })) });
   (rp.publishablePublish?.userErrors || []).forEach(e => errs.push('pub:' + e.message));

← d5d3db4 TK-10895: hardened Tranche B executor for the verified 269  ·  back to Designerwallcoverings  ·  guard TK-11357 Fix D: per-variant $0 gate in the two activat 2fe073d →