Skip to main content
r5d.chat has two moving parts: a control plane that owns identity and state, and one workspace per user that does the actual work.

The control plane

The control plane is a TanStack Start application running on Bun. It is the only component your browser talks to, and the only component that holds secrets. It owns:
  • Identity: accounts, sessions, invitations, and optional OIDC.
  • Configuration: encrypted provider credentials, models, and MCP servers.
  • Conversations: the durable message history in PostgreSQL.
  • Model streaming: it calls the model provider and streams the response.
  • Reconciliation: it creates and scales the Kubernetes objects per user.
PostgreSQL is authoritative for users, chats, messages, workspace intent, and audit history.

Workspaces

Every user maps to a deterministic set of Kubernetes objects, named from a hash of the user ID: The complete PVC mounts at /home/r5d. The chart never uses subPath, which keeps it compatible with runtimes like Kata. Inside the pod, r5dchat daemon exposes a private authenticated HTTP API for file, search, and process operations. The control plane calls it with the workspace’s bearer token. The browser never receives that token, and all file traffic is proxied through the control plane.
Tenant pods run as root on purpose so agents can install packages, but they receive no service-account token, host path, runtime socket, or Linux capability. See Security for the full model and its limits.

The idle lifecycle

Workspaces are expensive to keep running and cheap to restart, so they scale to zero automatically.
1

Activity starts the workspace

A chat run, file operation, upload, preview, or command scales the Deployment to one and waits for the daemon’s readiness probe.
2

Leases track in-flight work

Long-running operations such as shell commands take an active lease so a busy workspace is never reaped mid-task.
3

Idle workspaces scale to zero

When every lease has ended and WORKSPACE_IDLE_SECONDS has elapsed, a reconciler running every 60 seconds scales compute to zero.
4

The data stays

The Service, identity Secret, database records, and PVC all remain. The next request scales the same Deployment back up and remounts the same home directory.

Providers and models

A provider is an OpenAI-compatible endpoint: a base URL, an API key, and optional custom headers. A model belongs to a provider and adds a provider model ID, a display name, a context-window limit, and a maximum output size. Each user configures their own providers. Credentials are encrypted with SETTINGS_ENCRYPTION_KEY and never leave the control plane. Exactly one model per user is the default, enforced by a partial unique index in the database. Deleting or disabling the default promotes the oldest remaining enabled model, so a user is never left without one.

Configure providers

Base URLs, custom headers, the outbound URL guard, and default-model rules.

Conversations and fresh context

A conversation owns one ordered message stream. Starting a fresh context does not create a new conversation: it appends a flagged system prompt to the same stream. Provider context begins at the most recent flag, while the durable transcript stays complete. This lets the agent recover earlier detail on demand from inside the workspace:
The CLI authenticates with workspace identity, and the server re-checks that the requesting workspace’s user actually owns the conversation.

Artifacts

/home/r5d/artifacts is the convention for user-facing deliverables. Uploads land there, and the agent is instructed to write outputs there and link them with the workspace form [filename](~/artifacts/filename). The UI turns those links into authenticated downloads.

How a message flows

1

The browser posts to the control plane

POST /api/chat with the conversation ID and the new message.
2

The control plane prepares the run

It authenticates the session, loads the user’s default model, decrypts the provider credentials, and ensures the workspace is running.
3

The model streams back

Text, reasoning, and tool calls stream to the browser as they arrive.
4

Tool calls execute in the workspace

Each tool call becomes an authenticated request to the workspace daemon, refreshing the activity timestamp.
5

Everything is persisted

Messages and tool results are written to PostgreSQL, so a reload or a new device shows the same conversation.

Full architecture

Component boundaries, trust boundaries, and the threat model.