# Package Layering Architecture from Clients to ACN in Magnitude: Complete Guide

> Understand magnitudedev/magnitude's package layering architecture from clients to ACN. Explore the strict four-tier hierarchy and how each layer enforces its public API for robust development.

- Repository: [Magnitude/magnitude](https://github.com/magnitudedev/magnitude)
- Tags: architecture
- Published: 2026-09-08

---

**The package layering architecture in magnitudedev/magnitude enforces a strict four-tier hierarchy—clients (cli/web) → client-common → sdk → acn (daemon)—with each layer exposing only its public API and prohibiting direct imports from lower levels.**

Magnitude is built on a hierarchical package structure that separates concerns and maintains strict import boundaries from the user interface down to the server daemon. This **package layering architecture from clients to ACN** is explicitly documented in the project's [`AGENTS.md`](https://github.com/magnitudedev/magnitude/blob/main/AGENTS.md) file and implemented across the `packages/` directory to ensure clean, maintainable, and testable code.

## The Four-Layer Hierarchy

The core architectural relationship is defined in the root [`AGENTS.md`](https://github.com/magnitudedev/magnitude/blob/main/AGENTS.md) file:

```

clients (cli/web) → client-common → sdk → acn (daemon)

```

Each layer has distinct responsibilities and strict export boundaries that prevent circular dependencies or implementation leakage.

### Clients (CLI and Web)

The **Clients** layer contains UI-level code for both command-line and web interfaces. Client code may only import from `@magnitudedev/client-common` and `@magnitudedev/sdk`. Direct imports from lower layers—including `acn`, `agent`, or `ai`—are strictly prohibited by architectural convention.

**Public API**: `@magnitudedev/client-common`, `@magnitudedev/sdk`

### client-common

The **client-common** layer provides shared state management, React hooks, and display synchronization components. It maintains a single connection-scoped Effect Query (`AgentClient`) that operates over the SDK instance, serving as the bridge between UI concerns and the portable RPC client.

**Responsibilities**: State management, hook implementations, display synchronization.

### sdk

The **sdk** layer implements a private, portable Effect RPC client that handles fixed-endpoint admission, connection recovery, and optional service-starter capabilities. The SDK re-exports only pure protocol contracts from `acn-protocol` and contains no SQLite logic, process supervision, or query caching. It serves as the public RPC façade that completely hides ACN implementation details.

**Public API**: `@magnitudedev/sdk`

The SDK defines RPC methods using protocol schemas without importing the daemon:

```typescript
// packages/sdk/src/rpc/session.ts
import { Rpc } from '@magnitudedev/acn-protocol';

export const startSession = Rpc.make('session.start', {
  request: SessionStartRequestSchema,
  response: SessionStartResponseSchema,
});

```

### acn (daemon)

The **acn** layer hosts the server daemon that implements the Agent Control Network protocol. It manages the agent runtime, session handling, file operations, and display streams. This layer implements the RPC handlers defined in `acn-protocol` but exposes no public API to upper layers.

**Responsibilities**: Daemon runtime, session management, RPC handler implementation.

RPC handlers are implemented in the ACN package:

```typescript
// packages/acn/src/handlers/session.ts
import { RpcHandler } from '@magnitudedev/acn-protocol';

export const startSessionHandler: RpcHandler = async (req) => {
  // Daemon-level session creation logic
  return { sessionId: createSession(req) };
};

```

## Supporting Packages Outside the Core Chain

Several packages support the architecture without being part of the direct client-to-ACN import chain:

- **daemon-management** – Handles owner store, process supervision, binary acquisition, and OS-service implementation. Used only by privileged composition roots.
- **acn-protocol** – Defines wire contracts shared by SDK and ACN. Never imported directly by client code.
- **ai** – Contains provider-agnostic contract definitions for LLM interactions.
- **providers** – Implements concrete provider implementations and registries.
- **agent**, **event-core**, **roles**, **storage** – Provide runtime execution, event sourcing, role specialization, and persistent storage layers.

## Data Flow Through the Architecture

When adding a new backend operation, developers must follow a strict path to maintain architectural integrity:

1. Declare the RPC in `packages/acn-protocol/src/boundary/`
2. Implement the handler in the **acn** package
3. Expose a method in the **sdk** package
4. Optionally add caching or synchronization logic in **client-common**

This ensures a single source of truth and consistent replay policies across the entire stack.

### Client Usage Pattern

Client code remains isolated from implementation details:

```typescript
// packages/cli/src/commands/start.ts
import { useAgent } from '@magnitudedev/client-common';
import { startSession } from '@magnitudedev/sdk';

const session = await startSession({ name: 'test-run' });

```

### SDK Facade Implementation

The **client-common** layer consumes the SDK without exposing RPC internals:

```typescript
// packages/client-common/src/operations/start.ts
import { sdk } from '@magnitudedev/sdk';

export const start = sdk.makeRpc('session.start');

```

## Strict Import Boundaries and Enforcement

The architecture enforces import direction through convention and documentation. The root [`AGENTS.md`](https://github.com/magnitudedev/magnitude/blob/main/AGENTS.md) file explicitly defines the layering, while individual package [`AGENTS.md`](https://github.com/magnitudedev/magnitude/blob/main/AGENTS.md) files (located in `packages/client-common/`, `packages/sdk/`, `packages/acn-protocol/`, and `packages/acn/`) provide detailed implementation notes for each layer.

**Forbidden Pattern**: Clients cannot import directly from `acn` or `agent` packages. All communication must flow through the SDK's RPC façade, ensuring that UI code remains agnostic to daemon implementation details, database schemas, or process management.

## Summary

- The **package layering architecture from clients to ACN** follows a strict four-tier hierarchy: clients → client-common → sdk → acn.
- **Clients** (CLI/Web) may only import from `client-common` and `sdk`, never from `acn` or internal runtime packages.
- **client-common** manages state and synchronization using a single Effect Query over the SDK instance.
- **sdk** provides a portable RPC façade that hides daemon complexity and re-exports only pure protocol contracts from `acn-protocol`.
- **acn** implements the server daemon, session management, and RPC handlers without exposing internal APIs upward.
- New features must follow the declaration path: `acn-protocol` → `acn` → `sdk` → `client-common` (optional).

## Frequently Asked Questions

### What is the exact import order from clients to ACN in Magnitude?

The exact import hierarchy is **clients (cli/web) → client-common → sdk → acn (daemon)**. Each layer may only import from the layer immediately below it or from shared protocol packages like `acn-protocol`. Direct imports that skip layers—such as a client importing from `acn`—are prohibited by architectural convention.

### Can clients in Magnitude import directly from the ACN daemon layer?

No. Clients are explicitly forbidden from importing directly from the `acn` package or any internal runtime packages (`agent`, `ai`, `storage`). All communication must occur through the `@magnitudedev/sdk` RPC façade, which isolates UI code from daemon implementation details and database dependencies.

### Where are RPC contracts defined in the Magnitude architecture?

RPC contracts are defined in the **`acn-protocol`** package, specifically within `packages/acn-protocol/src/boundary/`. This package serves as the source of truth for wire contracts shared between the SDK and ACN layers, ensuring type safety across the client-server boundary without creating circular dependencies.

### How does Magnitude handle state synchronization between layers?

State synchronization is handled primarily in the **client-common** layer, which runs a connection-scoped Effect Query (`AgentClient`) over the SDK instance. This layer manages hooks and display synchronization, ensuring that UI components receive consistent state updates while the underlying SDK handles RPC communication with the ACN daemon.