---
title: "Clean Architecture for Agent Harnesses"
date: "2026-08-25"
description: "How Uncle Bob's 2012 Dependency Rule and boundary isolation principles solve the durability, containment, and testability crises in modern AI agent harnesses."
---
# Clean Architecture for Agent Harnesses

When developers first build with large language models, they treat the model as the application. Prompts get tangled with business logic, database queries are assembled inline inside tool wrappers, and system state is sprayed across raw chat histories. It works for a demo, but collapses the moment a frontier model updates, a tool format shifts, or an unexpected hallucination corrupts the database.

Fourteen years ago, [Robert C. Martin](/wiki/robert-c-martin) synthesized a unified approach to system boundaries in [Clean Architecture](/wiki/clean-architecture), drawing together [Alistair Cockburn](/wiki/alistair-cockburn)'s [Hexagonal Architecture](/wiki/hexagonal-architecture) (Ports and Adapters) and [Jeffrey Palermo](/wiki/jeffrey-palermo)'s [Onion Architecture](/wiki/onion-architecture). The core organizing axiom was deceptively simple: **The Dependency Rule**.

> "This rule says that source code dependencies can only point inwards. Nothing in an inner circle can know anything at all about something in an outer circle. In particular, the name of something declared in an outer circle must not be mentioned by the code in the an inner circle."

As the agent ecosystem matures into systematic [agent harness engineering](/wiki/agent-harness-engineering), the central revelation of 2026 is that an LLM is not your core domain. An LLM is a mechanism — an external driver sitting on the outermost circle alongside databases, web servers, and third-party APIs. When you apply Clean Architecture to agent infrastructure, the fragility disappears.

## The Five Characteristics of an Agent Harness

In his 2012 formulation, Martin defined five properties that clean boundaries guarantee:
1. **Independent of Frameworks:** The architecture does not depend on a feature-laden library; frameworks are tools, not constraints.
2. **Testable:** Business rules can be verified without the UI, database, or external agencies.
3. **Independent of UI:** Presentation layers can change without touching business policies.
4. **Independent of Database:** Persistence technologies can be swapped without rewriting business logic.
5. **Independent of any external agency:** "In fact your business rules simply don't know anything at all about the outside world."

In agentic systems, the stochastic model is the ultimate "external agency." If your domain policies require calling Claude or DeepSeek directly inside core entities, your business logic is hostage to model non-determinism.

By placing the agentic loop on the outer boundary and treating the LLM as an interchangeable adapter, your domain rules remain deterministic, inspectable, and independently testable via [red-green TDD](/wiki/red-green-tdd).

## Dependency Inversion at the Agent Boundary

How do you orchestrate complex agent workflows without violating the Dependency Rule? The answer is the [Dependency Inversion Principle](/wiki/dependency-inversion-principle).

In Clean Architecture, when an inner use case needs to communicate with an outer mechanism, it defines an interface (an input or output port) in the inner circle. The outer mechanism implements that interface, flipping the source code dependency so it opposes runtime control flow.

We see this exact pattern in production harnesses today:

- **Pluggable Agent Runtimes:** In the [DeepSeek Harness](/wiki/deepseek-harness), the core orchestration loop relies on the [Cordis framework](/wiki/cordis-framework) microkernel. Services are registered in containers (`ctx.tools`, `ctx.llm`, `ctx.sessions`). The inner lifecycle manages task states and dispatching without importing concrete model providers or tool runners.
- **Sandboxed Containment:** [Anthropic](/wiki/anthropic)'s architecture for Claude Code enforces strict [agent containment and blast radius](/wiki/agent-containment-and-blast-radius). The agent executes within an isolated container substrate. File modifications, bash commands, and network requests cross structured interface boundaries governed by mechanical permission policies before execution.
- **Progressive Capability Delivery:** Rather than dumping the entire world into prompt context, modern harnesses use [progressive disclosure](/wiki/progressive-disclosure) to pass simple data transfer objects across boundaries on demand, preventing [context rot](/wiki/context-rot).

## Verifiability Over Model Hype

For years, teams ignored software architecture in AI. As [Drew Breunig](/wiki/drew-breunig) noted, when frontier models were dropping in cost while leaping in capability, "A new model would arrive at the same price (or cheaper!) and paper over most of your problems." But once free-lunch gains leveled off, teams "started to think about what work went where."

When you isolate the model behind clean ports, evaluation stops being an intractable mystery. As [Hamel Husain](/wiki/hamel-husain) argues in [designing for verifiability](/wiki/designing-for-verifiability), "it's hard to eval is a product smell." When an agent's domain policies are decoupled from external mechanisms, you can evaluate the agent's decision boundaries with precision instead of guessing which prompt sentence caused a regression.

Clean Architecture was never about dogmatic folder structures or enterprise boilerplate. It is about drawing clear lines so that unstable details do not contaminate enduring policies. In agent engineering, the model will always be an unstable detail. Build the harness around clean boundaries, enforce the Dependency Rule, and let the outer world change without breaking what you built.