← back to Commercialrealestate
enrich-condo-brokers: cost circuit-breaker (Codex dissent) — abort after 8 consecutive WAF blocks OR 12 session-min (~$1.80 ceiling); preserves data, tells you to rerun --only-missing when WAF cools
8e1bfaa1f531032219cddaa865bd2bc521e99659 · 2026-08-03 11:14:53 -0700 · Steve Abrams
Files touched
M scripts/enrich-condo-brokers.js
Diff
commit 8e1bfaa1f531032219cddaa865bd2bc521e99659
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Aug 3 11:14:53 2026 -0700
enrich-condo-brokers: cost circuit-breaker (Codex dissent) — abort after 8 consecutive WAF blocks OR 12 session-min (~$1.80 ceiling); preserves data, tells you to rerun --only-missing when WAF cools
---
scripts/enrich-condo-brokers.js | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/scripts/enrich-condo-brokers.js b/scripts/enrich-condo-brokers.js
index 0cd183c..0dc76bd 100644
--- a/scripts/enrich-condo-brokers.js
+++ b/scripts/enrich-condo-brokers.js
@@ -209,8 +209,16 @@ async function main() {
console.log(`condo-broker enrich: ${targets.length} target(s) of ${exp.length} fha_expired · delay ~${DELAY}ms · $0 local`);
const blocked = [];
let done = 0, gotBroker = 0, gotDre = 0;
+ // Cost/abort guardrails (Codex dissent): a hot Redfin WAF polls ~25s per blocked listing, so an
+ // unbounded run can blow past its cost estimate. Bail early when the WAF is clearly hot.
+ const MAX_CONSEC_BLOCKS = +process.env.MAX_CONSEC_BLOCKS || 8;
+ const MAX_SESSION_MIN = +process.env.MAX_SESSION_MIN || 12; // ~$1.80 hard ceiling at $0.15/min
+ let consecBlocks = 0, aborted = null;
for (const c of targets) {
if (done >= LIMIT) break;
+ const elapsedMin = (Date.now() - startedAt) / 60000;
+ if (elapsedMin > MAX_SESSION_MIN) { aborted = `session cap ${MAX_SESSION_MIN}min (~$${(MAX_SESSION_MIN * 0.15).toFixed(2)})`; break; }
+ if (consecBlocks >= MAX_CONSEC_BLOCKS) { aborted = `${consecBlocks} consecutive WAF blocks — WAF is hot, stopping to save spend`; break; }
done++;
const { status, html } = await fetchRedfin(c.source, page);
let b = html ? extractBroker(html) : {};
@@ -220,8 +228,8 @@ async function main() {
const r2 = await fetchRedfin(c.source, page);
if (r2.html) { const b2 = extractBroker(r2.html); if (b2.broker_name) b = b2; }
}
- if (!b.broker_name && !b.firm_name) { blocked.push(c.id); }
- else gotBroker++;
+ if (!b.broker_name && !b.firm_name) { blocked.push(c.id); consecBlocks++; }
+ else { gotBroker++; consecBlocks = 0; }
let dre = null;
if (b.broker_dre) { dre = await hookDre(b.broker_dre, dreCache); if (dre && dre.dre_status) gotDre++; }
// Hook EVERY license number on the listing into its full CA DRE record (Steve: record all
@@ -252,6 +260,7 @@ async function main() {
await sleep(jitter());
}
process.stdout.write('\n');
+ if (aborted) console.log(` ⚠ ABORTED EARLY: ${aborted}. Processed ${done}/${targets.length}; rerun later (WAF cooler) with --only-missing to finish. Existing data preserved.`);
if (browser) await browser.close();
if (bbSession) {
const mins = (Date.now() - startedAt) / 60000;
← d3c49a3 enrich-condo-brokers (Cody gate): FIX partial-hit clobber (m
·
back to Commercialrealestate
·
condos table: add drillable DRE# column (License# → CA DRE r ea6498d →