Files
cleveragents-core/docs/adr/ADR-023-server-mode.md

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.url and server.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.url and server.token to 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.
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