← back to Dw Activation Debug TK11314
rotation-activator: block $4.25 sample-leak price from passing the activation gate (TK-10456)
d9e84e1c0d0ef978e9a7d281305653a5231ac9f3 · 2026-08-31 12:42:22 -0700 · Steve
The 5-field gate required a sellable variant with price>0, but the universal
$4.25 memo-sample price is >0, so any draft whose only sellable roll was stuck
at $4.25 passed the gate and the rotation flipped it DRAFT->ACTIVE — re-leaking
reverted discontinued/no-price products (5 Thibaut murals + 6 Chloe re-activated
at $4.25 hours after being reverted). Now a sellable variant priced at exactly
the sample-leak $4.25 no longer counts as a real price; a real price on any
sellable variant still passes. Fail-safe: can only block an activation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M lib/five-field-extra.jsM test/five-field-extra.test.js
Diff
commit d9e84e1c0d0ef978e9a7d281305653a5231ac9f3
Author: Steve <steve@designerwallcoverings.com>
Date: Mon Aug 31 12:42:22 2026 -0700
rotation-activator: block $4.25 sample-leak price from passing the activation gate (TK-10456)
The 5-field gate required a sellable variant with price>0, but the universal
$4.25 memo-sample price is >0, so any draft whose only sellable roll was stuck
at $4.25 passed the gate and the rotation flipped it DRAFT->ACTIVE — re-leaking
reverted discontinued/no-price products (5 Thibaut murals + 6 Chloe re-activated
at $4.25 hours after being reverted). Now a sellable variant priced at exactly
the sample-leak $4.25 no longer counts as a real price; a real price on any
sellable variant still passes. Fail-safe: can only block an activation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
lib/five-field-extra.js | 17 ++++++++++++++++-
test/five-field-extra.test.js | 22 ++++++++++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/lib/five-field-extra.js b/lib/five-field-extra.js
index 6fd9940..57b0c00 100644
--- a/lib/five-field-extra.js
+++ b/lib/five-field-extra.js
@@ -1,5 +1,13 @@
'use strict';
+// The universal memo-sample price. A "sellable" (non-sample) variant stuck at
+// exactly this value is the $4.25 sample-price LEAK, NOT a real sellable price —
+// so it must NOT satisfy the price>0 gate (else the activator flips DRAFT→ACTIVE
+// on a product that is orderable at $4.25). Fail-safe: this can only BLOCK an
+// activation, never cause one. (TK-10456, 2026-08-31 — the rotation was
+// re-activating reverted $4.25 murals/Chloe because $4.25 > 0 passed the gate.)
+const SAMPLE_LEAK_PRICE = 4.25;
+
function fiveFieldExtra(product) {
const hasValidVariantsShape = Array.isArray(product?.variants?.nodes);
const hasValidTagsShape = Array.isArray(product?.tags);
@@ -9,11 +17,17 @@ function fiveFieldExtra(product) {
: [];
const hasSample = variants.some((variant) => /-sample$/i.test(variant.sku || ''));
const sellable = variants.filter((variant) => !/-sample$/i.test(variant.sku || ''));
- const hasSellablePriced = sellable.some((variant) => {
+ const pricedSellable = sellable.filter((variant) => {
if (typeof variant.price !== 'string' || !/^\d+(?:\.\d+)?$/.test(variant.price)) return false;
const price = Number(variant.price);
return Number.isFinite(price) && price > 0;
});
+ const hasSellablePriced = pricedSellable.length > 0;
+ // If the ONLY priced sellable variant(s) sit at the sample-leak price, this is a
+ // $4.25 leak, not a real price → block. A real price on any sellable variant
+ // (e.g. a $384 roll alongside a $4.25 sample) still passes.
+ const onlySampleLeakPriced = hasSellablePriced &&
+ pricedSellable.every((variant) => Number(variant.price) === SAMPLE_LEAK_PRICE);
const isQuoteOnly = tags.includes('quotes');
const reasons = [];
if (!hasValidVariantsShape) reasons.push('invalid-variants-shape');
@@ -21,6 +35,7 @@ function fiveFieldExtra(product) {
if (!hasSample) reasons.push('no-sample-variant');
if (!sellable.length && !isQuoteOnly) reasons.push('no-sellable-variant');
if (!hasSellablePriced && !isQuoteOnly) reasons.push('sellable-price-not-gt-0');
+ else if (onlySampleLeakPriced && !isQuoteOnly) reasons.push('sellable-price-is-sample-leak-4.25');
if (tags.length < 2) reasons.push('fewer-than-2-tags');
return { ok: reasons.length === 0, reasons };
}
diff --git a/test/five-field-extra.test.js b/test/five-field-extra.test.js
index 8e68d11..374e7e0 100644
--- a/test/five-field-extra.test.js
+++ b/test/five-field-extra.test.js
@@ -27,6 +27,28 @@ test('rejects missing, zero, malformed, and negative sellable prices', () => {
}
});
+test('blocks the $4.25 sample-leak price on the sellable variant (TK-10456)', () => {
+ // a "sellable" roll stuck at the memo-sample price 4.25 is the leak, not a real price
+ const leak = fiveFieldExtra(product([
+ { sku: 'DW-100-Sample', price: '4.25' }, { sku: 'DW-100-Roll', price: '4.25' },
+ ]));
+ assert.equal(leak.ok, false);
+ assert.ok(leak.reasons.includes('sellable-price-is-sample-leak-4.25'));
+
+ // a real price alongside a 4.25 sample still passes
+ const real = fiveFieldExtra(product([
+ { sku: 'DW-100-Sample', price: '4.25' }, { sku: 'DW-100-Roll', price: '384.00' },
+ ]));
+ assert.deepEqual(real, { ok: true, reasons: [] });
+
+ // mixed: a real sellable + a leaked sellable still passes (any real price is enough)
+ const mixed = fiveFieldExtra(product([
+ { sku: 'DW-100-Sample', price: '4.25' }, { sku: 'DW-100-Roll', price: '4.25' },
+ { sku: 'DW-100-DR', price: '768.00' },
+ ]));
+ assert.equal(mixed.ok, true);
+});
+
test('fails closed on non-array variants and tags with explicit shape reasons', () => {
const variants = [{ sku: 'DW-100-SAMPLE', price: '5.00' }, { sku: 'DW-100', price: '125.00' }];
const tagsString = fiveFieldExtra({ variants: { nodes: variants }, tags: 'wallpaper' });
← c4f1747 Fail closed on malformed activation fields
·
back to Dw Activation Debug TK11314
·
feat(golive-gate): mfr_sku provenance gate blocks blank/fabr 99013ea →