← back to Hollywood Import
generator forward-fix revised to DTD-C: HW-<deterministic opaque hash of Momentum number>; raw number internal-only; collision-guarded; kill-switch frozen
3844a4f6e534471764dfc95262b32a0a2057d8c2 · 2026-08-17 17:12:06 -0700 · steve
Files touched
M momentum-feed/assign-sku.mjs
Diff
commit 3844a4f6e534471764dfc95262b32a0a2057d8c2
Author: steve <steve@designerwallcoverings.com>
Date: Mon Aug 17 17:12:06 2026 -0700
generator forward-fix revised to DTD-C: HW-<deterministic opaque hash of Momentum number>; raw number internal-only; collision-guarded; kill-switch frozen
---
momentum-feed/assign-sku.mjs | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/momentum-feed/assign-sku.mjs b/momentum-feed/assign-sku.mjs
index e41e3e1..39f9fdf 100644
--- a/momentum-feed/assign-sku.mjs
+++ b/momentum-feed/assign-sku.mjs
@@ -18,6 +18,7 @@ const COMMIT = process.argv.includes('--commit');
// `number` / manufacturer_sku, not a minted DW code). The kill-switch halts
// the daily drip; this guard also blocks a direct `--commit` re-mint.
import { existsSync } from 'node:fs';
+import { createHash } from 'node:crypto';
if (COMMIT && existsSync(`${process.env.HOME}/.dw-fixer-stop`)) {
console.error('[assign-sku] BLOCKED: ~/.dw-fixer-stop present. DWHD minting is FROZEN (brand-as-vendor bug, TK-10634). Remove the kill-switch only after the real-code redesign.');
process.exit(3);
@@ -58,12 +59,17 @@ function buildPool(need, used) {
async function main() {
const used = (await pool.query(`SELECT DISTINCT pl_city_name c FROM momentum_colorways WHERE pl_city_name IS NOT NULL`))
.rows.map(r => r.c).filter(Boolean);
- // --- FORWARD-FIX (DTD-B, 2026-08-17): mint a Hollywood PRIVATE-LABEL code from the REAL
- // Momentum number, NOT a sequential DW-vendor DWHD mint. The prefix is the private-label
- // wrapper (Hollywood), the number is the product's real identity; the raw number is ALSO
- // kept internal in manufacturer_sku. NEVER the bare number customer-facing ("always pl
- // momentum"), NEVER a sequential mint divorced from the product. Prefix is configurable. ---
+ // --- FORWARD-FIX (DTD verdict C, 2026-08-17): the customer-facing SKU = Hollywood prefix +
+ // a DETERMINISTIC, OPAQUE transform of the real Momentum number — NOT the raw number and
+ // NOT a stateful sequential mint. Why C over "HW-<raw number>": the variant SKU propagates
+ // to the Google/Meta merchant feed, order emails, packing slips, and CSV/EDI exports, so a
+ // raw Momentum number there is one prefix-strip from a momentumco.com lookup = a private-
+ // label LEAK ("always pl momentum"). The hash is deterministic (same number → same code,
+ // idempotent, no counter to drift like DWHD) AND opaque (competitor-safe). The RAW number
+ // stays ONLY in the internal manufacturer_sku metafield. Prefix + hash length configurable.
const PL_PREFIX = process.env.HW_PL_PREFIX || 'HW';
+ const HASH_LEN = Number(process.env.HW_HASH_LEN || 12); // hex chars; 12 = 48 bits ≈ collision-free at catalog scale (guarded below)
+ const plSku = num => `${PL_PREFIX}-${createHash('sha256').update(String(num)).digest('hex').slice(0, HASH_LEN).toUpperCase()}`;
// Deterministic order: WC before Acoustic, then pattern, then colorway.
const { rows } = await pool.query(
`SELECT id, pattern_name, color_name, color_number, category, momentum_sku FROM momentum_colorways
@@ -76,12 +82,12 @@ async function main() {
if (pool2.length < patterns.length) throw new Error(`pool short: ${pool2.length} < ${patterns.length}`);
const cityOf = new Map(patterns.map((p, i) => [p, pool2[i]]));
- const plan = codeable.map(r => ({ id: r.id, dw_sku: `${PL_PREFIX}-${r.momentum_sku}`, city: cityOf.get(r.pattern_name),
+ const plan = codeable.map(r => ({ id: r.id, dw_sku: plSku(r.momentum_sku), city: cityOf.get(r.pattern_name),
pattern: r.pattern_name, color: r.color_name, cat: r.category, mfr: r.momentum_sku }));
- // collision guard: a real number appearing twice would collide (must be unique)
+ // collision guard: fail loud if the opaque transform ever collides (raise HW_HASH_LEN)
const codes = plan.map(p => p.dw_sku);
- if (new Set(codes).size !== codes.length) throw new Error('duplicate momentum_sku → SKU collision; aborting');
- console.log(`assign-sku (forward-fix ${PL_PREFIX}-<number>): ${plan.length} colorways / ${patterns.length} patterns. SKIPPED ${noNumber.length} with no momentum_sku (need real number).`);
+ if (new Set(codes).size !== codes.length) throw new Error('opaque-SKU hash collision → raise HW_HASH_LEN; aborting');
+ console.log(`assign-sku (forward-fix ${PL_PREFIX}-<opaque hash>): ${plan.length} colorways / ${patterns.length} patterns. SKIPPED ${noNumber.length} with no momentum_sku. Raw number stays in manufacturer_sku only.`);
console.log(' samples:'); plan.slice(0, 4).forEach(p => console.log(` ${p.dw_sku} ${p.cat} "${p.pattern}" / ${p.color} → ${p.city}`));
if (!COMMIT) { console.log('DRY-RUN — re-run with --commit to write.'); await pool.end(); return; }
← 61c9a76 TK-10634 generator forward-fix (DTD-B): mint HW-<real moment
·
back to Hollywood Import
·
TK-10679: add ^DWHD/DWHW2 SKU-shape guard to hollywood-creat f7109e8 →