Gates only. No release, no version bump, no binary published; the agent stays
v0.128.0 at 28ba8593b8 and nothing on a customer's machine changes.
THE COUPLING DEFECT. The registry stopped serving 0.120.0 and older while
check-published-versions.py demanded every tag still be downloadable. Both rules
are sensible and together they are impossible, so CI went red at a commit whose
own run had been GREEN the day before -- and would have gone red again at the
next publish when 0.121.0 was evicted. scripts/retention-policy.json is now THE
number and both readers take it from there.
WHAT CI NO LONGER COVERS, and it prints this on every run rather than leaving it
to be discovered: a released version older than the retention window is no longer
asserted downloadable. Its git tag and its config tree ARE still asserted -- only
the binary's presence is dropped. A missing policy file is INCONCLUSIVE (exit 2),
never silently unbounded.
THE NUMBER IS NOT A LOCATED RULING and the file says so in its own header. Ten is
what the registry demonstrably holds; no register row records a prune, R-210 says
"Nothing was deleted; this is a list, not an action" and concerns local Docker
images, and container packages hold 19 each. The principled bound is the hub's
vouched min_agent floor -- nothing can install below it -- and that is the
recorded follow-up.
check-release-complete.py is the tag half as a machine. release-agent.sh already
warned that "a released version without a git tag 404s a box mid-install, as
root" and the step was still missed, so this is a gate and not a reminder. Legs
1-2 need no network and run in --fast, so the pre-push hook is the earliest
catch. Red-proved by repointing the CHANGELOG head at an unreleased v0.129.0:
both legs convicted and each named its fix command.
Three controls run: green at 10 naming what it dropped; widened to 11 the evicted
version re-enters and convicts; policy removed gives INCONCLUSIVE naming the path.
3.2 KiB
REPORT — felhom-agent, 2026-08-09 (gates only)
No release. No version bump. No binary published. scripts/ only — nothing that runs on a
customer's machine changed, and the agent stays v0.128.0 at 28ba8593b8.
What changed
| file | why |
|---|---|
scripts/retention-policy.json (new) |
THE retention number, in one place, with its reasoning and its honesty about where the number came from |
scripts/check-published-versions.py |
reads that number; bounds its assertion to the newest N; prints what it stopped covering |
scripts/check-release-complete.py (new) |
asserts the CHANGELOG-head version is tagged, placed in this history, and published |
scripts/agent_gates.py |
registers the new gate; legs 1–2 are offline so it runs in --fast too |
The coupling defect, and the fix
The prune keeps the newest N; the published-versions check demanded that every tag be
downloadable. Nothing connected them, so CI went red at 28ba8593b8 — a commit whose own run had
been green the day before — and would have gone red again at the next publish when 0.121.0 was
evicted. Both now read generic_versions_kept from one file.
What CI no longer covers: a released version older than the retention window is no longer asserted downloadable. Its git tag and its config tree are still asserted; only the binary's presence is dropped. The check names the dropped versions on every run.
The number is not a located ruling. generic_versions_kept: 10 is what the registry demonstrably
holds; no register row records a prune, and container packages hold 19 each. The file says so in its
own header. The principled bound is the hub's vouched min_agent floor — nothing can install below
it — and that is recorded as the follow-up.
Controls, all three run
| control | expected | got |
|---|---|---|
| live run, policy = 10 | green, and it names 0.120.0 as not asserted |
exit 0, and it did |
| widen policy to 11 | 0.120.0 re-enters the window and convicts |
exit 1, FAIL v0.120.0 |
| policy file removed | INCONCLUSIVE, never silently unbounded | exit 2, naming the path it tried |
Red-proof of the new gate
Mutation: CHANGELOG.md head repointed to ## v0.129.0 — never tagged, never published. Asserted
applied (grep -c '^## v0.129.0' → 1). Result exit 1, both legs convicting:
- TAG v0.129.0 DOES NOT EXIST. … without the tag every install 404s mid-run, as root.
Fix: git tag -a v0.129.0 <released-commit> && git push origin v0.129.0
- PACKAGE 0.129.0 IS NOT PUBLISHED (HTTP 404 …).
Fix: bash scripts/release-agent.sh 0.129.0
Reverted; git status clean on CHANGELOG.md.
Green gate
python3 scripts/agent_gates.py — reuse-refs OK · instructions OK · published OK · release-complete OK · all agent gates OK.
Not done here
The deleter of 0.120.0 is still not established and a second attempt failed — Gitea keeps no
package-deletion trail, its container log no longer reaches the window, and the activity feed carries
no package operation. Recorded in R-287, including the withdrawal of my own earlier over-claim that
the router logs showed no DELETE: they do not cover the window, so they never said anything.