Repository navigation
Description
Problem (observed in source + live sizes, 2026-10-27)
The three highest-traffic pages — / (board), /today, /attention — are shells (#1444): the server returns nav + a skeleton ("Loading the board…", "Loading today…") and the real content streams in as a Datastar fragment (data-on-load="@get('/frag/…')"). The only fallback in the shell markup is a <noscript> meta-refresh to ?full=1.
There is no error or timeout path: src/render.ts / src/server.ts contain no fragment error handling at all (verified by grep — no data-on-error, no watchdog). If the fragment request fails or stalls — tailnet hiccup, server busy (full renders measured today at 2.36 MB for the board and 3.53 MB for attention), a wedged source — the page sits on its skeleton indefinitely: no message, no retry affordance, no link through to the full render. To the reader that is indistinguishable from "the dashboard doesn't load", and it is a plausible contributor to exactly that report that is not a data problem.
Design
A shell-side watchdog, no protocol change: if the fragment has not replaced the skeleton within ~10 s, the skeleton is swapped for an inline notice — the live view didn't arrive — <a href="?full=1">load the full page</a> — implemented in the shell's own inline script / Datastar error hooks. The ?full=1 server render already exists and is the no-JS path; this just gives the JS path a way to reach it when the fragment dies.
Acceptance
- With
/frag/*requests blocked, each of/,/today,/attentionshows the notice with a working full-page link within the time bound. - Normal path unchanged: when the fragment lands, no notice ever appears.
?full=1renders are untouched.
Related: #1444 (introduced the shells), #1179 (fragment weight — the stall risk grows with it).
Activity
developing-today commentedon Oct 27, 2026
CODE-568
dezren39 commentedon Oct 27, 2026
Intake review
Related: #1444 (shells), #1179 (fragment weight). Liveness: no merged PR adds fragment error handling — checked merged aggregator PRs through 2026-10-27 (#1434, #1330 latest); issue is live. Its
## Acceptancesection is a full criteria set in substance, so no duplicate section was appended.Notes / risks / suggested approach: Risk: watchdog must never fire on the normal path (slow-but-live fragments on a busy server) — the time bound and the fragment-replaced check are the delicate parts. Suggested approach: shell inline script / Datastar error hooks only, no protocol change, exactly as designed; test with
/frag/*blocked per page.🤖 Agent note · filed
/,/today,/attention) spin forever when the Datastar fragment stalls/fails; add a ~10s shell-side watchdog swapping the skeleton for a notice linking?full=1.dezren39 commentedon Nov 1, 2026
🤖 Agent note · picked up
4 remaining items
dezren39 commentedon Nov 1, 2026
🤖 Agent note · picked up
dezren39 commentedon Nov 1, 2026
🤖 Agent note · blocked — packet defect
origin/maineb226be58,server.ts:671-673servesrenderBoard(...)directly for/board; it has no shell/full?full=1branch.renderBoardShell()exists atrender.ts:1689but is unused;/frag/boardis only a fragment endpoint. The packet requires a/boardwatchdog and working/board?full=1link, so this is more than the stated watchdog-only change./boardshould become a shell with?full=1preserving the full render, or whether acceptance is limited to the active shell routes. No source edits were made.developing-today commentedon Nov 3, 2026
agent-note:v1
state: reviewed (coverage loop-back)
Coverage pass 2026-11-03, loop-back review: this issue was re-reviewed (drift / overlap / already-handled / stale / blockers / ordering) so every open issue in the four repos is reviewed and in the system. Verdict: still live; in the system as task 5019 (small_fix, blocked, priority 50) in repo-health-code-pilot. Labels audited and synced. If it is already handled at current main, its triage closes it with evidence; if oversized, the triage files the split; blockers belong on this issue.
Found via: coverage loop-back 2026-11-03