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.
This commit is contained in:
2026-11-09 11:00:27 -05:00
parent d629a0ff51
commit c43a088ce8
30 changed files with 1600 additions and 214 deletions
+4 -4
View File
@@ -67,7 +67,7 @@ namespace {
// tests/test_relayctl.py ("the page the transport sends"). The page carries one
// 19-byte #if KR_TLS build marker and both spellings are the same length, so this
// number is build-independent -- a fact test_relayctl pins, not a hope.
constexpr size_t kServedPageBytes = 59286;
constexpr size_t kServedPageBytes = 59262;
/** The pump's shape, without a socket: hand out chunks, accept what a peer takes. */
struct DrainLog {
@@ -311,10 +311,10 @@ int main() {
CHECK_EQ(fs.sent(), 20);
CASE("flash send: the real page, on the real budget");
// 59 286 bytes (the count .agents/validate.sh prints) through kPageChunkBytes per write
// 59 262 bytes (the count .agents/validate.sh prints) through kPageChunkBytes per write
// and kPageBytesPerTick per tick: the exact numbers the device check compares against.
{
// A stand-in of the served page's size (59 286 B, the `page bytes:` line the gate
// A stand-in of the served page's size (59 262 B, the `page bytes:` line the gate
// prints). tests/test_relayctl.py pins this constant against the raw string in
// src/web_page.h, so if the page changes and this number does not, a check fails --
// the same "test the table" rule as the mouse bits and the evdev codes.
@@ -342,7 +342,7 @@ int main() {
CHECK_EQ(total, sizeof(big));
CHECK(worstPiece <= kPageChunkBytes);
CHECK(worstTick <= kPageBytesPerTick);
// 59 286 / 1460 = 41 chunks; / 5840 per tick = 11 ticks. If either number changes in
// 59 262 / 1460 = 41 chunks; / 5840 per tick = 11 ticks. If either number changes in
// config.h this line moves, and the report has to move with it.
CHECK_EQ((sizeof(big) + kPageBytesPerTick - 1) / kPageBytesPerTick, 11);
CHECK_EQ((sizeof(big) + kPageChunkBytes - 1) / kPageChunkBytes, 41);