← back to Dw Yolo Loop
scripts/contract-scope-auditor/contract-scope-auditor.mjs
64 lines
// contract-scope-auditor — read-only dw_unified canary for VENDOR-SCOPE / contract
// integrity, complementing dw-map-auditor (which owns Kravet MAP + Nicolette).
//
// This auditor covers the SCOPE gaps the MAP auditor intentionally leaves:
// 1) FAIL Discontinued-but-ACTIVE — products tagged 'Discontinued' still status=ACTIVE.
// Discontinued SKUs must be archived (vendor 404s, dead links, and they
// compound the GMC $4.25 risk). Bounded + actionable.
// 2) FAIL Photos-only vendor carrying a REAL price — Cowtan & Tout is crawl-images-only
// by design (0% cost-coverage intentional). A Cowtan product with price>$5 is a
// data error / scope violation.
// 3) INFO Gated-vendor ACTIVE snapshot — Koroseal/Newmor/Desima/Wolf Gordon/Innovations/
// Scalamandre are uncosted/push-GATED but KNOWINGLY live. Counts only, never a
// FAIL (flagging thousands daily = cry-wolf, per dw-map-auditor's own note).
//
// MAP-floor + Nicolette tripwire are NOT re-checked here — dw-map-auditor owns them.
// READ-ONLY local psql. No writes except the local report JSON. Cost: $0.
import { execFileSync } from 'node:child_process';
import fs from 'node:fs';
const HOME = process.env.HOME, DIR = `${HOME}/.claude/yolo-queue`;
const PSQL = [ '/opt/homebrew/opt/postgresql@14/bin/psql', '/usr/local/opt/postgresql@14/bin/psql', 'psql' ]
.find(p => { try { execFileSync(p, ['--version'], { stdio: 'ignore' }); return true; } catch { return false; } }) || 'psql';
const DBURL = process.env.DW_UNIFIED_URL || 'postgresql:///dw_unified?host=/tmp';
function q(sql) {
const out = execFileSync(PSQL, [DBURL, '-At', '-F', '|', '-c', sql], { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });
return out.trim() ? out.trim().split('\n').map(r => r.split('|')) : [];
}
// 1) Discontinued-but-ACTIVE (sample the worst 200 for the report; count all)
const discoCount = +(q(`select count(*) from shopify_products where status='ACTIVE' and tags ~* 'discontinu'`)[0]?.[0] || 0);
const discoByVendor = q(`select vendor, count(*) from shopify_products where status='ACTIVE' and tags ~* 'discontinu' group by vendor order by 2 desc`);
const discoRows = q(`select vendor, mfr_sku, price, handle from shopify_products where status='ACTIVE' and tags ~* 'discontinu' order by vendor, mfr_sku limit 200`);
// 2) Photos-only vendor (Cowtan) carrying a real price
const cowtanPriced = q(`select vendor, mfr_sku, price, handle from shopify_products where status='ACTIVE' and vendor ~* 'cowtan' and price::numeric > 5 order by price::numeric desc limit 100`);
// 3) Gated-vendor ACTIVE snapshot (informational)
const gated = q(`select vendor, count(*) from shopify_products where status='ACTIVE' and vendor ~* 'koroseal|newmor|desima|wolf *gordon|innovations|scalamandre' group by vendor order by 2 desc`);
const findings = [];
if (discoCount) findings.push({ sev: 'FAIL', check: 'discontinued_active',
msg: `${discoCount} ACTIVE product(s) tagged Discontinued (should be archived)`,
by_vendor: discoByVendor.map(r => ({ vendor: r[0], count: +r[1] })),
sample: discoRows.map(r => ({ vendor: r[0], sku: r[1], price: +r[2], handle: r[3] })) });
if (cowtanPriced.length) findings.push({ sev: 'FAIL', check: 'photosonly_priced',
msg: `${cowtanPriced.length} Cowtan (photos-only) product(s) carry a real price >$5 (scope/data error)`,
rows: cowtanPriced.map(r => ({ vendor: r[0], sku: r[1], price: +r[2], handle: r[3] })) });
findings.push({ sev: 'INFO', check: 'gated_vendor_active_snapshot',
msg: `gated/uncosted vendors knowingly live (counts only, not a violation)`,
by_vendor: gated.map(r => ({ vendor: r[0], count: +r[1] })) });
const fail = findings.filter(f => f.sev === 'FAIL').length;
const verdict = fail ? 'FAIL' : 'PASS';
const out = { scanned_at: new Date().toISOString(), verdict, fail, findings,
note: 'Kravet MAP-floor + Nicolette tripwire are owned by dw-map-auditor (ran separately).' };
fs.mkdirSync(DIR, { recursive: true });
fs.writeFileSync(`${DIR}/contract-scope-audit-${new Date().toISOString().slice(0,10)}.json`, JSON.stringify(out, null, 2));
console.log(`[contract-scope-auditor] ${verdict} · ${fail} FAIL`);
for (const f of findings) console.log(` ${f.sev === 'FAIL' ? '✗' : f.sev === 'INFO' ? 'ℹ' : '△'} ${f.check}: ${f.msg}`);
if (verdict === 'PASS') console.log(' ✓ no discontinued-active, no photos-only mispricing');