hub v0.102.0 — refuse to vouch a version that cannot be installed (R-273)

The guard owed since Friday morning. Agent v0.128.0 was published as a package
and never git-tagged; it was vouched here; and because felhom-host-install.sh
fetches an agent's configs from raw/tag/v<version>/configs/, every fresh install
and reinstall died at step 5 of 8, as root, on a virgin machine, for most of a
day. handleSetArtifacts is the sole UI path to SetArtifactManifest, so the check
belongs here and nowhere else.

TWO LEGS, because both failed inside two days: the TAG (missing, R-273) and the
PACKAGE (pruned from under a still-tagged version, R-287). Either alone catches
one of them.

It asserts configs/felhom-mkfs-guarded.sh -- the FIRST of the installer's sixteen
fetch_raw calls and literally the file whose 404 broke Friday. A test pins the
constant, because probing a path that merely exists is how it stayed invisible.
The golden gets the package leg only: it has no config tree, so a tag probe would
assert something the installer never does.

"Could not verify" refuses too, with its own message. No override -- the registry
is the operator's own server, so if it is unreachable the vouch can wait.

ORDERING IS LOAD-BEARING AND A FAILING TEST FOUND IT. The probes run before
resolveArtifactSHA, whose flash conflates "missing", "unreachable" and "bad sha".
Probing first means an unreachable registry is reported as unreachable.

Five scenarios each naming the wrong outcome; three red-proofs, mutations asserted
applied and reverted. With the tag check removed, scenario A reports artifacts_set
-- Friday's exact defect returns.
This commit is contained in:
2026-08-09 19:13:45 +02:00
parent 6088afcbed
commit b55fc17d82
5 changed files with 428 additions and 0 deletions
+32
View File
@@ -1,3 +1,35 @@
## v0.102.0 — the hub refuses to vouch a version that cannot be installed (2026-08-09, R-273)
**The guard owed since 2026-08-09 morning.** Agent v0.128.0 had been published as a package and never
git-tagged. It was vouched here. `felhom-host-install.sh` fetches an agent's config files from
`raw/tag/v<version>/configs/`, so **every fresh install and every reinstall died at step 5 of 8 — as
root, on a virgin machine — for most of a day.** Nothing checked, and the moment of risk is this
handler: `handleSetArtifacts` is the sole UI path to `SetArtifactManifest`.
**Two independent legs, because both failed within two days of each other.** The TAG was missing on
2026-08-08 (R-273); the PACKAGE was pruned out from under a still-tagged version on 2026-08-08/09
(R-287). Checking either alone would have caught one of them.
- **It asserts the path the installer really fetches.** `configs/felhom-mkfs-guarded.sh` is the FIRST
of the sixteen `fetch_raw` calls and is literally the file whose 404 broke Friday. A probe against
some other path that merely exists is how that failure stayed invisible; a test pins the constant.
- **The golden gets the package leg only** — it is fetched by version and has no config tree, so a tag
probe on it would assert something the installer never does.
- **"Could not verify" is also a refusal, and says so differently.** An unreachable registry refuses
with its own message rather than saving with a warning: a warning beside a success is read as a
success. **There is deliberately no override** — the registry is the operator's own server, so if it
cannot be reached the vouch can wait.
- **Ordering is load-bearing, and a failing test found it.** The probes run BEFORE `resolveArtifactSHA`,
whose failure flash reads *"version missing / Gitea unreachable / bad sha"* — three facts in one
message. Probing first means an unreachable registry is reported as unreachable.
New in `internal/gitea`: `TagServesFile`, `PackageDownloadable`, and a three-valued `ProbeResult`
(yes / no / could-not-tell) so "absent" and "unanswerable" cannot collapse into each other.
Five scenarios, each naming the wrong outcome it prevents (`artifact_installability_test.go`), and
three red-proofs: the tag check removed (scenario A then reports `artifacts_set` — **Friday's exact
defect returns**), the package check removed, and the inconclusive branch mapped onto the success path.
## v0.101.0 — the artifact dropdown is memoised for 60 seconds (2026-08-08, R-267, operator ruling)
v0.100.x took `/configuration` from 26.2 s to a mean of ~9.85 s by removing the serialisation. What