This article is written for architects, senior engineers, and tech leads who want a clear account of agent harness design principles using Claude Code as the foundation. Business efficiency, ROI, and executive decision-making are covered in the companion article Putting AI Agents at the Center of Your Business. Here we focus on the structure of the design itself.
Terminology note: Throughout this article, “3 layers” refers to the harness structure (director agent / skill / fallback), while “3 phases” refers to the internal stages within fallback (retry / alternative path / human escalation).
The first wall you hit after delegating work to agents is the question: “When something goes wrong, who is responsible?” When an agent hallucinates, times out, or an external API goes down — how processing continues from that point is left undefined in most organizations at the time of design.
An agent harness is a structure that implements this “safety net for work delegation” in a concrete form. This article walks through the three design principles that support a harness — ownership through director agents, separation of deterministic tasks through skill delegation, and the safety net provided by fallback — in that order. Using Claude Code’s .claude/agents/ structure as the foundation, these are presented as actionable patterns.
Three key takeaways:
- The core of a harness is the division of roles among “director agent,” “skill,” and “fallback.” All three layers must be in place before work delegation becomes safe.
- A skill is the unit for carving out deterministic tasks (tasks where input reliably determines output). It is a design tool for narrowing the agent’s domain of judgment.
- Fallback cannot be bolted on later. At the time you define the business flow, define the three failure classes (hallucination / timeout / external dependency) and their corresponding three phases (retry / alternative path / human escalation) together.
What Is a Harness — The Core of AI Agent Architecture Harness Design
The Harness Metaphor — Control and Delegation at the Same Time
The word “harness” comes from horse tack. By combining reins, a body strap, and a pulling harness, a horse’s strength is channeled and directed toward the intended destination without losing control. Applied to AI agents, a harness means “a structure that safely draws out an agent’s capabilities while keeping work pointed in the right direction.”
The key point is that a harness exists not to “constrain an agent” but to “make delegation safe.” An agent given no constraints will indeed operate flexibly. But in a business context, an “overly flexible agent” causes problems. Signing up for an external service without budget approval, sending emails without authorization, accidentally deleting files — these are all failures caused by “delegation that was too free.”
Designing a harness is the act of resolving this trade-off between freedom and safety through structure. The director agent declares the scope of work, the skill encapsulates deterministic tasks, and the fallback guarantees a path when things go wrong — when all three layers are in place, delegation becomes safe.
Typical Failures When Delegating to Agents Without a Harness
When business is delegated to agents without a harness, failure patterns are consistent.
Failure Pattern 1: Unclear ownership
There is an instruction to “have the agent handle it,” but what authority it operated under is not defined. When something fails, tracing where the problem was becomes difficult. “Responsibility gaps” emerge — multiple agents compete for the same task, or conversely, no agent claims it and a human must step in to coordinate.
Failure Pattern 2: Skills and agents intermingled
“Summarize the document,” “write to the spreadsheet,” “send the email” are all delegated to a single agent. This looks simple on the surface, but failures at each step become intermingled and impossible to trace. “The summary was correct but the write failed,” “the send succeeded but the content was wrong” — pinpointing where things broke takes time.
Failure Pattern 3: Fallback relies on humans alone
When an agent fails, the only response is “a human notices and retries.” A nightly batch stops and nobody notices until morning. Errors are swallowed silently. A system that assumes constant human monitoring does not scale.
These failures are not solved by “stopping the use of agents.” They are design problems. By assembling the harness’s three layers — director agent / skill / fallback — you can structurally prevent these failures while keeping the same agent capabilities.
Design Principle 1: Ownership Through Director Agents
What Is a Director Agent (The {domain}-director Pattern)
The {domain}-director pattern is a design where, for each business domain, a “director agent for that area” is established as a {domain}-director.md file. Examples: blog-director.md / sales-director.md / dev-director.md / seo-director.md / editor-in-chief.md.
A director agent established under the {domain}-director pattern declares three things:
- Scope of responsibility: The types of tasks this agent handles
- Delegation targets: Which skills or sub-agents execution is handed off to
- Authority limits: The boundary within which this agent can make autonomous decisions, and the line where human confirmation is required
The term “director agent” is Yakumo’s internal naming, but the pattern itself is general-purpose. Other organizations call it a “team leader agent,” “domain agent,” or “coordinator agent.” The essence is “mapping a business domain to a responsibility scope on a one-to-one basis.”
A director agent does not do all the work itself. It handles judgment (what to do) and passes execution (how to do it) to a skill or sub-agent. This “separation of judgment and execution” is the prerequisite for “skill delegation,” discussed next.
The Design Philosophy of Assigning a Director to Each Business Domain
A common early mistake in agent design is “delegating everything to one all-purpose agent.” It appears simple, but maintaining it becomes difficult as the scope of work grows.
Having a director for each business domain offers three advantages.
Advantage 1: Fault isolation
If the sales agent fails, the recruiting agent and finance agent are unaffected. Domain boundaries act as barriers to fault propagation.
Advantage 2: Clearer authority design
“This agent may call external APIs.” “This agent cannot delete files.” Permission policies can be set at the agent level. Trying to do the same with an all-purpose agent requires a policy definition that accounts for every business context, and complexity explodes.
Advantage 3: Focused system prompts
Because each agent handles a limited context, system prompts can be kept short and sharp. All-purpose agent system prompts tend to grow long, raising the risk that the model skips over important constraints.
Structure of a Director Agent Definition File (.claude/agents/)
In Claude Code, director agents are defined as Markdown files under the .claude/agents/ directory.
.claude/agents/
├── sales-director.md # Director for the sales domain
├── dev-director.md # Director for the engineering domain
├── blog-director.md # Director for the content domain
└── seo-director.md # Director for the SEO domain
Each file includes the following declarations:
---
name: sales-director
description: Director agent for sales operations. Handles proposal drafting, estimates, and invoice generation.
tools:
- read_file
- write_file
- bash # Script execution only
---
# sales-director
## Responsibilities
- Drafting proposals
- Generating estimates and invoices
- Managing the sales pipeline
## Delegated Skills
- /propose: Generate proposal drafts
- /estimate: Calculate estimated amounts
- /invoice: Issue invoices
## Authority Limits
- Final proposal submissions require human approval
- Do not auto-generate estimates over 1,000,000 JPY (require human confirmation)
This single file functions as the “definition of a director agent.” Its existence documents the agent’s authority scope and delegation targets, and declares to all team members — human and agent alike — “what this agent is responsible for.”
Design Principle 2: Skill Delegation — Separating Deterministic Tasks in Claude Code Agent Design
Division of Roles Between Agents and Skills
The difference between an agent and a skill, in one sentence, is: “does it judge / or does it execute?”
| Property | Agent | Skill |
|---|---|---|
| Operation | Interprets the situation and decides the next action | Returns a defined output from a defined input |
| Failure risk | Misjudgment / hallucination / overreach | Out-of-spec input / external dependency failure |
| Reusability | Hard to reuse due to context dependence | Callable from multiple agents if I/O contract is defined |
| Testing | Difficult to define expected behavior | Testable via input → expected output |
Skills should handle “deterministic tasks.” Here “deterministic” means “given the same input, the same output is expected.” Even when using an LLM, if the prompt and structure are fixed, it can be treated as practically deterministic.
Criteria for Extracting Deterministic Skills
Which tasks should be carved out into skills? There are three decision axes.
Axis 1: Can input and output be defined?
“Receive proposal materials (company name, challenge, budget) and return a proposal Markdown” — tasks where the input and output types can be defined are candidates for skill extraction. Conversely, “assess the situation and decide what to do” is the agent’s job and not suited to a skill.
Axis 2: Is it called from multiple contexts?
When the same task needs to be called from multiple agents, abstracting it as a skill is valuable. If “invoice generation” should be callable from both the sales agent and the finance agent, skill extraction is the right call.
Axis 3: Can humans review the specification?
A skill’s definition (input / process / output) can be documented at a level non-engineers can read. When documented, specification errors can be caught early. Instead of “the agent did it on its own,” you can demonstrate accountability as “it operated according to the skill’s specification.”
Tasks that are typically suited to deterministic skills:
✅ Skill-appropriate (deterministic tasks)
- /propose: Input form → proposal Markdown generation
- /estimate: Requirements list → estimated cost calculation
- /invoice: Billing information → invoice PDF generation
- /publish: Article frontmatter → publish decision and schedule registration
- /translate: Japanese text → English text conversion
❌ Agent-appropriate (context-dependent tasks)
- "Decide whether to advance this deal"
- "Assess the client's situation and propose next steps"
- "Select the optimal option from multiple candidates"
Skill I/O Contract and Reusability
When defining a skill, explicitly stating the I/O contract (the promise about inputs and outputs) determines its reusability.
Skills in Claude Code are defined as Markdown files under .claude/skills/:
.claude/skills/
├── propose/
│ └── SKILL.md # Defines I/O contract and processing flow
├── estimate/
│ └── SKILL.md
└── publish/
└── SKILL.md
Minimum elements to include in SKILL.md:
# /propose — Proposal Draft Generation Skill
## Input
- `company_name`: Name of the target organization (string)
- `pain_points`: List of challenges (string[])
- `budget_range`: Budget range (string, e.g., "500K–1M JPY")
## Process
1. Set writing style in accordance with BRAND.md voice guidelines
2. Organize `pain_points` as challenges and generate solutions
3. Scope the proposal content to what is achievable within `budget_range`
## Output
- `draft.md`: Proposal Markdown draft
- `estimated_hours`: Rough estimated hours (number)
## Error handling
- If `pain_points` is empty: Return an error and prompt to re-check the input
- If `budget_range` cannot be parsed: Continue with a default value ("up to 500K JPY") and emit a warning
When the I/O contract is explicit, the agent calling the skill can confirm “what to pass / what comes back.” In fallback design (the next principle), this contract also serves as the basis for listing “what kinds of failures could occur.”
Currently, .claude/skills/ has 15 skills defined — 14 for blog operations and 1 general-purpose.
Design Principle 3: Fallback Design — How to Implement Fallback When an Agent Fails
Classifying Agent Failures (3 Types)
Before designing fallback, agent failures must be classified. Different types of failure call for different responses.
Failure Class 1: Hallucination (output quality failure)
The LLM generates incorrect information, fails to follow a specified format, or takes out-of-spec actions — these are “output quality failures.” This type of failure can sometimes be detected as “a violation of the skill’s specification” (structural validation).
Response approach: Automatically detect what can be caught through structural validation. For what cannot be detected, provide a human review path.
Failure Class 2: Timeout (execution time failure)
The LLM response is delayed, or processing does not complete within the allotted time — this is an “execution time failure.” Causes include LLM congestion, oversized input, or inefficient processing logic.
Response approach: Explicitly define a timeout threshold; design the number of retries and wait time when it is exceeded. When the retry limit is reached, transition to an alternative path or human escalation.
Failure Class 3: External dependency failure
The Google Drive API is down, the email service returns a 5xx, the database connection is lost — this is “external system dependency failure.” It occurs due to external problems, unrelated to the agent or skill design.
Response approach: For each external dependency, define “the alternative behavior when unavailable.” Choose from caching / queuing / degraded-mode continuation / error notification.
The 3 Fallback Phases (Retry / Alternative Path / Human Escalation)
Fallback is structured as three phases that answer “what to do when something fails.”
Layer 1: Retry
The simplest response. If the error is transient, retry the same process after a delay. Temporary external API failures, network latency, LLM congestion — these are often resolved by retrying.
What to design:
- Retry limit (e.g., 3 attempts)
- Retry interval backoff (exponential backoff recommended: 1s → 2s → 4s)
- What happens when the retry limit is reached (transition to Layer 2)
async function withRetry<T>(
fn: () => Promise<T>,
options: { maxAttempts: number; backoffMs: number }
): Promise<T> {
let lastError: Error | undefined;
for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {
try {
return await fn();
} catch (err) {
lastError = err as Error;
if (attempt < options.maxAttempts) {
await sleep(options.backoffMs * Math.pow(2, attempt - 1));
}
}
}
throw lastError;
}
Layer 2: Alternative Path
When retry does not resolve the issue, achieve the same goal through a different route. If an external API is unavailable, fall back to a local cache; if email delivery fails, switch to a Slack notification; if real-time processing fails, queue the work for asynchronous processing — these are alternative paths.
What to design:
- For each external dependency, define “the alternative behavior when unavailable”
- Explicitly state the “difference from the intended behavior” in the alternative (e.g., when switching to Slack as an email alternative, attachments cannot be sent)
- Log switches to the alternative path so they can be reviewed later
Layer 3: Human Escalation
When Layer 1 and Layer 2 cannot resolve the issue, escalate to a human for judgment. Design the escalation target, notification method, and expected response time at the design stage.
The key point is to position “escalation as the last resort in the design” — not the first. A design that says “just ask a human” will see escalation frequency spike, driving up operational burden. Expand the range that Layers 1 and 2 can handle, and reserve Layer 3 for “cases that genuinely require human judgment.”
// Minimal escalation notification example
async function escalate(context: {
taskName: string;
error: Error;
attemptedLayers: ('retry' | 'fallback')[];
requiredAction: string;
}): Promise<void> {
await notifySlack({
channel: '#agent-escalations',
message: [
`[Escalation] ${context.taskName}`,
`Error: ${context.error.message}`,
`Attempted: ${context.attemptedLayers.join(', ')}`,
`Required action: ${context.requiredAction}`,
].join('\n'),
});
}
Designing Fallback at the Right Time — Not as an Afterthought
The biggest pitfall in fallback design is treating it as an afterthought. “Build something that works first, then add fallback later” — when development follows this order, fallback frequently ships to production unimplemented.
As a principle of director agent and skill delegation design for AI agents, fallback must be defined at the same time the business flow is defined. Concretely:
- When defining a business flow, simultaneously describe “what happens if this step fails” for each step
- Always include an
Error handlingsection in a skill’s I/O contract (see the SKILL.md example above) - In the director agent’s definition file, describe the failure classes that agent handles and the corresponding response approaches
Even if implementation priority follows “happy path → Layer 1 → Layer 2 → Layer 3,” what each Layer consists of must be fully defined at design time. Layers that are not defined do not get added later.
In May 2026, the three fallback phases were integrated into the business flow. The trigger was a recurring rework loop: a writing skill would generate output with fewer HUMAN_INPUT markers than required, the draft would flow downstream into review and publish stages undetected, and only then would the quality gate reject it, requiring costly recovery. The fix combined three changes simultaneously: (1) a marker validation loop in the writing skill (up to 2 retries), (2) blockers recorded in _state.json, and (3) a human-review step (blocking) in the pipeline DAG — restructuring things so failures are caught at the source rather than downstream.
Implementation Patterns — How to Assemble a Harness in Claude Code
.claude/agents/ Directory Structure and Naming Conventions
When implementing a harness in Claude Code, the following directory structure is the baseline:
.claude/
├── agents/
│ ├── {domain}-director.md # Director agent ({domain}-director pattern)
│ └── ...
├── skills/
│ ├── {verb}/
│ │ └── SKILL.md # I/O contract for a deterministic skill
│ └── ...
└── README.md # Design overview of the entire harness
Naming convention principles:
| File type | Naming pattern | Example |
|---|---|---|
| Director agent | {domain}-director.md | sales-director.md, dev-director.md |
| General-purpose agent | {role}.md | reviewer.md, planner.md |
| Skill | {verb}/SKILL.md | propose/SKILL.md, translate/SKILL.md |
The “director” suffix signals “this is the responsible party for this domain.” Consistent naming makes it immediately clear, just by looking at .claude/agents/, which agent is responsible for which domain.
Declaring Harness Design in CLAUDE.md
Write the harness design intent in CLAUDE.md. CLAUDE.md is the first file Claude Code reads to understand the project context. Writing the harness overview here allows Claude Code — both humans and AI agents — to reference the design intent.
Elements to include in the harness declaration in CLAUDE.md:
## Agent Organization (Harness Design)
This project uses the following breakdown for agent roles:
### Director Agents (.claude/agents/{domain}-director.md)
Each business domain has a dedicated director. Director agents handle "judgment"; execution is delegated to skills.
| Agent | Domain |
|---|---|
| sales-director | Proposal, estimate, and invoice generation |
| dev-director | Implementation planning, code review, and test design |
### Skills (.claude/skills/{verb}/SKILL.md)
Reusable processing units carved out from deterministic tasks (tasks where input determines output).
### Implementation Rules
- Use CLAUDE.md as the starting point for implementation
- Before delegating to an agent, consider whether the task could instead be a skill
- Define fallback at the same time as the business flow
With this declaration in place, when new team members — human or agent — join the project, they can immediately understand the harness design approach.
The Harness in Full — Synapse as an Example
3 director agents (blog-director / editor-in-chief / seo-director) / 15 skills / initial commit in March 2026, in production since.
Synapse — Yakumo’s cross-functional agent organization built on Claude Code — operates this three-layer harness in production. Multiple director agents defined in .claude/agents/ each cover their business domain and call into the deterministic skill library in .claude/skills/ (proposal generation, cost estimation, article publishing, and more).
Concretely: when the director agent for the sales domain receives a request to “create a proposal,” it does not generate the text itself. It passes the materials to the proposal generation skill. The skill returns a draft, and the director agent reviews it before handing it to the human — this “separation of judgment and execution” is the foundational pattern of Synapse. For implementation details, see Implementation Details of Synapse’s Director Agent Design.
The harness functions because each director agent’s definition file states “authority limits,” each skill’s SKILL.md states an I/O contract, and human escalation paths are designed into critical processes. Remove any one of the three layers and the business delegation structure falls apart.
Anti-Patterns — What Not to Do in Agent Responsibility Allocation Architecture
Before adopting this pattern, the middleware pattern (routing processing through a fixed-order pipeline) and the event-driven pattern (multiple listeners react in parallel when an event fires) were both considered. Neither was adopted for a single reason: predictability of token consumption.
With middleware, every request passes through every stage in order, causing all agents to load context for each request — even Opus runs for directors unrelated to the decision at hand. Event-driven goes the other way: an event fires and multiple listeners activate simultaneously, spinning up agents that aren’t needed and consuming their context windows. In both cases, estimating “how many tokens a single request will use” in advance is difficult.
The {domain}-director pattern has the main thread (Opus) first determine “which domain does this belong to,” then route to exactly one relevant director. Combining that with the separation where Opus handles judgment and Sonnet / Haiku do the actual work via skills, token consumption becomes predictable: main 1 + relevant director 1 + working skill 1.
This architectural choice is also a hedge against the end of the AI subsidy era. According to the AI Subscription Time Bomb survey, Anthropic users consume roughly $8 in compute costs for every $1 of revenue, and GitHub Copilot is shifting to usage-based billing starting June 1, 2026. When the era of flat subscription fees absorbing these costs ends, organizations that cannot control token consumption at the design level will be broken by operational costs. Agent architecture must be designed with token economics in mind.
Anti-Pattern 1: Flat Structure With No Director
All agents are on equal footing with no definition of who handles what.
Symptoms:
- Multiple agents compete for the same task and conflict
- Tasks go unclaimed and a human must intervene to coordinate
- When an agent fails, tracing the cause is difficult
Fix: Use the {domain}-director pattern to assign a director to each business domain. When domain boundaries are ambiguous, explicitly state in CLAUDE.md “whether this case falls under sales-director or dev-director.”
Anti-Pattern 2: Conflating Skills and Agents in Design
Putting judgment-requiring tasks into skills, or delegating deterministic tasks to agents.
Symptoms:
- A skill is implemented to “assess the situation and choose the optimal approach”
- An agent is handling simple transformation work (format conversion, text reformatting, etc.)
- A skill’s I/O contract is specified as “the return value depends on the input”
Fix: Use the skill vs. agent decision axis (“is it deterministic?”) to reclassify tasks. When the boundary is unclear, ask: “If I call this skill from a different context with the same input, will it return the same output?” If not, it is the agent’s job.
Anti-Pattern 3: Fallback That Relies on Humans Alone
The only design for when an agent fails is “the responsible person handles it manually.”
Symptoms:
- Nightly or weekend batch processes fail and nobody notices until the next business day
- Reports of “the agent did something strange” only arrive after the fact
- No escalation target is defined, so it is unclear who to contact
Fix: Define the three fallback phases (retry / alternative path / human escalation) at the design stage. In particular, explicitly document the escalation target (channel / person / expected response time). “A human makes the call” is the last resort in fallback — not the first.
In May 2026, Opus overstepped its judgment role and began handling mechanical editing work directly, causing scope creep. The root cause: the division of roles among director agent / working skill / main thread Opus had not been stated in writing, and Opus decided “it would be faster to do it myself” and executed directly (retro: blog-ops/retros/2026-05-18-opus-mechanical-edit-overreach.md). The fix added explicit usage axes to CLAUDE.md and .claude/README.md stating “Opus = judgment only; mass writing / mechanical editing goes through skills.”
Summary — Harness Design Checklist
The three design principles of an agent harness, restated.
Principle 1: Ownership Through Director Agents
- Have you defined
.claude/agents/{domain}-director.mdfor each business domain? - Have you declared each director agent’s scope, delegation targets, and authority limits?
- Have you written the overall harness design in
CLAUDE.md?
Principle 2: Skill Delegation
- Have you carved out “deterministic tasks” (input → fixed output) into skills?
- Have you defined an I/O contract (Input / Process / Output / Error handling) for each skill?
- Is each skill designed to be callable from multiple director agents?
Principle 3: Fallback Design
- Have you classified agent failures into three types (hallucination / timeout / external dependency)?
- Have you defined the three fallback phases (retry / alternative path / human escalation) at the same time as the business flow?
- Have you documented the escalation target, notification method, and expected response time?
Additional conventions within Yakumo’s organization
- Before adding a new agent or skill, review the “delegation policy” in
.claude/README.mdand ask: “Could this agent/skill be called as-is from a different project?” (If NO, place it in the project-side.claude/) - Before editing code or config under any directory, read that directory’s
_README.md(if it exists). It describes the directory’s purpose, conventions, update policy, and relationships to other files. - Before launching a new article writing pipeline, read the DAG in
blog-ops/config/pipelines/new-article-{pillar,spoke}.jsonand confirm all steps.review skip is prohibited; any remainingHUMAN_INPUTis handled at thehuman-review(blocking) step.
Having all three layers of the harness in place versus missing even one is a fundamental difference in the safety of delegating work to agents. The design of “build something that works first, add fallback later” does not work. Define all three layers at the design stage, and implement in that order — that is the core of agent harness design.
The business perspective — ROI, cost comparisons, and organizational transformation — is covered in detail in Putting AI Agents at the Center of Your Business. Read the design principles laid out here alongside the business decision-making context in that article.
Skills that do not reference SSOT: Because writing skills lacked context pointing to the SSOT (brand.ts / members.ts / .claude/skills/), even information that could have been retrieved deterministically from SSOT (agent counts / skill counts / failure case details) became HUMAN_INPUT markers. This was prevented from recurring by explicitly stating a “mapping table of SSOT sources to consult” in SKILL.md at skill definition time (retro: blog-ops/retros/2026-05-19-ssot-driven-human-input-fill.md).
In May 2026, blog gate G1 (HUMAN_INPUT marker detection) produced false positives on articles that described failures in their body text — a contradiction where an article about its own failures caused the gate to fail. Root cause: simple grep with no context-aware stripping, meaning explanatory text inside code blocks was also being inspected (retro: blog-ops/retros/2026-05-18-gate-false-positive.md). The fix implemented stripCodeContexts to exclude code blocks and inline code, evolving the gate into a context-aware checker.