7.9 KiB
ADR-023: Server Mode
Status: Accepted
Date: 2026-02-16
Supersedes: None
Author(s): Jeffrey Phillips Freeman Jeffrey.Freeman@CleverThis.com
Approver(s): Jeffrey Phillips Freeman Jeffrey.Freeman@CleverThis.com
Context
CleverAgents starts as a single-user local CLI tool, but the specification envisions a collaborative multi-user deployment where teams share entity definitions, execute plans on shared infrastructure, and collaborate on projects. The system needs a server deployment mode that enables this without requiring a separate codebase — the same domain and application layers must support both local and server modes.
Decision
CleverAgents supports two deployment modes that share the same Domain and Application layers. Local mode is a single-process CLI application with SQLite storage. Server mode is a multi-user service where the CLI acts as a thin client communicating with a remote server over HTTPS. The Infrastructure Layer provides swappable implementations for each mode, enabled by the hexagonal architecture (ADR-001).
Design
Local Mode
- Single-process CLI application.
- All components run in the same Python process.
- SQLite database for persistence (WAL mode for concurrent reads).
- All resources are local to the machine.
- The
local/namespace is always available. - No server dependency — works fully offline.
Server Mode
- The CLI operates as a thin client.
- Communication with the server over HTTPS using
server.urlandserver.token. - The server hosts shared storage (PostgreSQL), namespace resolution, and remote plan execution.
- Server namespaces (
<username>/,<orgname>/) are available when connected. - Entity definitions (actors, actions, skills, tools) can be synced between local and server.
- Plans can execute on the server, with sandbox environments managed remotely.
Server Infrastructure
- REST API: FastAPI application served by uvicorn (>= 0.30.1).
- Database: PostgreSQL via SQLAlchemy (same ORM, different dialect from local SQLite).
- Deployment: Helm chart in
k8s/directory for Kubernetes deployment. - Authentication: Token-based authentication (
server.token).
Sync Mechanism
Entity synchronization between client and server:
- Auto-sync: Controlled by
server.sync.auto(default:true). When enabled, entities are synced on startup and after registration changes. - Sync interval: Background syncs at
server.sync.interval(default: 300 seconds). - Manual sync: Can be triggered explicitly when auto-sync is disabled.
- Direction: Server namespaces are downloaded to local cache; local namespace entities are never uploaded automatically.
Namespace Resolution in Server Mode
local/always resolves locally, regardless of server connection.<username>/and<orgname>/resolve against the server.- Server-qualified names (
dev:freemo/actor) resolve against a specific server when multiple servers are connected. - The default namespace can be configured to a server namespace via
core.namespace.
Project Types and Execution Location
| Project Type | Definition | Plan Execution |
|---|---|---|
| Local | Contains at least one local-only resource | Client only |
| Remote | All resources are remotely accessible | Client or Server |
Remote projects can have their plans executed on the server, enabling shared infrastructure and centralized execution.
Shared Architecture
The key architectural enabler is the hexagonal pattern (ADR-001):
- Domain Layer: Identical between modes. All business rules, domain models, and domain events are shared.
- Application Layer: Identical between modes. Service facades, workflow engine, and event bus are shared.
- Infrastructure Layer: Swappable implementations per mode:
- SQLite ↔ PostgreSQL (database)
- Local file access ↔ Remote API calls (resource access)
- Local sandbox ↔ Remote sandbox (execution environment)
- Direct component invocation ↔ HTTPS API calls (service communication)
Constraints
- The
local/namespace must never be synced to a server. - Server mode requires
server.urlandserver.tokento be configured. - The Domain and Application layers must have zero mode-specific code. All mode differences must be in the Infrastructure Layer.
- Token authentication is required for all server API calls.
- Local-only projects (containing local-only resources) cannot execute plans on the server.
- The CLI must function fully offline in local mode, with no server dependency.
Consequences
Positive
- A single codebase supports both local-first development and collaborative server deployment.
- The hexagonal architecture ensures mode switching is purely an infrastructure concern.
- Local mode has zero configuration requirements — no server needed.
- Teams can share entity definitions and execute plans on shared infrastructure without each member maintaining local copies.
Negative
- Server mode requires operating a server (PostgreSQL, Kubernetes, Helm, authentication).
- The sync mechanism adds complexity and potential for stale or conflicting entity definitions.
- Network latency affects all operations in server mode.
Risks
- Sync conflicts between local modifications and server-side changes could produce inconsistent entity states.
- Server downtime renders server-namespaced entities unavailable.
- Security of the authentication token and HTTPS transport must be ensured.
Alternatives Considered
Separate server codebase — Would require maintaining two implementations of the same domain logic, leading to divergence and doubled maintenance. The shared-layer approach avoids this.
Peer-to-peer sync (no central server) — More resilient but significantly more complex for conflict resolution, namespace management, and access control. A central server provides simpler semantics for organizational namespaces and shared execution.
Compliance
- Mode isolation tests: Tests verify that Domain and Application layer code has no mode-specific imports or branching.
- Infrastructure swappability tests: Tests verify that swapping SQLite for PostgreSQL, local sandbox for remote sandbox, etc., produces correct behavior.
- Offline functionality tests: Tests verify that local mode works completely without network access.
- Sync tests: Integration tests verify entity sync behavior including auto-sync, manual sync, and conflict handling.
- Authentication tests: Tests verify that server API calls require valid tokens and that unauthenticated requests are rejected.
Related ADRs
| ADR | Title | Relationship |
|---|---|---|
| ADR-001 | Layered Architecture | Both deployment modes share Domain and Application layers, differing only in Presentation and Infrastructure |
| ADR-002 | Namespace System | Server mode introduces server-prefixed namespaces for multi-server entity resolution |
| ADR-005 | Technical Stack | FastAPI, uvicorn, and Helm/Kubernetes are the server mode stack choices |
| ADR-019 | Storage and Persistence | Server mode uses PostgreSQL instead of SQLite for multi-user persistence |
| ADR-026 | Agent Client Protocol (ACP) | ACP is the client-server contract implemented by the REST API in server mode; its transport duality (in-process facade for local, HTTPS + JSON for server) is the mechanism that keeps both modes behaviorally identical |
Acceptance
Votes For
| Voter | Comment |
|---|---|
| Jeffrey Phillips Freeman Jeffrey.Freeman@CleverThis.com | Sharing Domain and Application layers across both modes maximizes code reuse and behavioral consistency |
Total: 1
Votes Against
| Voter | Comment |
|---|
Total: 0
Abstentions
| Voter | Comment |
|---|
Total: 0