diff --git a/.agents/phases/todo/25_masthead_control_placement/00_phase.md b/.agents/phases/todo/25_masthead_control_placement/00_phase.md
new file mode 100644
index 0000000..9641736
--- /dev/null
+++ b/.agents/phases/todo/25_masthead_control_placement/00_phase.md
@@ -0,0 +1,34 @@
+# 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
+1. `01_status_dots_on_admin_pages.md` — `#nav-status` on `/certs` and `/settings` (markup only — `initChrome` already builds the dots when the container exists); the two no-dots pins flip to dots-present
+2. `02_right_justify_masthead_rows.md` — `justify-content: flex-end` on `#nav-status` and `.masthead-right`, the comment block re-worded, the three-rows pin re-pinned to the new alignment
+3. `03_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-*.cjs` script in the `20-task01-rows.cjs` convention, run against the restarted dev server at 1280 px and 360 px on all seven tabbed pages plus `/login` (unsigned), with screenshots in `data/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 the `dash.css` header comment. `README.md` is checked for the same sentences; none is expected.
+
+## Completion Criteria
+- [ ] `/certs` and `/settings` render 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 pytest` green, coverage not down, `ruff` + `pyright` clean
+- [ ] `bash .agents/validate.sh` green
+- [ ] no behavior change in completed work: the row-break mechanism (`flex-wrap` + the two `flex-basis: 100%`), the non-sticky bar, the dropdown's slide and its four close paths, and the dots' refresh semantics are all untouched
diff --git a/.agents/phases/todo/25_masthead_control_placement/01_status_dots_on_admin_pages.md b/.agents/phases/todo/25_masthead_control_placement/01_status_dots_on_admin_pages.md
new file mode 100644
index 0000000..64f8756
--- /dev/null
+++ b/.agents/phases/todo/25_masthead_control_placement/01_status_dots_on_admin_pages.md
@@ -0,0 +1,27 @@
+# Task 01 — The badges render on the admin pages too
+
+**Phase:** `25_masthead_control_placement` · **Source:** `TODO.md:3–4` — "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"
+**Story:** n/a
+
+## Objective
+
+`#nav-status` exists in the `.masthead-right` of `/certs` and `/settings`, exactly as it does in the five dashboard pages, so `Dash.initChrome()` builds the four badges (`hosts`/`disks`/`engines`/`UPS`) there without any change to `app.js` — the "disappear when in the certs/account page" symptom is the missing container, and the fix is the container.
+
+## Work
+
+1. `src/dashboards/web/pages/certs.html` — add `
` as the **first** child of `
` (before the ``), the same position the five dashboard pages use (`index.html:23` is the reference).
+2. `src/dashboards/web/pages/settings.html` — the same addition, and delete the `` comment — the premise it states is what the operator overruled (the badges report the fleet, and the fleet is the point of the site, on every page).
+3. `src/dashboards/web/static/app.js` — **no change** (stated so the executor does not "improve" it): `initChrome()`'s `if (nav)` block already builds the four chips and refreshes them from `/api/health` every 15 s whenever `#nav-status` exists; `setDot`'s `idle` state already covers a dashboard the page's config does not run.
+4. `tests/test_api.py` — flip the two pins, one assertion each: in `test_the_settings_page_is_not_one_of_the_dashboards`, `assert 'id="nav-status"' not in html` becomes `in html` (message re-worded: the session page grew the badges the operator asked for); in `test_the_certs_page_is_a_page_and_not_a_sixth_dashboard`, the same flip, and the docstring sentence "no `#nav-status` (a CA page has no fleet reachability to report)" is re-worded to the new fact. `test_the_certs_page_is_a_page_and_not_a_sixth_dashboard`'s other assertions (zero `aria-current`, the tab strip, the head) are untouched, and `tests/test_auth_api.py`'s assertion that **`/login`** has no `#nav-status` is untouched — `/login` still renders the brand link and the theme toggle only.
+
+## Testing & Quality
+- Unit/integration: the two flipped pins above; `test_the_header_status_dot_picks_up_the_disks_job` and `test_the_disks_tab_is_in_the_masthead_of_every_page` stay green unchanged
+- Coverage: **>90%** on this task's new/modified code (markup + pins)
+- The badges populating on the two admin pages is the phase's real-browser check (task 03), run against the live dev fleet so the dots are `ok` green, not grey `idle`
+
+## Completion Criteria
+- [ ] `GET /certs` and `GET /settings` (signed in) both contain `
` as the first child of `.masthead-right` (pinned)
+- [ ] in a browser, both admin pages show the four badges and they answer the same `ok`/`warn`/`fail` state the dashboard pages show (measured, screenshots in `data/logs/`)
+- [ ] `/login` (unsigned) still carries no `#nav-status` (`tests/test_auth_api.py` green)
+- [ ] `uv run pytest` green, `ruff` + `pyright` clean
+- [ ] no behavior change in completed work: `initChrome` is byte-identical, and the badge refresh cadence and `idle` semantics are untouched
diff --git a/.agents/phases/todo/25_masthead_control_placement/02_right_justify_masthead_rows.md b/.agents/phases/todo/25_masthead_control_placement/02_right_justify_masthead_rows.md
new file mode 100644
index 0000000..ac28202
--- /dev/null
+++ b/.agents/phases/todo/25_masthead_control_placement/02_right_justify_masthead_rows.md
@@ -0,0 +1,29 @@
+# Task 02 — The dots row and the controls row are right-justified
+
+**Phase:** `25_masthead_control_placement` · **Source:** `TODO.md:4` — "I made a mistake earlier, I did want hosts disks engines UPS badges and certs/account/dark right justified don the navbar"
+**Story:** n/a
+
+## Objective
+
+Phase 20 task 01 made the two right-hand rows of the masthead flush left; this task moves them flush **right**. The mechanism is two declarations — `justify-content: flex-end` on `#nav-status` and on `.masthead-right` — and nothing else: the row breaks (the two `flex-basis: 100%` items inside the `flex-wrap: wrap` bar), the `min-height`, the gaps and the ≤640px block all stay exactly as they are, so the bar is still three rows at every width and the phone's wrapped control row still wraps *within itself*.
+
+- ASSUMPTION: the three-row shape is preserved at every width and only the alignment changes. A return to the old single-row bar is not the ask — the row breaks are what make the bar fit at 360 px (phase 18/20 measured that), and the operator's word is "right justified in the navbar", not "one row".
+
+## Work
+
+1. `src/dashboards/web/static/dash.css` — two declarations: `#nav-status`'s `justify-content: flex-start` becomes `flex-end`, and `.masthead-right`'s `justify-content: flex-start` becomes `flex-end`. `margin-inline-start: auto` stays **absent** from `.masthead-right` (the old single-row right-pinning is gone; `flex-end` on a full-basis row is the alignment now).
+2. `src/dashboards/web/static/dash.css` — re-word the comments that state the old alignment, so a future reader is not sent to a left-justified bar that no longer exists: the header comment block (the "three left-justified rows at every width" sentence, and its row-2/row-3 descriptions), the `Row 3:` comment above `.masthead-right` (which currently cites the old `TODO.md` word for `flex-start` — the new sentence states the operator overruled it: the badges and the cluster are right-justified), the `Row 2:` comment above `#nav-status`, and the ≤640px block's comment "Row 3 alignment is the base rule's `flex-start`, restated nowhere" (now `flex-end`). The `#nav-toggle { margin-inline-start: auto }` line in the mobile block is **unchanged**: the hamburger sits at the right of row 1 (brand + toggle + tabs), which is where a phone's thumb already is — it was never part of the right-justified cluster.
+3. `tests/test_api.py` — rename `test_the_masthead_is_three_left_justified_rows_at_every_width` to `test_the_masthead_is_three_rows_right_justified_at_every_width` and change its two alignment assertions from `== "flex-start"` to `== "flex-end"` (the dots line and the cluster line), re-wording the assertion messages and the docstring ("two of them flush left" → "two of them flush right"). Every other assertion in the test stays: `flex-wrap: wrap`, the `flex-direction: row` check, the no-`height`/`min-height: var(--header-h)` pair, the gap, the two `flex-basis: 100%` row breaks, and the "no `margin-inline-start` on the cluster" guard — the row-break mechanism is exactly what must survive the re-justify.
+4. `tests/test_api.py` — `test_the_mobile_masthead_block_declares_no_second_bar_height` and `test_the_masthead_scrolls_away_and_stays_the_dropdown_anchor` stay green **unchanged** (neither reads `justify-content`); confirm they do not need a word change in their docstrings before moving on.
+
+## Testing & Quality
+- Unit/integration: the re-pinned alignment pin above; the two untouched mobile/sticky pins as the guard that the row mechanism survived
+- Coverage: **>90%** on this task's new/modified code (CSS + pin)
+- The measured half (the rows actually render right-justified) is the phase's real-browser check (task 03)
+
+## Completion Criteria
+- [ ] the served stylesheet reads `justify-content: flex-end` on both `#nav-status` and `.masthead-right`, with `margin-inline-start` still absent from the cluster (pinned)
+- [ ] the ≤640px block still declares `#nav-status { flex-wrap: nowrap; }` and the wrapping cluster, and still declares no second bar height (existing pins green)
+- [ ] in a browser at 1280 px and 360 px, the dots row and the controls row are flush with the bar's right padding edge and the bar is still three rows (measured, screenshots in `data/logs/`)
+- [ ] `uv run pytest` green, `ruff` + `pyright` clean
+- [ ] no behavior change in completed work: the dropdown slide, the hamburger reveal and the dots' content are untouched
diff --git a/.agents/phases/todo/25_masthead_control_placement/03_clock_rightmost.md b/.agents/phases/todo/25_masthead_control_placement/03_clock_rightmost.md
new file mode 100644
index 0000000..433da59
--- /dev/null
+++ b/.agents/phases/todo/25_masthead_control_placement/03_clock_rightmost.md
@@ -0,0 +1,30 @@
+# Task 03 — The clock is the farthest-right item, and the phase's browser proof
+
+**Phase:** `25_masthead_control_placement` · **Source:** `TODO.md:5` — "The time should show up as the farthest right item on the navbar"
+**Story:** n/a
+
+## Objective
+
+On a right-justified control row, the farthest-right item is the **last** one in markup order, so the clock moves from the first control (before `⚷ Certs`) to the last control (after the theme toggle). The new order on all eight signed-in pages is `⚷ Certs` → `⚙ Account` → `☾ Dark` → clock. This is the phase's verification task as well: the layout change is CSS + markup, so the served-byte pins cannot say the rows actually render right-justified — this task measures them in a real browser (invariant 10).
+
+- ASSUMPTION: "farthest right" is achieved by markup order (the clock is the last child of `.masthead-right`), not by a CSS `order` declaration — the one-loop order pin compares markup, and a `order:` property the pin cannot see is a drift waiting to happen.
+
+## Work
+
+1. The seven page templates that render `.masthead-right` — `src/dashboards/web/pages/index.html`, `system.html`, `disks.html`, `llm.html`, `ups.html`, `settings.html`, `certs.html` — move the line `--:--:--` from its current position (first control, before the Certs link) to **after** the `