phase: 35_llm_equal_window_heights
**Phase 35 final verification pass — complete.** - Both task files (01, 02) already in `complete/`; verified the work in-tree: `#engines` = `grid cols-2`, `.strip` has no `align-items` (keeps `display: grid`, `gap: .85rem`, `auto-fit minmax(min(340px, 100%), 1fr)`), `.grid.items-start` rule + corrected comment intact, rewritten pin `test_llm_engine_windows_stretch_to_a_common_row_height` in place. - Live re-verified in browser (fresh `35-llm-verify.cjs` run, screenshots re-captured): both engines answering; strip cards 456 px / panel cards 422 px with flat equal bottoms; row gaps 13.6 px (uniform `.85rem`); `n/a` cells preserved; 360 px viewport single-column, no overflow/clip. `/system` no-regress: `grid auto items-start`, expanded disclosure does not stretch collapsed siblings (325.4 → 325.4). - Completion criteria: served `/llm` markup ✓ · live equalized rows + screenshot ✓ · `/system` bytes unchanged ✓ · full suite/coverage/lint ✓ · README/AGENTS.md ✓ · no behaviour change (all existing pins pass) ✓. - Tests: `bash .agents/validate.sh` → **exit 0**: `uv run pytest --cov` **2031 passed, 19 skipped** (15 live + 4 store_perf, opt-in), coverage **98.71%** (94% floor reached); `ruff` all checks passed; `pyright` 0 errors; `node --check` + repo hygiene clean. - Live suite (`--live`, read-only): 4/15 pass (LLM engines); 5 fail solely on host-agent/upsd **connectivity timeouts** (9120/3051 unreachable from this machine — same errors as `dev-server.sh status`); environmental, no code defect. No live changes made (all verification read-only). - Docs: README.md reviewed in full — verified quickstart, installer/agent flags, config defaults, Containerfile facts, script flags, fixtures, test files, polling cadences: **consistent, no changes needed**. AGENTS.md: fixed one stale statement (hermetic skip count "12 live" → "15 live"); nothing else stale. - Dev server up (pid 811266), `/api/health` 200; hosts/upsd DOWN is the pre-existing environmental state, LLM source ok. - Next pending phase: **none** — `todo/` contains only this phase (35).
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# Phase 35 — `/llm` engine windows equalized: the strip and panel rows stretch to a common row height
|
||||
|
||||
**Source:** operator request, 2026-10-25 — "The LLM engines page looks kinda awkward, there's a big gap between gufo's two windows and radiance + the throughput charts. I want the windows to be equalized in height." (With the `data/logs/34-llm-radiance-rest.png` state: the gufo strip card ~320 px shorter than the radiance strip card, the radiance panel shorter than the gufo panel — dead space below the shorter card in each row, before the next row.)
|
||||
**Story:** n/a
|
||||
**Context:** `src/dashboards/web/pages/llm.html` (`#strip`, the `#engines` grid at `grid cols-2 items-start`), `src/dashboards/web/static/dash.css` (`.strip { … align-items: start; }`, the `.grid.items-start` rule with its "cards sit at their own height" comment, `.stack { align-content: start }` which keeps stretched-card content top-aligned), `tests/test_api.py` (`test_llm_engine_panels_are_not_stretched_to_their_tallest_sibling` — the served-byte pin of the **old** decision; the `/system` hosts-grid pin at the `.grid auto items-start` assertion is a *different* context and stays), `README.md` (the one `items-start` mention, L1104–1105, is the system disclosure — stays).
|
||||
|
||||
## Objective
|
||||
|
||||
The two "window" rows on `/llm` — the stats strip row and the engine panel row — render each pair of engine cards at the row's common height instead of their natural heights, so the dead gap below the shorter card (gufo strip under the taller radiance strip; radiance panel under the taller gufo panel, before the four throughput/trend charts) is gone and every row ends on a flat edge.
|
||||
|
||||
## Scope decisions taken with the operator (binding for this phase)
|
||||
|
||||
| # | Decision | Consequence |
|
||||
|---|----------|-------------|
|
||||
| 1 | **Equalize = stretch within the row.** The operator wants the window *heights* equalized: each row's cards share the tallest card's height (CSS grid default `stretch`). The extra space on the shorter card is bottom card padding — content stays top-aligned via `.stack { align-content: start }` — never a `0` or an invented number (rule 2 untouched: missing cells still print `n/a`). | `align-items: start` leaves the `.strip` rule; `items-start` leaves the `#engines` div. At ≤ 640 px the `auto-fit` grids are single-column, where stretch is a visual no-op — mobile is unaffected. |
|
||||
| 2 | **This reverses the pinned anti-stretch decision.** The pin `test_llm_engine_panels_are_not_stretched_to_their_tallest_sibling` recorded the `llm_monitor`-era finding (a 172 px blank bottom read as "no data"). The operator now judges the inter-row gap worse than an equalized card and asks for the heights equalized. The pin is **rewritten in place** to pin the new decision both directions (markup carries no `items-start` on `#engines`; the `.strip` block sets no `align-items` and keeps `display: grid` + the `auto-fit` single-engine columns), and the `.grid.items-start` comment in `dash.css` is corrected to the new fact. | `tests/test_api.py` is the only test file touched. The `/system` hosts grid (and the `certs`/`settings`/`gateway`/`disks` `items-start` grids) keep `items-start` — the system case (an expanded disclosure must not stretch collapsed siblings, `README.md` L1104–1105) is a different context and is pinned separately. |
|
||||
| 3 | **No API, no data, no new technology.** | No `/api` route, metric, payload field, dependency, or JS change. The change is two layout declarations and their pin. No `charts.js`/`page-llm.js` edit is needed: `.stack` already top-aligns the content of a stretched card. |
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `34_radiance_llm_engine` (complete) — the current two-engine strip/panel shape whose height mismatch (the radiance strip's extra rows, spec curve, and `reqs` block vs the gufo strip; the gufo panel's slot grid vs the radiance panel's latency rows) this phase equalizes.
|
||||
- `07_llm_monitor_style_pages` (complete) — the strip/panel split and the served-byte pin this phase rewrites.
|
||||
|
||||
## Tasks
|
||||
|
||||
1. `01_stretch_the_llm_rows.md` — the two layout declarations and the pin that records the operator's decision.
|
||||
2. `02_live_verify_and_docs.md` — the dev-server live browser verification with screenshot, the `/system` no-regress check, the README/AGENTS.md pass.
|
||||
|
||||
## Testing & Quality
|
||||
- Unit/integration: the rewritten served-byte pin in `tests/test_api.py` — the served `/llm` markup's `#engines` div carries no `items-start`, the served `dash.css` `.strip` block sets no `align-items` while keeping `display: grid` and the `auto-fit` columns, and the served `/system` markup still carries `grid auto items-start` (the unchanged context, re-pinned alongside). The pre-existing `tests/test_api.py` pins for the system hosts grid (`grid auto items-start`) must pass untouched.
|
||||
- Coverage: **>90%** on new/modified code (this phase's code surface is markup + one rewritten pin; the suite's overall floor — 94% via `validate.sh` — must not drop).
|
||||
- The phase is "Complete" only when the **entire** project test suite passes 100% (every test in the project, not just this phase's — pre-existing failures included) and achieves **>90%** code coverage on new/modified code.
|
||||
- Every UI change is verified in a real browser against live data, screenshot in `data/logs/` (AGENTS.md rule 10) — with gufo and radiance both answering, the strip row and the panel row each end on a flat edge with no dead gap before the trend charts.
|
||||
|
||||
## Documentation & Consistency
|
||||
- The final pass reviews `README.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**. For `AGENTS.md` it fixes only *stale statements* (a dead command, changed rule, or outdated fact) and **never adds or expands its content** (a file that states its own update policy, e.g. "updated rarely, if ever", wins).
|
||||
- Tasks update `README.md` immediately when their own changes are user-visible (setup, commands, configuration, features, conventions) — expected here: none beyond confirming the L1104–1105 `items-start` sentence still describes the system disclosure accurately — and `AGENTS.md` only when a statement in it became stale (expected: none — a layout preference is not a rule, command, or fleet fact).
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] served `GET /llm` markup: the `#engines` div's class list is `grid cols-2` (no `items-start`); served `dash.css`: the `.strip` block has no `align-items` declaration and still carries `display: grid`, its `gap`, and the `auto-fit` `minmax(min(340px, 100%), 1fr)` columns; the `.grid.items-start` rule still exists (used by `/system` and the other pages).
|
||||
- [ ] live browser, both engines answering: the strip row's two cards and the panel row's two cards each share a common height (flat row bottoms); the gap between a row and the next is the uniform `.85rem` grid gap only — screenshot in `data/logs/`; at a 360 px viewport the page is single-column and unbroken.
|
||||
- [ ] served `GET /system` markup still carries `grid auto items-start` on `#hosts` and its pin passes — the disclosure behaviour is byte-for-byte unchanged.
|
||||
- [ ] full test suite **100% passing** (every test in the project, not just this phase's), coverage not down (94% floor via `bash .agents/validate.sh`); `ruff` + `pyright` clean.
|
||||
- [ ] README.md is accurate and consistent with the whole project; AGENTS.md has no stale statements (verified in the final pass).
|
||||
- [ ] no behaviour change in completed work: payloads, alerts, served bytes of every page this phase does not touch (the suite's existing pins), and the `n/a`/`never 0` rendering of every `/llm` cell are untouched.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Task 01 — Stretch the LLM strip and panel rows; pin the operator's decision
|
||||
|
||||
**Phase:** `35_llm_equal_window_heights` · **Story:** n/a
|
||||
|
||||
## Objective
|
||||
|
||||
The two engine-window rows on `/llm` (the stats strip row and the panel row) share a common row height — CSS grid default `stretch` — so the dead gap below the shorter card is gone, and the served-byte pin records that decision in both directions instead of forbidding it.
|
||||
|
||||
## Work
|
||||
1. `src/dashboards/web/pages/llm.html` — the `#engines` div: `class="grid cols-2 items-start"` → `class="grid cols-2"` (drop `items-start`; the grid's default `align-items: stretch` takes over). The section comment above it stays — it does not name the alignment.
|
||||
2. `src/dashboards/web/static/dash.css` — the `.strip` rule: remove `align-items: start;` from the declaration list (keep `display: grid; gap: .85rem;` and the `auto-fit` `minmax(min(340px, 100%), 1fr)` columns — the single-engine rule is untouched). Also correct the comment block above `.grid.items-start` (the "cards sit at their own height instead of being stretched" prose, which cites the `/llm` 172 px finding): the rule still exists and still serves `/system` (an expanded disclosure must not stretch collapsed siblings — `README.md` L1104–1105) and the `certs`/`settings`/`disks`/`gateway` grids; the `/llm` strip and panel rows now use the default stretch, with the shorter card's extra space reading as bottom card padding (content stays top-aligned through `.stack { align-content: start }`). The comment must name only classes the served CSS still defines.
|
||||
3. `tests/test_api.py` — replace `test_llm_engine_panels_are_not_stretched_to_their_tallest_sibling` with the pin of the **new** decision, e.g. `test_llm_engine_windows_stretch_to_a_common_row_height`:
|
||||
- the served `/llm` markup (comments stripped, as the old pin did via `_code()`): the `#engines` div's class list contains no `items-start`;
|
||||
- the served `dash.css`: the `.strip {` block contains no `align-items` declaration and still contains `display: grid`, its `gap`, and the `auto-fit` `minmax(min(340px, 100%), 1fr)` columns (the rule stays alive, not just de-aligned);
|
||||
- the served `/system` markup still carries `grid auto items-start` on `#hosts` (the unchanged context re-pinned in the same test, so the two contexts cannot silently converge);
|
||||
- the docstring records the operator's 2026-10-25 decision — the inter-row gap read as worse than an equalized card, the heights are equalized by stretch, and the extra space is bottom card padding, never a number (rule 2: missing cells still print `n/a`, never `0`).
|
||||
4. Nothing else: `page-llm.js`, `charts.js`, every other page, and the `README.md` L1104–1105 sentence (it describes the system disclosure and stays accurate) are untouched by this task.
|
||||
|
||||
## Testing & Quality
|
||||
- Unit/integration: the rewritten pin above runs in the hermetic suite (`create_app()`, served bytes); the pre-existing `tests/test_api.py` pin for the system hosts grid (`grid auto items-start` at the L2138/L2140 assertions) passes untouched.
|
||||
- Coverage: **>90%** on this task's new/modified code (markup + one rewritten pin; the 94% overall floor via `validate.sh` must not drop).
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] `uv run pytest` green, including the new pin and the untouched system-grid pin.
|
||||
- [ ] served `GET /llm` (any authenticated or fixture config): the `#engines` div is `class="grid cols-2"`; the served `dash.css` `.strip` block has no `align-items` line.
|
||||
- [ ] `uv run ruff check src tests agent && uv run pyright` clean; `uv run pytest --cov` floor not down.
|
||||
- [ ] no change to any served page, payload, or asset this task does not name.
|
||||
- [ ] commit with `--no-gpg-sign` and the `LLM-Generated: true` trailer (per task, per PLAN.md's validation workflow).
|
||||
@@ -0,0 +1,33 @@
|
||||
# Task 02 — Live verification, the no-regress check, and the documentation pass
|
||||
|
||||
**Phase:** `35_llm_equal_window_heights` · **Story:** n/a
|
||||
|
||||
## Objective
|
||||
|
||||
Prove the equalized rows in a real browser against the live fleet (AGENTS.md rule 10), confirm the `/system` disclosure behaviour did not move, and close the phase with the README/AGENTS.md consistency pass.
|
||||
|
||||
## Work
|
||||
1. Dev server and ground truth: source `.env.dev` (`set -a; . ./.env.dev; set +a`), `./scripts/dev-server.sh restart`, and confirm `./scripts/dev-server.sh status` shows the `llm` source ok (gufo and radiance both answering — the strip row only renders two cards when two engines are configured, which is the state the fix is about).
|
||||
2. Live browser verification of `http://127.0.0.1:8090/llm` (sign in with `testpass`), with both engines answering:
|
||||
- the strip row: the gufo and radiance strip cards share one height — a flat bottom edge; the dead space below the shorter (gufo) card is card padding inside the border, not a gap between the row and the panel row;
|
||||
- the panel row: the gufo and radiance panels share one height — the shorter (radiance) panel's extra space is bottom card padding, content top-aligned;
|
||||
- the only vertical space between the strip row, the panel row, and the four trend-chart cards is the uniform `.85rem` grid gap;
|
||||
- every missing value still prints `n/a` (never `0`), and the severity colours are unchanged — the layout change must not have touched a single number;
|
||||
- at a 360 px viewport the page is single-column (the `auto-fit` grids collapse), rows stack, nothing is clipped.
|
||||
Save the screenshot to `data/logs/35-llm-equal-windows.png` (a mobile-360 shot beside it if taken).
|
||||
3. No-regress check: `GET /system` (browser) — expanding one host's disclosure still does not stretch its collapsed siblings (the `items-start` context from `README.md` L1104–1105, byte-for-byte the served markup `grid auto items-start`).
|
||||
4. Documentation pass (the phase's final pass):
|
||||
- `README.md` reviewed in full against the project as it stands after this phase — fix every inconsistency found, including pre-existing ones. Expected outcome: the L1104–1105 `items-start` sentence still describes the system disclosure and needs no change; confirm nothing in the README describes the `/llm` rows as own-height.
|
||||
- `AGENTS.md` — fix only *stale statements* (a dead command, changed rule, or outdated fact); never add or expand. Expected outcome: no change — a layout preference is not a rule, command, or fleet fact, and no statement in the file became stale. Record the check either way.
|
||||
|
||||
## Testing & Quality
|
||||
- Unit/integration: `uv run pytest` (full suite, 100% green — pre-existing failures included), `uv run pytest --cov` (floor not down; 94% via `bash .agents/validate.sh`), `uv run ruff check src tests agent && uv run pyright` clean, `bash .agents/validate.sh` green.
|
||||
- Coverage: **>90%** on this task's new/modified code (none expected — verification and documentation only).
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] `data/logs/35-llm-equal-windows.png` exists and shows both `/llm` rows ending on flat, equal-height card edges with only the uniform grid gap between rows, `n/a` cells still `n/a`, and no colour change.
|
||||
- [ ] the `/system` disclosure no-regress check passes (served markup still `grid auto items-start`; browser behaviour unchanged).
|
||||
- [ ] `./scripts/dev-server.sh status` sane after the restart; `/api/health` answers.
|
||||
- [ ] README.md is accurate and consistent with the whole project; AGENTS.md has no stale statements (both verified in this pass, whatever the expected outcome).
|
||||
- [ ] full test suite **100% passing**, coverage not down, lint/type checks clean, `bash .agents/validate.sh` green.
|
||||
- [ ] commit with `--no-gpg-sign` and the `LLM-Generated: true` trailer (per task, per PLAN.md's validation workflow).
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
**Phase 35 final verification pass — complete.**
|
||||
|
||||
- Both task files (01, 02) already in `complete/`; verified the work in-tree: `#engines` = `grid cols-2`, `.strip` has no `align-items` (keeps `display: grid`, `gap: .85rem`, `auto-fit minmax(min(340px, 100%), 1fr)`), `.grid.items-start` rule + corrected comment intact, rewritten pin `test_llm_engine_windows_stretch_to_a_common_row_height` in place.
|
||||
- Live re-verified in browser (fresh `35-llm-verify.cjs` run, screenshots re-captured): both engines answering; strip cards 456 px / panel cards 422 px with flat equal bottoms; row gaps 13.6 px (uniform `.85rem`); `n/a` cells preserved; 360 px viewport single-column, no overflow/clip. `/system` no-regress: `grid auto items-start`, expanded disclosure does not stretch collapsed siblings (325.4 → 325.4).
|
||||
- Completion criteria: served `/llm` markup ✓ · live equalized rows + screenshot ✓ · `/system` bytes unchanged ✓ · full suite/coverage/lint ✓ · README/AGENTS.md ✓ · no behaviour change (all existing pins pass) ✓.
|
||||
- Tests: `bash .agents/validate.sh` → **exit 0**: `uv run pytest --cov` **2031 passed, 19 skipped** (15 live + 4 store_perf, opt-in), coverage **98.71%** (94% floor reached); `ruff` all checks passed; `pyright` 0 errors; `node --check` + repo hygiene clean.
|
||||
- Live suite (`--live`, read-only): 4/15 pass (LLM engines); 5 fail solely on host-agent/upsd **connectivity timeouts** (9120/3051 unreachable from this machine — same errors as `dev-server.sh status`); environmental, no code defect. No live changes made (all verification read-only).
|
||||
- Docs: README.md reviewed in full — verified quickstart, installer/agent flags, config defaults, Containerfile facts, script flags, fixtures, test files, polling cadences: **consistent, no changes needed**. AGENTS.md: fixed one stale statement (hermetic skip count "12 live" → "15 live"); nothing else stale.
|
||||
- Dev server up (pid 811266), `/api/health` 200; hosts/upsd DOWN is the pre-existing environmental state, LLM source ok.
|
||||
- Next pending phase: **none** — `todo/` contains only this phase (35).
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
== uv run pytest --cov (hermetic: no network, live tests skip) ==
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 17%]
|
||||
........................................................................ [ 21%]
|
||||
........................................................................ [ 24%]
|
||||
........................................................................ [ 28%]
|
||||
........................................................................ [ 31%]
|
||||
...................................s.................................... [ 35%]
|
||||
........................................................................ [ 38%]
|
||||
........................................................................ [ 42%]
|
||||
........................................................................ [ 45%]
|
||||
........................................................................ [ 49%]
|
||||
........................................................................ [ 52%]
|
||||
........................................................................ [ 56%]
|
||||
........................................................................ [ 59%]
|
||||
........................................................................ [ 63%]
|
||||
........................................................................ [ 66%]
|
||||
........................................................................ [ 70%]
|
||||
........................................................................ [ 73%]
|
||||
............sssssssssssssss............................................. [ 77%]
|
||||
........................................................................ [ 80%]
|
||||
........................................................................ [ 84%]
|
||||
........................................................................ [ 87%]
|
||||
........................................................................ [ 91%]
|
||||
........................................................................ [ 94%]
|
||||
................................................sss..................... [ 98%]
|
||||
.................................. [100%]
|
||||
=============================== warnings summary ===============================
|
||||
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
|
||||
/home/ducoterra/Projects/Personal/dashboards/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
|
||||
from starlette.testclient import TestClient as TestClient # noqa
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||
================================ tests coverage ================================
|
||||
_______________ coverage: platform linux, python 3.14.8-final-0 ________________
|
||||
|
||||
Name Stmts Miss Cover Missing
|
||||
------------------------------------------------------------------
|
||||
src/dashboards/__init__.py 3 0 100%
|
||||
src/dashboards/__main__.py 14 1 93% 32
|
||||
src/dashboards/alerts.py 201 0 100%
|
||||
src/dashboards/api.py 625 9 99% 229, 1278-1280, 1315-1318, 1387, 1395, 1451, 1454
|
||||
src/dashboards/app.py 190 0 100%
|
||||
src/dashboards/auth.py 265 0 100%
|
||||
src/dashboards/certs.py 292 0 100%
|
||||
src/dashboards/collectors.py 256 4 98% 405, 409-410, 445
|
||||
src/dashboards/config.py 132 0 100%
|
||||
src/dashboards/debug.py 14 0 100%
|
||||
src/dashboards/poller.py 165 3 98% 192-194, 279
|
||||
src/dashboards/prom.py 112 5 96% 126, 163, 177, 180, 183
|
||||
src/dashboards/rates.py 73 0 100%
|
||||
src/dashboards/severity.py 49 0 100%
|
||||
src/dashboards/sources/__init__.py 0 0 100%
|
||||
src/dashboards/sources/disks.py 134 0 100%
|
||||
src/dashboards/sources/gateway.py 613 10 98% 339, 588, 601-602, 652, 785, 1089, 1140, 1207, 1569
|
||||
src/dashboards/sources/host.py 209 0 100%
|
||||
src/dashboards/sources/llm.py 282 4 99% 467, 517, 554, 607
|
||||
src/dashboards/sources/nut.py 413 20 95% 153, 172, 186, 198, 204, 217, 225, 241, 319-320, 322, 579, 591, 626, 657, 661, 718-719, 724, 736
|
||||
src/dashboards/sources/nut_sim.py 134 0 100%
|
||||
src/dashboards/store.py 313 2 99% 553-554
|
||||
------------------------------------------------------------------
|
||||
TOTAL 4489 58 99%
|
||||
Required test coverage of 94% reached. Total coverage: 98.71%
|
||||
2031 passed, 19 skipped, 1 warning in 201.30s (0:03:21)
|
||||
== uv run ruff check src tests agent ==
|
||||
All checks passed!
|
||||
== uv run pyright ==
|
||||
0 errors, 0 warnings, 0 informations
|
||||
== node --check src/dashboards/web/static/*.js ==
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
All checks pass. The old pin name remains only in the phase files (untouched by design); `.strip` no longer carries `align-items`; `llm.html` no longer has `items-start`. (Note: the task's "commit per task" line is overridden by the harness rules — the harness makes the one atomic commit per phase, so I left everything in the working tree.)
|
||||
|
||||
**Report — Task 01 (phase 35): stretch the LLM strip and panel rows**
|
||||
|
||||
- `llm.html`: `#engines` div is now `class="grid cols-2"` (dropped `items-start`; grid default `stretch` takes over). Section comment untouched — it names no alignment.
|
||||
- `dash.css`: `.strip` rule lost `align-items: start;` (keeps `display: grid`, `gap: .85rem`, the `auto-fit minmax(min(340px, 100%), 1fr)` columns); the `.grid.items-start` comment rewritten to the new fact — still serves `/system`, `/disks`, `certs`, `settings`, `gateway`; `/llm` rows now use default stretch, extra space = bottom card padding, content top-aligned via `.stack { align-content: start }`.
|
||||
- `tests/test_api.py`: `test_llm_engine_panels_are_not_stretched_to_their_tallest_sibling` replaced in place by `test_llm_engine_windows_stretch_to_a_common_row_height` — pins exact `#engines` class list `grid cols-2`, the `.strip` block (no `align-items`, rule still alive with columns+gap), and `/system`'s `grid auto items-start` in the same test (both directions, no silent convergence); docstring records the 2026-10-25 operator decision incl. rule 2 (`n/a`, never `0`).
|
||||
- Tests: `uv run pytest` → **2031 passed, 19 skipped, 0 failed**; `uv run pytest --cov` → 98.71% (94% floor held); `ruff check src tests agent` clean; `pyright` 0 errors; `bash .agents/validate.sh` → **exit 0**; `uv pip list --outdated` empty (no deps moved).
|
||||
- Docs: no impact — README L1104–1105 `items-start` sentence describes the `/system` disclosure, still accurate; AGENTS.md unaffected (layout preference is not a rule/command/fleet fact). No other served page, payload, or asset changed.
|
||||
- Notable: pre-existing working-tree edits to `NOTES.md`/`TODO.md` (operator's) were left untouched; no live-infra involvement in this task.
|
||||
|
||||
Next pending task: `02_live_verify_and_docs.md` (live browser verification + screenshot, `/system` no-regress, README/AGENTS.md pass).
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
== uv run pytest --cov (hermetic: no network, live tests skip) ==
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 17%]
|
||||
........................................................................ [ 21%]
|
||||
........................................................................ [ 24%]
|
||||
........................................................................ [ 28%]
|
||||
........................................................................ [ 31%]
|
||||
...................................s.................................... [ 35%]
|
||||
........................................................................ [ 38%]
|
||||
........................................................................ [ 42%]
|
||||
........................................................................ [ 45%]
|
||||
........................................................................ [ 49%]
|
||||
........................................................................ [ 52%]
|
||||
........................................................................ [ 56%]
|
||||
........................................................................ [ 59%]
|
||||
........................................................................ [ 63%]
|
||||
........................................................................ [ 66%]
|
||||
........................................................................ [ 70%]
|
||||
........................................................................ [ 73%]
|
||||
............sssssssssssssss............................................. [ 77%]
|
||||
........................................................................ [ 80%]
|
||||
........................................................................ [ 84%]
|
||||
........................................................................ [ 87%]
|
||||
........................................................................ [ 91%]
|
||||
........................................................................ [ 94%]
|
||||
................................................sss..................... [ 98%]
|
||||
.................................. [100%]
|
||||
=============================== warnings summary ===============================
|
||||
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
|
||||
/home/ducoterra/Projects/Personal/dashboards/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
|
||||
from starlette.testclient import TestClient as TestClient # noqa
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||
================================ tests coverage ================================
|
||||
_______________ coverage: platform linux, python 3.14.8-final-0 ________________
|
||||
|
||||
Name Stmts Miss Cover Missing
|
||||
------------------------------------------------------------------
|
||||
src/dashboards/__init__.py 3 0 100%
|
||||
src/dashboards/__main__.py 14 1 93% 32
|
||||
src/dashboards/alerts.py 201 0 100%
|
||||
src/dashboards/api.py 625 9 99% 229, 1278-1280, 1315-1318, 1387, 1395, 1451, 1454
|
||||
src/dashboards/app.py 190 0 100%
|
||||
src/dashboards/auth.py 265 0 100%
|
||||
src/dashboards/certs.py 292 0 100%
|
||||
src/dashboards/collectors.py 256 4 98% 405, 409-410, 445
|
||||
src/dashboards/config.py 132 0 100%
|
||||
src/dashboards/debug.py 14 0 100%
|
||||
src/dashboards/poller.py 165 3 98% 192-194, 279
|
||||
src/dashboards/prom.py 112 5 96% 126, 163, 177, 180, 183
|
||||
src/dashboards/rates.py 73 0 100%
|
||||
src/dashboards/severity.py 49 0 100%
|
||||
src/dashboards/sources/__init__.py 0 0 100%
|
||||
src/dashboards/sources/disks.py 134 0 100%
|
||||
src/dashboards/sources/gateway.py 613 10 98% 339, 588, 601-602, 652, 785, 1089, 1140, 1207, 1569
|
||||
src/dashboards/sources/host.py 209 0 100%
|
||||
src/dashboards/sources/llm.py 282 4 99% 467, 517, 554, 607
|
||||
src/dashboards/sources/nut.py 413 20 95% 153, 172, 186, 198, 204, 217, 225, 241, 319-320, 322, 579, 591, 626, 657, 661, 718-719, 724, 736
|
||||
src/dashboards/sources/nut_sim.py 134 0 100%
|
||||
src/dashboards/store.py 313 2 99% 553-554
|
||||
------------------------------------------------------------------
|
||||
TOTAL 4489 58 99%
|
||||
Required test coverage of 94% reached. Total coverage: 98.71%
|
||||
2031 passed, 19 skipped, 1 warning in 198.59s (0:03:18)
|
||||
== uv run ruff check src tests agent ==
|
||||
All checks passed!
|
||||
== uv run pyright ==
|
||||
0 errors, 0 warnings, 0 informations
|
||||
== node --check src/dashboards/web/static/*.js ==
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
All checks complete. The skip set is exactly the expected opt-in set (live + store_perf markers).
|
||||
|
||||
## Report
|
||||
|
||||
- **Live verification (AGENTS.md rule 10):** dev server restarted; `llm:gufo`/`llm:radiance` both ok. Browser (Playwright, live data): strip row cards share height 456 px / flat bottom 812 px; panel row cards share 422 px / flat bottom 1247.7 px; row-to-row gaps both exactly 13.6 px (`.85rem`); `n/a` cells render `n/a` (queue time/p95/slot remaining), severity colours unchanged; 360 px viewport: single column, no overflow/clipping. Screenshot `data/logs/35-llm-equal-windows.png` (+ `35-llm-equal-windows-mobile-360.png`, `35-system-no-regress.png`; script `data/logs/35-llm-verify.cjs`).
|
||||
- **`/system` no-regress:** served `#hosts` still `grid auto items-start`, CSS rule intact; expanding a host's Charts disclosure leaves the collapsed sibling at 325.4 px before and after — no stretch.
|
||||
- **Docs pass:** README reviewed (env table cross-checked against `.env.example` — complete; quickstart/`dev-server.sh` commands match; gateway 1.2.0/1.3.0/1.4.0, routectl, radiance, LLM sections all current). The only `items-start` mention (L1104–1105) is the system-disclosure sentence — still accurate, nothing in the README describes `/llm` rows as own-height. **No README/AGENTS.md changes** (AGENTS.md states no layout-related statement, so nothing became stale; check recorded).
|
||||
- **Tests/gate:** `uv run pytest` → 2031 passed, 19 skipped (only live/store_perf opt-ins), 100% green; `uv run pytest --cov` → 98.71% (floor 94% reached); `ruff` + `pyright` clean; `bash .agents/validate.sh` green.
|
||||
- **Live suite note (no live changes made):** `pytest -m live --live` → 4 passed (the engine tests — the sources this phase touches), 5 failed, all dial timeouts to the real fleet agents (10.1.0.126/10.1.0.51/10.1.1.27) and upsd — the same pre-existing fleet-down state `dev-server.sh status` shows (agents down ~21 h, 8664 consecutive failures); not a regression (phase touched no Python code). I would have re-run the live suite once the agents are reachable; I made no changes to fleet infrastructure.
|
||||
- **Commit:** not made — the harness makes one atomic commit per phase (overrides the per-task commit instruction).
|
||||
- **Next pending task:** none in `todo/35_llm_equal_window_heights/` — phase 35 is complete pending the harness's final pass.
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
== uv run pytest --cov (hermetic: no network, live tests skip) ==
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 10%]
|
||||
........................................................................ [ 14%]
|
||||
........................................................................ [ 17%]
|
||||
........................................................................ [ 21%]
|
||||
........................................................................ [ 24%]
|
||||
........................................................................ [ 28%]
|
||||
........................................................................ [ 31%]
|
||||
...................................s.................................... [ 35%]
|
||||
........................................................................ [ 38%]
|
||||
........................................................................ [ 42%]
|
||||
........................................................................ [ 45%]
|
||||
........................................................................ [ 49%]
|
||||
........................................................................ [ 52%]
|
||||
........................................................................ [ 56%]
|
||||
........................................................................ [ 59%]
|
||||
........................................................................ [ 63%]
|
||||
........................................................................ [ 66%]
|
||||
........................................................................ [ 70%]
|
||||
........................................................................ [ 73%]
|
||||
............sssssssssssssss............................................. [ 77%]
|
||||
........................................................................ [ 80%]
|
||||
........................................................................ [ 84%]
|
||||
........................................................................ [ 87%]
|
||||
........................................................................ [ 91%]
|
||||
........................................................................ [ 94%]
|
||||
................................................sss..................... [ 98%]
|
||||
.................................. [100%]
|
||||
=============================== warnings summary ===============================
|
||||
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
|
||||
/home/ducoterra/Projects/Personal/dashboards/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
|
||||
from starlette.testclient import TestClient as TestClient # noqa
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||
================================ tests coverage ================================
|
||||
_______________ coverage: platform linux, python 3.14.8-final-0 ________________
|
||||
|
||||
Name Stmts Miss Cover Missing
|
||||
------------------------------------------------------------------
|
||||
src/dashboards/__init__.py 3 0 100%
|
||||
src/dashboards/__main__.py 14 1 93% 32
|
||||
src/dashboards/alerts.py 201 0 100%
|
||||
src/dashboards/api.py 625 9 99% 229, 1278-1280, 1315-1318, 1387, 1395, 1451, 1454
|
||||
src/dashboards/app.py 190 0 100%
|
||||
src/dashboards/auth.py 265 0 100%
|
||||
src/dashboards/certs.py 292 0 100%
|
||||
src/dashboards/collectors.py 256 4 98% 405, 409-410, 445
|
||||
src/dashboards/config.py 132 0 100%
|
||||
src/dashboards/debug.py 14 0 100%
|
||||
src/dashboards/poller.py 165 3 98% 192-194, 279
|
||||
src/dashboards/prom.py 112 5 96% 126, 163, 177, 180, 183
|
||||
src/dashboards/rates.py 73 0 100%
|
||||
src/dashboards/severity.py 49 0 100%
|
||||
src/dashboards/sources/__init__.py 0 0 100%
|
||||
src/dashboards/sources/disks.py 134 0 100%
|
||||
src/dashboards/sources/gateway.py 613 10 98% 339, 588, 601-602, 652, 785, 1089, 1140, 1207, 1569
|
||||
src/dashboards/sources/host.py 209 0 100%
|
||||
src/dashboards/sources/llm.py 282 4 99% 467, 517, 554, 607
|
||||
src/dashboards/sources/nut.py 413 20 95% 153, 172, 186, 198, 204, 217, 225, 241, 319-320, 322, 579, 591, 626, 657, 661, 718-719, 724, 736
|
||||
src/dashboards/sources/nut_sim.py 134 0 100%
|
||||
src/dashboards/store.py 313 2 99% 553-554
|
||||
------------------------------------------------------------------
|
||||
TOTAL 4489 58 99%
|
||||
Required test coverage of 94% reached. Total coverage: 98.71%
|
||||
2031 passed, 19 skipped, 1 warning in 201.59s (0:03:21)
|
||||
== uv run ruff check src tests agent ==
|
||||
All checks passed!
|
||||
== uv run pyright ==
|
||||
0 errors, 0 warnings, 0 informations
|
||||
== node --check src/dashboards/web/static/*.js ==
|
||||
Reference in New Issue
Block a user