← 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');