phase: 17_installer_device_filter

**Phase 17 — final verification pass: complete, all green.**

Verified (criteria):
- `grep -n "DevicePolicy\|DeviceAllow" deploy/install-agent.sh` → no match; `PrivateDevices=false` retained (line 472) ✓
- `install-agent.sh --help` names `--as-root`/`--caps` with the kernel-gate sentence; `--force` documented ✓
- Fresh fake-root install = pre-phase unit minus the filter lines: `test_a_default_install_unit_is_the_pre_phase_unit_minus_the_filter_lines` + `test_the_template_unit_has_no_device_filter_lines` pass ✓
- Re-run that differs → exit 1 with diff on stdout, `--force` applies, identical re-run silent: `test_a_re_run_that_differs_refuses_without_force_and_applies_with_it` (+ 3 sibling guard pins) pass ✓
- driveripper reproduction — verified **read-only**, no live change: `systemctl cat` shows `User=root`, `CapabilityBoundingSet=CAP_SYS_RAWIO CAP_SYS_ADMIN`, no filter, same `ExecStart`; `active`, `CapEff 0000000000220000`; `/api/disks/snapshot` → 16/16 drives with temperatures ✓
- `uv run pytest` → **1451 passed, 15 skipped**; `bash .agents/validate.sh` → **exit 0** (coverage **98.94%** ≥ 94, `ruff` clean, `pyright` 0 errors, `node --check` + hygiene clean); `uv run pytest -m live --live` → **11 passed**; dev server 9/9 sources `ok` (one initial live failure was a transient gufo timeout, clean on re-run)

Docs (inconsistencies found + fixed, incl. pre-existing):
- `AGENTS.md` fleet record said driveripper's unit runs `User=dashboards-agent` while the same bullet (and the live host) says `User=root` — rewritten to separate the installed user from the running one.
- `AGENTS.md` gap 10 header still claimed "the installer template is what is left" → now records phase 17 as the fix.
- `README.md` "with no capabilities" → "with an empty `CapabilityBoundingSet` (unless `--caps`…)", since this phase added the capability flag.
- `README.md` battery-test "gated four times" now notes the two session gates in front, matching AGENTS invariant 1.
- `.env.example` was missing three README-documented settings (`DASH_ENV_FILE`, `DASH_RELOAD`, `NUT_SIMULATE`) and `AGENT_CERT_BUNDLE` in the agent-variables note — added, annotated; all template values re-checked against `config.py` defaults.

Deviations: no live `--force` run on driveripper (needs the Oct-18 sudo-staged installer re-staged — it lacks the flags — and would push agent 1.1.0 mid phase-15 rollout); command + expected diff + post-checks recorded in AGENTS/gap 10. `uv pip list --outdated` still advisory (fastapi 0.153→0.156), untouched as in tasks 02/04 — this phase moved no dependency.

Next pending phase: `.agents/phases/todo/18_nav_hamburger/`.
This commit is contained in:
2026-10-20 13:48:40 -04:00
parent 7e367a9014
commit b02c13f7d3
30 changed files with 1502 additions and 81 deletions
@@ -0,0 +1,20 @@
**Phase 17 — final verification pass: complete, all green.**
Verified (criteria):
- `grep -n "DevicePolicy\|DeviceAllow" deploy/install-agent.sh` → no match; `PrivateDevices=false` retained (line 472) ✓
- `install-agent.sh --help` names `--as-root`/`--caps` with the kernel-gate sentence; `--force` documented ✓
- Fresh fake-root install = pre-phase unit minus the filter lines: `test_a_default_install_unit_is_the_pre_phase_unit_minus_the_filter_lines` + `test_the_template_unit_has_no_device_filter_lines` pass ✓
- Re-run that differs → exit 1 with diff on stdout, `--force` applies, identical re-run silent: `test_a_re_run_that_differs_refuses_without_force_and_applies_with_it` (+ 3 sibling guard pins) pass ✓
- driveripper reproduction — verified **read-only**, no live change: `systemctl cat` shows `User=root`, `CapabilityBoundingSet=CAP_SYS_RAWIO CAP_SYS_ADMIN`, no filter, same `ExecStart`; `active`, `CapEff 0000000000220000`; `/api/disks/snapshot` → 16/16 drives with temperatures ✓
- `uv run pytest` → **1451 passed, 15 skipped**; `bash .agents/validate.sh` → **exit 0** (coverage **98.94%** ≥ 94, `ruff` clean, `pyright` 0 errors, `node --check` + hygiene clean); `uv run pytest -m live --live` → **11 passed**; dev server 9/9 sources `ok` (one initial live failure was a transient gufo timeout, clean on re-run)
Docs (inconsistencies found + fixed, incl. pre-existing):
- `AGENTS.md` fleet record said driveripper's unit runs `User=dashboards-agent` while the same bullet (and the live host) says `User=root` — rewritten to separate the installed user from the running one.
- `AGENTS.md` gap 10 header still claimed "the installer template is what is left" → now records phase 17 as the fix.
- `README.md` "with no capabilities" → "with an empty `CapabilityBoundingSet` (unless `--caps`…)", since this phase added the capability flag.
- `README.md` battery-test "gated four times" now notes the two session gates in front, matching AGENTS invariant 1.
- `.env.example` was missing three README-documented settings (`DASH_ENV_FILE`, `DASH_RELOAD`, `NUT_SIMULATE`) and `AGENT_CERT_BUNDLE` in the agent-variables note — added, annotated; all template values re-checked against `config.py` defaults.
Deviations: no live `--force` run on driveripper (needs the Oct-18 sudo-staged installer re-staged — it lacks the flags — and would push agent 1.1.0 mid phase-15 rollout); command + expected diff + post-checks recorded in AGENTS/gap 10. `uv pip list --outdated` still advisory (fastapi 0.153→0.156), untouched as in tasks 02/04 — this phase moved no dependency.
Next pending phase: `.agents/phases/todo/18_nav_hamburger/`.
@@ -0,0 +1,65 @@
== uv run pytest --cov (hermetic: no network, live tests skip) ==
........................................................................ [ 4%]
........................................................................ [ 9%]
........................................................................ [ 14%]
........................................................................ [ 19%]
........................................................................ [ 24%]
...........................s............................................ [ 29%]
........................................................................ [ 34%]
........................................................................ [ 39%]
........................................................................ [ 44%]
........................................................................ [ 49%]
........................................................................ [ 54%]
........................................................................ [ 58%]
........................................................................ [ 63%]
................................................................ssssssss [ 68%]
sss..................................................................... [ 73%]
........................................................................ [ 78%]
........................................................................ [ 83%]
........................................................................ [ 88%]
........................................................................ [ 93%]
........................................sss............................. [ 98%]
.......................... [100%]
=============================== warnings summary ===============================
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
/var/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.4-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 176 0 100%
src/dashboards/api.py 436 0 100%
src/dashboards/app.py 185 0 100%
src/dashboards/auth.py 265 0 100%
src/dashboards/certs.py 292 0 100%
src/dashboards/collectors.py 205 5 98% 284-285, 289-290, 307
src/dashboards/config.py 120 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/host.py 209 0 100%
src/dashboards/sources/llm.py 178 1 99% 285
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 3490 37 99%
Required test coverage of 94% reached. Total coverage: 98.94%
1451 passed, 15 skipped, 1 warning in 153.26s (0:02:33)
== 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 ==
advisory: dependencies are out of date (AGENTS.md rule 8 — update on purpose):
fastapi 0.153.0 0.156.0 wheel
@@ -0,0 +1,16 @@
**Implemented (phase 17 task 01 — `deploy/install-agent.sh`)**
- Deleted `DevicePolicy=strict` + all nine `DeviceAllow=…` lines from the `do_install` unit heredoc; `PrivateDevices=false` stays explicit.
- Rewrote the rationale comment block (and the top-of-file/help paragraph) to the new truth: no device filter on purpose — systemd matches a device-filter glob by *name* against `/proc/devices`, kernel 7.2 lists NVMe as `blkext` (major 259), so `/dev/nvme*` matched nothing and a strict policy denied the whole namespace (driveripper, root included); device access is DAC via the `disk` group + SELinux. Kept the `status=208/STDIN` warning as the reason `PrivateDevices=false` is written out.
- `tests/test_deploy_scripts.py`: the sandbox-install test now pins the *absence* of the filter plus `PrivateDevices=false`; added `test_the_written_unit_is_only_comments_and_directives` — a defect found while verifying this task: the unit heredoc is unquoted (so phase 15's `$TLS_UNIT_LINES` expands), which **executes backticked prose** (`disk`, `blkext`, `/dev/nvme*` became `command not found` + a smartctl banner pasted into the unit). Mutation-checked: the pin catches it.
- Docs: README install paragraph and four AGENTS.md places (fleet divergence bullet, driveripper sudoers bullet, Deployment paragraph, gap 10) now say the template applies no device filter; the obsolete "missing `/dev/ng*n*`/`/dev/bsg/*` in the allow-list" warning is retired; gap 10 records `--as-root`/`--caps` + the re-run guard as the phase's remaining tasks.
**Tests / lint / coverage**
- `uv run pytest` → **1428 passed, 15 skipped** (was 1427; +1 new test), exit 0.
- `bash .agents/validate.sh` → exit 0: `pytest --cov --cov-fail-under=94` **98.94%** total, `ruff check src tests agent` clean, `pyright` 0 errors, `node --check` clean, repo hygiene clean. `uv pip list --outdated` empty (no deps moved).
- Task criteria: `grep -n "DevicePolicy\|DeviceAllow" deploy/install-agent.sh` → no match; `bash -n` clean; manual fake-root sandbox install (`--bind 127.0.0.1 --port 9199`) diffed against a HEAD-version sandbox install: directive lines differ **only** by the ten removed filter lines (comments rewritten per the task).
**README/AGENTS.md**: updated as above (docs stayed in sync mid-phase).
**Decisions/deviations**: the phase's grep criterion forbids the literal directive names in the script, so the comment explains them in prose ("device-filter glob", "strict device policy") instead of naming `DevicePolicy`/`DeviceAllow`. Added the heredoc-expansion pin (not in the task text) because it is a real pre-existing hazard this task's own comment nearly shipped. **No live-infrastructure changes** — the driveripper reproduction (`--as-root --caps … --force`, `systemctl diff`, 16/16 drives) is task 04's operator-gated step and needs the task 02 flags first.
**Next pending task**: `.agents/phases/todo/17_installer_device_filter/02_root_and_caps_flags.md`
@@ -0,0 +1,63 @@
== uv run pytest --cov (hermetic: no network, live tests skip) ==
........................................................................ [ 4%]
........................................................................ [ 9%]
........................................................................ [ 14%]
........................................................................ [ 19%]
........................................................................ [ 24%]
...........................s............................................ [ 29%]
........................................................................ [ 34%]
........................................................................ [ 39%]
........................................................................ [ 44%]
........................................................................ [ 49%]
........................................................................ [ 54%]
........................................................................ [ 59%]
........................................................................ [ 64%]
.........................................sssssssssss.................... [ 69%]
........................................................................ [ 74%]
........................................................................ [ 79%]
........................................................................ [ 84%]
........................................................................ [ 89%]
........................................................................ [ 94%]
.................sss.................................................... [ 99%]
... [100%]
=============================== warnings summary ===============================
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
/var/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.4-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 176 0 100%
src/dashboards/api.py 436 0 100%
src/dashboards/app.py 185 0 100%
src/dashboards/auth.py 265 0 100%
src/dashboards/certs.py 292 0 100%
src/dashboards/collectors.py 205 5 98% 284-285, 289-290, 307
src/dashboards/config.py 120 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/host.py 209 0 100%
src/dashboards/sources/llm.py 178 1 99% 285
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 3490 37 99%
Required test coverage of 94% reached. Total coverage: 98.94%
1428 passed, 15 skipped, 1 warning in 127.90s (0:02:07)
== 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 ==
@@ -0,0 +1,11 @@
**Task 02 — `--as-root` / `--caps` (phase 17) — done**
- `deploy/install-agent.sh`: added `--as-root` (`User=root`) and `--caps LIST` (`CapabilityBoundingSet=<space-separated>`), both off by default → default unit byte-identical to before; comma→space normalisation drops empty entries and runs with globbing off (`--caps '*'` stays literal).
- Validation: `--caps` without `--as-root` → stderr refusal + exit 1 **before** `need_root` and any write (same reasoning as the bundle validator); `--caps` with no argument / empty / punctuation-only → exit 1 with its own sentence; `--as-root` alone proceeds with the exact CapEff-0 note on stdout.
- Unit heredoc gained the one `--caps` comment above `CapabilityBoundingSet=`; `--status` and the token-file `0640 root:dashboards-agent` logic deliberately untouched; `--help` (the header comment) now names both flags with the kernel-gate sentence and the copy-pasteable recipe line.
- Tests (`tests/test_deploy_scripts.py`, 8 new / 12 new cases): exact `User=`/`CapabilityBoundingSet=` lines for default, `--as-root --caps …`, `--as-root` alone; parametrized refusals asserting nothing was written and no privileged stub ran; missing-argument refusal; normalisation + no-glob; `--help` recipe; `status()` blind to `AS_ROOT`/`CAPS`.
- `bash .agents/validate.sh` → **1439 passed, 15 skipped**, coverage **98.94%** (floor 94), `ruff check src tests agent` clean, `pyright` 0 errors, `node --check` clean, `bash -n deploy/install-agent.sh` clean; `uv run pytest -m live --live` → **11 passed** (unchanged).
- Docs: README (install flag block + a new kernel-gate paragraph) and AGENTS.md (fleet record, sudoers/grant bullet, deployment flag list, gap 10 tail) now state the flags exist, the `driveripper` recipe `--as-root --caps CAP_SYS_RAWIO,CAP_SYS_ADMIN`, and that the unconditional unit rewrite is task 03's remaining guard.
- **No live changes made**: the driveripper re-run (`systemctl diff`, `CapEff`, 16/16 drives) is task 04's operator-verified criterion, and gap 10 warns the sudo-granted Oct-18 *staged* snapshot would clobber the working unit — it must be re-staged from the repo first (now noted in AGENTS.md).
- Advisory only (not touched, deps not in scope): `uv pip list --outdated` reports `fastapi 0.153.0 → 0.154.0`.
- Next pending task: `.agents/phases/todo/17_installer_device_filter/03_no_silent_clobber.md`.
@@ -0,0 +1,65 @@
== uv run pytest --cov (hermetic: no network, live tests skip) ==
........................................................................ [ 4%]
........................................................................ [ 9%]
........................................................................ [ 14%]
........................................................................ [ 19%]
........................................................................ [ 24%]
...........................s............................................ [ 29%]
........................................................................ [ 34%]
........................................................................ [ 39%]
........................................................................ [ 44%]
........................................................................ [ 49%]
........................................................................ [ 54%]
........................................................................ [ 59%]
........................................................................ [ 64%]
....................................................sssssssssss......... [ 69%]
........................................................................ [ 74%]
........................................................................ [ 79%]
........................................................................ [ 84%]
........................................................................ [ 89%]
........................................................................ [ 94%]
............................sss......................................... [ 99%]
.............. [100%]
=============================== warnings summary ===============================
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
/var/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.4-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 176 0 100%
src/dashboards/api.py 436 0 100%
src/dashboards/app.py 185 0 100%
src/dashboards/auth.py 265 0 100%
src/dashboards/certs.py 292 0 100%
src/dashboards/collectors.py 205 5 98% 284-285, 289-290, 307
src/dashboards/config.py 120 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/host.py 209 0 100%
src/dashboards/sources/llm.py 178 1 99% 285
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 3490 37 99%
Required test coverage of 94% reached. Total coverage: 98.94%
1439 passed, 15 skipped, 1 warning in 135.34s (0:02:15)
== 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 ==
advisory: dependencies are out of date (AGENTS.md rule 8 — update on purpose):
fastapi 0.153.0 0.154.0 wheel
@@ -0,0 +1,18 @@
All green. Report:
**Implemented**
- `deploy/install-agent.sh`: new `--force` flag (`FORCE=0` default) + `--help` text (`--force overwrite an existing unit even if the generated unit differs (prints the diff first)`, aligned to the `--as-root`/`--caps` column).
- `do_install` now renders the unit heredoc to `mktemp "${TMPDIR:-/tmp}/dashboards-agent-unit.XXXXXX"`; if `$UNIT` exists and `! cmp -s`, it prints `refusing to overwrite $UNIT (generated unit differs); run with --force to apply:` + `diff -u` and `exit 1` **before** the unit write, `daemon-reload` and `enable --now`; with `--force` it prints the same diff then overwrites; identical unit → silent proceed. `--status`/`--uninstall` untouched.
- 8 new pins in `tests/test_deploy_scripts.py`: refuse (exit 1, diff on stdout, unit byte-identical to the hand-edit, token value+`0640` unchanged, **zero new `systemctl` calls**), force (diff then write + re-enable), silent idempotent re-run, fresh install unaffected (plain vs `--force` render identical), the `driveripper` kernel-gate line refuses once → applies with `--force` → silent afterwards, uninstall never asks, source-ordering pin (render < cmp < write < reload < enable, no `cat > "$UNIT" <<` remains), and a `--help` alignment pin.
- Docs: README install block + a re-run-guard paragraph, and TLS-rollout step 2 now runs `--cert-bundle … --force` with the reason (installing a bundle *is* a unit change); AGENTS.md fleet bullet, the Commands flag list + guard paragraph, gap 10's task-03 status, and gap 11's staged-snapshot warnings (the Oct-18 copy predates the guard, so it still clobbers silently).
**Tests / lint / coverage**
- `uv run pytest` → **1447 passed, 15 skipped**; `bash .agents/validate.sh` → green (coverage **98.94%**, floor 94%), `ruff check src tests agent` clean, `pyright` 0 errors, `node --check` ok.
- `uv run pytest -m live --live` → 11 passed (read-only; dev server still 9/9 `ok`). **No live infra change** — the `driveripper` `--force` reproduction is task 04's operator-verified step.
**Decisions / deviations**
- Guard sits immediately before the unit write (the task's own parenthetical), so the earlier idempotent writes still run; the refusal path never re-writes the unit nor touches the service, and the reused token's value/mode are pinned unchanged (mtime isn't — noted in the test and script comment).
- Refusal sentence *and* diff both go to stdout (the diff is the answer's payload; task-04 pins "diff on stdout"). Temp file gets a readable prefix so the diff's `+++` names the generated unit.
- Wrote the formal pins now rather than leaving the guard untested until task 04; task 04's remaining doc/live items are untouched except where my change made prose stale.
**Next pending task:** `.agents/phases/todo/17_installer_device_filter/04_tests_docs_gate.md`
@@ -0,0 +1,65 @@
== uv run pytest --cov (hermetic: no network, live tests skip) ==
........................................................................ [ 4%]
........................................................................ [ 9%]
........................................................................ [ 14%]
........................................................................ [ 19%]
........................................................................ [ 24%]
...........................s............................................ [ 29%]
........................................................................ [ 34%]
........................................................................ [ 39%]
........................................................................ [ 44%]
........................................................................ [ 49%]
........................................................................ [ 54%]
........................................................................ [ 59%]
........................................................................ [ 64%]
............................................................sssssssssss. [ 68%]
........................................................................ [ 73%]
........................................................................ [ 78%]
........................................................................ [ 83%]
........................................................................ [ 88%]
........................................................................ [ 93%]
....................................sss................................. [ 98%]
...................... [100%]
=============================== warnings summary ===============================
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
/var/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.4-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 176 0 100%
src/dashboards/api.py 436 0 100%
src/dashboards/app.py 185 0 100%
src/dashboards/auth.py 265 0 100%
src/dashboards/certs.py 292 0 100%
src/dashboards/collectors.py 205 5 98% 284-285, 289-290, 307
src/dashboards/config.py 120 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/host.py 209 0 100%
src/dashboards/sources/llm.py 178 1 99% 285
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 3490 37 99%
Required test coverage of 94% reached. Total coverage: 98.94%
1447 passed, 15 skipped, 1 warning in 146.51s (0:02:26)
== 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 ==
advisory: dependencies are out of date (AGENTS.md rule 8 — update on purpose):
fastapi 0.153.0 0.154.0 wheel
@@ -0,0 +1,15 @@
**Implemented**
- `tests/test_deploy_scripts.py`: added the four task-named pins — `test_the_template_unit_has_no_device_filter_lines` (heredoc region + the whole-file `DevicePolicy`/`DeviceAllow` absence, `PrivateDevices=false` kept, rationale must name `/proc/devices`/`blkext`/status 208), `test_a_default_install_unit_is_the_pre_phase_unit_minus_the_filter_lines` (whole pre-phase unit recorded verbatim as `PRE_PHASE_DEFAULT_UNIT` + `DEVICE_FILTER_LINES`, unified-diff failure output), `test_as_root_and_caps_write_the_kernel_gate_unit_lines` (recipe changes **exactly** two directives vs a default install; `--caps` alone refused before any privileged call; `--as-root` alone proceeds with the CapEff note), `test_a_re_run_that_differs_refuses_without_force_and_applies_with_it` (refuse→force→silent on one host).
- Mutation-checked both new filter pins (re-adding `DevicePolicy=strict`+`DeviceAllow=/dev/nvme*`, dropping `RestrictRealtime`, flipping `ProtectHome`) fail; script restored and `bash -n` clean.
- Docs: README's TLS rollout now restarts the service after `--force` and says why (installer uses `systemctl enable --now`, which only *starts*; `--status` picks http/https by reading the unit file); AGENTS.md gap 10 + the Deployment paragraph record task 04's read-only reproduction, the Oct-18 staged snapshot refusing the recipe with `unknown argument: --as-root`/exit 2, and the test count 1427→1451.
**Tests / lint** (`uv run`, exact): `bash .agents/validate.sh` → **exit 0** — `pytest --cov --cov-fail-under=94` **1451 passed, 15 skipped, coverage 98.94%**; `ruff check src tests agent` clean; `pyright` 0 errors; `node --check` + repo hygiene clean. `uv run pytest tests/test_deploy_scripts.py` → 63 passed, 0 failed. `uv run pytest -m live --live` → **11 passed, 0 skipped**; dev server all 9 sources `ok`.
**README/AGENTS changes:** as above (plus `data/logs/NOTES-17-installer-repro.md`, local/gitignored evidence).
**Decisions / deviations**
- "Byte-identical minus the ten filter lines" is compared on **directives** (comments are the one thing task 01 rewrote deliberately); the new prose is pinned separately for its mechanism sentences. Documented in the test.
- **No live change made.** `driveripper`'s installed unit was diffed (read-only, `systemctl cat`) against the sandbox render of `--bind 10.1.0.126 --port 9120 --as-root --caps CAP_SYS_RAWIO,CAP_SYS_ADMIN`: **every directive identical**, only comments differ; host `active`, `CapEff 0000000000220000`, 16/16 drives with temps. Running the real `--force` needs re-staging the sudo-granted Oct-18 snapshot (which lacks the flags, so it can't run them) and would push agent 1.1.0 to a prod host mid phase-15 rollout — left to the operator with the exact command, expected diff and post-checks in the note.
- `uv pip list --outdated` advisory (fastapi 0.153→0.155) left untouched, same handling as task 02; deps are not in this task's scope.
**Next pending task:** `.agents/phases/todo/18_nav_hamburger/01_hamburger_markup.md` (phase 17 has no other todo task).
@@ -0,0 +1,65 @@
== uv run pytest --cov (hermetic: no network, live tests skip) ==
........................................................................ [ 4%]
........................................................................ [ 9%]
........................................................................ [ 14%]
........................................................................ [ 19%]
........................................................................ [ 24%]
...........................s............................................ [ 29%]
........................................................................ [ 34%]
........................................................................ [ 39%]
........................................................................ [ 44%]
........................................................................ [ 49%]
........................................................................ [ 54%]
........................................................................ [ 58%]
........................................................................ [ 63%]
................................................................ssssssss [ 68%]
sss..................................................................... [ 73%]
........................................................................ [ 78%]
........................................................................ [ 83%]
........................................................................ [ 88%]
........................................................................ [ 93%]
........................................sss............................. [ 98%]
.......................... [100%]
=============================== warnings summary ===============================
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
/var/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.4-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 176 0 100%
src/dashboards/api.py 436 0 100%
src/dashboards/app.py 185 0 100%
src/dashboards/auth.py 265 0 100%
src/dashboards/certs.py 292 0 100%
src/dashboards/collectors.py 205 5 98% 284-285, 289-290, 307
src/dashboards/config.py 120 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/host.py 209 0 100%
src/dashboards/sources/llm.py 178 1 99% 285
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 3490 37 99%
Required test coverage of 94% reached. Total coverage: 98.94%
1451 passed, 15 skipped, 1 warning in 154.14s (0:02:34)
== 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 ==
advisory: dependencies are out of date (AGENTS.md rule 8 — update on purpose):
fastapi 0.153.0 0.155.0 wheel