**Phase 25 final verification pass** (all 3 tasks were already in `complete/`, so this was the phase-level verify + docs pass) **Verified** - `#nav-status` first child of `.masthead-right` on all 7 signed-in templates (incl. `/certs`, `/settings`); `app.js`/`charts.js` untouched - `#nav-status` + `.masthead-right` both `justify-content: flex-end`, `margin-inline-start` still absent, row-break (`flex-wrap` + two `flex-basis: 100%`), non-sticky bar, dropdown slide + 4 close paths, `setInterval(refreshStatus, 15000)` all intact (dash.css diff = comments + the two alignment values) - Clock is the last control on all 7 templates; no `order:` anywhere in the bar **Fixed (defects found in this pass)** - `tests/test_api.py::test_every_page_links_to_both_admin_pages` — duplicated `tabs = html[...]` statement (task 03 edit artifact) - `certs.html` / `settings.html` comments said "all **eight** signed-in pages"; the signed-in set is seven (`/login` is the eighth, anonymous, and has no links/clock) - `AGENTS.md` — suite tally `1542 → 1543 passed`; "the three phase-20 tests" re-worded, since task 02 renamed one to `test_the_masthead_is_three_rows_right_justified_at_every_width` **Results** - `uv run pytest` → **1543 passed, 15 skipped**, 0 failed - `bash .agents/validate.sh` → **exit 0**: coverage **98.94 %** (floor 94 %), `ruff` All checks passed, `pyright` 0 errors, `node --check` clean, hygiene clean - `uv run pytest -m live --live` (`.env.dev` sourced) → **11 passed**; `./scripts/dev-server.sh status` → 9/9 sources `ok` - Browser: `node data/logs/25-task03-verify.cjs` → **235 checks, 0 FAIL**, exit 0 (`data/logs/25-task03-verify.out`, 16 `masthead-25-*.png`) **Completion criteria**: badges pinned+measured (green `system/disks/llm/ups` on both admin pages, 1280 px and 360 px) ✅ · both rows flush right, three rows + dropdown unchanged (pinned + measured) ✅ · clock farthest-right (pinned markup; measured right edge 1260.0 at 1280 px, ≤900 px hidden by the long-standing readout rule with source order asserted) ✅ · pytest/coverage/ruff/pyright ✅ · validate.sh ✅ · no behaviour change in completed work ✅ **Docs**: README reviewed end-to-end against the code (served-route audit vs documented routes, env table vs `config.py`, commands vs `scripts/`, public-path table, `web/` masthead bullet) — consistent, no changes needed beyond the phase's own edits. AGENTS.md — two fixes above; spot-checked every doc-named test, function, script, threshold, `install-agent.sh` sha256 (`ffbcd91f…` matches) and agent version (1.1.0). **Deviations**: left the pre-existing `fastapi 0.153.0 → 0.159.0` advisory (validate prints it as advisory; no dependency work in scope, AGENTS rule 8 triggers on touching deps). No live-infra changes. Overview's "all eight signed-in pages" for the clock is verified against seven templates + `/login` (which has no clock, pinned). **Next pending phase**: `.agents/phases/todo/26_ups_event_split/` (3 tasks).
5.4 KiB
Phase 25 — Masthead control placement: badges everywhere, right-justified, clock rightmost
Source: TODO.md L3–L5 — "hosts disks engines UPS disappear when in the certs/account page" · "I made a mistake earlier, I did want hosts disks engines UPS badges and certs/account/dark right justified don the navbar" · "The time should show up as the farthest right item on the navbar"
Story: n/a
Context: phase 20 (complete) — the masthead is three rows at every width (row 1 brand + #nav-toggle + the five tabs, row 2 the #nav-status per-source dots, row 3 the .masthead-right controls), not sticky (position: relative, z-index: 40), with the ≤640px dropdown sliding on nav.tabs.is-open; phase 18 — the hamburger reveal through --nav-toggle-display. The dots are built by Dash.initChrome() in src/dashboards/web/static/app.js (the if (nav) block on #nav-status, one chip per system/disks/llm/ups dashboard from /api/health, refreshed every 15 s), and exist in the markup only of the five dashboard pages — certs.html and settings.html ship no #nav-status (the comment in settings.html says a session page "has no fleet reachability to report"), which is what L3 names. The served-CSS pins for the bar are in tests/test_api.py: test_the_masthead_is_three_left_justified_rows_at_every_width (the two justify-content: flex-start declarations, the two flex-basis: 100% row breaks, the min-height/gap), test_the_mobile_masthead_block_declares_no_second_bar_height, test_the_masthead_scrolls_away_and_stays_the_dropdown_anchor; the one-loop control-order audit is test_every_page_links_to_both_admin_pages (clock → ⚷ Certs → ⚙ Account → theme toggle on all eight signed-in pages), and the two pins that assert the admin pages have no dots are in test_the_settings_page_is_not_one_of_the_dashboards and test_the_certs_page_is_a_page_and_not_a_sixth_dashboard. tests/test_auth_api.py asserts /login carries no #nav-status — unchanged by this phase.
Objective
The four per-source badges (hosts · disks · engines · UPS) render on every page that renders the masthead — including /certs and /settings — and the two right-hand rows (the dots, the controls) are right-justified, with the clock the farthest-right item on the bar. The three-row shape at every width is preserved; only the alignment and the control order move, and the clock's position is what L5 asks for.
Dependencies
- — (none) — the phase builds on complete phase 20 and phase 18; it is scheduled first of the three appended phases on purpose, because the mobile audit phase (27) measures the masthead in the shape this phase leaves it in.
Tasks
01_status_dots_on_admin_pages.md—#nav-statuson/certsand/settings(markup only —initChromealready builds the dots when the container exists); the two no-dots pins flip to dots-present02_right_justify_masthead_rows.md—justify-content: flex-endon#nav-statusand.masthead-right, the comment block re-worded, the three-rows pin re-pinned to the new alignment03_clock_rightmost.md— the clock moves to the end of the control row on all eight signed-in pages; the one-loop order pin updated; the phase's real-browser verification (badges on the admin pages, both rows right-justified, clock rightmost, at 1280 px and 360 px)
Testing & Quality
- Unit/integration: the served-byte pins in
tests/test_api.py— the flipped admin-page pins (task 01), the re-pinned row-alignment pin (task 02), the updated control-order pin (task 03);tests/test_auth_api.py's/login-has-no-dots pin must stay green untouched - Coverage: >90% on new/modified code (the new code is the pins themselves; the change is CSS and template markup)
- Real-browser check (invariant 10): a
data/logs/25-task03-*.cjsscript in the20-task01-rows.cjsconvention, run against the restarted dev server at 1280 px and 360 px on all seven tabbed pages plus/login(unsigned), with screenshots indata/logs/
Documentation & Consistency
- The final pass updates the now-stale sentences in
AGENTS.md: "The masthead is three left-justified rows at every width" (alignment), "A page with no dots (/certs,/settings) renders two rows" (gone — all masthead pages carry the dots), "the two links therefore sit on all eight signed-in pages in one order (clock →⚷ Certs→⚙ Account→ theme toggle)" (new order:⚷ Certs→⚙ Account→ theme toggle → clock), and the "left-justified" wording in thedash.cssheader comment.README.mdis checked for the same sentences; none is expected.
Completion Criteria
/certsand/settingsrender the four badges, populated from/api/health(pinned + verified in a browser against the live dev fleet)- the dots row and the controls row are right-justified at every width; the three-row shape and the ≤640px dropdown are unchanged (pinned + measured in a browser)
- the clock is the farthest-right item on the bar on all eight signed-in pages (pinned + measured)
uv run pytestgreen, coverage not down,ruff+pyrightcleanbash .agents/validate.shgreen- no behavior change in completed work: the row-break mechanism (
flex-wrap+ the twoflex-basis: 100%), the non-sticky bar, the dropdown's slide and its four close paths, and the dots' refresh semantics are all untouched