Skip to content

Brain & agent

The brain is the stateful, central, user-facing half. One per organization.

Responsibilities:

  • Serve the dashboard (React 19.2, TanStack Start v1, Tailwind 4, shadcn/ui).
  • Serve the REST API (/api/v1/*).
  • Accept WebSocket connections from agents at /ws.
  • Persist everything to PostgreSQL.
  • Authenticate users (argon2id + server-side sessions).
  • Enforce RBAC.
  • Emit audit log entries (HMAC-chained).
  • Run the reconciliation worker (background task).
  • Rate-limit unauthenticated endpoints.
  • Redact secrets from events before persist.

Does not:

  • Connect to your broker. The brain has no knowledge of Redis/RabbitMQ/SQS credentials. Agents do that.
  • Connect outward to agents. All WebSockets are inbound (agent → brain).
  • Hold queue state in memory. It’s all in Postgres.

The agent is the thin, distributed, in-your-process half. One per application process.

Responsibilities:

  • Open and maintain one WebSocket to the brain.
  • On connect, send hello advertising: protocol version, framework, engines, schedulers, capabilities map.
  • On engine task events, capture → redact → buffer → dispatch to brain.
  • On command frames from brain, route to the engine adapter and execute (retry, cancel, purge, schedule CRUD).
  • Heartbeat every 30 seconds; reconnect on failure with backoff.
  • Discover schedules on registered schedulers and emit on change.

Does not:

  • Store events locally (except transient buffer during network partition).
  • Authenticate users, serve UI, or accept external connections.
  • Know about other agents.
  • User → Brain - server-side session cookie (SameSite=Lax, HttpOnly, Secure). Password = argon2id. Session secret from Z4J_SESSION_SECRET.
  • Agent → Brain - bearer token minted by an admin in the dashboard. Stored HMAC-SHA256 hashed in Postgres. Rotated by minting a new token and revoking the old one.

Tokens are per-agent, not per-project - revoke individually without affecting other agents.

events flow ───────────────►
┌────────────┐ ┌─────────────┐
│ agent │ ───── ws ────► │ brain │
│ (in-proc) │ ◄──── ws ───── │ (container) │
└────────────┘ └─────────────┘
◄────────────── commands flow

Both directions on the same WebSocket. Sequence numbers on each direction give at-least-once semantics; the brain dedupes on persist.

ConcernBrainAgent
Postgres
Queue credentials✓ (only your queue’s creds)
HTTP UI/API
WebSocket endpoint✓ (server)✓ (client)
Session cookies
Engine-specific code
RBAC rules
Audit log
Task runtime✗ (Celery/RQ/… runs separately)