README advertised `uv run pytest -m live --live`, but there was no --live
option and no `live` marker registered — the command errored out, so the
one workflow that catches an upstream renaming a series did not exist.
- conftest adds --live and skips `live`-marked tests without it, so the
default run stays hermetic (258 passed, 6 skipped, no network).
- tests/test_live_fleet.py drives the real code paths (collectors.*,
NutMonitor.collect) against the fleet, both engines, and upsd. Each
skips when its source is unset, and none of them may write — a battery
test on live hardware is not a unit test. The host test polls twice
because a rate has no second point on the first scrape.
- The agent's real-/proc test stays in the default run and is explicitly
not `live`: it touches only the box running pytest.
- dev-tunnels.sh grows DEV_FORWARDS for services already listening
remotely, which is how upsd gets reachable without opening 3493;
pidfiles are now host+port so one host can carry two tunnels.
- requires-python, ruff and pyright were still on 3.13 while the venv and
Containerfile are 3.14, so the lock resolved for a stack nobody deploys.
LLM-Generated: true
The README referenced `deploy/install-agent.sh` and a `Containerfile` that
did not exist, so a fresh clone had no way to actually run this anywhere.
* agent: `--token-file` (and AGENT_TOKEN_FILE). The token guards hostname,
mounts, disk and GPU models and process names, and argv is world-readable
through `ps`, so a file has to win over the flag. Missing or empty token
files are fatal — falling back to "no token" would expose the host.
* deploy/install-agent.sh: creates a system user, generates the token once
(re-runs reuse it, --rotate-token for a new one), stores it 0600
root-owned, and runs the agent under ProtectSystem=strict with no
capabilities; --status and --uninstall included.
* Containerfile: two-stage, uv.lock resolved in the builder and slim Python
in the runtime. Verified with podman — the image serves /api/health as an
unprivileged user and writes its history under /var/lib/dashboards.
UV_PROJECT_ENVIRONMENT and --no-editable are what make the venv survive
being copied into the runtime stage.
* .containerignore keeps .git, .venv, data/ and .env out of the build
context.
258 tests, 94% coverage; ruff and pyright clean.
LLM-Generated: true
Three dashboards served by one FastAPI app with a SQLite history store
(raw / 1m / 1h) and hand-written SVG charts: no Prometheus, no Grafana,
no CDN, no build step. Nothing is fetched from the internet at runtime.
* system: a stdlib-only agent (agent/host_agent.py) reports /proc and
/sys counters; the dashboard turns them into rates over a labelled
window, so every number says how it was measured.
* llm: gufo/llama.cpp and vLLM /metrics are parsed by an in-house
exposition parser. Measured delta/elapsed throughput beats a native
per-request gauge, and each value carries its provenance.
* ups: a NUT wire-protocol client plus health checks that name what
they looked at. Commands are gated by NUT_ALLOW_ACTIONS,
DASH_READ_ONLY and a DANGER confirmation, re-checked server-side.
Missing values render as n/a rather than 0, and an unconfigured source
answers 404 {"configured": false} without dialling anything, so "not
deployed here" never looks like an outage.
253 tests at 94% coverage against captured real fixtures; ruff and
pyright clean.
LLM-Generated: true