← back to Dw Unbuyable Recovery Pilot
TK-11041: make the auth-proof failure self-diagnosing instead of silently fatal
0e76f2d7d9546e2c8a03e07c630d4ca5ee6fa409 · 2026-09-12 07:27:14 -0700 · Steve Abrams
Nobody here has seen innovationsusa.com logged in. The June 2026 crawl saved only
cookies — no localStorage, no captured markup — so the 'Sign Out / My Account'
markers the auth proof keys off are an INFORMED GUESS. If they are wrong, every
page reports SESSION_FAILURE and the run looks exactly like bad credentials. That
ambiguity is the actual hazard, not the guess.
On auth-proof failure the script now dumps the identity-like lines the page really
carries, says plainly that this may be the marker guess rather than the login, and
prints the one-line re-run with INNOVATIONS_AUTH_POSITIVE set. Markers are env-
overridable so a fix needs no code edit. The diagnostic is also written into the
staged JSON.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Files touched
M tk11041-innovations-reconcile/rescrape/innovations-trade-pull.js
Diff
commit 0e76f2d7d9546e2c8a03e07c630d4ca5ee6fa409
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sat Sep 12 07:27:14 2026 -0700
TK-11041: make the auth-proof failure self-diagnosing instead of silently fatal
Nobody here has seen innovationsusa.com logged in. The June 2026 crawl saved only
cookies — no localStorage, no captured markup — so the 'Sign Out / My Account'
markers the auth proof keys off are an INFORMED GUESS. If they are wrong, every
page reports SESSION_FAILURE and the run looks exactly like bad credentials. That
ambiguity is the actual hazard, not the guess.
On auth-proof failure the script now dumps the identity-like lines the page really
carries, says plainly that this may be the marker guess rather than the login, and
prints the one-line re-run with INNOVATIONS_AUTH_POSITIVE set. Markers are env-
overridable so a fix needs no code edit. The diagnostic is also written into the
staged JSON.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---
.../rescrape/innovations-trade-pull.js | 44 ++++++++++++++++++++--
1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/tk11041-innovations-reconcile/rescrape/innovations-trade-pull.js b/tk11041-innovations-reconcile/rescrape/innovations-trade-pull.js
index f3f2191..abc71c0 100644
--- a/tk11041-innovations-reconcile/rescrape/innovations-trade-pull.js
+++ b/tk11041-innovations-reconcile/rescrape/innovations-trade-pull.js
@@ -53,8 +53,34 @@ const THROTTLE_MS = 350; // matches the public sweep's courtesy rate
// ---------------------------------------------------------------- extraction
// Authentication is asserted on EVERY page, not just at login: a portal can drop a session
// mid-run and keep serving 200s. "SIGN IN" present with no account marker == logged out.
-const AUTH_POSITIVE = /sign\s*out|log\s*out|my\s*account|58315/i;
-const AUTH_NEGATIVE = /sign\s*in|log\s*in/i;
+// HONEST LIMITATION: nobody here has seen this site logged in. The June 2026 crawl saved only
+// cookies (hollywood-import/innov-auth.json) — no localStorage, no captured markup — so these
+// markers are an INFORMED GUESS at what the authenticated chrome says, not a verified fact.
+// If they are wrong, every page would report SESSION_FAILURE and the run would look exactly
+// like bad credentials. That ambiguity is the danger, so on the FIRST auth-proof failure the
+// script DUMPS what the page actually says (see authDiagnostic) instead of just failing — one
+// run tells you the real marker. Override without editing code:
+// INNOVATIONS_AUTH_POSITIVE='sign out|logout|account #' node innovations-trade-pull.js --probe
+const AUTH_POSITIVE = new RegExp(
+ process.env.INNOVATIONS_AUTH_POSITIVE || 'sign\\s*out|log\\s*out|logout|my\\s*account|account\\s*#|58315', 'i');
+const AUTH_NEGATIVE = new RegExp(
+ process.env.INNOVATIONS_AUTH_NEGATIVE || 'sign\\s*in|log\\s*in', 'i');
+
+// What the page says about identity, so a wrong guess above is a 60-second fix rather than a
+// dead end that reads as "the credentials must be wrong".
+function authDiagnostic(text) {
+ const lines = String(text).split(/\n+/).map(l => l.trim()).filter(Boolean);
+ const hits = lines.filter(l => l.length < 80 &&
+ /sign|log|account|welcome|hello|my |dealer|trade|cart|58315|\bhi\b/i.test(l)).slice(0, 14);
+ return {
+ note: 'Auth markers are a GUESS (nobody has seen this site logged in). If the lines below ' +
+ 'show you ARE logged in, set INNOVATIONS_AUTH_POSITIVE to a phrase from them and re-run.',
+ first_lines: lines.slice(0, 8),
+ identity_like_lines: hits,
+ matched_positive: AUTH_POSITIVE.source,
+ matched_negative: AUTH_NEGATIVE.source,
+ };
+}
function authState(text) {
const pos = AUTH_POSITIVE.test(text);
@@ -208,6 +234,7 @@ function creds() {
const results = [];
let aborted = null;
+ let diagnostic = null;
try {
// --- login
await page.goto(url, { waitUntil: 'domcontentloaded' });
@@ -228,8 +255,16 @@ function creds() {
const homeText = await page.evaluate(() => document.body.innerText);
const proof = authState(homeText);
if (proof !== 'AUTHENTICATED') {
- throw new Error(`login NOT proven (auth=${proof}). Refusing to fetch pages — an unproven ` +
- 'session produces false absences that look exactly like "vendor has no price".');
+ diagnostic = authDiagnostic(homeText);
+ console.error('\n[!] login NOT proven (auth=' + proof + '). Refusing to fetch pages — an ' +
+ 'unproven session produces false absences that look exactly like "the vendor ' +
+ 'has no price".');
+ console.error('[?] BUT this may be MY marker guess being wrong rather than a bad login.');
+ console.error(' What the page actually says:');
+ for (const l of diagnostic.identity_like_lines) console.error(' | ' + l);
+ console.error(' If those show you ARE logged in, re-run with:');
+ console.error(" INNOVATIONS_AUTH_POSITIVE='<a phrase from above>' node innovations-trade-pull.js --probe");
+ throw new Error(`login NOT proven (auth=${proof}) — see diagnostic above and in the staged JSON`);
}
console.log('[+] session AUTHENTICATED (positively proven, not merely error-free)');
@@ -283,6 +318,7 @@ function creds() {
not_measured: results.filter(r => r.status === 'NOT_MEASURED').length,
basis_unknown: results.filter(r => r.price && r.price.basis === 'UNKNOWN').length,
aborted,
+ auth_diagnostic: diagnostic,
retail_computed: false,
retail_blocked_reason:
'TWO separate unknowns, both of which must be closed before retail is computed. ' +
← ecd3849 TK-11041: the portal prices live per-colorway, not on the pa
·
back to Dw Unbuyable Recovery Pilot
·
TK-11041: email price-list reconciliation for the 39 Innovat 9005ea5 →