chore(agent): phase roadmap from TODO.md, 5 phases
The five UI items in TODO.md become an executable pipeline. Planning files only — no application code changed. - 01_severity_language: one Python threshold table + `severity` on the values the pages colour, plus the .hero style. Today the thresholds are magic numbers at six JS call sites (75/90 here, 80/92 there), which is exactly how "same colour, four meanings" happens. - 02_overview_fleet_and_alerts: /api/summary gains a derived `alerts` list; the page drops to fleet + warnings. Unconfigured sources must not alert — that is invariant 3, tested. - 03_system_per_host_panels: per-host hero cards, no per-core, shared multi-host charts and the detail picker deleted. The six card metrics already exist in the payload, so the first task pins them with tests instead of inventing fields. - 04_llm_chart_readability: charts.js already exports sparkline() and no page calls it — that is why the page reads flat. Port llm_monitor's drawSpark behaviour (fixed max, right growth, p95 foots) and keep the provenance tags. - 05_ups_hero_battery_glyph: charge/load/runtime hero + an SVG battery whose fill is the charge, verified against both real UPSes and the low-charge/on-battery states only the simulator can produce. PLAN.md records the ratified anchors and the deviation worth knowing: severity vocabulary is ok|warn|fail, matching dash.css and nut.py, not the "danger" wording in the proposal — one synonym for one colour. TODO.md cleared to a bare heading; the items are now phases. .gitignore stops ignoring all of .agents/ (the roadmap is project history) while keeping phase-sessions/ and pipeline.log out. deploy/nut-sudoers rewritten: its header still blamed a port mystery that is solved; the remaining need is reading upsd.users so adding a scoped dashboards user does not delete the accounts upsmon authenticates as. LLM-Generated: true
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# Phase 01 — Severity language
|
||||
|
||||
**Source:** `TODO.md` L5, L7 — "proper green (good), yellow (warn), red (danger) color coding" / "charge, load, and runtime left to be big, obvious, and color coded"
|
||||
**Story:** n/a
|
||||
**Context:** `.agents/PLAN.md` → *Architectural Anchors* (severity computed in Python, JS renders classes), `src/dashboards/sources/host.py`, `src/dashboards/sources/nut.py`, `src/dashboards/api.py`, `src/dashboards/web/static/dash.css`, `src/dashboards/web/static/app.js`
|
||||
|
||||
## Objective
|
||||
|
||||
Introduce one place that decides whether a number is fine, worrying, or bad, and put that
|
||||
verdict on the values the API already returns. Phases 02–05 all want the same colour
|
||||
language; doing it here means they render a class instead of each inventing its own
|
||||
thresholds.
|
||||
|
||||
Deliverable: `severity` next to the value in the payloads the pages colour, and CSS/JS
|
||||
helpers that make a "hero number" one call.
|
||||
|
||||
## Dependencies
|
||||
|
||||
— (none)
|
||||
|
||||
## Tasks
|
||||
|
||||
1. `01_severity_module.md` — `src/dashboards/severity.py`: the threshold table and the classifier, unit-tested.
|
||||
2. `02_severity_in_payloads.md` — attach `severity` to host and UPS values and to the `/api/summary` rows; API tests.
|
||||
3. `03_hero_number_style.md` — a `.hero` big-number style on the existing `.ok/.warn/.fail` colours, plus `Dash.hero()` and `Dash.severityFrom(payload)` so pages read the verdict instead of passing thresholds.
|
||||
|
||||
## Testing & Quality
|
||||
|
||||
- Unit: every threshold boundary (below warn, exactly at warn, between, exactly at danger,
|
||||
above), `None` input, and the "unknown is not ok" rule — a value the upstream does not
|
||||
publish must get `severity: null`, never a green pass.
|
||||
- API: `/api/system/snapshot`, `/api/ups/snapshot`, `/api/summary` carry `severity` where
|
||||
the spec says, and **no existing field changes name or meaning** (additive-only anchor).
|
||||
- Coverage: **>90%** on new/modified code.
|
||||
- Live: `uv run pytest -m live --live` must stay at 6 passed.
|
||||
|
||||
## Completion Criteria
|
||||
|
||||
- [ ] `uv run python -c "from dashboards import severity; print(severity.classify('cpu.usage_pct', 95))"` → `fail`; `60` → `ok`; `None` → `None`
|
||||
- [ ] `curl -s localhost:8090/api/ups/snapshot | python3 -m json.tool` shows `severity` beside `charge_pct`, `load_pct`, `battery_runtime`
|
||||
- [ ] no new colour vocabulary: classes stay `.ok` / `.warn` / `.fail` as in `dash.css`
|
||||
- [ ] `uv run pytest` green; coverage ≥94% overall, >90% on `severity.py`
|
||||
- [ ] `uv run ruff check src tests agent && uv run pyright` clean
|
||||
- [ ] Existing pages render unchanged (severity is additive; nothing consumes it yet) — one screenshot in `data/logs/`
|
||||
- [ ] no behavior change in completed phases
|
||||
Reference in New Issue
Block a user