Skip to content

fix(broker): restore live agent roster after reconnect - #1494

Merged
khaliqgant merged 3 commits into
mainfrom
fix/restore-live-agent-roster-on-reconnect
Aug 12, 2026
Merged

fix(broker): restore live agent roster after reconnect#1494
khaliqgant merged 3 commits into
mainfrom
fix/restore-live-agent-roster-on-reconnect

Conversation

@khaliqgant

@khaliqgant khaliqgant commented Aug 12, 2026

Copy link
Copy Markdown
Member

Summary

  • retain each successfully launched, node-registered worker in the broker reconnect inventory
  • resolve opaque caller-supplied and HTTP-fallback tokens to their authoritative agent IDs, validating the requested name before inventorying them
  • deliver inventory updates reliably and in order under fleet-control backpressure
  • replay that inventory through the existing inventory.sync reconnect path so Relaycast reactivates live workers
  • preserve invocation and resumable-session metadata in the snapshot

Root cause

Relaycast deliberately marks all agents attached to a node provider offline when its node-control socket disconnects. The broker reconnect path can restore those agents through inventory.sync, but production fleet_inventory started empty and successful agent.register calls only populated FleetDeliveryBook. The node therefore reconnected with an empty inventory while its local worker processes remained alive. Node heartbeat and activeAgents could be healthy at the same time that individual roster rows remained offline.

This records inventory only after process launch succeeds, so a failed spawn is not advertised as live. Existing release and failed-spawn cleanup paths already prune the same inventory. Opaque pre-minted tokens are resolved through the authenticated current-agent endpoint; a token for a different name is rejected from reconnect inventory. Inventory publication now awaits bounded-channel capacity instead of dropping the only updated snapshot.

Refs #1458. This is complementary to #1462: that PR detects blackholed node-control sockets; this PR makes any eventual reconnect restore individual agent state.

Test Plan

  • Added regression coverage for retaining a successful registration and publishing the complete reconnect inventory
  • Added supplied-token identity resolution and name-mismatch regression coverage
  • Added bounded-channel backpressure coverage proving inventory publication waits instead of dropping
  • cargo test -p agent-relay-broker --lib (916 passed, 0 failed, 4 ignored)
  • cargo test -p agent-relay-broker successful_node_registration_is_added_to_reconnect_inventory
  • cargo test -p agent-relay-broker supplied_agent_token_
  • cargo test -p agent-relay-broker fleet_inventory_snapshot_waits_for_backpressure_instead_of_dropping
  • cargo test -p agent-relay-broker node_control_reconnect_sends_inventory_sync
  • cargo test -p agent-relay-broker refresh_fleet_inventory_session_ref_publishes_immediate_sync
  • cargo fmt -p agent-relay-broker -- --check
  • cargo clippy -p agent-relay-broker --lib -- -D warnings
  • Forced production node disconnect (not performed because it would mark every worker on the shared node offline)

Note: clippy with --tests reaches two pre-existing unrelated warnings in crates/broker/src/snippets.rs and crates/broker/src/runtime/worker_events.rs. The non-test library target is clean.

Screenshots

Not applicable.

@cursor

cursor Bot commented Aug 12, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4e27a946-1c41-41f1-9beb-d78f3567d506

📥 Commits

Reviewing files that changed from the base of the PR and between 6e4981b and ac33371.

📒 Files selected for processing (1)
  • crates/broker/src/runtime/fleet.rs

📝 Walkthrough

Walkthrough

Worker spawn flows now retain registration metadata, resolve supplied-token identities, and record successful workers in fleet reconnect inventory. Inventory updates preserve existing entries and await control-channel delivery. The changelog records roster recovery after node-control reconnects.

Changes

Fleet inventory recovery

Layer / File(s) Summary
Retain registration metadata
crates/broker/src/runtime/relaycast_events.rs, crates/broker/src/runtime/api.rs
HTTP, node-registration, and supplied-token spawn paths retain registration tokens, invocation IDs, and session references.
Resolve identities and update fleet inventory
crates/broker/src/runtime/fleet.rs, crates/broker/src/runtime/relaycast_events.rs, crates/broker/src/runtime/api.rs
Supplied tokens resolve through Relaycast and the delivery book. Name mismatches are rejected. Successful spawns record agent metadata and publish updated inventory. Tests cover preservation, backpressure, identity resolution, and mismatch rejection.
Record the patch behavior
CHANGELOG.md
The unreleased changelog entry documents fleet roster recovery after node-control reconnects.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant FleetSpawn
  participant SpawnRequest
  participant Relaycast
  participant WorkerSpawn
  participant FleetInventory
  participant FleetControl
  FleetSpawn->>SpawnRequest: pass mutable fleet inventory
  SpawnRequest->>Relaycast: resolve registration identity
  Relaycast-->>SpawnRequest: return agent and session metadata
  SpawnRequest->>WorkerSpawn: start worker
  WorkerSpawn-->>SpawnRequest: report successful spawn
  SpawnRequest->>FleetInventory: record agent metadata
  FleetInventory->>FleetControl: publish updated snapshot
Loading

Possibly related PRs

Suggested reviewers: willwashburn, miyaontherelay

Poem

A rabbit records each worker’s name,
Tokens and sessions join the game.
The roster waits through channels tight,
Then returns after reconnects bring light.
Hop, hop—the fleet is right.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes restoring live agent roster state after reconnects, which is the primary change.
Description check ✅ Passed The description includes a complete summary, root cause, test plan, test results, and screenshots status; the unperformed production test is clearly documented.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/restore-live-agent-roster-on-reconnect

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0eb4abd1da

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +584 to +586
if let Some((token, invocation_id, session_ref)) = fleet_registration.take()
{
super::fleet::record_fleet_inventory_agent(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Include token-supplied workers in reconnect inventory

When a successful HTTP spawn uses the caller-supplied agent_token path—or falls back to HTTP registration and node binding—fleet_registration remains None, so this new inventory code never records the live, node-bound worker. After node control disconnects, Relaycast marks that worker offline, and the subsequent inventory.sync still omits it, reproducing the offline-roster failure for these supported spawn paths. The equivalent supplied-token branch in spawn_worker_from_request has the same omission.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 6e4981b. Supplied and HTTP-fallback tokens are now resolved through the authenticated current-agent endpoint to recover the authoritative agent ID; the requested name must match before the identity enters delivery bookkeeping or reconnect inventory. Both HTTP and action.invoke spawn paths retain the resolved registration only after process launch succeeds. Added matching-identity and mismatched-name regression tests; full broker lib suite is green (915 passed, 4 ignored).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/broker/src/runtime/api.rs (1)

350-354: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Preserve fleet registration metadata for supplied tokens.

If a supplied token can represent a node-control registration, preserve its AgentRegistrationToken identity and invocation/session metadata before spawning. Both supplied-token branches leave fleet_registration as None, so record_fleet_inventory_agent never updates fleet_inventory; reconnect cannot restore that worker through inventory.sync.

Apply this to crates/broker/src/runtime/api.rs and crates/broker/src/runtime/relaycast_events.rs. Otherwise, enforce that these inputs are never fleet registrations.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/broker/src/runtime/api.rs` around lines 350 - 354, Preserve fleet
registration metadata for supplied tokens in
crates/broker/src/runtime/api.rs:350-354 and
crates/broker/src/runtime/relaycast_events.rs:492-499 by recognizing
node-control AgentRegistrationToken values and populating fleet_registration
with their identity, invocation, and session metadata before spawning; ensure
record_fleet_inventory_agent can update fleet_inventory for reconnect via
inventory.sync, or explicitly enforce that these supplied-token inputs cannot be
fleet registrations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@crates/broker/src/runtime/api.rs`:
- Around line 350-354: Preserve fleet registration metadata for supplied tokens
in crates/broker/src/runtime/api.rs:350-354 and
crates/broker/src/runtime/relaycast_events.rs:492-499 by recognizing
node-control AgentRegistrationToken values and populating fleet_registration
with their identity, invocation, and session metadata before spawning; ensure
record_fleet_inventory_agent can update fleet_inventory for reconnect via
inventory.sync, or explicitly enforce that these supplied-token inputs cannot be
fleet registrations.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2f03335c-0408-4df5-bc62-8758bce058dc

📥 Commits

Reviewing files that changed from the base of the PR and between f7b1e22 and 0eb4abd.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • crates/broker/src/runtime/api.rs
  • crates/broker/src/runtime/fleet.rs
  • crates/broker/src/runtime/relaycast_events.rs

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread crates/broker/src/runtime/api.rs
Comment thread crates/broker/src/runtime/fleet.rs

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="crates/broker/src/runtime/api.rs">

<violation number="1" location="crates/broker/src/runtime/api.rs:363">
P2: A failed HTTP spawn can leave a dead worker's authoritative identity in `FleetDeliveryBook` even though no reconnect inventory entry was created. Deferring the identity binding until launch succeeds, or explicitly rolling it back on the spawn error path, would prevent later delivery and release operations from targeting stale state.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

.await
{
Ok(registration) => {
fleet_registration = Some((registration, None, session_ref.clone()));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: A failed HTTP spawn can leave a dead worker's authoritative identity in FleetDeliveryBook even though no reconnect inventory entry was created. Deferring the identity binding until launch succeeds, or explicitly rolling it back on the spawn error path, would prevent later delivery and release operations from targeting stale state.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/broker/src/runtime/api.rs, line 363:

<comment>A failed HTTP spawn can leave a dead worker's authoritative identity in `FleetDeliveryBook` even though no reconnect inventory entry was created. Deferring the identity binding until launch succeeds, or explicitly rolling it back on the spawn error path, would prevent later delivery and release operations from targeting stale state.</comment>

<file context>
@@ -348,16 +348,35 @@ impl BrokerRuntime {
+                    .await
+                    {
+                        Ok(registration) => {
+                            fleet_registration = Some((registration, None, session_ref.clone()));
+                        }
+                        Err(error) => {
</file context>

@khaliqgant
khaliqgant merged commit a622bb0 into main Aug 12, 2026
39 checks passed
@khaliqgant
khaliqgant deleted the fix/restore-live-agent-roster-on-reconnect branch August 12, 2026 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant