From 4b0f53c4997f3cca55bce93a55de3fa73fa84ef3 Mon Sep 17 00:00:00 2001 From: ducoterra Date: Tue, 20 Oct 2026 10:37:30 -0400 Subject: [PATCH] chore(agent): phase roadmap from TODO.md, 2 phases Convert the two TODO items into append-mode phases (Protocol B): 18_nav_hamburger (TODO L3) and 19_ups_events_expandable (TODO L4), numbered after the existing todo phases. TODO.md is cleared to an empty list; its items now live in .agents/phases/todo/. LLM-Generated: true --- .../phases/todo/18_nav_hamburger/00_phase.md | 36 ++++++++++++ .../18_nav_hamburger/01_hamburger_markup.md | 31 +++++++++++ .../todo/18_nav_hamburger/02_dropdown_css.md | 29 ++++++++++ .../18_nav_hamburger/03_toggle_binding.md | 55 +++++++++++++++++++ .../04_tests_and_verification.md | 32 +++++++++++ .../todo/19_ups_events_expandable/00_phase.md | 36 ++++++++++++ .../01_events_disclosure.md | 40 ++++++++++++++ .../02_events_lazy_loading.md | 49 +++++++++++++++++ .../03_disclosure_css.md | 42 ++++++++++++++ .../04_tests_and_verification.md | 31 +++++++++++ TODO.md | 3 - 11 files changed, 381 insertions(+), 3 deletions(-) create mode 100644 .agents/phases/todo/18_nav_hamburger/00_phase.md create mode 100644 .agents/phases/todo/18_nav_hamburger/01_hamburger_markup.md create mode 100644 .agents/phases/todo/18_nav_hamburger/02_dropdown_css.md create mode 100644 .agents/phases/todo/18_nav_hamburger/03_toggle_binding.md create mode 100644 .agents/phases/todo/18_nav_hamburger/04_tests_and_verification.md create mode 100644 .agents/phases/todo/19_ups_events_expandable/00_phase.md create mode 100644 .agents/phases/todo/19_ups_events_expandable/01_events_disclosure.md create mode 100644 .agents/phases/todo/19_ups_events_expandable/02_events_lazy_loading.md create mode 100644 .agents/phases/todo/19_ups_events_expandable/03_disclosure_css.md create mode 100644 .agents/phases/todo/19_ups_events_expandable/04_tests_and_verification.md diff --git a/.agents/phases/todo/18_nav_hamburger/00_phase.md b/.agents/phases/todo/18_nav_hamburger/00_phase.md new file mode 100644 index 0000000..7143b88 --- /dev/null +++ b/.agents/phases/todo/18_nav_hamburger/00_phase.md @@ -0,0 +1,36 @@ +# Phase 18 — Collapse the nav bar into a hamburger + +**Source:** `TODO.md` L3 — "The nav bar needs to collapse into a hamburger like brain of reese does" +**Story:** n/a +**Context:** the seven mastheads that carry the tab nav — `src/dashboards/web/pages/{index,system,disks,llm,ups,settings,certs}.html` (each has `nav class="tabs" aria-label="Dashboards"` with the five dashboard links; `login.html` deliberately has no tabs — it renders only the brand link and the theme toggle, and stays untouched), `src/dashboards/web/static/app.js` (`Dash.initChrome()`, called from the one `DOMContentLoaded` at line 786 — the `themeButton`/`clock`/`nav-status` blocks there are the per-element `if (element)` no-op pattern this phase's binding follows), `src/dashboards/web/static/dash.css` (`.masthead` at line 95 — `position: sticky; z-index: 40; height: var(--header-h)`, `nav.tabs` at line 131, the existing `@media (max-width: 640px)` block at line 286, the `prefers-reduced-motion` block at line 938), and the reference implementation the TODO names — `brain_of_reese` (sibling repo, read-only): `frontend/assets/header.js` lines 326–366 (the phase-46 binding: `#nav-toggle` shown ≤640px, `setNavMenu(open)` funnel, close on link click / Esc with focus return / `matchMedia` resize-back). Pinned test neighbours: `tests/test_api.py::test_the_disks_tab_is_in_the_masthead_of_every_page` (line 3837) and the served-page orphan-`id` audit in `tests/test_auth_api.py` (line 1654) + +## Objective + +On viewports ≤640px the masthead's five tab links collapse into a dropdown opened by a hamburger button, mirroring brain of reese's phase-46 behaviour: one shared binding in `app.js` (a no-op on any page without the elements — `/login`), the inline nav hidden and the dropdown absolutely positioned under the sticky masthead, and the desktop masthead byte-identical in behaviour above the breakpoint. The `masthead-right` cluster stays visible on phones; only the tab nav collapses. + +## Dependencies +- — (none; builds on the shipped masthead, `initChrome`, and the 640px media block) + +## Tasks +1. `01_hamburger_markup.md` — the `#nav-toggle` button and the `nav` id, identical across the seven tabbed pages, absent from `/login` +2. `02_dropdown_css.md` — the ≤640px block: toggle visible, inline tabs hidden, `.is-open` dropdown under the masthead, two-row masthead +3. `03_toggle_binding.md` — the `initChrome` binding: toggle + `aria-expanded`, close on link click / Esc / resize-back +4. `04_tests_and_verification.md` — the pins (present on all seven, absent on `/login`, CSS and binding), the orphan-`id` audit, and the narrow-viewport browser verification with screenshots + +## Testing & Quality +- Unit/integration: `tests/test_api.py` — the served-page pins (see task 04); the existing masthead/tab pins (`test_the_disks_tab_is_in_the_masthead_of_every_page`, `test_every_page_links_to_both_admin_pages`) and the `tests/test_auth_api.py` orphan-`id` audit pass untouched — the new `id`s are referenced by `aria-controls`, the stylesheet, and `app.js`, so the audit must still clear +- Coverage: **>90%** on new/modified code (the phase is markup + CSS + one small JS binding; the coverage gate applies to the changed Python test files) +- The gate (`bash .agents/validate.sh`) includes `node --check` of `web/static` — the modified `app.js` must pass it + +## Documentation & Consistency + +- The final pass reviews `README.md` and `AGENTS.md` in full against the project as it stands after this phase — fixing every inconsistency found, **including pre-existing ones not caused by this phase**. +- AGENTS.md's `UI conventions` section gains the masthead-collapsing convention (the 640px breakpoint, the toggle's identity, the close paths, and that `/login` carries no toggle) so a future masthead edit knows the contract. The README's page table is unchanged — the nav is the same five links at every width. + +## Completion Criteria +- [ ] at ≤640px: the tab links are hidden, the hamburger is visible, and clicking it opens a dropdown containing the five links; above 640px the desktop masthead is unchanged +- [ ] the dropdown closes on link click, on Esc (focus returns to the button), and on resize back above 640px; `aria-expanded` tracks the state +- [ ] `uv run pytest` green, coverage not down, `ruff` + `pyright` clean +- [ ] `bash .agents/validate.sh` green (including `node --check` of the modified `app.js`) +- [ ] narrow-viewport screenshots (closed, open, and one desktop no-regression shot) in `data/logs/` against the running dev server (invariant 10) +- [ ] no behavior change in completed work: the desktop masthead and every page render identically at widths >640px diff --git a/.agents/phases/todo/18_nav_hamburger/01_hamburger_markup.md b/.agents/phases/todo/18_nav_hamburger/01_hamburger_markup.md new file mode 100644 index 0000000..25cf70b --- /dev/null +++ b/.agents/phases/todo/18_nav_hamburger/01_hamburger_markup.md @@ -0,0 +1,31 @@ +# Task 01 — The hamburger button markup + +**Phase:** `18_nav_hamburger` · **Source:** `TODO.md:3` — "The nav bar needs to collapse into a hamburger like brain of reese does" +**Story:** n/a + +## Objective + +The seven pages that carry the tab nav each gain the hamburger button and the `nav` id, so the (later task's) CSS and binding have stable anchors to work on. The markup is identical on every page, and `/login` — which deliberately renders only the brand link and the theme toggle — stays untouched. + +## Work + +1. `src/dashboards/web/pages/index.html` · `system.html` · `disks.html` · `llm.html` · `ups.html` · `settings.html` · `certs.html` — in each masthead, immediately before `nav class="tabs"`, add the toggle: + ```html + + ``` + and give the nav its id: `