You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Let agents discover and message channels on peer hosts #57
Human channel routing reaches peer hosts, but the native channels/message tools currently use the local catalog. #13 covers hosted-channel messaging; #11 and #15 cover different boundaries.
Acceptance
Discover reachable peer channels with stable identity and enough project/host context to select the intended destination.
Deliver attributed messages and optional agent invocations through the existing tailnet and collaborator-agent policy; expose a supported reply path.
Preserve destination-host execution, idempotent delivery, and clear offline/reconnect outcomes.
Verify with real channels/models on two hosts, including duplicate delivery/reconnect and a target whose name changes.
Keep agents in different channels as messaging peers, not parent/child owners.
This is an extension beyond #10's baseline human collaboration check. Preserve the runtime-neutral channel and injected delivery boundary.
Implemented in draft #160 (branch codex/peer-channel-messaging, commit 14c6923). It stays a draft until the change is checked on two real hosts.
What changed
Workers reach their host through an owner-only, token-authenticated host.sock in the host's data directory. They find it by home, not port, so ace serve --port and desktop profiles work. It accepts only channels and deliver. Requests share the gateway's closing/updating admission and drain.
channels lists local channels, reachable peers' channels, and offline channels from the directory, with id, host, owner, state and project. A name shared by several channels is refused with the candidate ids.
message delivers to a channel this host runs, or is relayed once through a new peer-only deliver request. Peers never forward further.
The destination host stamps agent.<source id>@<login>: its own owner's login, or the peer login that tailscale whois verified. Caller-supplied authors are ignored, and agents are never treated as the channel owner, so sharing off still refuses agent invocation. The source id is the reply address and survives renames.
Relayed request ids are scoped to the verified login (peer/<login>/…) because pi dedupes per chat regardless of author. Local ids are unchanged.
With no host running (CLI-only), workers fall back to local delivery only on ENOENT/ECONNREFUSED, and say so.
Verified locally, with real Anthropic models on a disposable ace serve --port 4357 profile and only disposable ace57-* channels:
say and invoke, plus a reply by source id after the sender was renamed;
name ambiguity, and sharing off (say allowed, invoke refused);
request id replay and peer/local id isolation, confirmed in SQLite;
token, home, from and request id refusals, and that a forged author is ignored;
peer deliver over the real self-tailnet listener, which ran real whois with the owner's own login;
socket lifecycle: clean stop, conflicting host, stale-socket recovery, and draining a delivery admitted at SIGTERM;
CLI-only fallback.
Still open for acceptance
The only online peer Mac (nate16-1, a different login) refuses 4140/4141/4142, so no Ace gateway is running there.
Unverified: two-host discovery and delivery, collision isolation between distinct logins, duplicate delivery and reconnect across machines, and offline peers listed by the directory.
Closing draft PR #160 without merging. Main has changed too much for its branch to be worth rebasing. If this feature is picked up again, rebuild it on main using the notes below.
Discovery:channels lists local channels, reachable peers' channels, and offline ones from the directory, with id, host, owner, state and project. A repeated name is refused, and the refusal lists the candidate ids.
Delivery:message delivers locally, or relays once to the peer that runs the channel through a peer-only deliver request. Peers never forward further.
Authorship:
The destination host stamps the author. It uses its owner's login, or the peer's login verified through Tailscale.
Authors supplied by the caller are ignored.
Agents are never the owner, so with sharing off, invocation is refused.
Request ids: relayed request ids are scoped to the verified login, so redelivery is a no-op without colliding with local ids.
Lifecycle: discovery and delivery follow the gateway's shutdown and update rules. A CLI-only worker with no running host falls back to local delivery only on ENOENT or ECONNREFUSED, and says so.
Validation record: see the earlier comment on this issue.
Absorbing #180, so this issue covers both cases: agents in local channels and agents in hosted channels discovering and messaging channels on other hosts.
For hosted sources, the cell has no host socket. Delivery has to go through the channel's injected directory boundary (Directory.deliver in packages/channel/src/agents.ts), with the source attributed by the team authority rather than by the caller. The rebuild notes from #160 above still apply.
Activity
iamnbutler commentedon Oct 6, 2026
Implemented in draft #160 (branch
codex/peer-channel-messaging, commit 14c6923). It stays a draft until the change is checked on two real hosts.What changed
host.sockin the host's data directory. They find it by home, not port, soace serve --portand desktop profiles work. It accepts onlychannelsanddeliver. Requests share the gateway's closing/updating admission and drain.channelslists local channels, reachable peers' channels, and offline channels from the directory, with id, host, owner, state and project. A name shared by several channels is refused with the candidate ids.messagedelivers to a channel this host runs, or is relayed once through a new peer-onlydeliverrequest. Peers never forward further.agent.<source id>@<login>: its own owner's login, or the peer login thattailscale whoisverified. Caller-supplied authors are ignored, and agents are never treated as the channel owner, so sharing off still refuses agent invocation. The source id is the reply address and survives renames.peer/<login>/…) because pi dedupes per chat regardless of author. Local ids are unchanged.Verified locally, with real Anthropic models on a disposable
ace serve --port 4357profile and only disposableace57-*channels:fromand request id refusals, and that a forged author is ignored;deliverover the real self-tailnet listener, which ran realwhoiswith the owner's own login;Still open for acceptance
nate16-1, a different login) refuses 4140/4141/4142, so no Ace gateway is running there.Dogfooding: #5.
iamnbutler commentedon Oct 15, 2026
Closing draft PR #160 without merging. Main has changed too much for its branch to be worth rebasing. If this feature is picked up again, rebuild it on main using the notes below.
From #160, still applies:
channelslists local channels, reachable peers' channels, and offline ones from the directory, with id, host, owner, state and project. A repeated name is refused, and the refusal lists the candidate ids.messagedelivers locally, or relays once to the peer that runs the channel through a peer-onlydeliverrequest. Peers never forward further.What has changed on main since then:
agent@<prefix>, and the sender's current name is resolved throughdirectory.list(fix(channel): name handoff senders by their channel's current name #405, fix(app): name and link the channel that sent an agent handoff #300). Peer delivery should extend that scheme rather than use feat(host): let agents discover and message channels on peer hosts #160'sagent.<id>@<login>.host.sockfrom inside the worker.Still to verify: two real hosts with two distinct logins. The two-Mac study (#10, now closed) provides the setup for this.
iamnbutler commentedon Oct 15, 2026
Absorbing #180, so this issue covers both cases: agents in local channels and agents in hosted channels discovering and messaging channels on other hosts.
For hosted sources, the cell has no host socket. Delivery has to go through the channel's injected directory boundary (
Directory.deliverinpackages/channel/src/agents.ts), with the source attributed by the team authority rather than by the caller. The rebuild notes from #160 above still apply.