--- name: homepage-theme-smoke description: "Locally smoke-test the Dankclaw homepage theme (style.css/app.js/docs.html) in the managed headless browser, with the stale-server traps that fake the result." --- Goal: prove a homepage theme change on a throwaway tree before commit/deploy. Protocol: 1. Stage a fresh copy: `cp -r shared/homepage/. /tmp/hp-smoke-/`, drop `.AGENTTRASH` dirs, and write a fake `status.json` (`{"generated_at":"x","services":[{"name":...,"state":"up"}]}`) — app.js fetches services.json + status.json and renders NOTHING without both. 2. Serve: `cd && nohup python3 -m http.server 8099 --bind 127.0.0.1 &`. 3. STALE-LISTENER TRAP (fakes every census): a survivor server from an older wave keeps answering on 8099 — `ss -ltn | grep 8099` proves a listener exists, not WHICH tree it serves. After every (re)start verify identity: `for p in $(pgrep -f "http.server 8099"); do readlink /proc/$p/cwd; done` must print the NEW tree; then `curl -s localhost:8099/ | grep -c `. `kill` the stale pid — never trust a `||`-guarded restart. Also: `pkill -f "http.server 8099"` from a shell whose own command line contains that string kills the shell; kill by pid. 4. Browser census: navigate with `?v=` cache-bust (browser disk-caches http.server responses); `waitForSelector('.mi-card', ...)` before evaluating — rendering is async (fetch). Geometry checks: rect-gap to 1px for bottom-pinned chips; screenshot for visual proof. `screenshot({path})` may not write — use the returned omp-sshots artifact. 5. In headless pages `new Audio()` is detached: prove voice playback via `tab.requests()` (206 on the /sfx file) + the `mi-speaking` class, not a DOM `