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

9.4 KiB

adr_number, title, status_history, tier, authors, superseded_by, related_adrs, acceptance
adr_number title status_history tier authors superseded_by related_adrs acceptance
23 Server Mode
2026-02-16
Proposed
Jeffrey Phillips Freeman
2026-02-16
Accepted
Jeffrey Phillips Freeman
4
Jeffrey Phillips Freeman
null
number title relationship
1 Layered Architecture Both deployment modes share Domain and Application layers, differing only in Presentation and Infrastructure
number title relationship
2 Namespace System Server mode introduces server-prefixed namespaces for multi-server entity resolution
number title relationship
5 Technical Stack A2A Python SDK, LangGraph Platform, PostgreSQL, and Helm/Kubernetes are the server mode stack choices
number title relationship
19 Storage and Persistence Server mode uses PostgreSQL instead of SQLite for multi-user persistence
number title relationship
26 Agent-to-Agent Protocol (A2A) A2A (external standard, JSON-RPC 2.0) is the sole client-server protocol; server mode uses A2A over HTTP, local mode uses A2A over stdio
number title relationship
47 A2A Standard Adoption ADR-047 defines the adoption of the external A2A standard that replaces the previous REST-based protocol
number title relationship
48 Server Application Architecture ADR-048 defines the concrete server architecture (LangGraph Platform, PostgreSQL, A2A endpoint) that implements server mode
votes_for votes_against abstentions
voter comment
Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com> Sharing Domain and Application layers across both modes maximizes code reuse and behavioral consistency

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 Drivers

  • The same domain and application logic must run identically in both single-user local and multi-user server deployments
  • Teams need to share entity definitions, execute plans on shared infrastructure, and collaborate without maintaining separate codebases
  • Local mode must work fully offline with zero server dependency
  • Client and server must share namespaces and resolve names identically regardless of deployment mode
  • Infrastructure concerns (database, sandbox, transport) must be swappable without touching domain or application code

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 and A2A over stdio. Server mode is a multi-user service where the CLI acts as a thin client communicating with a remote server via A2A over HTTP (JSON-RPC 2.0). 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.
  • A2A flows over stdio — the agent runs as a subprocess, JSON-RPC messages over stdin/stdout.
  • Extension methods (_cleveragents/*) resolved in-process by A2aLocalFacade.
  • 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 via A2A over HTTP (JSON-RPC 2.0) 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 via _cleveragents/sync/* extension methods.
  • Plans can execute on the server, with actor graphs running on LangGraph Platform via RemoteGraph.

Server Infrastructure

  • A2A endpoint: A2A JSON-RPC 2.0 server implemented using the A2A Python SDK's server-side connection handler. This is the sole client-facing interface.
  • Database: PostgreSQL via SQLAlchemy (same ORM, different dialect from local SQLite).
  • Actor execution: LangGraph Platform via RemoteGraph — each actor graph deploys as a separate RemoteGraph.
  • Deployment: Helm chart in k8s/ directory for Kubernetes deployment.
  • Authentication: Token-based authentication via HTTP auth schemes declared in the server's Agent Card.

Sync Mechanism

Entity synchronization between client and server uses A2A extension methods (_cleveragents/sync/*):

  • 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. When server-hosted agents need to access client-local resources, _cleveragents/ extension method callbacks (fs/*, terminal/*) forward the requests to the connected client.

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 ↔ A2A callbacks (resource access)
    • Local sandbox ↔ LangGraph Platform RemoteGraph (execution environment)
    • A2aLocalFacade (stdio) ↔ A2A SDK server endpoint (HTTP) (transport)

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 A2A method calls (enforced via HTTP auth schemes declared in the Agent Card).
  • 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, LangGraph Platform, 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 RemoteGraph, 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 via _cleveragents/sync/* methods.
  • Authentication tests: Tests verify that the A2A authentication flow works correctly and that unauthenticated requests are rejected.