# Understanding the DimOS Spec Pattern for Type-Safe RPC Wiring

> Discover the DimOS Spec pattern for type-safe RPC wiring. Learn how this protocol-based interface system auto-connects modules with structural and annotation compliance.

- Repository: [Dimensional/dimos](https://github.com/dimensionalOS/dimos)
- Tags: deep-dive
- Published: 2026-03-15

---

**The DimOS Spec pattern is a Protocol-based interface system that enables automatic, type-safe RPC wiring between modules by detecting Spec-typed attributes during blueprint construction and injecting concrete implementations that satisfy both structural and annotation compliance.**

The **Spec pattern** in the [dimensionalOS/dimos](https://github.com/dimensionalOS/dimos) repository provides a declarative mechanism for defining RPC interfaces between modules. By inheriting from a special `Spec` marker Protocol, developers can create type-safe contracts that the blueprint system resolves automatically at build time. This eliminates manual dependency injection while maintaining strict compile-time and runtime type checking across distributed module boundaries.

## What Is the DimOS Spec Pattern?

A **Spec** is a thin Python Protocol that also inherits from the internal `Spec` marker class defined in [`dimos/spec/utils.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/spec/utils.py) (lines 22-25). Unlike standard Protocols, Specs serve as explicit interface declarations that the DimOS blueprint system recognizes during module assembly.

When a module declares an attribute typed with a Spec subclass, the system:

1. **Detects** the Spec during blueprint construction in `_BlueprintAtom.create` (lines 95-100 in [`dimos/core/blueprints.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/blueprints.py))
2. **Searches** for concrete implementations matching the Spec's method signatures
3. **Validates** type annotation compatibility between the Spec and candidate modules
4. **Injects** the concrete module instance, enabling transparent RPC calls via the `@rpc` decorator

This architecture provides **static typing** through Protocols, **runtime safety** through compliance checks, and **automatic wiring** without explicit object passing.

## Core Implementation Files

The Spec pattern relies on three primary components across the codebase:

- **[`dimos/spec/utils.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/spec/utils.py)** – Defines the `Spec` marker Protocol and helper functions `is_spec`, `spec_structural_compliance`, and `spec_annotation_compliance`
- **[`dimos/core/blueprints.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/blueprints.py)** – Implements the wiring logic through `_BlueprintAtom.create` and `_connect_module_refs` (lines 35-78)
- **[`examples/rpc_calls.py`](https://github.com/dimensionalOS/dimos/blob/main/examples/rpc_calls.py)** – Demonstrates practical usage with the `ComputeSpec` example

## How the Blueprint System Detects Specs

### The Spec Marker Protocol

The foundation resides in [`dimos/spec/utils.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/spec/utils.py) (lines 22-25), where the base `Spec` class distinguishes interface Protocols from normal Python Protocols:

```python

# dimos/spec/utils.py

class Spec(Protocol):
    """Marker protocol for DimOS Spec interfaces"""
    pass

```

The `is_spec` helper function (lines 27-39) validates that a class is a Protocol, inherits from `Spec`, and is not the base `Spec` itself. This check runs during blueprint construction to identify which module attributes require automatic wiring.

### Blueprint Atom Creation

During module registration in `_BlueprintAtom.create` ([`dimos/core/blueprints.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/blueprints.py), lines 95-100), the system scans class annotations. Any attribute where `is_spec()` returns `True` becomes a `ModuleRef`—a placeholder indicating that this module depends on an RPC interface rather than a concrete class.

## Module Resolution and Wiring

### Structural Compliance Checking

The `_connect_module_refs` method (lines 35-78 in [`dimos/core/blueprints.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/blueprints.py)) performs two-phase validation. First, it checks **structural compliance** via `spec_structural_compliance`, verifying that candidate modules implement methods with compatible signatures (name, parameters, and return type compatibility including subclasses).

### Annotation Compliance Validation

Second, the system enforces **annotation compliance** through `spec_annotation_compliance`. This strict check ensures that type hints in the concrete implementation match the Spec exactly, catching mismatches such as returning `list` instead of `int` even when the method signature appears compatible.

### Runtime Injection

Once validated, the concrete module is injected into the requesting module's attribute (lines 84-93):

```python

# dimos/core/blueprints.py

setattr(base_module_proxy, module_ref_name, target_module_proxy)

```

The module reference is stored for reciprocal RPC calls, allowing the client to invoke methods like `self.calc.compute1(...)` while the `@rpc` decorator handles the actual remote procedure call.

## Complete Code Example

The following example from [`examples/rpc_calls.py`](https://github.com/dimensionalOS/dimos/blob/main/examples/rpc_calls.py) demonstrates the full workflow:

```python

# spec.py – define the interface

from dimos.spec.utils import Spec
from typing import Protocol
from dimos.core.core import rpc

class ComputeSpec(Spec, Protocol):
    @rpc
    def compute1(self, a: int, b: int) -> int: ...

    @rpc
    def compute2(self, a: float, b: float) -> float: ...

```

```python

# calculator.py – concrete implementation

from dimos.core.module import Module
from dimos.core.core import rpc

class Calculator(Module):
    @rpc
    def compute1(self, a: int, b: int) -> int:
        return a + b

    @rpc
    def compute2(self, a: float, b: float) -> float:
        return a + b

```

```python

# client.py – request the spec

from dimos.core.module import Module

class Client(Module):
    # Blueprint system injects Calculator automatically

    calc: ComputeSpec

    @rpc
    def start(self) -> None:
        print("c1:", self.calc.compute1(2, 3))   # 5

        print("c2:", self.calc.compute2(1.5, 2.5))  # 4.0

```

Wiring occurs through blueprint composition:

```python
from dimos.core.blueprints import autoconnect

autoconnect(
    Calculator.blueprint(),
    Client.blueprint(),
).build().loop()

```

The client module never references `Calculator` directly—only the `ComputeSpec` interface—enabling loose coupling with compile-time type safety.

## Why It Guarantees Type Safety

The DimOS Spec pattern provides multiple layers of type verification:

- **Static analysis**: Because Specs are Protocols, IDEs and type checkers (mypy, pyright) validate method signatures before runtime
- **Structural verification**: The `spec_structural_compliance` check in [`dimos/spec/utils.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/spec/utils.py) ensures method existence and signature compatibility
- **Annotation matching**: `spec_annotation_compliance` enforces exact type hint equality between Spec and implementation
- **Clear error messages**: The blueprint raises descriptive exceptions for ambiguous matches, missing implementations, or annotation mismatches, guiding developers to use `.remappings()` or correct type hints

## Summary

- The **Spec pattern** uses a marker Protocol ([`dimos/spec/utils.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/spec/utils.py)) to declare RPC interfaces between DimOS modules
- **Blueprint construction** automatically detects Spec-typed attributes in `_BlueprintAtom.create` (lines 95-100)
- **Two-phase validation** checks structural and annotation compliance before wiring modules together
- **Automatic injection** eliminates manual dependency management while maintaining strict type safety
- The pattern appears in production code at [`dimos/agents/agent.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/agents/agent.py) and `dimos/agents/skills/` for agentic system composition

## Frequently Asked Questions

### What distinguishes a DimOS Spec from a standard Python Protocol?

A DimOS Spec inherits from both `Spec` (defined in [`dimos/spec/utils.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/spec/utils.py)) and `typing.Protocol`, whereas standard Protocols only inherit from `Protocol`. The `is_spec` helper function (lines 27-39) checks for this dual inheritance to identify which interfaces should participate in automatic RPC wiring during blueprint construction.

### How does the blueprint system handle multiple modules implementing the same Spec?

The `_connect_module_refs` method ([`dimos/core/blueprints.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/blueprints.py), lines 35-78) raises an informative error if multiple candidate modules satisfy the Spec's structural and annotation requirements. Developers must then use the `.remappings()` API to explicitly specify which concrete module should satisfy the Spec interface, preventing ambiguous wiring.

### Can Spec methods have different return types in the implementation than declared in the interface?

Structural compliance allows covariant return types (subclasses of the declared return type), but annotation compliance requires exact type hint matches. If the Spec declares `-> int` but the implementation declares `-> float`, the blueprint will fail validation even if both are numeric types, ensuring strict type contracts across module boundaries.

### Where can I see production usage of the Spec pattern in the DimOS codebase?

Real-world usage appears in [`dimos/agents/agent.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/agents/agent.py), where agentic systems declare Spec-typed attributes for skills like navigation and perception. The concrete implementations reside in `dimos/agents/skills/`, demonstrating how the Spec pattern enables modular, type-safe composition of complex agent behaviors without tight coupling between components.