feat(broker): declare node_kind broker in spawn capability metadata
Summary
AgentWorkforce/cloud#5310 makes Cloud spawn placement refuse an unclaimed node unless one of its spawn:<harness> capabilities declares metadata.configured.node_kind ("desktop" or "broker"). The CLI broker sent metadata: None on its spawn capacity, so every unclaimed CLI broker became non-spawnable until someone ran agent-relay node claim.
build_node_register(crates/broker/src/node_control.rs) now runs every capability through a new helper,spawn_capability_metadata. Onspawn:*capabilities it setsmetadata.configured.node_kind = "broker"only when no kind is already declared, and it leaves the rest ofconfigured(andlive) untouched. Non-spawn capabilities pass through unchanged.- Every register and re-register path goes through
build_node_register, and the heartbeat descriptor reuses the registered capabilities, so the declaration is on both frames. - Relay Desktop builds its own node frames in the relay-desktop repo (
probe/src/relay/spawn/wire.rs, which declaresnode_kind: "desktop"). It does not use this code path. If a manifest that reaches the broker already declaresdesktop, that value is preserved (covered by a test).
Tests
- New:
build_node_register_declares_broker_node_kind_on_every_spawn_capabilitychecks the wire JSON and the heartbeat.build_node_register_preserves_declared_node_kind_and_configured_factschecks that a desktop kind and existingconfigured/livefacts are preserved. Updated:build_node_register_prefers_manifest_identity. cargo test -p agent-relay-broker --lib -- node_control::tests runtime::init: 121 passed, 0 failed.- Mutation 1 (helper returns metadata unchanged): 3 tests fail (
declares_broker_node_kind…,preserves_declared…,prefers_manifest_identity). - Mutation 2 (always overwrite
node_kind): onlypreserves_declared_node_kind…fails, withleft: {"node_kind":"broker",…} right: {"node_kind":"desktop",…}. The other tests surviving is expected, because they never declare a kind. cargo fmt --check: OK.cargo clippy --lib --bins -D warnings: OK.--all-targetsreports 2 existing test-code lints (node_control.rs:8057,:8677) from older commits. This diff does not touch them.
RelayFlow proof
- Change type:
feature - RelayFlow case:
5310-broker-node-kind
The case runs the broker artifact against a fake Relaycast, accepts the first node.register, and records each capability's metadata.configured.node_kind. I verified it locally with the fix mutated out (base) and with it in place (head). Both runs exited 0:
- base:
absent spawn_capabilities_state_no_node_kind. All sixspawn:*havenode_kind: null. - head:
fixed spawn_capabilities_declare_broker_node_kind. All sixspawn:*declare"broker".release, native-delivery and delivery-cursor capabilities staynull.
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
[!NOTE]
Low Risk
Narrow registration-metadata change with tests and a relayflow proof; only affects spawn capability wire shape for brokers missing node_kind.
Overview
Fixes Cloud spawn placement for unclaimed CLI brokers after cloud#5310 started requiring metadata.configured.node_kind on spawn:<harness> capabilities.
build_node_register now runs capabilities through spawn_capability_metadata, which sets configured.node_kind to "broker" only on spawn:* entries when no kind is already present; existing values (e.g. "desktop") and other configured/live metadata are unchanged. Non-spawn capabilities are untouched. Because registration and heartbeats reuse this path, the declaration appears on node.register and heartbeat capability snapshots.
Adds unit tests for default injection, preservation of declared kinds/facts, and an updated identity test; adds RelayFlow case 5310-broker-node-kind that observes the first node.register from a broker binary. CHANGELOG documents the patch under Unreleased.
Reviewed by Cursor Bugbot for commit 57cd5800526bb7f5349b2e056c2456ba89db223f. Bugbot is set up for automated code reviews on this repo. Configure here.
Agent Relay sessions
claudesession942cd2fb· opened viagh pr create· last active 2026-10-18