---
title: Harness engineering
description: "A harness is everything around the model that turns it into an agent. Harness engineering is designing that system on purpose: the guides that steer the agent before it acts and the sensors that let it correct itself after. It became a named discipline in early 2026, and it is where most reliability gains come from."
author: Asem Abdo
course: Agentic Engineering
lesson: Harness engineering
url: https://openplanr.dev/learn/agentic-engineering/harness-engineering
updated: 2026-10-17
related:
  - https://openplanr.dev/learn/agentic-engineering/context-engineering.md
  - https://openplanr.dev/learn/agentic-engineering/primitives.md
---

# Harness engineering

By [Asem Abdo](https://www.linkedin.com/in/asemabdo/) · Updated 2026-10-17

*What the agent can do, and what keeps it honest*

A harness is everything around the model that turns it into an agent. Harness engineering is designing that system on purpose: the guides that steer the agent before it acts and the sensors that let it correct itself after. It became a named discipline in early 2026, and it is where most reliability gains come from.

## The seven layers of a harness

Level 1 · The rules

Claude Code, Codex, Cursor and Gemini CLI are harnesses. The same model behaves differently in each because these layers differ.

**Figure: Improve any layer and the same model gets better. That is harness engineering..** Seven harness layers stacked around the model: system prompt and instructions, tools, permissions, hooks, context management, memory, and orchestration.

> **Note:** **Say it:** "I spend more time on the harness than on prompts. Reliability comes from what the agent sees, what it can do, and what is enforced in code."

## Two harnesses: the builder's and yours

Level 1 · The rules

Part of the harness ships inside the product: its system prompt, tools, retrieval and loop. The part you control is the outer harness for your codebase. Martin Fowler's site describes it as concentric rings: model in the middle, builder harness around it, user harness outside.

**Builder harness** (built by the agent's makers)

- Core system prompt and loop
- Built-in tools, compaction, subagents
- You choose it, you don't edit it
- Why one agent beats another on the same model

**User harness** (built by your team)

- AGENTS.md, skills, custom tools and MCP servers
- Permissions, hooks, linters, tests
- Specific to your system and conventions
- Where your engineering effort pays off

## Guides and sensors

Level 2 · Why it works

Guides act before the agent does: they anticipate mistakes (feedforward). Sensors act after: they detect mistakes and feed the result back so the agent corrects itself (feedback). Each can be computational (deterministic code) or inferential (another model judges).

|  | Computational (code decides) | Inferential (a model decides) |
| --- | --- | --- |
| **Guide** · before | Scaffolds, templates, generators, a bootstrap script | AGENTS.md conventions, skills, reference docs |
| **Sensor** · after | Type checker, linter, tests, structural tests, a blocking hook | A reviewer agent, an LLM judge with a rubric |

Prefer computational sensors where they exist: they are fast, cheap and give the same answer every time. Use inferential ones for what code cannot judge, such as readability or whether a spec covers the request.

```python check=run title="A sensor loop: deterministic checks feed back until the output passes"
def lint(code):
    return [] if "print(" not in code else ["no print statements in library code"]

def types_ok(code):
    return [] if "-> int" in code else ["public functions need a return type"]

attempts = [
    "def total(xs):\n    print(xs)\n    return sum(xs)",
    "def total(xs):\n    return sum(xs)",
    "def total(xs) -> int:\n    return sum(xs)",
]
for round_no, code in enumerate(attempts, start=1):
    problems = lint(code) + types_ok(code)
    print(f"round {round_no}:", problems or "all sensors pass")
    if not problems:
        break
```

```text title="Output (Python 3.14.8)"
round 1: ['no print statements in library code', 'public functions need a return type']
round 2: ['public functions need a return type']
round 3: all sensors pass
```

> **Note:** **The key move:** sensor output goes back into the agent's context as feedback, so it fixes the problem itself in the same session. A failing check that only a human sees later is a report, not a sensor.

## Where to put a rule

Level 3 · Mastery

The most useful harness decision you will make, again and again. Match the strength of the mechanism to the cost of the mistake.

- "Use pnpm, not npm." → **AGENTS.md**: Cheap mistake; a reminder is enough.

- "Follow our release checklist." → **Skill**: Long procedure, needed only sometimes.

- "Never hand-edit migration files." → **PreToolUse hook**: Expensive mistake; must be enforced, not requested.

- "Never touch production credentials." → **Permissions + sandbox**: Catastrophic; remove the capability entirely.

## Keeping a harness healthy

Level 3 · Mastery

- **Every repeated failure becomes a control:** When the agent makes the same mistake twice, add a guide or a sensor so it cannot happen a third time.
- **Instructions fade, enforcement doesn't:** Long instruction files get skimmed and their tail is ignored. Move anything critical into a check.
- **Watch for drift:** As a harness grows, guides and sensors start to contradict each other. Audit it like code, and let agents help maintain it.
- **The repo is the interface:** When agents write most code, the repository itself becomes how humans and agents communicate: docs, tests and structure carry intent.

## Predict the output

### Hook exit codes

Level 1.

```python
def outcome(code):
    return "blocked" if code == 2 else "runs"

for code in (0, 2, 1):
    print(outcome(code))
```

1.

   ```text
   runs
   blocked
   runs
   ```
2.

   ```text
   runs
   blocked
   blocked
   ```
3.

   ```text
   blocked
   blocked
   runs
   ```
4.

   ```text
   runs
   runs
   runs
   ```

**Answer:** option 1.

```text title="Output (Python 3.14.8)"
runs
blocked
runs
```

**Why:** Only exit code 2 blocks. Exit 1 is a non-blocking error, so the tool still runs. This is the most common guardrail bug.

## Check your understanding

Levels 1 to 3.

**Q:** What is the difference between a guide and a sensor?

**A:** A guide acts before the agent does, steering it away from mistakes (AGENTS.md, skills, templates). A sensor acts after, detecting mistakes and feeding them back so the agent self-corrects (tests, linters, review agents).

**Q:** Why prefer computational sensors?

**A:** They are deterministic, fast and cheap, so the agent gets the same reliable signal every time. Inferential sensors are slower, cost tokens and can be wrong, so use them where code cannot judge.

**Q:** Two teams use the same coding agent and model. Why do their results differ?

**A:** Their user harnesses differ: instructions, skills, tools, permissions, hooks and the checks their codebase runs. The builder harness and model are the same.

**Q:** Where should "never touch production credentials" live?

**A:** In permissions and a sandbox that remove the capability entirely. A catastrophic mistake should be impossible, not discouraged.
