{"slug":"doing-viewer","total":19,"limit":100,"offset":0,"since":null,"commits":[{"hash":"ce5ba32","date":"2026-09-14 01:06:24 -0700","author":"Steve Abrams","subject":"5x: record honest cross-browser outcome — chromium+Chrome+HTTP+render green; webkit/firefox blocked by playwright engine-build version churn (tooling, not a build defect)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"961d840","date":"2026-09-14 00:42:05 -0700","author":"Steve Abrams","subject":"5x: REPORT.md — fold in contrarian FIX FIRST round (false-green + money-endpoint verified, framing corrected)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_017Yk9ehSqj2L4frMztZNM2j"},{"hash":"04dd24f","date":"2026-09-14 00:35:45 -0700","author":"Steve Abrams","subject":"5x/contrarian FIX FIRST: make exit code honest — transient source-down exits 0, SUSTAINED (>=10m) exits 1","body":"Cody caught that commit 3fad9e6 cited cron-fire-canary's artifact-freshness as\nthe safety net for its silent exit-0, but the job is manifest-flagged\nartifact_weak (publish.log is StandardOutPath AND StandardErrorPath, refreshed\nby a console line on EVERY tick regardless of outcome) — so the canary trusts\nthe launchd EXIT CODE for this job, and a blanket exit-0 made a SUSTAINED\nsource outage invisible (TK-11431 false-green).\n\nFix: track continuous source-down duration across launchd runs via\ndata/source-down-since.json. Exit 0 only while inside a 10-min self-heal grace\n(transient pm2 restart), exit 1 once the outage is sustained so the canary\ngenuinely warns. Success/recovery clears the state. A real publish-path failure\n(source up but rsync/JSON fails) still exits 1.\n\nVerified: success->0+clear; first-down->0+record; sustained(20m)->1;\nrecovery->0+clear; source-up-but-garbage->1.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_017Yk9ehSqj2L4frMztZNM2j"},{"hash":"234c987","date":"2026-09-14 00:27:54 -0700","author":"Steve Abrams","subject":"5x: REPORT.md — clean twice (favicon 404 fixed)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_017Yk9ehSqj2L4frMztZNM2j"},{"hash":"ea854b7","date":"2026-09-14 00:25:42 -0700","author":"Steve Abrams","subject":"5x sweep 1: /favicon.ico -> 204 (was 404, console error on every load)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_017Yk9ehSqj2L4frMztZNM2j"},{"hash":"3fad9e6","date":"2026-09-14 00:16:19 -0700","author":"Steve Abrams","subject":"TK-11446: exit 0 (not 1) when doing-viewer source :9790 is transiently down","body":"The canary reopened TK-11446 with a NEW failure mode the earlier timeout-retry\nfix (9033cbe) didn't cover: connect ECONNREFUSED 127.0.0.1:9790. When the\ndoing-viewer source pm2 server is transiently down (e.g. a pm2 thundering-herd\nrestart, TK-11688), publish-snapshot.js exit-1'd every 180s tick, flapping\ncron-fire-canary. That is a dependency outage, not a failure of this cron job's\nown logic — and it is self-healing (keep-alive restarts the process; a LONG\noutage makes the Kamatera snapshot go stale, which cron-fire-canary catches via\nits primary artifact-freshness signal).\n\nClassify connection-level source-down (ECONNREFUSED/ECONNRESET/ENOTFOUND/\nEHOSTUNREACH) distinctly and exit 0 + WARN after a retry. A summarizer timeout,\nmalformed JSON (source up but broken), or a rsync-to-Kamatera failure still\nexit 1 so a real publish-path problem genuinely warns — no false green.\n\nVerified: source-up->exit0+published; source-down->exit0+WARN; source-up-but-\ngarbage->exit1.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_017Yk9ehSqj2L4frMztZNM2j"},{"hash":"9033cbe","date":"2026-09-12 23:31:59 -0700","author":"Steve Abrams","subject":"TK-11446: make doing-viewer publish resilient to transient timeouts (retry once, bump local fetch to 30s)","body":"Root cause: getLocal() fetch of the local board occasionally exceeded its 20s\ntimeout while computing summaries for ~56 doing tickets, throwing 'timeout' and\ncrashing an otherwise-healthy 180s run — cron-fire-canary flapped warn/recovered.\nNow retries once with 5s backoff before exiting non-zero; a sustained failure\nstill exits 1 so the canary genuinely warns. Verified: success->exit0, dead\nendpoint->retry->exit1.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01M7Y6Sqsc2PzELRH1a3g4oy"},{"hash":"311bd4d","date":"2026-08-25 10:48:55 -0700","author":"Steve","subject":"creds-safe fetch guard: resolve relative fetch vs credential-free location (creds-in-URL trap)","body":"Fleet inoculation — opening this basic-auth app with credentials in the URL\npoisoned document.baseURI and made relative fetch('/api/…') throw. Guard resolves\nnon-absolute request URLs against location instead. Ref: creds-in-url-fetch-guard-fleet-pattern.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"5fb10ff","date":"2026-08-20 14:09:17 -0700","author":"Steve Abrams","subject":"5x: fix dead view-only Restart/Nudge buttons over public tunnel — every button now responds; security gate unchanged","body":""},{"hash":"bbe853b","date":"2026-08-20 13:25:45 -0700","author":"Steve","subject":"chore: untrack auto-generated data/snapshot.json (stop commit churn) — session close","body":""},{"hash":"4b326d6","date":"2026-08-20 13:01:19 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-20T13:00:52 (1 data files) — data/snapshot.json","body":""},{"hash":"76a7418","date":"2026-08-20 12:55:33 -0700","author":"Steve","subject":"doing-viewer: owner-cookie unlock — keep public URL live but route actions to owner device","body":""},{"hash":"5e55b38","date":"2026-08-20 12:37:26 -0700","author":"Steve","subject":"doing-viewer: remove per-card scroll trap (clamp+more toggle), smooth page scroll","body":""},{"hash":"4688fc8","date":"2026-08-20 12:36:02 -0700","author":"Steve","subject":"doing-viewer: lock actions to localhost/LAN (CF-header + private-IP gate); public + mirror are view-only","body":""},{"hash":"b7399f9","date":"2026-08-20 12:33:43 -0700","author":"Steve","subject":"doing-viewer: col 4 active buttons — Restart/Nudge launch run-ticket.sh (guarded, logged); mirror read-only","body":""},{"hash":"802a86f","date":"2026-08-20 12:30:12 -0700","author":"Steve","subject":"doing-viewer: col 4 — why-slow + restart verdict (age + last-action + pm2 liveness)","body":""},{"hash":"72f6ce7","date":"2026-08-20 12:25:20 -0700","author":"Steve","subject":"doing-viewer: Kamatera mirror (snapshot publish + mirror server + 3min launchd sync)","body":""},{"hash":"4e2d1e3","date":"2026-08-20 12:15:38 -0700","author":"Steve","subject":"doing-viewer: add Basic Auth (admin/DW2024!) gate","body":""},{"hash":"b2a0530","date":"2026-08-20 12:08:55 -0700","author":"Steve","subject":"doing-viewer: live 3-column board (doing / what it's doing / plain words via local qwen3)","body":""}]}