Skip to content

Local dev: loopback hosts are seeded as separate communities, so desktop-managed agents silently discover 0 channels #3283

Description

@linearuncle

Summary

In local dev, scripts/seed-local-community.sh seeds localhost:3000 and 127.0.0.1:3000 as separate rows in communities — i.e. two isolated tenants — while the desktop app connects as ws://localhost:3000 but spawns managed-agent harnesses with the canonicalized URL ws://127.0.0.1:3000. The result: every desktop-managed agent lands in an empty tenant, discovers 0 channels, and silently never responds to mentions. This cost us several hours to debug, because nothing errors — the agents just sit idle.

Environment

  • macOS, current main (6f19a18 era), just setup + just dev
  • Default .env (RELAY_URL=ws://localhost:3000), default scripts/instance-env.sh (BUZZ_RELAY_URL="${BUZZ_RELAY_URL:-ws://localhost:3000}")

Steps to reproduce

  1. just setup (seeds communities), just dev
  2. Complete desktop onboarding against ws://localhost:3000; create a channel
  3. Create a managed agent (e.g. Honey), add it to the channel, start it
  4. Mention the agent in the channel

Expected: the agent responds.

Actual: nothing happens. The harness log (~/Library/Application Support/<app-id>/agents/logs/<agent-pubkey>__<relay-hash>.log) shows:

INFO buzz_acp: buzz-acp starting: relay=ws://127.0.0.1:3000 ...
INFO buzz_acp: discovered 0 channel(s)
WARN buzz_acp: no channel subscriptions resolved — agent will sit idle

Root cause

Three pieces interact:

  1. Seeding: scripts/seed-local-community.sh inserts each loopback host variant (localhost, 127.0.0.1, localhost:3000, 127.0.0.1:3000) as its own communities row. The comment says these are "loopback aliases", but with row-zero host binding each row is a fully isolated tenant:

    SELECT id, host FROM communities;
    -- 4 rows, 4 distinct community ids
    
  2. Desktop app tenant: scripts/instance-env.sh defaults the app to ws://localhost:3000, so all channels/messages/profiles are created in the localhost:3000 tenant.

  3. Managed-agent tenant: the managed-agent backend keys runtime pairs by the canonical relay URL — normalize_relay_url (crates/buzz-core/src/relay.rs, mirrored in desktop/src/features/agents/managedAgentRuntimeStatus.ts) folds loopback hosts to 127.0.0.1 — so spawned harnesses get BUZZ_RELAY_URL=ws://127.0.0.1:3000. The relay resolves tenants from the literal Host header with no such normalization, so the agents authenticate into the empty 127.0.0.1:3000 tenant. buzz-acp discovery (kind:39002 membership scan) legitimately finds nothing.

The design assumption behind normalize_relay_url ("localhost and 127.0.0.1 are the same relay") and the tenant model ("one host = one community") contradict each other, and the seed script bakes the contradiction into the default dev database.

Impact

  • Out-of-the-box just dev + managed agents = agents never respond, with no user-visible error (members panel shows them stuck on "Waking").
  • Anything keyed by tenant (channels, membership, 39002 discovery, media) silently splits between the two loopback tenants depending on which client wrote it.

Workaround we used

Re-point the data tenant at the canonical host and align every client on 127.0.0.1:3000:

BEGIN;
UPDATE communities SET host = '__swap__'       WHERE host = '127.0.0.1:3000';
UPDATE communities SET host = '127.0.0.1:3000' WHERE host = 'localhost:3000';
UPDATE communities SET host = 'localhost:3000' WHERE host = '__swap__';
COMMIT;

plus RELAY_URL=ws://127.0.0.1:3000 / BUZZ_RELAY_URL=ws://127.0.0.1:3000 in .env, then re-join the community from the desktop app. After that the agent logs flip to discovered 2 channel(s) and mentions work.

Suggested fixes (any one of these would prevent the trap)

  1. Normalize loopback hosts in tenant resolution (apply normalize_relay_url semantics to the Host header before the communities lookup), so all loopback variants resolve to one tenant in dev; or
  2. Seed only the canonical loopback host (127.0.0.1:3000) and default instance-env.sh / .env to ws://127.0.0.1:3000, so the app and the spawned harnesses agree; or
  3. Don't canonicalize the relay URL handed to spawned harnesses — pass through the community URL the app itself uses; or
  4. At minimum, surface a loud warning: if a managed agent's discovery returns 0 channels while the app's tenant has channels for that agent, log/notify a tenant-mismatch hint instead of idling silently.

Happy to provide more logs or test a patch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions