Skip to content

fix(desktop): spawn managed agents with the configured relay URL - #3484

Open
JHSeo-git wants to merge 1 commit into
block:mainfrom
JHSeo-git:fix/managed-agent-relay-url-tenancy
Open

fix(desktop): spawn managed agents with the configured relay URL#3484
JHSeo-git wants to merge 1 commit into
block:mainfrom
JHSeo-git:fix/managed-agent-relay-url-tenancy

Conversation

@JHSeo-git

Copy link
Copy Markdown

Summary

On a local relay, desktop-managed agents silently never respond: the relay derives the community boundary from the HTTP Host header, but every managed-agent spawn path handed the child ManagedAgentRuntimeKey.relay_url — the canonical identity form, whose normalization folds every loopback spelling to 127.0.0.1. With a community configured as ws://localhost:3000, the UI writes all channels, memberships, and messages into the localhost:3000 community while every agent connects to the empty 127.0.0.1:3000 community. Each harness logs discovered 0 channel(s) / no channel subscriptions resolved — agent will sit idle, the member list shows the agent stuck on "Waking", and mentions are never answered. No error surfaces anywhere.

This also violates the contract documented on buzz_core::relay::normalize_relay_url itself:

Connection code may retain the configured URL; this canonical form is for identity, receipts, status and deduplication.

Related issue

Fixes #2444. Same root cause family as #3283 (loopback tenant split on the seed side). Closest existing PR: #2446 — same diagnosis and direction; it now has merge conflicts against main and its description notes the missing automated regression test as an honest gap. This PR is rebased on current main, adds that regression coverage via a small testable seam, and additionally pins the spawn-config hash to the canonical form so restart-drift detection cannot false-positive. Happy to close this in favor of a revived #2446 if maintainers prefer — the test seam here grafts onto it cleanly.

Fix

Keep the canonical form for identity only (runtime-map keys, receipts, log paths, spawn-config hash). Dial the configured URL everywhere a child or probe actually connects:

  • child_connect_relay_url(configured, key) — new seam in runtime.rs that returns the configured URL for the child's BUZZ_RELAY_URL and git-credential scope, with a debug_assert that the configured URL canonicalizes to the runtime key's relay (callers cannot hand it a URL from a different pair).
  • The three spawn call sites (start_pair, launch restore, ensure-running) pass their already-resolved configured URL instead of key.relay_url.
  • The reconcile fan-out passes the requested community URL to start_pair instead of the canonical echo.
  • probe_agent_relay_access probes over the requested authority, so spawn eligibility is checked against the same community the child will join.
  • start_pair fills requested_relay_url in its status rows, so the frontend's existing requestedRelayUrl ?? relayUrl fallback re-dials the configured URL on restart.
  • The spawn-config hash deliberately stays on runtime_key.relay_url: status_for recomputes that hash from key.relay_url, so hashing the configured spelling would read as permanent drift and flag a spurious restart on every status pass.

Testing

  • Two new regression tests pin the seam: child_connect_relay_url_preserves_configured_loopback_authority (canonical key is ws://127.0.0.1:3000 while the child still gets ws://localhost:3000) and child_connect_relay_url_is_identity_for_non_loopback_relays.
  • just ci passes locally; cargo test --lib on the Tauri crate: 1851 passed, 0 failed; clippy clean.
  • Manual end-to-end on macOS against a fresh local relay and a fresh desktop dev instance: before the fix, all three starter-team agents logged discovered 0 channel(s) and never replied (memberships verified present in the relay DB, all events under the localhost:3000 community while harnesses connected to 127.0.0.1:3000); after the fix, each harness logs discovered 1 channel(s) and a mention in the Welcome channel gets an agent reply within ~50s.

Follow-up candidates (out of scope here, discussed in #2444/#3283): collapsing loopback spellings into one community key on the relay side (#2619 explores this), and surfacing the agent-idle state in the UI instead of only in the harness log.

Relay tenancy is derived from the HTTP Host header, but the managed-agent
spawn path handed the child the canonical runtime-key relay URL, whose
normalization rewrites loopback spellings to 127.0.0.1. Against a local
relay joined as ws://localhost:3000, every harness therefore connected to
the empty 127.0.0.1:3000 community, discovered 0 channels, and never saw
a mention while the UI showed the agent stuck on Waking.

Spawn now hands the child the caller's configured relay URL (BUZZ_RELAY_URL
and the git-credential scope) through a small child_connect_relay_url seam,
and every path that reaches spawn passes the configured spelling through:
start_pair, launch restore, ensure-running, the reconcile fan-out, and the
relay-access probe (which now probes the requested authority). start_pair
also fills requested_relay_url in its status rows so the frontend's
requestedRelayUrl fallback re-dials the configured URL on restart.

The canonical form remains the identity for runtime keys, receipts, log
paths, and the spawn-config hash: status_for recomputes that hash from
key.relay_url, so hashing the configured spelling would read as permanent
drift and flag a spurious restart.

Signed-off-by: JHSeo <qnfqnfqnf@gmail.com>
@JHSeo-git
JHSeo-git force-pushed the fix/managed-agent-relay-url-tenancy branch from 556d776 to cb11965 Compare July 30, 2026 00:39
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.

[Bug] Desktop 0.4.23 spawns managed agents on ws://127.0.0.1:3000 while the community uses ws://localhost:3000 - agents silently stop responding

1 participant