# Understanding the Layered Architecture of the Magnitude Project

> Explore the Magnitude project's layered architecture. Understand its five distinct tiers, from UI to core services, and discover how unidirectional dependencies ensure code organization and maintainability.

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

---

**The Magnitude project implements a strict package layering model that organizes code into five distinct tiers—clients, client-common, SDK, and ACN daemon—enforcing unidirectional dependencies from UI down to core services.**

The `magnitudedev/magnitude` repository structures its TypeScript codebase as a vertical stack where each layer exposes only the abstractions it owns. This layered architecture prevents circular dependencies and isolates the web and CLI front-ends from implementation details of the agent runtime, AI providers, and event-sourcing infrastructure.

## Package Layering Overview

The architecture follows a strict dependency chain:

```

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

```

This directional flow ensures that lower-level packages never import from higher-level ones. According to [`AGENTS.md`](https://github.com/magnitudedev/magnitude/blob/main/AGENTS.md) at the repository root, violating this rule requires refactoring the functionality into a core **Effect Query** primitive declared in `packages/acn-protocol/src/boundary/` and implemented under `packages/acn/src/boundary/`.

## The Five Core Layers

### Clients (CLI and Web)

The **client** layer contains the command-line (`cli`) and web (`web`) front-ends. These applications import only from `@magnitudedev/client-common` and `@magnitudedev/sdk`. They explicitly never reach into `acn`, `agent`, `acn-protocol`, `ai`, or `providers` packages. This constraint keeps the UI thin and prevents business logic from leaking into presentation code.

### client-common

The **client-common** package houses shared state, React hooks, and display synchronization logic. It provides the `AgentClient` Effect Query—a connection-scoped interface that communicates with the daemon over the SDK-provided ACN transport. All reusable client-side atoms, query-derived values, and side-effect utilities reside here, as documented in [`packages/client-common/AGENTS.md`](https://github.com/magnitudedev/magnitude/blob/main/packages/client-common/AGENTS.md).

### SDK

The **SDK** layer implements the typed RPC surface and daemon lifecycle management. Located in `packages/sdk/src/`, it exports `DaemonSpawner`, `ProviderClient`, and binary resolution utilities. The SDK re-exports ACN protocol types and acts as the bridge between UI concerns in `client-common` and the server-side runtime in `acn`. The JIT-RPC system in `packages/sdk/src/jit-rpc/*` generates the client-side RPC stubs from the boundary definitions.

### ACN Protocol

The **acn-protocol** package defines the wire contract shared by the SDK and daemon. It contains the `AcnBoundary` interface in `packages/acn-protocol/src/boundary/`—the single source of truth for all remote procedure calls. The `AcnRpc` system derives the complete RPC protocol from this boundary, ensuring type safety across the network boundary.

### ACN Daemon

The **acn** package hosts the server daemon that runs the agent runtime. It manages sessions, file operations, display streams, and implements the ACN protocol RPCs in `packages/acn/src/boundary/`. This layer contains the concrete business logic for agents, workers, tools, and projection materialization.

## Supporting Infrastructure Packages

Beyond the core stack, several specialized packages handle cross-cutting concerns:

- **agent** – Agent runtime, projections, workers, tools, and display materialization (`packages/agent/src/*`).
- **event-core** – Event-sourcing infrastructure and addressed state management (`packages/event-core/*`).
- **storage** – Persistent storage for sessions, configuration, and authentication (`packages/storage/*`).
- **ai** – Provider-agnostic contracts including `Provider`, `ModelCatalog`, `BoundModel`, and `BaseCallOptions`.
- **providers** – Concrete AI provider implementations and registry.
- **roles** – Role and slot definitions for worker specialization.

## Dependency Flow and Communication Patterns

The following patterns demonstrate how data flows through the stack. Clients consume reactive queries and mutations through the Effect Query system, while new RPC boundaries extend the protocol at the `acn-protocol` layer.

### Consuming the SDK from a Client

```typescript
// Client (e.g., web UI) – only imports public packages
import { useAgentClient } from '@magnitudedev/client-common';
import { ProviderClient } from '@magnitudedev/sdk';

// Create a connection-scoped client
const client = useAgentClient();

// Query a server-side session (client-common atom)
const session = client.Sessions.GetSession({ sessionId: 'abc123' });
const sessionData = useAtomValue(session);

// Trigger a mutation
const sendMessage = useAtomSet(client.Agent.SendMessage);
sendMessage({ text: 'Hello, world!' });

```

### Extending the RPC Boundary

When adding functionality, developers declare the contract in `acn-protocol` and implement it in `acn`:

```typescript
// 1. Define boundary in acn-protocol
export interface NewFeatureBoundary {
  /** Fetch data from the daemon */
  fetchData: (input: { id: string }) => QueryAtom<DataResult>;
}

// 2. Implement handler in acn (daemon side)
export class NewFeatureService implements NewFeatureBoundary {
  constructor(private readonly store: Store) {}

  fetchData({ id }) {
    return QueryAtom.make(() => this.store.get(id));
  }
}

```

### Accessing New RPCs from the SDK

The SDK automatically exposes new boundary methods through its generated RPC client:

```typescript
import { createAcnRpc } from '@magnitudedev/sdk';

const rpc = createAcnRpc();
const data = await rpc.NewFeature.fetchData({ id: 'xyz' });

```

## Summary

- **Magnitude** enforces a strict five-layer architecture: **clients → client-common → SDK → acn-protocol → acn**.
- **Clients** never import from `acn`, `agent`, or `providers`, ensuring UI layers remain isolated from runtime internals.
- **acn-protocol** serves as the single source of truth for RPC contracts, located in `packages/acn-protocol/src/boundary/`.
- **Effect Query primitives** bridge layers, with `AgentClient` providing the primary interface for client-daemon communication.
- **ACN RPC** derives TypeScript clients automatically from boundary definitions, maintaining type safety across the network.

## Frequently Asked Questions

### What is the dependency direction in Magnitude's architecture?

Dependencies flow strictly downward from UI packages toward infrastructure. The `cli` and `web` clients depend on `client-common` and the SDK, while the SDK depends on `acn-protocol` and communicates with the `acn` daemon. Lower layers never reference higher layers, preventing circular dependencies.

### How does the SDK communicate with the ACN daemon?

The SDK uses a typed RPC system (`AcnRpc`) generated from the `AcnBoundary` interface defined in `packages/acn-protocol/src/boundary/`. The SDK's `createAcnRpc()` function builds a complete RPC client from these definitions, while the daemon implements the corresponding handlers in `packages/acn/src/boundary/`.

### Where is the RPC protocol defined in Magnitude?

The wire contract lives in the `acn-protocol` package, specifically within `packages/acn-protocol/src/boundary/`. This directory contains TypeScript interfaces that define all remote procedure calls, ensuring both the SDK client and ACN daemon share a single source of truth for the API surface.

### How can I add new functionality to the Magnitude daemon?

Declare a new **Effect Query** primitive in the appropriate domain group under `packages/acn-protocol/src/boundary/`, then implement its handler under `packages/acn/src/boundary/`. The SDK will automatically expose the new capability through the `AcnRpc` system without requiring changes to the client-common or client packages.