Categories
Uncategorized

What Is a Claude Code Harness? A PM’s Guide, With the One I Run

A Claude Code harness is everything around the model: rules, skills, hooks, memory. See the one I run, what each hook blocks, and how to start yours.

A Claude Code harness is everything around the model that tells it how you work. Ryan Lopopolo wrote OpenAI’s post on harness engineering. In my write-up of his episode, I described his view of the harness: the environment inside the repo that teaches the agent how your team builds software. I run one for my content business, and the table below shows what’s in it.

Anthropic’s Prithvi Rajasekaran puts it this way: “every component in a harness encodes an assumption about what the model can’t do on its own.” Birgitta Böckeler’s article on Martin Fowler’s site calls the harness “everything in an AI agent except the model itself” and writes it as Agent = Model + Harness.

Table of what sits around the model in the author's Claude Code harness: CLAUDE.md, hard-rules file, 63 skills, 3 agents, 6 hook scripts and more than 140 Python scripts, counted October 16, 2026
What sits around the model in my Claude Code harness. Counts taken from the repo by script on October 16, 2026.

Claude Code is a harness. So is your repo.

Claude Code is Anthropic’s harness around its models. You don’t build that one. The files in your repo are the second harness, and you do build it. Böckeler’s article names two kinds of control in that second harness:

  • Guides steer the agent before it acts. In Böckeler’s words, they’re feedforward controls.
  • Sensors check what the agent did and help it correct itself. Those are feedback controls.

In my repo, the guides are CLAUDE.md and the skills, along with the context files they import. The sensors are the hooks and the scripts that check a result before it ships.

What’s inside mine

I counted everything in this table by script on October 16, 2026.

PartWhat it holdsRole
CLAUDE.md119 lines. 6 voice and context files load into every session through @ imports.Guide
advanced/hard-rules.md252 lines. Each CLAUDE.md rule in full, with the reasoning behind it.Guide
.claude/skills/63 skills, one slash command per job (newsletter, LinkedIn post, quote tweet, social pack). 15 are ports of an MIT-licensed open-source collection.Guide
.claude/agents/3 reviewer agents that run in their own context.Sensor
.claude/hooks/6 scripts. settings.json holds 12 registrations across 6 event types: 10 for these scripts and 2 for session-start and session-end housekeeping.Sensor and gate
.claude/scripts/More than 140 Python scripts: data pulls, the tracked-link builder, the card renderer, publishing gates.Tools and checks

CLAUDE.md stays short. Each hard rule is one line, and the detail lives in the file the line points to. I wrote the same thing about a team’s root file in my Team OS guide: treat it as a routing table.

The Claude Code docs on memory say: “To block an action regardless of what Claude decides, use a PreToolUse hook instead.”

That sentence is why I run hooks.

What each hook blocks

Hooks are shell commands Claude Code runs automatically at set points. A hook that exits with code 2 stops the action and sends its message back to the model. As of October 16, 2026, my CLAUDE.md has 6 hard rules labeled “hook-enforced”, and the repo has 6 hook scripts. Each script protects one rule.

HookWhat it blocksThe rule it protects
spend_guardAn agent launch with no BUDGET line in the brief, or a budget over 150 tool calls. A forked agent once the parent context is large. Any subagent’s 151st tool call.Every agent brief carries a budget. A fork inherits the parent’s whole context, so forks are capped by context size.
block_paid_transcriptionAny call to a paid transcription API.Every podcast already has three free transcripts: YouTube, my site and the Substack post. The repo reads those.
block_list_emailAny tool call that publishes, sends or schedules a Substack post.Sending a post emails my whole list, so that decision stays mine. Creating or editing a draft is allowed.
li_slot_guardA personal LinkedIn post outside the 10:00 AM or 9:00 PM Pacific slots, or a third post in a day.The posting grid: two slots a day.
chrome_tab_guardThe first attempt to finish a task while the agent still has browser tabs it opened. The hook names the tabs and asks the agent to close them. A second attempt goes through, so a tab I have to act in can stay open.The agent closes what it opens. The hook tracks the tabs a session opens and asks the agent to close them first.

I show five of the six scripts. The sixth, li_human_pace, paces every LinkedIn action and caps how many I can do in a day.

What a hook looks like

Claude Code passes each tool call to a hook as JSON on stdin. The hook checks it and exits. Here’s the core of block_paid_transcription.py. I left out the docstring, the pattern list, the message text and a few other lines:

import json
import re
import sys

PATTERNS = [
    # ... one regular expression per paid service
]

def main():
    try:
        data = json.load(sys.stdin)
    except Exception:
        return 0
    tool = data.get("tool_name", "")
    inp = data.get("tool_input", {}) or {}
    if tool == "Bash":
        text = inp.get("command", "")
    # ... the same check for Write and Edit calls
    if any(re.search(p, text, re.I) for p in PATTERNS):
        print(MSG, file=sys.stderr)
        return 2
    return 0

if __name__ == "__main__":
    sys.exit(main())

Exit code 0 lets the call through. Exit code 2 blocks it and sends what the hook printed to stderr back to the model.

In my repo, each rule is one line in CLAUDE.md. The rules that have to hold also get a hook. In my memory-system guide I wrote about two checks like that. One runs when a session ends and holds it open until the lessons are filed. The other runs as a file is written and stops any claim that has no source. The model doesn’t have to remember either one. The harness runs both.

A rule the agent can skip

In my skill tests, a self-review pass at step 6 of 7 gets skipped 4 out of 5 runs. Claude takes the shortest path to a response. I wrote that up in my May 2026 skills guide.

Repeating “run the self-review pass” doesn’t fix it. Claude already read that instruction and routed around it. The Claude Code docs give the fix: when Claude skipped a rule that must hold every time, move the rule into a hook.

Three tools the harness carries

Cloud sessions can’t reach everything my laptop can, so the repo carries tools that check the work.

Links. Both of my newsletter domains are blocked in cloud sessions. The repo keeps an offline index of published URLs, 695 records on October 16, 2026. A slug in the index is real. A slug that isn’t in it doesn’t get suggested.

Cards. My card renderer, render_card.py, checks aspect ratio, clipped content, minimum font size and file size before it writes a file. A failed check exits non-zero and writes no PNG.

Gates. A file in the repo lists every publishing gate, what it catches and whether it can run in a cloud session. A gate that can’t run hasn’t passed.

The same idea at OpenAI

In my write-up of Ryan Lopopolo’s episode, his team’s experiment asked whether Codex could do the entire software engineering job for a new internal agent product. It came with four constraints. Start from an empty repository. Build an app that supports non-engineering knowledge work inside OpenAI. Let the agent handle on-call triage, internal tools and text-heavy workflows. And no human is allowed to type production code. Engineers can only touch the harness. Whenever the agent failed, the team asked what was missing in the harness. Fixing the environment made the codebase better.

A line from OpenAI’s harness engineering post, which I quoted in my Team OS guide, says a Slack discussion that aligned the team on an architectural pattern is “illegible in the same way it would be unknown to a new hire joining three months later” if the agent can’t find it.

In my write-up of Ryan’s episode, I said the PM’s contribution came from writing artifacts that the harness understands. That is my read of the episode. Take your next feature. Could you express it as PRD + tests + evals the agent can run on its own?

The MEMORY.md size limit

Claude Code’s auto memory loads only the first 200 lines or 25KB of its MEMORY.md index each session. Anything past that doesn’t load at startup, so keep the index short and put the detail in topic files. My post on building memory for Claude Code covers the layout, and why a memory system has to suit the harness it runs in.

How to start yours, in order

  1. Pick the one mistake the agent keeps making in your work. Not five.
  2. Write the rule as one line in CLAUDE.md, and link to a file for the detail.
  3. If the rule has to hold even when the model skips it, make it a hook: a short script that exits with code 2.
  4. Turn the steps you repeat into a skill. My guide to writing Claude skills has the results from 75+ tests.
  5. Check the output before it goes to a customer. A script or a reviewer agent will do.
  6. Re-test each rule when the model changes. Anthropic’s post suggests re-examining the harness when a new model lands, stripping away the pieces that are no longer load-bearing.

Start with one workflow that does one thing well, as I wrote in practical AI agents for PMs. Get it working reliably. Then add complexity. When you find a gap in your harness, ask Claude Code to build a solution. My memory guide makes the same point.

For a team version, my Team OS in Claude Code post covers a harness for a PM’s team, and my Job Search OS post covers one for a job search. The Job Search OS guide says the harness needs to be customizable. To share context across tools, see how to build a shared context repo any AI harness can read.

I published Harness Engineering: Your Complete Guide on October 1, 2026 for paid subscribers. I write about building with Claude Code at www.news.aakashg.com.

Claude Code harness FAQ

What is a Claude Code harness?

A Claude Code harness is everything around the model: instructions in CLAUDE.md, skills, subagents, hooks, scripts and memory. Birgitta Böckeler’s article on Martin Fowler’s site writes the idea as Agent = Model + Harness, everything in an agent except the model itself. Anthropic’s engineering post says every component in a harness encodes an assumption about what the model can’t do on its own.

Is Claude Code itself a harness?

Yes. Claude Code is Anthropic’s harness around its models. Böckeler’s article separates that from the outer harness that users build for their own project. In your repo, that’s the CLAUDE.md, skills and hooks.

What is harness engineering?

Harness engineering means fixing the harness when the agent fails, instead of fixing its output by hand. In the OpenAI team I covered, engineers could only touch the harness, and any time the agent failed they asked what was missing in it.

What goes in CLAUDE.md and what goes in a hook?

CLAUDE.md holds instructions the model should follow. A hook enforces the rules that have to hold regardless of what the model decides. The Claude Code docs recommend a PreToolUse hook to block an action outright.

Do PMs need to write hooks?

Not to start. Begin with one rule in CLAUDE.md and one skill. Add a hook when a rule has to hold every time.

By Aakash Gupta

15 years in PM | From PM to VP of Product | Ex-Google, Fortnite, Affirm, Apollo

Leave your thoughts