← back to York Reprice 2026 08
Fix two reproduced defects: silent-degrade in york-cadence + hard-exit-on-missing-secret regression
a908d02607b0bad98f14a21fe2d3af90a8386184 · 2026-09-15 19:06:38 -0700 · Steve
1. cadence/york-cadence.mjs: the bare try{}catch(e){} wrapping the naturals
single-roll (RPS) query and the onboard-candidate query silently emptied
both on a transient PG hiccup, letting the daily cadence run on degraded
data with no signal (silent-MAP-overprice class). Both catches now log an
explicit error naming the failed query and process.exit(1) instead of
proceeding on empty data. Pricing math unchanged.
2. All 6 scripts (bridge-reprice, build-rows-17, cadence/york-cadence,
diag-brewster-images, recover-7-settlement, recover-images-17): the prior
fix made a missing DW_ADMIN_PG_PASSWORD a hard process.exit(1). dw_admin on
127.0.0.1 is TRUST auth, so a wrong/empty password still connects — the
hard-exit was a new regression where the job previously ran. Softened to
WARN-and-proceed: wrap the .env read in try/catch, warn, set PGPASSWORD='',
and let the actual psql call fail loudly only if a password is truly
required on the host. Still reads the pw from secrets-manager/.env when present.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M bridge-reprice.mjsM build-rows-17.mjsM cadence/york-cadence.mjsM diag-brewster-images.mjsM recover-7-settlement.mjsM recover-images-17.mjs
Diff
commit a908d02607b0bad98f14a21fe2d3af90a8386184
Author: Steve <steve@designerwallcoverings.com>
Date: Tue Sep 15 19:06:38 2026 -0700
Fix two reproduced defects: silent-degrade in york-cadence + hard-exit-on-missing-secret regression
1. cadence/york-cadence.mjs: the bare try{}catch(e){} wrapping the naturals
single-roll (RPS) query and the onboard-candidate query silently emptied
both on a transient PG hiccup, letting the daily cadence run on degraded
data with no signal (silent-MAP-overprice class). Both catches now log an
explicit error naming the failed query and process.exit(1) instead of
proceeding on empty data. Pricing math unchanged.
2. All 6 scripts (bridge-reprice, build-rows-17, cadence/york-cadence,
diag-brewster-images, recover-7-settlement, recover-images-17): the prior
fix made a missing DW_ADMIN_PG_PASSWORD a hard process.exit(1). dw_admin on
127.0.0.1 is TRUST auth, so a wrong/empty password still connects — the
hard-exit was a new regression where the job previously ran. Softened to
WARN-and-proceed: wrap the .env read in try/catch, warn, set PGPASSWORD='',
and let the actual psql call fail loudly only if a password is truly
required on the host. Still reads the pw from secrets-manager/.env when present.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
bridge-reprice.mjs | 4 ++--
build-rows-17.mjs | 4 ++--
cadence/york-cadence.mjs | 10 ++++++----
diag-brewster-images.mjs | 4 ++--
recover-7-settlement.mjs | 4 ++--
recover-images-17.mjs | 4 ++--
6 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/bridge-reprice.mjs b/bridge-reprice.mjs
index 5935bdd..940f9f1 100644
--- a/bridge-reprice.mjs
+++ b/bridge-reprice.mjs
@@ -4,8 +4,8 @@ const SHOP='designer-laboratory-sandbox.myshopify.com',VER='2024-10';
const TOKEN=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^SHOPIFY_ADMIN_TOKEN=(.+)$/m)||[])[1]?.trim();
const URL=`https://${SHOP}/admin/api/${VER}/graphql.json`;
// PG auth: read dw_admin's real password from secrets-manager/.env (same source as SHOPIFY_ADMIN_TOKEN). Nothing exports PGPASSWORD and ~/.pgpass has no dw_unified/dw_admin line, so the old inline `PGPASSWORD=` prefix sent libpq an empty password → auth failure swallowed → silent MAP-only overpricing of naturals.
-const PGPW=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^DW_ADMIN_PG_PASSWORD=(.+)$/m)||[])[1]?.trim();
-if(!PGPW){console.error('FATAL: DW_ADMIN_PG_PASSWORD missing from ~/Projects/secrets-manager/.env — cannot price safely, aborting.');process.exit(1);}
+let PGPW; try{ PGPW=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^DW_ADMIN_PG_PASSWORD=(.+)$/m)||[])[1]?.trim(); }catch(e){}
+if(!PGPW){console.warn('WARN: DW_ADMIN_PG_PASSWORD missing from ~/Projects/secrets-manager/.env — proceeding with empty PGPASSWORD (dw_admin on 127.0.0.1 is TRUST auth); the psql loads below fail loudly (and abort) if a password is truly required on this host.'); PGPW=''; }
const args=Object.fromEntries(process.argv.slice(2).map(a=>{const[k,v]=a.replace(/^--/,'').split('=');return[k,v===undefined?true:v];}));
const APPLY=args.apply===true&&args['i-am-steve']===true;
const INCLUDE_DOWN=args['include-down']===true;
diff --git a/build-rows-17.mjs b/build-rows-17.mjs
index 73e0a27..65b6e71 100644
--- a/build-rows-17.mjs
+++ b/build-rows-17.mjs
@@ -3,8 +3,8 @@
// data/onboard-rows-17.json (exact phase1-enriched shape build-onboard-payloads expects). $0 local.
import fs from 'node:fs'; import { execSync } from 'node:child_process';
// PG auth: read dw_admin's real password from secrets-manager/.env (same source as SHOPIFY_ADMIN_TOKEN); nothing exports PGPASSWORD and ~/.pgpass has no dw_unified/dw_admin line, so an inline empty PGPASSWORD= would silently fail auth.
-const PGPW=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^DW_ADMIN_PG_PASSWORD=(.+)$/m)||[])[1]?.trim();
-if(!PGPW){console.error('FATAL: DW_ADMIN_PG_PASSWORD missing from ~/Projects/secrets-manager/.env');process.exit(1);}
+let PGPW; try{ PGPW=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^DW_ADMIN_PG_PASSWORD=(.+)$/m)||[])[1]?.trim(); }catch(e){}
+if(!PGPW){console.warn('WARN: DW_ADMIN_PG_PASSWORD missing from ~/Projects/secrets-manager/.env — proceeding with empty PGPASSWORD (dw_admin on 127.0.0.1 is TRUST auth); the psql call will fail loudly if a password is truly required on this host.'); PGPW=''; }
const cands = JSON.parse(fs.readFileSync('data-onboard17-candidates.json','utf8'));
const skus = cands.map(c=>`'${String(c.mfr_sku).replace(/'/g,"''")}'`).join(',');
const SEP=String.fromCharCode(31);
diff --git a/cadence/york-cadence.mjs b/cadence/york-cadence.mjs
index 46ccb84..b1db94e 100644
--- a/cadence/york-cadence.mjs
+++ b/cadence/york-cadence.mjs
@@ -17,8 +17,8 @@ const SHOP='designer-laboratory-sandbox.myshopify.com',VER='2024-10';
const TOKEN=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^SHOPIFY_ADMIN_TOKEN=(.+)$/m)||[])[1]?.trim();
const URL=`https://${SHOP}/admin/api/${VER}/graphql.json`;
// PG auth: read dw_admin's real password from secrets-manager/.env (same source as SHOPIFY_ADMIN_TOKEN); nothing exports PGPASSWORD and ~/.pgpass has no dw_unified/dw_admin line, so an inline empty PGPASSWORD= would silently fail auth.
-const PGPW=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^DW_ADMIN_PG_PASSWORD=(.+)$/m)||[])[1]?.trim();
-if(!PGPW){console.error('FATAL: DW_ADMIN_PG_PASSWORD missing from ~/Projects/secrets-manager/.env');process.exit(1);}
+let PGPW; try{ PGPW=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^DW_ADMIN_PG_PASSWORD=(.+)$/m)||[])[1]?.trim(); }catch(e){}
+if(!PGPW){console.warn('WARN: DW_ADMIN_PG_PASSWORD missing from ~/Projects/secrets-manager/.env — proceeding with empty PGPASSWORD (dw_admin on 127.0.0.1 is TRUST auth); the psql call will fail loudly if a password is truly required on this host.'); PGPW=''; }
// Connect over the /tmp UNIX socket (DW-standard canonical dw_unified path) instead of TCP
// 127.0.0.1:5432. TCP 5432's listener flaps transiently (it went down Aug 15 → uncaught execSync
// throw → cadence crash); the /tmp socket is always present. Keep -U dw_admin (md5/scram over the
@@ -53,7 +53,8 @@ for(const line of q(`select concat_ws(chr(31), upper(trim(export_sku)), coalesce
// natural (grasscloth/sisal/paperweave/cork) as "drift" and would propose re-breaking it daily.
const RPS=new Map();
try{ for(const line of q(`select concat_ws(chr(31), upper(trim(mfr_sku)), roll_price_single) from brewster_york_master where roll_price_single is not null and roll_price_single>0`).split('\n').filter(Boolean)){
- const [s,p]=line.split(String.fromCharCode(31)); if(!RPS.has(s)) RPS.set(s,parseFloat(p)); } }catch(e){}
+ const [s,p]=line.split(String.fromCharCode(31)); if(!RPS.has(s)) RPS.set(s,parseFloat(p)); } }
+catch(e){ console.error('FATAL: naturals single-roll (RPS) query against brewster_york_master failed — refusing to proceed on empty RPS, which would silently MAP-overprice naturals (the banned silent-MAP-overprice class). Aborting.',String(e.message||e).slice(0,160)); process.exit(1); }
// onboard-ready CANDIDATES from DB (master 'New', settlement-keyword-clear, has a local image in
// york_catalog OR brewster_catalog). york_catalog holds art for the archived York-branded line;
// brewster_catalog holds it for the live Brewster/A-Street->Malibu line — every 'New' SKU is the
@@ -66,7 +67,8 @@ let onboardCand=[]; try{ onboardCand=q(`
where coalesce(nullif(c.image_url,''), nullif(b.image_url,'')) is not null
and lower(concat_ws(' ',n.pattern_name,n.product_name,n.book_name)) !~ 'banana|grape|bird|butterfly|palm|frond|leaf|leaves|foliage|botanical|floral|flower|tropical|jungle|vine|fern|bloom|garden|blossom|deciduous|egret|flamingo|crane|heron|peacock|feather'`)
.split('\n').map(x=>x.trim()).filter(Boolean)
- .map(l=>{const [s,pat]=l.split(String.fromCharCode(31)); return {s,pat:pat||''};}); }catch(e){}
+ .map(l=>{const [s,pat]=l.split(String.fromCharCode(31)); return {s,pat:pat||''};}); }
+catch(e){ console.error('FATAL: onboard-candidate query (york_master_aug2026 New + local image + settlement-clear) failed — refusing to proceed on empty onboard candidates, which would silently degrade onboard-ready to 0 with no signal. Aborting.',String(e.message||e).slice(0,160)); process.exit(1); }
// 2. live Jeffrey Stevens
let cur=null, reprice=[], disco=[], liveMfr=new Set(), liveTitles=new Map();
diff --git a/diag-brewster-images.mjs b/diag-brewster-images.mjs
index 316d579..d00a3b7 100644
--- a/diag-brewster-images.mjs
+++ b/diag-brewster-images.mjs
@@ -3,8 +3,8 @@
// Token-overlap (not substring), accent-normalized, to avoid false pos/neg. READ-ONLY. $0 local.
import { execSync } from 'node:child_process'; import fs from 'node:fs';
// PG auth: read dw_admin's real password from secrets-manager/.env (same source as SHOPIFY_ADMIN_TOKEN); nothing exports PGPASSWORD and ~/.pgpass has no dw_unified/dw_admin line, so an inline empty PGPASSWORD= would silently fail auth.
-const PGPW=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^DW_ADMIN_PG_PASSWORD=(.+)$/m)||[])[1]?.trim();
-if(!PGPW){console.error('FATAL: DW_ADMIN_PG_PASSWORD missing from ~/Projects/secrets-manager/.env');process.exit(1);}
+let PGPW; try{ PGPW=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^DW_ADMIN_PG_PASSWORD=(.+)$/m)||[])[1]?.trim(); }catch(e){}
+if(!PGPW){console.warn('WARN: DW_ADMIN_PG_PASSWORD missing from ~/Projects/secrets-manager/.env — proceeding with empty PGPASSWORD (dw_admin on 127.0.0.1 is TRUST auth); the psql call will fail loudly if a password is truly required on this host.'); PGPW=''; }
const q=sql=>{fs.writeFileSync('/tmp/_bdiag.sql',sql);return execSync(`/opt/homebrew/opt/postgresql@14/bin/psql -h 127.0.0.1 -U dw_admin -d dw_unified -tA -F'\x1f' -f /tmp/_bdiag.sql`,{encoding:'utf8',env:{...process.env,PGPASSWORD:PGPW}}).trim();};
const norm=s=>String(s||'').normalize('NFD').replace(/[̀-ͯ]/g,'').toLowerCase();
diff --git a/recover-7-settlement.mjs b/recover-7-settlement.mjs
index 6881ba6..0115871 100644
--- a/recover-7-settlement.mjs
+++ b/recover-7-settlement.mjs
@@ -3,8 +3,8 @@
// image by name-slug from brewster_catalog (their own row is corrupt), download for eyeball. READ-ONLY. $0.
import fs from 'node:fs'; import { execSync } from 'node:child_process';
// PG auth: read dw_admin's real password from secrets-manager/.env (same source as SHOPIFY_ADMIN_TOKEN); nothing exports PGPASSWORD and ~/.pgpass has no dw_unified/dw_admin line, so an inline empty PGPASSWORD= would silently fail auth.
-const PGPW=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^DW_ADMIN_PG_PASSWORD=(.+)$/m)||[])[1]?.trim();
-if(!PGPW){console.error('FATAL: DW_ADMIN_PG_PASSWORD missing from ~/Projects/secrets-manager/.env');process.exit(1);}
+let PGPW; try{ PGPW=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^DW_ADMIN_PG_PASSWORD=(.+)$/m)||[])[1]?.trim(); }catch(e){}
+if(!PGPW){console.warn('WARN: DW_ADMIN_PG_PASSWORD missing from ~/Projects/secrets-manager/.env — proceeding with empty PGPASSWORD (dw_admin on 127.0.0.1 is TRUST auth); the psql call will fail loudly if a password is truly required on this host.'); PGPW=''; }
const q=sql=>{fs.writeFileSync('/tmp/_r7.sql',sql);return execSync(`/opt/homebrew/opt/postgresql@14/bin/psql -h 127.0.0.1 -U dw_admin -d dw_unified -tA -F'\x1f' -f /tmp/_r7.sql`,{encoding:'utf8',env:{...process.env,PGPASSWORD:PGPW}}).trim();};
const norm=s=>String(s||'').normalize('NFD').replace(/[̀-ͯ]/g,'').toLowerCase();
const STOP=new Set(['wallpaper','wallcovering','residential','wall','the','and','light','dark','off']);
diff --git a/recover-images-17.mjs b/recover-images-17.mjs
index c89be85..fe566c9 100644
--- a/recover-images-17.mjs
+++ b/recover-images-17.mjs
@@ -5,8 +5,8 @@
// $0 local. Does NOT write to brewster_catalog (that DB-level relink is a separate gated job).
import fs from 'node:fs'; import { execSync } from 'node:child_process';
// PG auth: read dw_admin's real password from secrets-manager/.env (same source as SHOPIFY_ADMIN_TOKEN); nothing exports PGPASSWORD and ~/.pgpass has no dw_unified/dw_admin line, so an inline empty PGPASSWORD= would silently fail auth.
-const PGPW=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^DW_ADMIN_PG_PASSWORD=(.+)$/m)||[])[1]?.trim();
-if(!PGPW){console.error('FATAL: DW_ADMIN_PG_PASSWORD missing from ~/Projects/secrets-manager/.env');process.exit(1);}
+let PGPW; try{ PGPW=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^DW_ADMIN_PG_PASSWORD=(.+)$/m)||[])[1]?.trim(); }catch(e){}
+if(!PGPW){console.warn('WARN: DW_ADMIN_PG_PASSWORD missing from ~/Projects/secrets-manager/.env — proceeding with empty PGPASSWORD (dw_admin on 127.0.0.1 is TRUST auth); the psql call will fail loudly if a password is truly required on this host.'); PGPW=''; }
const slug=s=>String(s||'').toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'').replace(/-wallpaper$/,'');
// load every brewster_catalog image once: filename-slug -> url
const out=execSync(`/opt/homebrew/opt/postgresql@14/bin/psql -h 127.0.0.1 -U dw_admin -d dw_unified -tA -F'|' -c "select image_url from brewster_catalog where image_url is not null and image_url<>''"`,{encoding:'utf8',env:{...process.env,PGPASSWORD:PGPW}}).trim();
← b984417 Fix broken PGPASSWORD psql auth in 6 scripts; read dw_admin
·
back to York Reprice 2026 08
·
auto-data-snapshot: 2026-09-15T19:39:01 (1 data files) — cad 8cd3aa3 →