← back to Dw Yolo Loop
Canary board: aggregate all DW canaries into one red/green health pane
a8d15897403981894fce600632bbc36d67a1aa76 · 2026-06-16 03:28:34 -0700 · Steve Abrams
Runs meta-watchdog + contract-scope + scraper-contract + dw-map-auditor +
cf-dns-drift + dw-scraper-canary into one JSON. First run OVERALL FAIL (3/3):
meta-watchdog 23 dead jobs, contract-scope 484 disco-active, dw-scraper-canary
flags Rebel Walls public collection 250 vs 1000 baseline (likely display cap).
PASS: scraper-contract 10/10, dw-map-auditor clean, cf-dns 35-zone baseline.
Network canaries time-boxed → UNKNOWN, never fail the board.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Files touched
A scripts/canary-board/canary-board.mjs
Diff
commit a8d15897403981894fce600632bbc36d67a1aa76
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jun 16 03:28:34 2026 -0700
Canary board: aggregate all DW canaries into one red/green health pane
Runs meta-watchdog + contract-scope + scraper-contract + dw-map-auditor +
cf-dns-drift + dw-scraper-canary into one JSON. First run OVERALL FAIL (3/3):
meta-watchdog 23 dead jobs, contract-scope 484 disco-active, dw-scraper-canary
flags Rebel Walls public collection 250 vs 1000 baseline (likely display cap).
PASS: scraper-contract 10/10, dw-map-auditor clean, cf-dns 35-zone baseline.
Network canaries time-boxed → UNKNOWN, never fail the board.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
scripts/canary-board/canary-board.mjs | 90 +++++++++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
diff --git a/scripts/canary-board/canary-board.mjs b/scripts/canary-board/canary-board.mjs
new file mode 100644
index 0000000..ffb2059
--- /dev/null
+++ b/scripts/canary-board/canary-board.mjs
@@ -0,0 +1,90 @@
+// canary-board — run every DW canary and aggregate into ONE red/green health pane.
+// Proves the tools built tonight actually run, and gives Steve a single morning view.
+// READ-ONLY: each underlying canary is read-only; this only runs them + reads their
+// JSON. Network canaries are time-boxed and degrade to UNKNOWN (never fail the board).
+import { execFileSync } from 'node:child_process';
+import fs from 'node:fs';
+
+const HOME = process.env.HOME;
+const PROJ = `${HOME}/Projects/designerwallcoverings`;
+const YQ = `${HOME}/.claude/yolo-queue`;
+const today = new Date().toISOString().slice(0, 10);
+const OUT = `${YQ}/canary-board-${today}.json`;
+const MD = `${YQ}/canary-board-${today}.md`;
+
+function run(cmd, args, opts = {}) {
+ try { execFileSync(cmd, args, { encoding: 'utf8', timeout: opts.timeout || 60000, stdio: ['ignore', 'ignore', 'ignore'], cwd: opts.cwd || PROJ }); return true; }
+ catch (e) { return false; }
+}
+function readJSON(p) { try { return JSON.parse(fs.readFileSync(p, 'utf8')); } catch { return null; } }
+
+const board = [];
+
+// 1) canary-meta-watchdog (launchd freshness) — fast local
+run('node', ['scripts/canary-meta-watchdog/canary-meta-watchdog.js']);
+{
+ const j = readJSON(`${YQ}/canary-meta-watchdog-${today}.json`);
+ if (j) board.push({ canary: 'meta-watchdog', verdict: j.summary?.FAIL ? 'FAIL' : 'PASS',
+ headline: `${j.total} jobs · FAIL ${j.summary?.FAIL||0} / WARN ${j.summary?.WARN||0} / PASS ${j.summary?.PASS||0}` });
+ else board.push({ canary: 'meta-watchdog', verdict: 'UNKNOWN', headline: 'no output' });
+}
+
+// 2) contract-scope-auditor — fast local DB
+run('node', ['scripts/contract-scope-auditor/contract-scope-auditor.mjs']);
+{
+ const j = readJSON(`${YQ}/contract-scope-audit-${today}.json`);
+ if (j) board.push({ canary: 'contract-scope', verdict: j.verdict, headline: (j.findings||[]).map(f=>`${f.sev}:${f.check}`).join(' ') || 'clean' });
+ else board.push({ canary: 'contract-scope', verdict: 'UNKNOWN', headline: 'no output' });
+}
+
+// 3) scraper-contract-test — fast local DB
+run('node', ['scripts/scraper-contract-test/scraper-contract-test.mjs']);
+{
+ const j = readJSON(`${YQ}/scraper-contract-test-2026-06-16.json`);
+ if (j) board.push({ canary: 'scraper-contract', verdict: j.summary?.FAIL ? 'FAIL' : j.summary?.WARN ? 'WARN' : 'PASS',
+ headline: `${j.vendors} vendors · ${Object.entries(j.summary).map(([k,v])=>`${k}=${v}`).join(' ')}` });
+ else board.push({ canary: 'scraper-contract', verdict: 'UNKNOWN', headline: 'no output' });
+}
+
+// 4) dw-map-auditor — fast local DB (existing skill)
+run('bash', ['run.sh'], { cwd: `${HOME}/.claude/skills/dw-map-auditor` });
+{
+ const j = readJSON(`${HOME}/.claude/skills/dw-map-auditor/data/latest.json`);
+ if (j) board.push({ canary: 'dw-map-auditor', verdict: j.verdict, headline: `${j.fail||0} FAIL / ${j.warn||0} WARN (Kravet MAP + Nicolette)` });
+ else board.push({ canary: 'dw-map-auditor', verdict: 'UNKNOWN', headline: 'no output' });
+}
+
+// 5) cf-dns-snapshot — read latest report (ran this session; re-run is fast/read-only)
+run('node', ['scripts/cf-dns-snapshot/cf-dns-snapshot.js'], { timeout: 90000 });
+{
+ const snap = readJSON(`${PROJ}/scripts/cf-dns-snapshot/snapshots/cf-zones-latest.json`);
+ board.push({ canary: 'cf-dns-drift', verdict: snap ? 'PASS' : 'UNKNOWN',
+ headline: snap ? `${snap.zone_count} zones baseline (diff vs HEAD)` : 'no snapshot' });
+}
+
+// 6) dw-scraper-canary — NETWORK (storefront fetch); time-boxed, degrade to UNKNOWN
+const ok = run('node', ['canary.mjs'], { cwd: `${HOME}/.claude/skills/dw-scraper-canary`, timeout: 120000 });
+{
+ const j = readJSON(`${HOME}/.claude/skills/dw-scraper-canary/data/latest.json`);
+ if (j) board.push({ canary: 'dw-scraper-canary', verdict: j.verdict || (j.fail? 'FAIL':'PASS'), headline: 'output-side (public feed) count/leak/image' });
+ else board.push({ canary: 'dw-scraper-canary', verdict: ok ? 'PASS' : 'UNKNOWN', headline: ok ? 'ran (no latest.json schema)' : 'network/timeout — not a failure' });
+}
+
+const rank = { FAIL: 0, WARN: 1, UNKNOWN: 2, PASS: 3 };
+board.sort((a, b) => rank[a.verdict] - rank[b.verdict]);
+const counts = board.reduce((m, b) => (m[b.verdict] = (m[b.verdict]||0)+1, m), {});
+const overall = board.some(b => b.verdict === 'FAIL') ? 'FAIL' : board.some(b => b.verdict === 'WARN') ? 'WARN' : 'PASS';
+
+const report = { generated_at: new Date().toISOString(), overall, counts, canaries: board };
+fs.writeFileSync(OUT, JSON.stringify(report, null, 2));
+
+let md = `# DW Canary Board — ${new Date().toISOString().slice(0,16)}\n\n`;
+md += `**Overall: ${overall}** · ${Object.entries(counts).map(([k,v])=>`${k}=${v}`).join(' · ')} · ${board.length} canaries\n\n`;
+md += `| Canary | Verdict | Headline |\n|---|---|---|\n`;
+for (const b of board) md += `| ${b.canary} | ${{FAIL:'🔴',WARN:'🟠',UNKNOWN:'⚪',PASS:'🟢'}[b.verdict]} ${b.verdict} | ${b.headline} |\n`;
+md += `\n_All read-only. Built/aggregated by overnight loop cycle 16. $0._\n`;
+fs.writeFileSync(MD, md);
+
+console.log(`[canary-board] OVERALL ${overall} · ${Object.entries(counts).map(([k,v])=>`${k}=${v}`).join(' ')}`);
+for (const b of board) console.log(` ${{FAIL:'🔴',WARN:'🟠',UNKNOWN:'⚪',PASS:'🟢'}[b.verdict]} ${b.canary.padEnd(20)} ${b.headline}`);
+console.log(`Report: ${MD}`);
← 4d885e1 Banned-word body-leak scanner: exact cleanup list + strip pr
·
back to Dw Yolo Loop
·
DRAFT reactivation staging plan (report-only, tiered, batche 30e9dc1 →