R-812 option A (hub): the Proxmox package set — candidate, operator approval, System page

Layer pve: never auto-approved; the candidate is the Proxmox userspace set
every ring-0 box reports (kernel / boot / firmware names left out); the
operator's "Approve Proxmox set" button appears only after 2 healthy night
pve steps on every ring-0 box; an approval nudges no box (ring 1 by a signed
os_pve_step). 11 §5.10 written (BUILT, unreleased, not yet proven live); §8
step 6 split (userspace §5.10, kernel R-836).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-07 10:11:45 +02:00
parent c01ea2e7e9
commit e7fb10200e
9 changed files with 289 additions and 8 deletions
+28
View File
@@ -185,3 +185,31 @@ func TestHostsPage_ProxmoxKernelColumn(t *testing.T) {
t.Fatalf("hosts column missing:\n%s", b[:min(len(b), 400)])
}
}
// R-812 option A: the "Approve Proxmox set" button appears ONLY when the rule allows it (one render test per branch).
//
// COMPANION RED-PROOF (observed): drop the `(eq .Waiting "")` from the pve button's condition → "button shown after ONE night".
func TestSystemPage_PVEButtonOnlyWhenReady(t *testing.T) {
s, st, svc := systemServer(t)
if strings.Contains(getSystem(t, s), `action="/os/approve-pve"`) {
t.Fatal("button shown with no Proxmox candidate")
}
_ = st.SetOSRing("full-1", 0)
clock := time.Date(2026, 10, 7, 3, 0, 0, 0, time.UTC)
svc.Now = func() time.Time { return clock }
night := func() {
r := osupdates.Report{RunID: time.Now().String(), Layer: "pve", Trigger: "night", Mode: "apply", Outcome: "nothing",
Healthy: true, Installed: []osupdates.Package{{Name: "pve-manager", Version: "9.2.21", Origin: "Proxmox"}}}
if err := svc.Ingest("full-1", r); err != nil {
t.Fatal(err)
}
}
night()
if strings.Contains(getSystem(t, s), `action="/os/approve-pve"`) {
t.Fatal("button shown after ONE night")
}
night()
if !strings.Contains(getSystem(t, s), `action="/os/approve-pve"`) {
t.Fatal("button missing after two healthy nights")
}
}