All in-repo path references (AGENTS.md, README, old scripts, report artifacts,
test code paths) rewritten in the same commit; focused-test map extended for
.gitignore, old/scripts/*, dankclaw/comfyui/*, and report/* per this repo's
own convention ('add one before committing'). Obsidian wikilinks are
title-based and unaffected.
6.0 KiB
Homepage Design Grilling
The decision log for the homepage design. All questions are settled (2026-08-23). This page records the final decisions and the places where the operator's answer changed the initial recommendation.
Final decisions
| # | Decision | Value |
|---|---|---|
| Q1 | How the page learns up/down | Server-side checker writes status.json; the page reads only that file. (Documented future intent: client-side probing.) |
| Q2 | How the checker runs | systemd timer, rewrites status.json every 3 minutes. |
| Q3 | Page model | Single site on Dankclaw. Root = user services (no host labels). /admin/ = admin services, second operator-only password. |
| Q5 | Service split | User: SearXNG, ComfyUI, OpenWebUI, Gitea, Calibre-Web, RomM, Copyparty, Plex, Jellyfin. Admin: Hermes, Grafana, Prometheus, Loki, Caddy, dnsmasq, Gluetun, LLM fleet, low-level backends (status-only). The *arr stack is excluded. |
| Q6 | Tourist /how/ page |
Defer — it is extra. |
| Q7 | status.json |
One file; each service carries a category field; each page filters. |
| Q8 | services.json |
One file with a category field. |
| Q9 | Checker language | python3. |
| Q10 | Probe method | Per service — tcp or http, set per entry. |
| Q11 | Probe timeout | 5 s per service. |
| Q12 | LLM loading | Three states; a listening port is Up (health 503 = Up). |
| Q13 | Checker location | scripts/homepage-status.py + .service + .timer, tracked in git. |
| Q14 | Reach backends | probe = full host:port (127.0.0.1:PORT or 192.168.0.235:PORT). |
| Q15 | WIP | static "wip": true; the checker skips the probe. |
| Q16 | Staleness | generated_at in status.json; the page warns when it is older than 10 min. |
| Q17 | Writes | atomic (write a temp file, then rename). |
| Q18 | Admin password | CADDY_ADMIN_HASH in the host .env (git-ignored), operator-only. |
| Q19 | Per-path basicauth | @admin path /admin/* with a second basicauth block. |
| Q20 | Descriptions | hand-written one-liners in services.json. |
| Q21 | Open link | the Caddy site URL; status-only backends set showLink: false. |
| Q22 | Docs link | a per-service /docs/ page. Do NOT link the existing reference docs (they may contain secrets). |
| Q23 | Layout | TUI-style cards/panels (a grid of panels), not a flat list. |
| Q24 | Summary line | yes — a placeholder for now; refine later. |
| Q25 | Terminus | bundle the font (woff2) + a monospace fallback. |
| Q26 | Palette | as proposed (green #33ff66, red #ff5555, amber #ffcc33, cyan #33ccff, bg #050805). |
| Q27 | Styling | toggleable: default = full theme; a toggle strips to bare unstyled HTML (motherfuckingwebsite.com style). |
| Q28 | Cursor | do not alter the user's cursor. |
| Q29 | Docs content | how a regular user uses the service; no maintenance details. |
| Q30 | Docs path | /docs/<svc>/ (not /usage/). |
| Q31 | Docs auth | the same auth as the homepage section (user docs = shared password, admin docs = admin password). |
| Q32 | Docs workstream | a separate effort; built as each service goes active. |
| Q33 | Deploy | git-driven; master always reflects the deployed state. |
| Q34 | /srv/homepage/ |
deploy.sh creates it and copies the assets. |
| Q35 | Timer | enabled at boot. |
| Q36 | Checker tests | full TDD. |
| Q37 | Page/config tests | full TDD. |
| Q38 | Security test | full TDD. |
| Q39 | Backend move | a config edit (probe host:port). |
| Q40 | LAN timeout | 5 s. |
| Q41 | Auto-refresh | no — the page reads status.json once on load. |
| Q42 | Mobile | responsive. |
| Q43 | Footer timestamp | last master deployment datetime (not last-check). |
Styling (settled): terminal TUI, Terminus (monospace fallback), green-on-black, 1995 phosphor palette. Default = full theme; a toggle strips to bare unstyled HTML. Do not alter the user's cursor.
Where the operator changed the recommendation
These are the deltas from the initial recommendations. Everything else was accepted as recommended.
- Q10 — the probe method is per service (
tcporhttp), not TCP-only. - Q11 / Q40 — the probe timeout is 5 s (not 3 s).
- Q22 — the docs link points to a per-service
/docs/page, never the existing reference docs (they may contain secrets). - Q23 — the layout is TUI-style cards/panels, not a flat list.
- Q27 — styling is toggleable: the full theme by default, with a toggle to bare unstyled HTML.
- Q28 — do not alter the user's cursor (no fake blinking cursor).
- Q29 — the docs are user-facing only; no maintenance details.
- Q30 — the docs path is
/docs/(not/usage/). - Q31 — the docs use the same auth as the homepage section.
- Q33 — git-driven; master always reflects the deployed state.
- Q36–Q38 — full TDD.
- Q41 — no client-side auto-refresh.
- Q43 — the footer shows the last master deployment datetime (not last-check).
Build status — complete (2026-08-23)
The build is done, slice by slice, full TDD (each slice red → green, committed and pushed). 116 tests pass. The render logic is verified with a Node DOM shim.
flowchart LR
A[write the checker tests] --> B[write the checker]
B --> C[write services.json]
C --> D[write the pages + theme + toggle]
D --> E[extend deploy.sh + Caddyfile]
E --> F[tests green]
F --> G[deploy to Dankclaw]
G --> H[verify in browser]
Slices: 1 the checker core (tcp/wip/atomic/generated_at), 2 the http probe, 3
the real services.json + schema, 4 the pages + theme + toggle, 5 the Caddyfile
auth split, 6 the git-driven deploy (both hashes, deployed.js, the timer).
Remaining to go live: the operator adds CADDY_ADMIN_HASH (the
operator-only password, caddy hash-password) to the target .env, then runs
./scripts/deploy.sh dankclaw. Until then the admin hash stays a placeholder.
The per-service docs pages (Q22/Q29/Q30/Q31) are a separate workstream, built as each service goes active.