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
just setup (seeds communities), just dev
- Complete desktop onboarding against
ws://localhost:3000; create a channel
- Create a managed agent (e.g. Honey), add it to the channel, start it
- 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:
-
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
-
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.
-
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)
- 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
- 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
- Don't canonicalize the relay URL handed to spawned harnesses — pass through the community URL the app itself uses; or
- 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.
Summary
In local dev,
scripts/seed-local-community.shseedslocalhost:3000and127.0.0.1:3000as separate rows incommunities— i.e. two isolated tenants — while the desktop app connects asws://localhost:3000but spawns managed-agent harnesses with the canonicalized URLws://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
main(6f19a18era),just setup+just dev.env(RELAY_URL=ws://localhost:3000), defaultscripts/instance-env.sh(BUZZ_RELAY_URL="${BUZZ_RELAY_URL:-ws://localhost:3000}")Steps to reproduce
just setup(seeds communities),just devws://localhost:3000; create a channelExpected: the agent responds.
Actual: nothing happens. The harness log (
~/Library/Application Support/<app-id>/agents/logs/<agent-pubkey>__<relay-hash>.log) shows:Root cause
Three pieces interact:
Seeding:
scripts/seed-local-community.shinserts each loopback host variant (localhost,127.0.0.1,localhost:3000,127.0.0.1:3000) as its owncommunitiesrow. The comment says these are "loopback aliases", but with row-zero host binding each row is a fully isolated tenant:Desktop app tenant:
scripts/instance-env.shdefaults the app tows://localhost:3000, so all channels/messages/profiles are created in thelocalhost:3000tenant.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 indesktop/src/features/agents/managedAgentRuntimeStatus.ts) folds loopback hosts to127.0.0.1— so spawned harnesses getBUZZ_RELAY_URL=ws://127.0.0.1:3000. The relay resolves tenants from the literalHostheader with no such normalization, so the agents authenticate into the empty127.0.0.1:3000tenant.buzz-acpdiscovery (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
just dev+ managed agents = agents never respond, with no user-visible error (members panel shows them stuck on "Waking").Workaround we used
Re-point the data tenant at the canonical host and align every client on
127.0.0.1:3000:plus
RELAY_URL=ws://127.0.0.1:3000/BUZZ_RELAY_URL=ws://127.0.0.1:3000in.env, then re-join the community from the desktop app. After that the agent logs flip todiscovered 2 channel(s)and mentions work.Suggested fixes (any one of these would prevent the trap)
normalize_relay_urlsemantics to theHostheader before thecommunitieslookup), so all loopback variants resolve to one tenant in dev; or127.0.0.1:3000) and defaultinstance-env.sh/.envtows://127.0.0.1:3000, so the app and the spawned harnesses agree; orHappy to provide more logs or test a patch.