carlos / platform Public

host: the system leg observes once at arming, not an hour later

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QCUCpfxbCyEAVQ2m51dH5
Paul Campbell pushed by paul@keymail.dev 1378dec1c29b82faa21f19b2eea8b9c84e286b50 parent c96a740
2 files changed, +12 −0
  • internal/host/agent.go +7 −0
  • internal/host/systemleg_test.go +5 −0
diff --git a/internal/host/agent.go b/internal/host/agent.go
index 9f509684f..4836f8f05 100644
--- a/internal/host/agent.go
+++ b/internal/host/agent.go
@@ -1534,6 +1534,13 @@ func fastConvergeLoop(reg *registry.Registry, svc *activator.Service, sd *schedu
// in a loop of its own because the spread deadline needs a seconds
// cadence to run down on, and this is the loop that already has one.
d.systemLeg = newSystemLeg(store, pub, os.Getenv, dd, optDir)
+ // One observe at arming, on restartSeed's precedent: the leg below only
+ // re-observes on a serial move or at its hourly floor, so a box that
+ // (re)starts under an already-promoted pointer would otherwise sit on the
+ // old build for up to an hour with nobody to bump the serial. observe
+ // handles "no pointer" itself, which is every deployment before its first
+ // `carlos system update`.
+ d.systemLeg.observe(ctx)
log.Printf("agent: fast converge loop armed (2s + jitter: serial poll + canary/* + unstaged routes + system pointer)")
for {
time.Sleep(fastTickEvery + rand.N(time.Second))
diff --git a/internal/host/systemleg_test.go b/internal/host/systemleg_test.go
index 437e74f3b..a8bc4bb56 100644
--- a/internal/host/systemleg_test.go
+++ b/internal/host/systemleg_test.go
@@ -101,6 +101,11 @@ func TestSystemLegFetchesVerifiesAndRequestsAfterTheSpread(t *testing.T) {
body := []byte("ELF v2")
f.promote("v2", body, 10*time.Minute)
f.leg.observe(context.Background())
+ // One observe with a pointer present arms the pending update — this is
+ // what fastConvergeLoop's observe-at-arming relies on.
+ if f.leg.pending == nil || f.leg.pending.version != "v2" {
+ t.Fatalf("observe armed pending = %+v, want v2", f.leg.pending)
+ }
if _, err := f.marker(); err == nil {
t.Fatal("requested before the spread elapsed")
}