Files
ducoterra c43a088ce8 phase: 04_controller_page_responsive
**Final verification pass** (all three task reports PASS; tasks already in `complete/`). One real defect found and fixed.

**Commands / results.** `bash tests/run_tests.sh` → `RESULT: all suites passed`, **5 104** checks (page **220**). `SANITIZE=1 bash tests/run_tests.sh` → passed. `bash .agents/validate.sh` → `validation OK`; bridge/console/rollback `SUCCESS`; `page bytes: 59262`; `README/AGENTS claims: OK`; `repo hygiene: OK`. Real-browser leg (headless Chromium, served assembled bytes): no horizontal scroll at 360/390/768/1440, ARM first-in-`main` and sticky, log height-capped, all 5 folds openable, all 3 changed page statements execute.

**Fix.** The folded notes' `<summary>` — the only route to five pinned safety sentences — rendered **17 px** on coarse pointers, under the page's own 44 px thumb floor, while every byte-level assertion stayed green. `src/web_page.h`: `button.k,.pill,input,summary{min-height:44px}` + `summary{padding:13px 0}`; `tests/test_page.js` +1 check (219→220); mutation-tested (reverting the CSS fails host *and* browser legs, then restored byte-for-byte).

**Criteria.** 1 ✓ browser-measured (physical phone still unobserved). 2 ✓ 220 checks + prose untouched. 3 ✓ page 59 286→**59 262 B** (−24 vs phase start), README = gate figure. 4 ✓ one `test_page` row at 220, intro 5 104 = measured. 5 ✓ gate green; phases 01–03 assertions unchanged apart from the re-pinned byte constant.

**Docs.** Re-pinned 59 262 (README, `config.h`, `test_conn.cpp`), totals 5 103→5 104, README Tests row 220; re-measured footprint rows (flash 1 257 901 / 1 178 141 / 1 157 593, TLS +6 176/+100 308); fixed stale "48 KB"/"~50 KB" (×4 src comments, ×2 README) and the 51 626-byte page-delivery row; added **bug 14** with root cause and renamed *Thirteen*→*Fourteen bugs* in README + AGENTS.md's two stale references; added the Phase 04 browser+device row to `.agents/HW_VERIFICATION.md`.

**Deviations.** Device leg stays open: live board serves 51 626 B (pre-phase image); no reflash attempted, per the standing no-unattended-reflash rule — no byte-equality claim made. `ruff check tools tests`: 29 findings, identical at HEAD and `--isolated`, `E9,F` clean, no repo lint config or gate step → left untouched. `.agents/validate.sh` is **untracked and has never been committed** (`git log --all --` empty) though README/AGENTS/PLAN cite it 13× — harness needs `git add` it; I did not stage anything.
2026-11-09 11:00:27 -05:00

3.9 KiB
Raw Permalink Blame History

Phase 04 — The controller page: less to read, works on a phone

Source: TODO.md L4 — "Clean up keyrelay interface, don't need as much text, make it responsive" Story: n/a Context: src/web_page.h (markup + <style> + script), tests/test_page.js, README "Controller page"; AGENTS.md "The page is served from flash"

Objective

Reorganise the page so the controls are the thing you see: single column and thumb-sized on a phone, unchanged on a laptop, and the explanatory prose folded away to where it is asked for instead of sitting between the operator and the ARM button. No safety statement gets weaker or shorter — they move, they do not shrink, and each one gets a test that fails if it disappears.

Why the prose is load-bearing anyway

Every long hint in this page exists because someone got hurt without it: the arming banner (Enter goes to another machine), the Esc-frees-the-pointer note (Pointer Lock is invisible), the layout caveat (characters are positions), the KDE paragraph (those three buttons are the laptop's until the board steals them). Trimming them is the right call for usability and the wrong call for safety unless the trimming is pinned. So this phase writes the assertions before it deletes the sentences.

Dependencies

  • 03_session_takeover (todo) — its TAKE OVER affordance and the tls pill/fingerprint line are new elements in the same markup; folding prose around them is easier once they exist, and the id-coverage check has to be updated once.

Tasks

  1. 01_responsive_layout.md — CSS and viewport only: breakpoints, thumb-sized targets, sticky ARM bar, safe-area insets, collapsed log; no markup restructure, no id changes.
  2. 02_prose_trim_pinned.md — the safety assertions first, then the fold: long hints into <details>, the footer shortened, the connection/mouse/paste paragraphs cut to one line each with the reasoning one tap away.
  3. 03_suite_size_and_docs.md — test_page.js extended for the new structure, the README's page-size claim and its duplicated test_page row corrected, totals made to agree, and the curl byte check re-derived.

Testing & Quality

  • tests/test_page.js is the only thing that can see this page before a browser does (AGENTS.md: a raw string is invisible to every compiler). It must cover, in addition to what it covers today:
    • safety strings still present: the arming warning names Enter and "every key"; the mouse hint names Esc and release; the paste hint names "stop typing"/disarm cancelling a run; the layout note says positions/US layout; the default-passphrase shout still exists.
    • every element id the script reaches for exists in the markup (existing rule, re-verified after the restructure);
    • the pinned page constants (TEXT_FRAME_MAX, TEXT_JOB_MAX) still equal config.h;
    • the script still behaves identically: arming, state frames, paste chunking, mouse capture/movement/button ordering, E12.
  • Coverage >90% on the page script's changed branches; CSS is checked by assertions on the served bytes (breakpoints present, sticky ARM bar) plus a phone observation.
  • Device (best effort, one attempt): curl -sk https://keyrelay.local/ | wc -c equals the byte count the gate prints, and a phone shows one column with the ARM bar reachable and the log not pushing it off screen.

Completion Criteria

  • The page works at 360 px wide and at 1440 px wide without horizontal scroll, ARM is reachable with a thumb, and the log is collapsible.
  • Every safety statement above is still on the page and asserted by test_page.js.
  • The page is smaller in bytes than it is today, and README's size claim matches.
  • README Tests table has one test_page row with the real count (the duplicate stale row at 47 checks is removed), and the intro's total check count matches the suite output.
  • bash .agents/validate.sh green; no behaviour change in phases 01–03.