# felhom.eu — task reports > **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md). ## BUNDLE slice — Day-0 artifact manifest + self-install the agent (2026-06-28) **Hub v0.15.0 → v0.16.0** @ `39ef64e`/`d5266ca` · **host-install v1.0.0 → v1.1.0** @ `30ecf73` The host-bootstrap script now **installs the agent itself** (the last manual Day-0 prerequisite is gone). It fetches the agent binary + golden from Gitea generic packages and **verifies each artifact's sha256 against a hub-vouched manifest** before installing/using it. The hub is the checksum **trust root** (a different root than Gitea, which only stores the bytes); the fetch credential is the git token already inside the customer's `controller.yaml` (config-retrieve) — **no new credential**. ### Hub (v0.16.0) - `store.go`: `ArtifactManifest{agent,golden version+sha256}` in the existing `hub_settings` table; `Get/SetArtifactManifest` + generic `getSetting/setSetting`. - `handler.go`: `GET /api/v1/artifacts/{customer_id}` — auth mirrors `handleConfigRetrieve` (`X-Retrieval-Password`, 404-then-401, constant-time). Unset manifest → 200 with empty fields. - `configs.go` + `configs.html`: operator UI "Day-0 artifacts" card (`POST /configs/artifacts`, semver + 64-hex validation). `main.go`: env-seed (`ARTIFACT_AGENT_VERSION`/`…_SHA256`/`GOLDEN_…`), empty-fields-only so a UI edit sticks (the operator UI is password-gated — same escape hatch as the Phase-2 floor). - Tests (`artifact_test.go`): returned-verbatim / unset-empty / 401 / 404 / store partial round-trip. ### host-install (v1.1.0) - New **step 5/8 agent-install**: resolve manifest + git token → fetch binary → **verify sha256 vs hub manifest** (abort on mismatch) → install the non-root `felhom-agent` user + binary + sudoers (`visudo -cf`-validated) + canonical unit. Installs the `sudo` package (the non-root model needs it). - New **step 7/8 golden**: local fallback else fetch+verify+import from Gitea (`--force-gitea-golden`). - Agent now runs **non-root** (`privileged.mode: "sudo"`); config chowned to the service user. - `--skip-provision` (agent-only install/verify), pre-flight relaxed (binary no longer required), README prerequisites trimmed to: install PVE + create the customer. ### Green gate Hub: `go build/vet/test ./...` green. Scripts: `bash -n` + `shellcheck -S warning` clean. ### Deployed + live-proven (felhom-pve, demo-felhom) - Hub **0.16.0** rolled out to k3s (`felhom-system/hub`); artifact manifest seeded via env. Endpoint live: correct passphrase returns the manifest; **wrong/missing → 401, unknown customer → 404**. - Published **agent 0.43.0** (sha `8b989917…`) + **golden 0.85.1** (sha `f87031cc…`) to Gitea generic. - **From-scratch agent install** (live agent moved fully aside): fetch → **verify sha256** → install (non-root user + binary + sudoers + unit + config) → service **active as `felhom-agent`** → `--selftest=hub` host-report landed → **9201 still managed**. The git token (from `controller.yaml`) reads Gitea generic packages (confirmed PUT/GET/DELETE). - **sha256 negative:** a corrupted published binary made the install **abort** ("Refusing to install — verify-before-use", exit 1); the good binary was then restored (sha re-verified). - **Golden fetch+verify+import** from Gitea proven; the test-imported copy was cleaned up. ### Two real bugs found + fixed live 1. The `sudo` package wasn't installed (the host ran the agent root+`direct`) — step 5 now installs it. 2. `felhom-agent.sudoers` had **unescaped commas** in the `lvs`/`lsblk -o` lists → `visudo -cf` rejected it (never validated live before). Fixed in felhom-agent (escaped commas). ### Observations - **Throwaway full provision SKIPPED** to protect the live demo: a guest provisioned with demo-felhom's config would fight the live 9201 for the Cloudflare tunnel/domain. The new code (agent install + golden fetch/verify/import) is fully proven; the golden→guest restore is unchanged from prior slices. Use a dedicated throwaway customer for an end-to-end provision proof. - **Non-root + PBS:** the agent can't read `/etc/pve/priv` as `felhom-agent` (PBS datastores skipped with a WARN; cadence disabled on the demo). Needs a pmxcfs group/ACL or sudoers grant for PBS in production — follow-up. - **Per-customer artifact pinning** is a future hook (the endpoint already takes the customer id; v0.16.0 returns the global current set). - felhom-pve left with a **healthy non-root agent 0.43.0** + 9201 managed; rollback bundle kept at `/root/agent-backup-bundle-test`.