EXPLORE THE CONNECTIONS

Follow every connection.

From a Matrix conversation to a coding agent’s workspace. Explore how Robrix2, Palpo, its companion web service, and Hagency work together.

MatrixHTTPSAppserviceACP / MCP
Reviewed development architecture · September 2026

Read the complete architecture below. The interactive diagram is available when its browser module loads.

Read the connections

The outbound transport and companion administration app describe the reviewed development integration, not a promise about every published package. The map is explanatory and never connects to live services.

01 / HTTPS

Hagency connects out. Palpo keeps the queue.

The contributor machine can stay behind NAT. Hagency’s bridge initiates HTTPS connections to the public Palpo web transport; the Matrix homeserver reaches a colocated relay on the server network.

Operation / APIDirectionWhat it means
Publish capabilities and statusPOST /api/fleet/v2/{fleetId}/updatesHagency → Palpo webA sequenced outbox carries heartbeat, resource snapshots and observed request state. Lost responses retry the identical sequence and payload.
Receive Matrix transactionsGET /api/fleet/v2/{fleetId}/poll?lane=matrixHagency requests → web respondsLong polling leases an original AS transaction from the durable Matrix lane. The HTTP connection is initiated by Hagency.
Receive work requestsGET /api/fleet/v2/{fleetId}/poll?lane=workHagency requests → web respondsA separate lane carries request/probe work with its source event and authority bindings. It does not bypass local admission.
Acknowledge custodyPOST /api/fleet/v2/{fleetId}/ackHagency → Palpo webAfter local persistence, ACK identifies delivery, lane and current lease token. It means receipt, not resource approval, task completion or permission to run a tool.
Deliver an Appservice transactionPUT /api/relay/v2/{fleetId}/_matrix/app/v1/transactions/{txnId}Palpo homeserver → server-side web relayThe relay validates hs_token and persists the transaction before HTTP 200. This is the Matrix AS hop, not an inbound call to Hagency.

Durability, with explicit states

The web relay persists before acknowledging Matrix. Hagency persists before acknowledging a delivery lease. Replayed IDs and content digests prevent duplicate admissions; conflicting payloads are refused. Processing, allocation and completion remain separate from both acknowledgments.

Connection proof, then heartbeats

The exact current-generation Matrix probe establishes the connection. Background heartbeats maintain liveness afterwards. A stale request observation cannot become “ready now” merely because a heartbeat or retransmission arrived later. Existing callback fleets need an explicit migration; the map shows the current outbound path.

02 / APPSERVICE

Register the service. Then verify the connection.

Matrix defines an application service registration. Palpo’s companion web app automates its installation and adds owner pairing and fleet transport around it.

  1. 01

    Authorize one fleet

    A Palpo administrator chooses an active local owner and outbound transport. The companion service persists a stable operation ID, random fleet ID and generated registration before contacting the homeserver. Retries reuse the operation; changed content conflicts.

  2. 02

    Install a scoped Appservice

    The companion service calls POST /_palpo/admin/v1/appservices with administrator authority. It generates a representative localpart, an exclusive local-user namespace, as_token and hs_token. The registration URL points to the server-side relay, not the contributor’s laptop.

  3. 03

    Read back and provision the representative

    The service reads the registration back and compares its ID, URL, tokens, sender and namespaces. In the reviewed Palpo implementation, an AS-authenticated whoami request with user_id provisions the representative; the exact MXID and appservice ownership are then checked. This provisioning behavior is Palpo-specific.

  4. 04

    Pair the owner’s Hagency

    Only the assigned owner can download this fleet’s configuration. The owner imports it through Hagency’s project-side onboarding. It contains the scoped Matrix registration and independent outbound machine credentials; it does not hand the Palpo administrator token to Hagency.

  5. 05

    Start outbound polling and publication

    Hagency starts separate matrix/work poll loops, stores deliveries locally, acknowledges their leases and publishes capabilities, heartbeats and request observations. The web service can answer from stored state even when a contributor is offline.

  6. 06

    Prove the actual Matrix round trip

    The owner’s connection action creates or recovers the reception room and emits com.hagency.connection.probe.v1. Palpo → relay → Hagency must deliver that exact event; current-generation transaction receipt and Hagency’s verified probe result establish the connection. A heartbeat alone cannot establish initial readiness.

  7. 07

    Admit a project and allocate an agent

    Project registration binds the owner and target room and establishes a separate private approval room. A named agent request still needs the contributor’s admission and allocation checks. The portal reports usable only after fulfillment and actual target-room membership are verified.

Inspect an illustrative Appservice registration
Example only · generated per fleet · no real secrets
# Illustrative values; generated separately for every fleet.
id: hf_0123456789abcdef0123456789abcdef
url: http://palpo-web:8090/api/relay/v2/hf_0123456789abcdef0123456789abcdef
as_token: <APP_SERVICE_SECRET>
hs_token: <HOMESERVER_SECRET>
sender_localpart: hf_0123456789abcdef0123456789abcdef_representative
namespaces:
  users:
    - exclusive: true
      regex: '^@hf_0123456789abcdef0123456789abcdef_[a-z0-9_]+:example\.org$'
  aliases: []
  rooms: []
rate_limited: true
receive_ephemeral: false

The relay URL is reachable by the homeserver. The local-user regular expression is anchored to one fleet and one Matrix server identity. This YAML illustrates fields; the companion service installs their JSON equivalent through Palpo’s admin API.

03 / ROBRIX2 → PALPO

A native client. A standard Matrix connection.

Robrix connects to the Matrix homeserver directly. Its conversations reach Hagency through Matrix events, room bindings, and the bridge.

Choose the Matrix endpoint and sign in

Robrix builds a matrix-sdk Client with the selected homeserver URL or server name. It uses the account’s supported login flow or restores an existing device session. The Matrix API origin and the companion admin portal may be different URLs.

Synchronize without blocking the UI

The Makepad UI hands MatrixRequest actions to a Tokio worker. matrix-sdk-ui SyncService discovers native sliding sync and feeds room-list and per-room timeline updates back to the UI. Media, typing, receipts and membership use the SDK’s corresponding Matrix operations.

Keep thread and identity information

Messages and replies use Matrix events and thread relations. Hagency validates the actual sender and stored room/thread binding; a displayed agent name or text mention is not an authorization credential.

Keep encryption on the client side

Robrix persists its device and crypto state locally. Hagency’s supported encrypted paths use their own real Matrix devices and persistent crypto stores. An AS registration or server-side relay does not itself provide the keys to read encrypted rooms.

A room’s power levels can grant a person and an agent the same room capabilities. Coding-tool execution still requires Hagency’s own runtime authorization. Explore Matrix’s permission model →

04 / HAGENCY → CODING AGENTS

One control plane. Several explicit runtime paths.

Hagency coordinates real coding-agent processes. It rebuilds context, chooses an eligible adapter, grants scoped tools, observes execution, and routes the result back to the originating conversation.

Claude Code

Current headless task runner
claude -p · stream-json

Fresh guarded process per dispatch; prompt on stdin; streamed activity/output; scoped MCP server. Context comes from durable Hagency state.

Permission checks follow the Claude runtime integration and configured tool policy.

Codex

Current App Server task runner
codex app-server --stdio

initialize → thread/start → turn/start. A fresh App Server thread receives rebuilt context. Notifications and native approval requests are bound to the dispatch.

Command, file, permission and supported MCP approvals require validated operation identity and owner decisions.

Octos

Explicit ACP adapter
octos acp --profile coding-full

ACP initialize → session/new → session/prompt. The reviewed adapter requires MCP servers in Octos’s own configuration; it ignores session/new mcpServers.

The reviewed capability declares no session loading and no blocking request_permission. Launch sandbox policy remains the control.

Hermes

Explicit ACP adapter
hermes-acp

Accepts session MCP configuration. Its ACP and MCP installation extras are both needed. Model selection follows Hermes configuration.

Hagency does not send unsupported --model or --cwd flags. Advertised session features are not a promise of task-runner parity.

Codex ACP

Separate adapter transport
codex-acp

A separate adapter wraps Codex and speaks ACP over stdio. It accepts session MCP configuration and reports progress through session/update.

Distinct from codex app-server. The reviewed adapter does not receive a filesystem sandbox flag; Hagency’s ACP permission callback restricts tool approval.

ACP, MCP and inference do different jobs

ACP is the session protocol between Hagency and compatible coding adapters. MCP exposes Hagency tools to the coding agent. The agent separately contacts its configured model provider. Octos’s config-based MCP injection and Hermes/Codex ACP session injection are deliberate adapter differences.

Durable sessions, disposable workers

The backend owns agent + room + scope + thread identity, accepted inputs, summaries and dispatch state. A fresh worker receives bounded rebuilt context. Coding work requires a task and real Matrix thread root. Retained tmux panes and runtime process IDs do not replace that authority.

05 / IDENTITY & AUTHORITY

Every connection has its own authority.

The same room permission model can apply to people and agents. The credentials below serve different network and execution boundaries.

CredentialCaller → serviceScope
as_tokenAppservice → Matrix homeserverActs for authorized local identities in its registered namespace. It is not the Palpo administrator token.
hs_tokenMatrix homeserver → AS relayAuthenticates transaction delivery to the registered relay. It is not the fleet machine token.
Machine token + generationHagency → Palpo web transportAuthorizes one fleet’s polling, ACKs and state publication. Rotation changes generation and invalidates stale transport authority.
Matrix user / device tokenRobrix or agent device → homeserverIdentifies a real user/device session. Room membership, power levels and encryption keys remain relevant.
Browser session + CSRFBrowser → Palpo companion appAuthorizes the signed-in human’s web actions. Administrative calls need the corresponding server authority.
Dispatch capabilityCoding runtime / MCP → HagencyScopes task and tool operations to a dispatch. Runtime execution approvals are independent of Matrix room roles.
Provider credentialsCoding agent → model endpointAuthorize model calls at the selected provider. The exact data destination follows that agent’s configuration.
06 / STATE & FEDERATION

State lives where its responsibility lives.

Robrix2

Local session and encryption database; room/timeline cache.

Palpo homeserver

Server-side Matrix accounts, room state/events and membership; media storage according to the server deployment.

Palpo companion web

Private SQLite state for registrations, fleet credentials, project operations, durable transport and audit records.

Hagency

Resource and engagement state, room/task/session bindings, inbox/outbox and dispatch ledger; separate device crypto stores.

Coding agents

Assigned repositories, working files and task artifacts. Model context is reconstructed within the configured budget.

Federation connects independently operated rooms

A person on another homeserver can participate in an authorized federated room. Their server exchanges room events with Palpo using the Matrix Server–Server API. This does not expose Hagency’s local API or share its filesystem. Room data, encryption availability and model-provider disclosure still depend on the actual room, devices and deployment.

07 / CONNECTION REFERENCE

Read the map, connection by connection.

The same connections as the interactive diagram, readable without JavaScript. Arrows identify the caller and recipient; a poll’s response carries deliveries back to Hagency.

Whole system

Robrix2 → Palpo homeserver

HTTPS · Matrix user/device token

Robrix authenticates to Palpo, sends messages and media, and receives room updates through SDK sync. It has no direct Hagency backend connection.

Owner / admin browser → Palpo web service

HTTPS · session cookie + CSRF

Humans use the companion app with their own Matrix identity. The server validates identity and the authority needed by each action.

Palpo web service → Palpo homeserver

POST /_palpo/admin/v1/appservices

The web service uses server administrator authority to install a generated, fleet-scoped registration, then reads it back and verifies the complete configuration. This is a Palpo admin API.

Palpo homeserver → AS relay + durable queues

PUT …/_matrix/app/v1/transactions/{txnId} · hs_token

Palpo pushes transactions to its colocated relay. The relay checks hs_token and persists the original ID and body before acknowledging. This hop stays server-side.

Hagency Matrix bridge → AS relay + durable queues

GET /poll · POST /ack · machine token + generation

Hagency initiates HTTPS requests; deliveries return in poll responses. Separate matrix/work lanes are leased. Local SQLite persistence precedes ACK; ACK is not approval.

Hagency Matrix bridge → Palpo web service

POST /updates · machine token + generation

Hagency publishes resource snapshots, heartbeats and request observations from a sequenced durable outbox. Retrying an old observation does not make it fresh.

Hagency Matrix bridge → Hagency control plane

Authenticated local API

The bridge verifies sender, room, namespace and project bindings. The control plane retains contributor approval, quotas, task ownership and execution authority.

Hagency console → Hagency control plane

Console server proxy → Hagency API

Resource configuration and engagement decisions use the authenticated local backend. Browser-side code does not become the backend authority.

Hagency control plane → Coding-agent adapters

Guarded subprocess / selected transport

The backend chooses an eligible configured agent and transport. It validates the dispatch and passes context as data, not executable shell text.

Coding-agent adapters → Configured model providers

Provider-specific endpoint + credentials

The agent runtime connects to its configured model service independently of Matrix transport. Local endpoints are possible when supported by that agent.

Agent Matrix devices → Palpo homeserver

Matrix device token · sync + media + crypto

Real device clients maintain keys and session stores for supported encrypted messaging and private approvals. Server-side relay custody is not possession of decryption keys.

Palpo homeserver → Other Matrix homeservers

Matrix Server–Server API · signed requests

Independent homeservers exchange authorized room events. The recipient homeserver applies Matrix event and membership rules; runtime permissions remain local to Hagency.

Appservice registration

Owner / admin browser → Palpo web service

HTTPS · session cookie + CSRF

Humans use the companion app with their own Matrix identity. The server validates identity and the authority needed by each action.

Palpo web service → Palpo homeserver

POST /_palpo/admin/v1/appservices

The web service uses server administrator authority to install a generated, fleet-scoped registration, then reads it back and verifies the complete configuration. This is a Palpo admin API.

Palpo homeserver → AS relay + durable queues

PUT …/_matrix/app/v1/transactions/{txnId} · hs_token

Palpo pushes transactions to its colocated relay. The relay checks hs_token and persists the original ID and body before acknowledging. This hop stays server-side.

Hagency Matrix bridge → AS relay + durable queues

GET /poll · POST /ack · machine token + generation

Hagency initiates HTTPS requests; deliveries return in poll responses. Separate matrix/work lanes are leased. Local SQLite persistence precedes ACK; ACK is not approval.

Hagency Matrix bridge → Palpo web service

POST /updates · machine token + generation

Hagency publishes resource snapshots, heartbeats and request observations from a sequenced durable outbox. Retrying an old observation does not make it fresh.

Hagency console → Hagency control plane

Console server proxy → Hagency API

Resource configuration and engagement decisions use the authenticated local backend. Browser-side code does not become the backend authority.

Hagency Matrix bridge → Hagency control plane

Authenticated local API

The bridge verifies sender, room, namespace and project bindings. The control plane retains contributor approval, quotas, task ownership and execution authority.

Hagency Matrix bridge → Agent Matrix devices

Persistent device/crypto state

The bridge starts and supervises the dedicated Matrix device clients and admits their decrypted messages through the same binding checks.

Agent Matrix devices → Palpo homeserver

Matrix device token · sync + media + crypto

Real device clients maintain keys and session stores for supported encrypted messaging and private approvals. Server-side relay custody is not possession of decryption keys.

Message → work → reply

Robrix2 → Palpo homeserver

HTTPS · Matrix user/device token

Robrix authenticates to Palpo, sends messages and media, and receives room updates through SDK sync. It has no direct Hagency backend connection.

Palpo homeserver → AS relay + durable queues

PUT …/_matrix/app/v1/transactions/{txnId} · hs_token

Palpo pushes transactions to its colocated relay. The relay checks hs_token and persists the original ID and body before acknowledging. This hop stays server-side.

Hagency Matrix bridge → AS relay + durable queues

GET /poll · POST /ack · machine token + generation

Hagency initiates HTTPS requests; deliveries return in poll responses. Separate matrix/work lanes are leased. Local SQLite persistence precedes ACK; ACK is not approval.

Hagency Matrix bridge → Hagency control plane

Authenticated local API

The bridge verifies sender, room, namespace and project bindings. The control plane retains contributor approval, quotas, task ownership and execution authority.

Hagency control plane → Coding-agent adapters

Guarded subprocess / selected transport

The backend chooses an eligible configured agent and transport. It validates the dispatch and passes context as data, not executable shell text.

Hagency Matrix bridge → Palpo homeserver

Matrix Client–Server API · as_token + scoped user_id

The bridge can send as registered local identities within its namespace using Appservice authentication. Supported encrypted paths use real device sessions instead.

Coding-agent adapters → Configured model providers

Provider-specific endpoint + credentials

The agent runtime connects to its configured model service independently of Matrix transport. Local endpoints are possible when supported by that agent.

Coding-agent adapters → Agent workspaces + files

Assigned cwd + runtime tool policy

Code and task artifacts are created in the assigned workspace. Publishing files back to a room is an explicit authorized operation.

Agent Matrix devices → Palpo homeserver

Matrix device token · sync + media + crypto

Real device clients maintain keys and session stores for supported encrypted messaging and private approvals. Server-side relay custody is not possession of decryption keys.

Execution approval → Agent Matrix devices

Verified Matrix owner binding

Approval requests and decisions travel through the verified owner channel. Granting a Matrix room role cannot bypass this execution check.

Coding-agent runtimes

Hagency control plane → Durable task + session state

SQLite transactions / dispatch ledger

Session identity and task state survive runner exit. Context is reconstructed from accepted inputs, summaries and room/thread bindings.

Hagency control plane → Claude Code runner

claude -p · stream-json

Spawn a guarded Claude child for the dispatch, stream activity and output, then settle or record an uncertain failure using the ledger.

Hagency control plane → Codex App Server

JSON-RPC / stdio

initialize, thread/start, turn/start; correlate notifications and approval responses with the current dispatch. Each worker starts a fresh App Server thread.

Hagency control plane → ACP adapter layer

Agent Client Protocol / stdio

Use the explicitly selected Octos, Hermes or Codex ACP adapter. Session/update reports progress; request_permission behavior is adapter-specific.

Hagency control plane → Retained tmux transport

tmux runtime interface

Retained terminal-managed agents use pane input/capture. This transport is not silently substituted for the headless runner or an ACP session.

Claude Code runner → Hagency MCP tools

MCP / stdio

Claude project configuration points at mcp-server.js; dispatch credentials arrive with the launched process rather than being embedded in public configuration.

Codex App Server → Hagency MCP tools

MCP / stdio

The App Server launch injects the Hagency MCP server configuration and allowed environment names; operation identity is checked for privileged tool calls.

ACP adapter layer → Hagency MCP tools

session/new mcpServers or agent-side config

Hermes and Codex ACP accept session MCP configuration. The reviewed Octos adapter requires its own config and coding-full profile instead.

Hagency MCP tools → Hagency control plane

Authenticated backend API + dispatch capability

MCP requests become checked task, conversation, messaging and file operations. Authority follows the dispatch and operation rather than text written by a model.

Codex App Server → Execution approval

Native JSON-RPC approval request

A command, file change or other supported native request pauses for a bound owner decision. An approval card is presentation; the backend validates the answer.

08 / SOURCE NOTES

Grounded in the implementation.

Reviewed September 2026 local development sources. The repository links identify upstream projects; these local revisions and integrations are not asserted to be the latest published releases or the exact currently deployed binary.

Hagency source

Reviewed local development revision 05dc46b: fleet-outbound-client/config/store, Matrix bridge, router/src/runner.ts and framework manifests.

Robrix2 source

Reviewed local revision d5523276: client builder, MatrixRequest worker, SyncService, message sending and persistent crypto.

The fleet /api/fleet/v2 transport, Palpo admin registration endpoint and companion app are project extensions. Standard Matrix supplies client/server communication, Appservices, room permissions and federation.

HAGENCY

Build something together.

Start with one project. Connect the others when your team is ready.

Search

Find your next step.

ESCClose⌘ / Ctrl + K

Project screenshot

Open original image