relaydmessage flow
Client Interaction
Read from live source

The journey of a message, chat client → model

One message, traced through relayd's deterministic control chain exactly as the code runs it (internal/relay/relay.go, Broker.Run). Each numbered gate can admit the message onward or divert it — the message only reaches the model if it survives every gate in order.

Inbound path & return path

message advancing diverted / refused reply retraces
Chat client Telegram · Discord relayd — the gate chain deterministic control, in Go relay-shim MCP over unix socket Claude Code the model user sends a message −1Lockdown?non-admins blocked while active refuse 0Session gategated user needs a live tailnet session challenge 0.5Anomaly scorestyle-drift vs sender history · fails open revoke / warn 1Slash command?handled locally — never hits the model local reply 2Budget / circuit gateglobal token budget + breaker over budget 2.5Per-conversation capcharge-then-reject token cap over cap 3Admitted → Backend.Sendthe message survived every gate over the unix socket MCP tool delivers the turn model composes reply reply retraces the path to the user

Order is the security

The gates run in a fixed sequence — lockdown, then session, then anomaly, before a slash command or the model is ever considered. A message must pass every one, in order, to be admitted.

Most paths never reach the model

A slash command is answered locally; an over-budget or over-cap message is refused; a gated user with no live session gets a re-auth challenge. Only an admitted message crosses to the backend.

The socket boundary

relayd and the model are separate processes. Admitted messages cross a unix socket to relay-shim, which the model runs as an MCP server — so the daemon and the model can restart independently.

Fail-open where it should

The anomaly gate is advisory: if its backing store is down it fails open and logs the outage, because the real boundary is the session/allowlist controls — an outage there must not lock everyone out.