← back to Sanderson Onboard
tk10873/reprice_sanity.mjs
153 lines
#!/usr/bin/env node
// reprice_sanity.mjs — TK-10873 INDEPENDENT data-quality gate over the 328 Zoffany
// Option-A REPRICE proposed prices.
//
// READ-ONLY. NO SHOPIFY/DB WRITES, NO http/fetch. Re-derives everything from the
// draft JSON (does NOT trust reprice_runbook_dryrun.json) so this is a genuine
// second check, not an echo of the runbook.
//
// Asserts, per REPRICE row:
// * proposed_sellable_price is a positive number (FAIL if not)
// * proposed_sellable_price > sample_price (4.25) (FAIL if not)
// * where staged_trade present: proposed >= staged_trade (FAIL if below cost)
// * flags any price outside [$20, $2000] as WARN (human eyes — NOT a fail)
// Reports the price distribution (min/median/max/count) and trade-backed vs
// retail-harvest-backed counts.
//
// Exit code: nonzero ONLY on a hard invariant violation (FAIL). WARN-only (band
// outliers) still exits 0 with the outliers listed.
import fs from 'node:fs';
import { SAMPLE_PRICE, classifyPrice, priceStats, BAND_MIN, BAND_MAX, ourPriceDeviationWarn, ID_RESOLUTION_DISCLOSURE } from './reprice_lib.mjs';
const DIR = new URL('.', import.meta.url).pathname;
const DRAFT_IN = `${DIR}zoffany_optionA_draft.json`;
const JSON_OUT = `${DIR}reprice_sanity.json`;
const MD_OUT = `${DIR}reprice_sanity.md`;
function main() {
const draft = JSON.parse(fs.readFileSync(DRAFT_IN, 'utf8'));
const reprice = draft.filter(p => p.action === 'REPRICE');
const fails = [];
const warns = [];
let tradeBacked = 0;
let retailBacked = 0;
for (const p of reprice) {
const price = p.proposed_sellable_price;
const sample = p.sample_price ?? SAMPLE_PRICE;
// staged_trade = price_trade in the draft; the cost floor when present.
const tradeFloor = p.price_trade == null ? null : Number(p.price_trade);
if (tradeFloor != null && Number.isFinite(tradeFloor) && tradeFloor > 0) tradeBacked++;
else retailBacked++;
const dw = p.live_dw_sku || p.staged_dw_sku || p.mfr_sku;
const { verdict, reasons } = classifyPrice(price, sample, tradeFloor);
// Provenance cross-check: where an independently-computed our_price exists, a sharp
// divergence from the proposed retail is a scraper-unit-error signal → WARN (not FAIL).
const devReason = ourPriceDeviationWarn(price, p.our_price);
if (verdict === 'FAIL') {
fails.push({ dw_sku: dw, mfr_sku: p.mfr_sku, proposed: price, sample, staged_trade: tradeFloor, reasons });
} else if (verdict === 'WARN' || devReason) {
warns.push({ dw_sku: dw, mfr_sku: p.mfr_sku, proposed: price, staged_trade: tradeFloor, reasons: [...reasons, ...(devReason ? [devReason] : [])] });
}
}
const ourPriceChecked = reprice.filter(p => p.our_price != null && Number(p.our_price) > 0).length;
const stats = priceStats(reprice.map(p => p.proposed_sellable_price));
const verdict = fails.length ? 'FAIL' : (warns.length ? 'WARN' : 'PASS');
const report = {
ticket: 'TK-10873',
generated_at: new Date().toISOString(),
read_only: true,
verdict,
status: verdict, // fleet-health-rollup vocabulary
reprice_count: reprice.length,
expected_reprice: 328,
sample_price: SAMPLE_PRICE,
band: { min: BAND_MIN, max: BAND_MAX },
price_distribution: stats,
trade_backed: tradeBacked,
retail_harvest_backed: retailBacked,
our_price_cross_checked: ourPriceChecked,
// Honest scope of what PASS means (Cody cycle-3): trade-backed rows are INVARIANT-VALIDATED
// (checked against a real cost floor); retail-harvest-backed rows are LEGIBILITY-CHECKED only
// (positive + > sample + in-band) unless they also carry an our_price to cross-check against.
validation_scope: {
invariant_validated: tradeBacked,
legibility_checked_only: retailBacked - ourPriceChecked,
cross_checked_via_our_price: ourPriceChecked,
note: 'A retail-only price with no cost floor and no our_price cannot be independently validated — PASS for those rows means legible, not verified-correct.',
},
id_resolution_disclosure: ID_RESOLUTION_DISCLOSURE,
hard_fail_count: fails.length,
warn_count: warns.length,
hard_fails: fails,
warnings: warns,
};
fs.writeFileSync(JSON_OUT, JSON.stringify(report, null, 2));
// human-readable markdown
const md = [];
md.push(`# TK-10873 Zoffany Option-A REPRICE — sanity report`);
md.push('');
md.push(`- **Verdict:** ${verdict}`);
md.push(`- Generated: ${report.generated_at}`);
md.push(`- REPRICE rows: ${reprice.length} (expected 328)`);
md.push(`- Sample price (unchanged): $${SAMPLE_PRICE}`);
md.push(`- Sane band: $${BAND_MIN}–$${BAND_MAX} (outside = WARN, not FAIL)`);
md.push('');
md.push(`## Price distribution`);
md.push(`| min | median | max | count |`);
md.push(`|---|---|---|---|`);
md.push(`| $${stats.min} | $${stats.median} | $${stats.max} | ${stats.count} |`);
md.push('');
md.push(`## Price backing & validation scope`);
md.push(`- **invariant-validated** (trade-backed, checked vs a real cost floor): **${tradeBacked}**`);
md.push(`- retail-harvest-backed (no trade floor): **${retailBacked}** — of which **${ourPriceChecked}** cross-checked vs our_price, **${retailBacked - ourPriceChecked}** legibility-checked only`);
md.push(`- _Honest scope: PASS for a legibility-checked row means the price is a positive, above-sample, in-band number — NOT that it is independently verified correct. A stale/unit-wrong scraped retail with no cost floor or our_price would still pass._`);
md.push('');
md.push(`## Hard invariant failures: ${fails.length}`);
if (fails.length) {
md.push(`| dw_sku | mfr_sku | proposed | sample | staged_trade | reasons |`);
md.push(`|---|---|---|---|---|---|`);
for (const f of fails) md.push(`| ${f.dw_sku} | ${f.mfr_sku} | ${f.proposed} | ${f.sample} | ${f.staged_trade ?? ''} | ${f.reasons.join('; ')} |`);
} else {
md.push('_none — every proposed price is positive, > sample, and not below cost._');
}
md.push('');
md.push(`## WARN (band outliers + our_price divergence — human eyes, not a fail): ${warns.length}`);
if (warns.length) {
md.push(`| dw_sku | mfr_sku | proposed | staged_trade | reasons |`);
md.push(`|---|---|---|---|---|`);
for (const w of warns) md.push(`| ${w.dw_sku} | ${w.mfr_sku} | ${w.proposed} | ${w.staged_trade ?? ''} | ${w.reasons.join('; ')} |`);
} else {
md.push('_none — every proposed price is inside the sane band and (where checkable) within 15% of our_price._');
}
md.push('');
md.push(`## Live-run caveat`);
md.push(`- ${ID_RESOLUTION_DISCLOSURE}`);
md.push('');
fs.writeFileSync(MD_OUT, md.join('\n') + '\n');
// stdout
console.log('=== Zoffany Option-A REPRICE sanity gate (READ-ONLY) ===');
console.log(`verdict=${verdict} reprice=${reprice.length} hard_fails=${fails.length} band_outliers=${warns.length}`);
console.log(`price min=$${stats.min} median=$${stats.median} max=$${stats.max} count=${stats.count}`);
console.log(`backing trade=${tradeBacked} retail-harvest=${retailBacked}`);
if (warns.length) {
console.log('band outliers (WARN, listed for human eyes):');
for (const w of warns) console.log(` ${w.dw_sku} (${w.mfr_sku}) $${w.proposed} — ${w.reasons.join('; ')}`);
}
if (fails.length) {
console.log('HARD FAILS:');
for (const f of fails) console.log(` ${f.dw_sku} (${f.mfr_sku}) $${f.proposed} — ${f.reasons.join('; ')}`);
}
console.log(`\nartifacts:\n ${JSON_OUT}\n ${MD_OUT}`);
process.exit(fails.length ? 1 : 0);
}
main();