Chapter 4: Harness Engineering at a Glance — Concepts and Core Patterns
4.1 The Agent Framework Paradox
Lance Martin (Anthropic) said it plainly: "Agent frameworks encode assumptions about Claude's limitations, but as the model evolves these assumptions become bottlenecks" [1].
This is the harness engineering paradox. The code you wrote to compensate for model limitations starts limiting the model as it improves. Good harness engineering evolves with the model.
But the more fundamental question: What is a harness, actually?
4.2 What a Harness Actually Is
After analyzing both Claude Code and Codex, Alex Fulton concluded [3]: "Both tools are basically a while True loop with tools attached. The magic is in context management, sandboxing, and structured output — not the LLM call itself."
# The harness, in pseudocode
while True:
context = load_context() # read CLAUDE.md / AGENTS.md
response = llm_call(context + user_input)
result = execute_tools(response.tool_calls)
save_context(result) # update memory
if response.is_done:
break
That's it. The three functions that create the difference:
- What
load_context()reads — the memory model - What
execute_tools()allows — the permissions model - What
save_context()stores — the persistence model
Harness engineering is designing these three functions well.
4.3 Three Patterns
Anthropic's "Harnessing Claude's Intelligence" [1] organizes harness design into three patterns.
Pattern 1: Use What the Model Already Knows
Models deeply understand bash and text editors from training data. Composing higher-level capabilities on these familiar tools beats building specialized interfaces from scratch.
The evidence: Claude 3.5 Sonnet achieved 49% on SWE-bench Verified using only bash + text editor (late 2024 SOTA). Sonnet 4.6 reached 76.3% with the same foundation [1]. Programmatic tool calling, skills, and memory are all compositions of these two tools.
By June 2026, Codex makes the same pattern visible beyond the terminal. The Chrome extension, remote/mobile continuation, Windows Computer Use, Sites, Worktree threads, hooks, plugins, and automations are not separate theories of agents. They are additional product surfaces around the same loop: read context, act through bounded tools, leave a diff or artifact, and preserve enough trace to review [10].
Pattern 2: Keep Asking "What Can I Stop Doing?"
Audit assumptions encoded in the harness. Remove structures that have become unnecessary. Three directions:
A. Self-orchestration: Instead of loading all tool results into context, give the model a code execution tool and let it chain tool calls itself. Opus 4.6 went from 45.3% → 61.6% on BrowseComp (+16.3%p) [1].
B. Progressive context: Pre-loading all task instructions depletes the attention budget. Use skill YAML frontmatter for brief overviews; the agent reads full content when needed. Subagents add +2.8% on BrowseComp for Opus 4.6.
C. Memory persistence: Long-running agents exceed a single context window. Two solutions:
- Compaction: Summarize past context. Opus 4.6: 84% on BrowseComp
- Memory folder: Write/read context to files. Sonnet 4.5's BrowseComp-Plus: 60.4% → 67.2%
Pattern 3: Set Boundaries Carefully
Here, "boundary" means the line between what the model may do freely and what humans or code must control. A model can read and edit code, but it does not automatically know which files are risky, which commands deploy to production, or which UI changes will confuse users. The harness has to tell the model: "you may act here" and "you must stop and ask here."
A simple example is file access. Documentation and tests may be safe for autonomous edits. Payment logic, auth configuration, and deployment scripts may require human approval before changes. Commands work the same way. npm test may be safe. npm publish, terraform apply, or a production database migration should not run automatically. A good harness expresses those differences structurally instead of relying on a vague prompt.
This pattern shows up in three concrete ways.
A. Separate stable information from changing information. Put stable rules such as project conventions, code style, and test commands near the front, in AGENTS.md or skill descriptions. Put changing information such as today's task, the current diff, and the latest failing test later. This gives the model a stable base and also improves prompt caching behavior [1].
B. Wrap risky actions in declarative tools or scripts. Do not hand the model a broad instruction like "deploy this." Give it a controlled entry point such as bin/deploy-preview, bin/check-release, or make verify. The tool decides which commands run, when to stop, and what logs to leave. The model calls the tool; it does not improvise the dangerous procedure.
C. Leave enough trace to replay what happened. You need to know what the agent read, which commands it ran, and what diff it produced. Logs, traces, HANDOFF.md, and test results all serve this purpose. Setting boundaries is not only about forbidding actions. It is also about making failures diagnosable.
4.4 Pattern-to-Codex Mapping
| Pattern | Claude Code | Codex |
|---|---|---|
| P1: General-purpose tools | bash + text editor (built-in) | bash + text editor (built-in) |
| P2a: Self-orchestration | subagents (invoke_subagent) |
.codex/agents/ |
| P2b: Progressive context | skills (SKILL.md) | skills (SKILL.md, same format) |
| P2c: Memory persistence | compaction + .claude/memory/ |
AGENTS.md/HANDOFF.md/TASKS.md + session compaction |
| P3a: Caching | Messages API prompt caching | (Codex-internal) |
| P3b: Declarative tools | hooks + custom tools | TOML agents + skills |
| Packaging reusable workflows | .claude/ harness folders |
Codex plugins bundling skills/hooks/assets |
| Command safety | hooks + allowlists | permissions profiles + .rules command policy |
| Long-running work | external loops / remote control | Goal mode, Worktree, Cloud, automations |
These three patterns are tool-agnostic. They apply to Codex, Claude Code, and any other LLM tool. Chapter 5 implements them concretely in Codex.
Hooks deserve a special caution. They are useful guardrails and logging points, but they are not a complete security boundary. Put irreversible operations behind wrapper scripts, permission profiles, and rules; let hooks observe and enforce local conventions rather than carrying the whole safety model.
4.5 The Counter-Argument
The concern from Lance Martin at the start of this chapter was this: agent frameworks and harnesses are built to compensate for the model's current weaknesses. When the model improves, yesterday's compensation can become today's bottleneck. For example, you may have hard-coded every step because an older model could not manage a long procedure on its own. If a newer model can plan longer and chain tool calls more reliably, that fixed procedure may now limit the model instead of helping it.
That counter-argument does not mean "do not build a harness." It means the opposite: because the harness matters, treat it like code that must be refactored. In this book, an evolvable harness has four properties.
- Separate rules from execution. Put project rules in human-readable files such as
AGENTS.md; put execution in commands such asmake verifyorbin/deploy-preview. You can change the rules without rewriting the execution layer, and you can change the execution layer without rewriting every model instruction. - Separate universal knowledge from tool-specific knowledge. Code style, test commands, and forbidden files should live where both Claude Code and Codex can read them. Claude-specific hooks and Codex-specific subagents should stay in their own tool directories. That way project knowledge does not disappear when one tool changes.
- Feed recurring failures back into the harness. If the agent repeats the same mistake, do not fix it with the same prompt every time. Add it to "Common Mistakes" in
AGENTS.mdor to a skill. A harness improves by absorbing failures. - Disable before deleting. If an old hook, skill, or subagent looks suspicious, do not delete it immediately. Record when and why it should be removed, and after which experiment. During a Claude Code to Codex transition, the ability to roll back is part of the harness.
Okhlopkov's 4-month Claude Code retrospective points in the same direction [5]: the first month was spent learning the tool, and the next three months optimizing the harness. The key is to refactor the harness the way you refactor code. If you have not revisited your harness since the last model update, it may be compensating for limitations that no longer exist.
The next chapter turns this principle into a concrete Codex file structure. It covers what belongs in AGENTS.md, what belongs in ~/.codex/config.toml, and when .codex/agents/ or skills become necessary. Chapter 4 explains how to think about the harness; Chapter 5 shows how to build one in Codex.
References
- Anthropic, "Harnessing Claude's Intelligence: Three Patterns for Agent Harness Design," 2026. [Martin and Anthropic, 2026]
- Anthropic, "Claude Code: Best practices for agentic coding," 2026. [Anthropic, 2026]
- Fulton, Alex, "Inside the agent harness," 2026. [Fulton, 2026]
- Promptshelf, "10 Claude Code hook examples," 2026. [Shelf, 2026]
- Okhlopkov, "Claude Code setup — 4-month retrospective," 2026. [Okhlopkov, 2026]
- Korean Developer, "하네스 엔지니어링 40분 정복," 2026. [Korean Dev Blog, 2026]
- HesReallyHim, "Awesome Claude Code — community catalog," 2026. [GitHub, 2026]
- OpenAI, "Codex hooks," 2026. [OpenAI, 2026]
- OpenAI, "Codex plugins," 2026. [OpenAI, 2026]
- OpenAI, "Codex automations," 2026. [OpenAI, 2026]