Persist unreported fleet node load honestly
What changed
- accept absent or null
node.heartbeat.loadand constrain measured values to[0,1] - persist an explicit
load_reportedbit for nodes and providers via migration0034 - return
load: nullwhen a node-wide load is not fully measured - preserve
max_agents: 0as unlimited across provider aggregates - rank unknown-load nodes by active agent count rather than treating them as measured idle
- update TypeScript, Python, Rust, and Swift SDK contracts and heartbeat producers
Why
Unbounded providers use max_agents: 0. Existing heartbeats and persistence converted the undefined utilization ratio into load: 0, so a node with 25 active agents appeared identical to one with 4 and consumers rendered both as confidently idle.
load now has one definition: managed-agent capacity utilization (active_agents / max_agents), bounded to [0,1]. CPU, memory, queue depth, and dispatch latency are separate metrics. When no finite denominator exists—or any constituent provider is unmeasured—the aggregate load is explicitly unavailable.
The migration also keeps old unbounded-provider load: 0 heartbeats unreported during a rolling upgrade, so legacy senders cannot revive the false idle state.
Impact
GET /v1/nodes now returns load: null when utilization is unavailable. SDK consumers must handle the nullable field. Finite-capacity nodes continue returning a numeric ratio.
Companion Relay broker PR: https://github.com/AgentWorkforce/relay/pull/1445
Validation
- 101 focused engine, fleet-wire, and TypeScript SDK tests passed
- TypeScript typechecks passed for engine, types, and SDK packages
- Python node SDK: 17 tests passed
- Rust SDK: 42 tests passed
- migration
0034backfill exercised against finite, unbounded, mixed-provider, and direct-node fixtures - Swift implementation sources compiled; Swift tests could not run on this host because the installed toolchain lacks
XCTest