hub: the held-floor REASON must match the CAUSE (CAMPAIGN-11 follow-on)
gates / gates (push) Successful in 7s

v0.97.0 introduced a second hold reason and left both surfaces printing the first. The
freshly deployed hub logged, for the campaign box:

  managed floor HELD for c11: agent "0.125.0" < MinAgent 0.113.0

which is FALSE — 0.125.0 is ABOVE 0.113.0. That box is held because its floor sits above
the vouched golden, not because of its agent. CLAUDE.md's corollary exactly: when a verdict
changes which field it counts from, the alarm text has to change with it, or a true alarm
reads as one to dismiss.

Both the ACK log line and the Hosts-dashboard HeldReason now come from one
ManagedFloorDecision.HoldReason(), and TestResolveManagedFloor_HoldReasonMatchesTheCause
pins each reason to its cause.
This commit is contained in:
2026-08-05 17:53:24 +02:00
parent cad0406e2b
commit a7f1d277b1
5 changed files with 111 additions and 5 deletions
+1 -2
View File
@@ -4,7 +4,6 @@ import (
"database/sql"
"encoding/json"
"errors"
"fmt"
"net/http"
"sort"
"strings"
@@ -401,7 +400,7 @@ func (s *Server) handleHostsList(w http.ResponseWriter, r *http.Request) {
// never silently stale.
if fd := s.store.ResolveManagedFloor(h.CustomerID); fd.Held {
row.FloorHeld = true
row.HeldReason = fmt.Sprintf("held: agent %s < MinAgent %s", agentOrUnknown(fd.AgentVersion), fd.MinAgent)
row.HeldReason = fd.HoldReason()
}
// Guest counts from the reality table (per-host accurate).