Skip to content

fix(desktop): spawn agents with the workspace relay URL, not the canonical identity - #7231

Open
changsheng1224 wants to merge 1 commit into
block:mainfrom
changsheng1224:fix/4888-agent-dial-relay-authority
Open

changsheng1224 wants to merge 1 commit into
block:mainfrom
changsheng1224:fix/4888-agent-dial-relay-authority

Conversation

@changsheng1224

Copy link
Copy Markdown

Problem

No managed agent can reply reliably in local dev when Desktop joins
ws://localhost:3000. Agents start, connect, then either sit idle:

INFO  buzz_acp: discovered 0 channel(s)
WARN  buzz_acp: no channel subscriptions resolved — agent will sit idle

or fail to connect with a Host-bound 404. The desktop itself is fine; only
the spawned harness is wrong. The failure is easy to miss unless you open
the per-agent log.

Cause

buzz_core::relay::normalize_relay_url folds loopback hosts to 127.0.0.1
for identity. That is correct for runtime keys, receipts, and dedup — its
own docs say connection code may retain the configured URL.

ManagedAgentRuntimeKey::new stores that canonical form, and
spawn_agent_child used runtime_key.relay_url as BUZZ_RELAY_URL.
Relay tenancy keys off the literal Host, and local seed/compose often
keeps localhost:3000 and 127.0.0.1:3000 as separate communities. So
the agent authenticates into a different (often empty or unmapped) tenant.

The HTTP path already pins this via
loopback_ws_localhost_preserves_authority. Spawn did not.

Fix

  • Add resolve_agent_dial_relay_url in buzz-core: keep identity
    canonical; when workspace and pair normalize to the same community,
    dial the workspace spelling; otherwise fail closed.
  • Wire spawn_agent_child through that helper for BUZZ_RELAY_URL /
    related HTTP / snapshot. Log identity= and dial= at start.
  • Promote empty-tenant idle lines to a readable AgentLogError.

Identity migration and receipt/restart dial persistence are out of scope.

Related

Testing

  • cargo test -p buzz-core --lib relay::tests
  • cargo test --manifest-path desktop/src-tauri/Cargo.toml --lib dial_
  • cargo test --manifest-path desktop/src-tauri/Cargo.toml --lib meaningful_agent_error_from_log_promotes_empty_tenant_idle
  • cargo test --manifest-path desktop/src-tauri/Cargo.toml --lib relay::tests
  • Local Desktop on ws://localhost:3000, started Fizz:
identity=ws://127.0.0.1:3000 dial=ws://localhost:3000
discovered 1 channel(s)

No sit idle. @Fizz received a setup-mode reply on the correct tenant.
Same machine: localhost:3000 had channels/membership;
127.0.0.1:3000 was empty — the old identity dial would land there.

Keep runtime identity canonical (loopback folds to 127.0.0.1) but dial
BUZZ_RELAY_URL with the workspace Host so agents join the same tenant as
Desktop (block#4888). Fail closed on community mismatch; surface empty-tenant
idle in agent logs.

Signed-off-by: changsheng1224 <152450618+changsheng1224@users.noreply.github.com>
@changsheng1224
changsheng1224 requested a review from a team as a code owner September 2, 2026 11:09
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is 1c8321cd08feb597f8bcff5195c21148fb3e98ed...fa1aa9eec02003592dc097194ab8cd39fc7d6fef.
A new review must complete for this exact range. When manual authorization
is required, a Block organization member must comment exactly
@buzz-security-review fa1aa9eec02003592dc097194ab8cd39fc7d6fef to authorize a new review.
Any previous review applies only to its recorded range.

@mrlong0129 mrlong0129 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.

Independent review of head fa1aa9eec02003592dc097194ab8cd39fc7d6fef after reproducing #4888 with the official 0.5.23 macOS build.

The baseline reproduction used an unconfigured provider, so the harness entered setup-listener mode. Desktop messaging and search worked, while the agent exited on a WebSocket 404. A handshake-only check against the same TCP endpoint returned 101 with Host: localhost:3030 and 404 with Host: 127.0.0.1:3030. This happens before model invocation.

Multi-community starts appear to regress

The new spawn-time lookup always obtains the active workspace URL, then compares it with the target pair's canonical URL. However, reconcile_managed_agent_runtimes deliberately starts eligible pairs across every configured community.

With community A active and a valid pair for community B, that existing fan-out calls start_pair(B)spawn_agent_child(B)resolve_agent_dial_relay_url(A, B), which returns CommunityMismatch before spawning. The config-change restart loop also starts multiple relay pairs. Preserving the target pair's original dial URL through those call paths would retain the Host fix without depending on which community is currently active. A two-community spawn/restart regression would cover this case; the resolver's mismatch unit test alone does not exercise that call path.

Setup-mode warning is not matched

The new log matcher requires agent will sit idle, whereas setup_mode.rs emits nudge listener will sit idle. That setup-mode warning will miss the new diagnostic promotion. It would help to cover both emitted messages.

Validation: cargo fmt --all -- --check and all 8 buzz-core relay::tests passed at this head. The desktop test build was blocked by a missing generated Tauri sidecar. The findings above come from the production call paths; I have not run a two-community desktop or GUI acceptance test of this candidate.

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.

Managed agents fail with 404: desktop spawns buzz-acp with ws://127.0.0.1:3000 while the community host is localhost:3000

2 participants