Repository navigation
Federation step 1: peers + strut/run-workflow (dispatch-through first, for a local strut calling a cloud explorer agent) - #123
Merged
Conversation
…oud explorer agent Revised 2026-10-08. The first use case is a desktop strut asking a swarm's strut to walk its knowledge graph, so the order flips: peers + strut/run-workflow + @slug in the builder come first, read-through follows on the same record. Rulings: the step waits on the peer's SSE tail with ?skip=N reattach, never a callback (a strut behind NAT cannot receive one); a peer is named by the hive workspace slug; a local strut gets its peers through a paste door since hive cannot push to it; `job` is explicit on the step, never forwarded; the pushed scope is lab:peer (read, launch, control what it launched). Billing across the call and actor secrets are deferred — the org fan-out is not built in hive, and an explorer needs neither. A Local tier row, the step order, validation and open questions updated to match.
…ion step 1)
A strut knows nothing about other struts. A PEER is a record someone put
here — `PUT /peers/:id { baseUrl, token, label? }` (hive, by workspace
slug) or STRUT_PEERS / createStrut({ peers }) on a strut nobody can push
to — in a fourth encrypted file, peers.json. GET /peers lists ids, labels
and base URLs; a token has no read route. Steps get ctx.services.peers,
a capability that names a peer and makes a request with the token
injected (readable by nothing); the builder gets list_peers and `peer`
on list_workflows / get_workflow / run_workflow, with @<id> in a prompt
naming a peer.
strut/run-workflow launches POST …/run on the peer with this run's
principal as x-strut-actor (billed and secret-bound there, for that
person; nothing crosses) and waits on the peer's SSE tail, reattaching
with ?skip=N after a dropped connection — reader-initiated, so a desktop
strut behind NAT can call a cloud one. Cancelling the caller's run POSTs
cancel to the peer; wait: false returns the handle; job is explicit and
never the caller's own (no shared directory across struts).
Tests: src/peers.test.ts — the store, the capability, launch/tail/cancel
against a fake peer (reattach, backoff, abort, refusals), the routes, and
two struts over real HTTP (result + actor forwarded, job only when named,
wait: false, cancel propagation, unknown peer, refused launch); three AI
tool tests. specs/API.md §10, AGENTS.md, plans/federation.md step 1
marked built. Not in this slice: a Peers dialog, pause/resume forwarding,
the lab:peer scope, read-through.
This was referenced Oct 8, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two commits: the plan amendment, then the build of its step 1.
1.
plans/federation.md— the 2026-10-08 rulingsThe use case in hand is a local (desktop) strut asking a swarm's strut to walk that swarm's knowledge graph and return what is relevant. That flips the plan's order: peers +
strut/run-workflow+@slugin the builder come first; read-through follows on the same peer record.?skip=N, never a callback: a strut behind NAT can reach a cloud strut but cannot receive a POST, and no strut knows its own public URL.@slug.STRUT_PEERS, a Peers dialog), since hive cannot push to it. New Local tier row.jobis an explicit field on the step, never forwarded fromctx.job: no shared directory across struts.lab:peer(read, launch, control what it launched);lab:readstays for a central that only reads.plans/org-gateway.md§3 is not built in hive, and an explorer needs neither.2. Step 1 built
src/peers.ts. A peer is{ id, baseUrl, token, label? }in a fourth encrypted file,peers.json, behindPUT/DELETE/GET /peers(the GET returns ids, labels and base URLs, never a token).STRUT_PEERSandcreateStrut({ peers })are the paste door.ctx.services.peersnames a peer and makes a request with the token injected; the token is readable by nothing. The client the step and the builder share:launchOnPeer,tailPeerRun(reattach with?skip=N, backoff, abort),cancelOnPeer,runOnPeer.strut/run-workflow.POST …/runon the peer with this run's principal asx-strut-actor, then the tail. Cancelling the caller's run POSTs cancel to the peer.wait: falsereturns the handle.jobis explicit only. Output:{ peer, workflow, runId, status, output?, error?, durationMs }; an artifact path in it is the peer's.list_peers, andpeeronlist_workflows/get_workflow/run_workflow; the prompt says@<id>names a peer and a peer run is awaited, never detached.specs/API.md§10, AGENTS.md (layout, env row, key concept), the plan's step 1 marked built.Two calls that differ from the plan text, both written into it: the capability sits on the services bag (the step has to reach the peer somehow; the token stays inside the process, and the token's scope bounds what a step can do through it), and
GET /peersincludesbaseUrl.Tests:
src/peers.test.ts— the store, the capability, launch/tail/cancel against a fake peer (reattach, backoff, abort, refusals), the routes, and two struts over real HTTP (listen(0)): result and actor forwarded,jobonly when named,wait: false, cancel propagation, unknown peer, refused launch. Three AI tool tests. The route-sweep test covers the new routes behind the key. 1360 tests pass.Not in this slice: a Peers dialog, pause/resume forwarding to the peer, the
lab:peerscope in mcp, read-through. A peer token today is the peer's whole key, so a laptop should not hold one until the scope lands.