| Flag | Default | Description |
|---|---|---|
--data-dir | ./data or RELIANT_DATA_DIR | Base directory for databases, logs, and certificates |
SIGTERM, SIGINT, or detects its parent process has exited (the “suicide pact” pattern used when launched by Electron).
Embedded components
The monolith bundles six subsystems that would be separate services in a distributed deployment.Temporal workflow engine
An embedded Temporal server backed by SQLite atdata/temporal.db. It registers two namespaces — default and reliant — and runs Temporal workers in-process so workflow activities execute without network round-trips.
The frontend port is auto-assigned by default (finds a free port at startup) but can be pinned with the TEMPORAL_FRONTEND_PORT environment variable. Auto-assignment is the normal mode; pinning is only needed when external tooling must connect to a known port.
Application database
A SQLite database atdata/reliant.db stores all application state: chats, messages, content blocks, workflows, projects, and worktrees. The schema is managed by embedded migrations that run automatically on startup.
HTTP API server
Serves REST endpoints for the web frontend. Defaults to port8080 (API_PORT). The API server handles CORS, JWT authentication, and optionally TLS — the same TLS configuration described below applies to both the HTTP and gRPC servers.
gRPC / ConnectRPC server
Provides real-time streaming and RPC for the desktop client. Defaults to port9090 (GRPC_PORT). Uses ConnectRPC for browser compatibility (gRPC-Web and Connect protocols over HTTP/2). This is where chat streaming, workflow execution updates, and user/chat update subscriptions are served.
Tools daemon
Runs in-process on port9190 (TOOLS_DAEMON_PORT). The daemon hosts the tool execution runtime — file operations, shell commands, LSP integration, MCP server connections — and exposes them over gRPC so workflow activities can invoke tools.
The daemon uses a LazyDaemonStarter lifecycle: if a user is already signed in when the monolith boots, the daemon starts eagerly. If no user session exists yet (first launch, signed-out state), it starts lazily on the first authenticated request. A LocalDaemonRouter handles in-process tool execution routing, avoiding the network hop that a distributed deployment would require.
Memory-based streaming
Real-time updates for chat events and user state changes flow throughMemoryUpdateHub instances — in-memory fan-out channels that push events to subscribed gRPC streams. No external message broker (Redis, NATS, etc.) is involved. This keeps the monolith self-contained but means streaming state is ephemeral and scoped to the lifetime of the process.
TLS configuration
TLS is evaluated in priority order. The first matching condition wins:| Priority | Condition | Behavior |
|---|---|---|
| 1 | DISABLE_TLS=true | Plain HTTP, no TLS. Useful behind a reverse proxy or in trusted networks. |
| 2 | TLS_CERT_FILE + TLS_KEY_FILE set | Uses the provided certificate and key files. Typical for local development with mkcert certificates. |
| 3 | Neither of the above | Auto-generates a self-signed certificate in data/certs/ and uses it for all servers. The certificate is persisted so subsequent restarts reuse it. |
PID locking
The monolith acquires a file-based PID lock (data/.reliant-backend.lock) before starting any component. This prevents multiple backend processes from running against the same data directory simultaneously, which would corrupt the SQLite and Temporal databases.
If the lock is already held, the process retries up to 3 times with a 2-second delay between attempts. If the holder is a stale process (no longer running), the lock is reclaimed automatically. If a live process holds the lock, startup fails with an error message identifying the conflicting PID.
Logging
Structured logs are written todata/logs/reliant.log using automatic rotation:
| Setting | Value |
|---|---|
| Max file size | 50 MB |
| Rotated backups kept | 3 |
| Max age | 30 days |
| Compression | Enabled (gzip) |
LOG_LEVEL environment variable. In production mode, the embedded Temporal server’s log level is reduced to warn to cut noise.
Environment variables
| Variable | Default | Description |
|---|---|---|
RELIANT_DATA_DIR | ./data | Base data directory for databases, logs, and certs |
API_PORT | 8080 | HTTP API server port |
GRPC_PORT | 9090 | gRPC/ConnectRPC server port |
TOOLS_DAEMON_PORT | 9190 | In-process tools daemon port |
TEMPORAL_FRONTEND_PORT | Auto-assigned | Temporal frontend port. Set to pin a specific port. |
BIND_ADDRESS | 127.0.0.1 | Network bind address for all servers |
CORS_ALLOWED_ORIGINS | * | Comma-separated list of allowed CORS origins, or * for wildcard |
DISABLE_TLS | — | Set to true to disable TLS across all servers |
TLS_CERT_FILE | — | Path to a PEM-encoded TLS certificate |
TLS_KEY_FILE | — | Path to the corresponding TLS private key |
PPROF_PORT | 6060 | Port for the pprof debug/profiling server (localhost only) |
Data directory layout
Shutdown behavior
The monolith shuts down gracefully when it receivesSIGINT, SIGTERM, or detects its parent process has exited (stdin EOF). The shutdown sequence runs with a 20-second timeout and proceeds in order:
- Kill all background shell processes to prevent orphans
- Stop the process monitor
- Stop the gRPC server (drains active streams)
- Shut down the tools daemon
- Stop the HTTP API server
- Stop the integration server (Temporal engine and workers)
- Flush analytics and error reporting
- Release the PID lock