# REPORT — felhom-agent v0.43.0 (BUNDLE slice: canonical unit + Gitea publish) **Date:** 2026-06-28 · **Baseline:** v0.42.0 @ `aaa276a` → **v0.43.0** @ `a8d14fc` ## What shipped Day-0 no longer needs a hand-installed agent. The binary is **published to Gitea** and the host-bootstrap script fetches → verifies (sha256 vs the hub-vouched manifest) → installs it. This commit adds the **canonical systemd unit** and the publish tooling; the binary is a version-only rebuild (no behavioural change). - **`configs/felhom-agent.service`** (NEW, canonical) — `User=felhom-agent` (the documented non-root production model; `privileged.mode: "sudo"` + the sudoers allowlist), `ExecStart=/usr/local/bin/felhom-agent --config /etc/felhom-agent/agent.json`, `Restart=on-failure`, `StateDirectory=felhom-agent`. **No `NoNewPrivileges`** (would block the `sudo` the agent needs) and **no mount-namespacing hardening** (would put the agent in a private mount namespace, breaking `mount --make-shared`/`--bind` drive propagation into guests) — both documented inline. - **`scripts/publish-agent.sh`** (NEW) — build (optional) + PUT binary to `/api/packages/admin/generic/felhom-agent//felhom-agent`, print `AGENT_VERSION`/`AGENT_SHA256`, GET round-trip re-verify. Pinned version, idempotent (delete-then-PUT), asserts `--version` matches. - **`configs/build-golden.sh`** — after vzdump, compute sha256 + PUT `/api/packages/admin/generic/felhom-golden//golden.tar.zst`, print `GOLDEN_VERSION`/`GOLDEN_SHA256`. Opt-in; local auto-discovery stays a fallback. - **`configs/felhom-agent.sudoers`** (latent bug fix) — escaped the commas in the `lvs -o …` and `lsblk -o …` argument lists. Bare commas are command separators in sudoers, so `visudo -cf` **rejected** the file; it had never been visudo-validated live because the demo ran the agent root+`direct` (sudoers unused). Surfaced by the live install's `visudo -cf` gate. - **`cmd/felhom-agent/main.go`** — `version` 0.42.0 → 0.43.0. - **README** — "Process model" section made canonical (non-root + publish/install). ## Green gate `go build ./... && go vet ./... && go test ./...` — all green. `scripts/publish-agent.sh` + `configs/build-golden.sh`: `bash -n` + `shellcheck -S warning` clean (the one SC2034 in build-golden.sh is a pre-existing DHCP-wait loop counter, not this change). ## Live (felhom-pve, demo-felhom) — proven - Built + published **agent 0.43.0** via `publish-agent.sh` → sha256 `8b989917…`; GET round-trip OK. - Published the existing **golden 0.85.1** (575 MiB) to Gitea → sha256 `f87031cc…`. - **From-scratch install** (after moving the live root+direct agent fully aside): the script fetched the binary from Gitea, **verified sha256 vs the hub manifest**, installed the non-root `felhom-agent` user + binary + sudoers (`visudo -cf`-validated) + the canonical unit + config (0600 `felhom-agent`); the service came up **active as non-root felhom-agent**, `--selftest=hub` landed a host-report, and guest **9201 stayed managed** (present in the host-report). `sudo -n` confirmed live for mkdir/smartctl/lvs (the escaped-comma sudoers works). - **sha256 negative:** a deliberately-corrupted published binary made the install **abort** ("Refusing to install (verify-before-use)", exit 1); the good binary was restored (sha re-verified). ## Observations - **Non-root + PBS:** the `felhom-agent` user cannot read `/etc/pve/priv/storage/*.pw` (root-only on pmxcfs), so PBS datastores are skipped with a WARN (graceful; PBS cadence is 0 on the demo). A production host using PBS needs the agent granted read access to that key (group/ACL on pmxcfs, or a sudoers entry) — follow-up, out of this slice. - **`sudo` package** must be present for the non-root model; the host-install script now `apt-get install`s it (a root+`direct` host won't have it).