Skip to content
mode

Writing

Introduction to Engineering and Managing Agent Harnesses

Dr. Florian PatzerFounder & Experienced Tech Lead
Agent harness stack with model, kernel harness and userspace harness

What agent harnesses are, how to reason about them, and why they're still hard to manage — built around one distinction: the kernel harness vs. the userspace harness.

The model gets the attention, but if you run coding agents seriously, most of your leverage sits in everything around it: the rules files, the slash commands, the subagents, the hooks, the MCP wiring, the conventions that keep the thing on rails. There's a growing name for this work "harness engineering" and it's real enough that people have started studying it empirically rather than just improvising it in private.

It's also young, and it shows. There are almost no standards. Almost nothing you build is portable between tools. And the moment more than one person is involved, keeping a shared setup consistent and reproducible is mostly manual labor. This piece is an introduction to the territory: what a harness actually is, the vocabulary you need to reason about one, the trade-offs that keep coming up, and why teams still can't manage these setups cleanly. It's organized around a single distinction that, once you have it, makes most of the rest easier to think about.

What a harness is

What a harness really is: the behavior layer inside the agent.

Modern coding models are already agentic. They're post-trained to plan, call tools, iterate, and recover from failures; most of that competence now lives in the weights, not in the software around them. But a model still only emits tokens. It can't read your repo, run your build, or invoke a tool by itself. The program that does that work is the agent: it executes the actions the model proposes, feeds results back, and keeps the loop running. Claude Code, Cursor, OpenAI's Codex, Gemini CLI, opencode, Windsurf: these are agents.

An agent is far more than any single part of it. But sitting inside every agent is the layer that decides how it behaves: the base system prompt, the tool definitions, the permission model, the context strategy, the rules and conventions it follows. That behavior-defining layer is the harness. The agent is the whole program; the harness is the part of it that shapes what the program does. The same model often sits behind several agents, so when people argue about which agent is better, they're usually comparing harnesses, not models.

Here's the part that confuses people. The vendor ships a harness baked into the agent, but the moment you write a CLAUDE.md, define a custom /review command, or register an MCP server, you're building a harness too. Same kind of layer, shaping the same agent's behavior, but a completely different owner. Lumping both under one word is why conversations about this get muddy.

The stack: model, kernel harness, userspace harness

That muddle clears the moment you separate the two. I've found it useful to name them: the kernel harness the vendor ships, and the userspace harness you build on top, borrowing the operating-system picture for the two layers above the model. Bottom to top:

  • The model: weights and inference. On its own it just predicts tokens (simplified); the agent runs it and the harness shapes how, but none of your setup lives in the model itself. You can swap it, but you don't reach in and rewire it.
  • The kernel harness: the behavior-defining layer the vendor ships and that you don't edit. It covers the built-in system prompt, the default tool setup, context handling, the permission model, and the extension points it chooses to expose. It comes baked into the agent (Claude Code, Cursor, Codex, opencode are agents, each with its own kernel harness), and the vendor versions it and changes it out from under you.
  • The userspace harness is everything you configure on top. This is where your engineering actually lives, and it's assembled from a small set of recurring primitives:
    • Instructions / rules: static behavioral guidance the agent reads each session (CLAUDE.md, AGENTS.md, .cursor/rules).
    • Prompts / commands: reusable, invocable prompt templates (slash commands).
    • Agents / subagents: named personas with their own model choice and tool whitelist.
    • Skills / capabilities: multi-file capabilities, loaded on demand, that bundle a procedure with its supporting scripts and references.
    • Hooks: lifecycle scripts fired on events like session start or finish.
    • MCP servers: external tools and context providers the agent can call at runtime.

Harness onien: Layered architecture of a harness with examples of concepts for each layer (non-exhaustive).

The kernel harness is given to you. The userspace harness is yours to design, version, and own. Almost every meaningful decision in harness engineering is a decision about the userspace layer. The term Harness Engineering usually describes exactly this layer you have complete control over.

Setting the vendor's own switches (permissions, which built-in tools are on, which model runs) is a third thing: you're configuring the kernel harness, not authoring a userspace harness, and not editing the kernel harness itself.

The boundary is an interface, and there's no standard one

In an operating system, the boundary between kernel and userspace is a narrow, documented, deliberately stabilized contract. The syscall interface is the canonical example: on Linux, not breaking it is treated as close to sacred, and a userspace binary keeps working across kernel versions because the kernel refuses to move that line. That deliberate stability is what lets userspace stay portable at all.

Agent tooling has the same kind of boundary in principle: an interface where the parts you author plug into the parts the vendor ships, defined by which files an agent reads, from which directories, in what format, and which lifecycle events it fires. But this boundary is neither standardized nor stable. Every kernel harness invents its own. Claude Code reads CLAUDE.md and a .claude/ tree; Cursor reads .cursor/rules; Codex reads AGENTS.md; each expresses "a subagent" or "a hook" differently, if it supports the concept at all.

The direct consequence: your userspace harness is not portable. Write it against one kernel harness and you've written it against one vendor's private interface. Add a second tool (a teammate who prefers Cursor, a CI agent on Codex) and you're re-authoring the same intent in a second dialect, then keeping both in sync by hand. This is the drift that quietly eats teams alive.

There is one partial exception, and it's instructive. The AGENTS.md convention emerged in 2025 as an attempt at a neutral, tool-agnostic instructions file, and it stuck: it's now read by dozens of tools, adopted across tens of thousands of repositories, and stewarded by the Linux Foundation's Agentic AI Foundation, the same body that stewards MCP. What's notable is that this convergence was bottom-up, driven by developers wanting one source of truth, not mandated by any vendor. But AGENTS.md standardizes exactly one primitive: static instructions. Commands, subagents, skills, hooks, and MCP wiring still have no cross-tool standard. The most portable part of your userspace harness is a single markdown file; everything more powerful remains vendor-locked.

The kernel harness moves under you

One property of harness engineering deserves its own heading, because it shapes how you have to work: the layer you build on is a moving target.

Kernel harnesses and their extension interfaces are volatile. Vendors change them often and without the deprecation guarantees you'd expect from a mature platform. A rules file, a hook, or a subagent definition that was picked up correctly last month can silently stop being read after an update: no error, just a setup that quietly no longer does what you think it does.

The model underneath moves too, and its movement is subtler. The same userspace harness steers different models differently; the instruction that reliably shaped one model's behavior lands differently on the next. So a change you never made to your own setup (a model swap, an agent update) can shift how your harness actually behaves. Your userspace harness is authored against a target that moves on two axes at once.

That's not a reason to avoid building one. It's the reason the management side of harness engineering matters as much as the authoring side: if your setup can drift without you touching it, you need to pin what you can, and you need a way to notice when behavior changes. Which is exactly where proper tooling gets interesting.

Agent-agnostic vs. agent-specific

Once you accept that the userspace harness is the thing you own, the first real design choice is how tightly to couple it to one kernel harness.

An agent-specific userspace harness is authored directly in one vendor's native format and exploits its full feature set, e.g. Claude Code's skills, hooks, and subagents. This means maximum power, but zero portability. Often teams end up here by accident: they started with one tool, wrote everything for it, and only feel the lock-in when a second tool shows up.

An agent-agnostic userspace harness is authored once against a neutral source and made to work across harnesses: either by staying within the lowest common denominator, or by compiling out to each vendor's format. It survives tool switches and mixed-tool teams. The cost is real: you either constrain yourself to the intersection of what every harness supports, or you take on a compile step. You trade some vendor-specific power for portability and a single source of truth. Important to note: compiling only works for deterministic concepts, however, most of your userspace harness is non-deterministic - e.g. should a policy be located in a rule, a skill, the AGENTS.md , or a combination of them all?

Harness types agent-specific and agent-agnostic in comparison.

Neither a vendor-specific, nor a common denominator approach is correct in the abstract. A solo developer committed to one tool has little reason to pay the agnostic tax. A team with mixed tooling, onboarding churn, and a need to reproduce setups across machines has little choice but to pay it.

However, I clearly recommend a hybrid approach. For example, take our spec-driven workflow [1], it is agent-agnostic with all the extra work of maintaining compilation (via scripts). But, it only defines a workflow which you usually want to share between team members or teams. At the same time it allows you to use it together with your agent-specific harness. Still a trade-off, but one done on purpose to allow high maintainability and specialization at the same time. More on that in the next chapter.

The management gap

We've built increasingly sophisticated userspace harnesses, but we manage them like it's 2005: copy files between repos, paste rules into a new project, walk a new hire through your personal pile of markdown by hand. There's no manifest describing what a project's agent setup requires. No lockfile pinning exact versions. No dependency resolution when one set of rules builds on another. No update process.

You can see the gap in what teams actually commit. An empirical study [2] of 2,853 public repositories that already ship at least one agent-config file, found context files (CLAUDE.md, AGENTS.md) dominating, often as the only mechanism present, with skills and subagents rarely committed and most committed skills carrying static instructions rather than executable scripts. The authors' own reading is that in open source, harness engineering today is mostly context engineering. That view is partial by construction, since repository mining cannot see the personal, global, or private setups that never get committed. But the committed slice is exactly the part that is meant to be shared, and even there the sophistication mostly is not showing up. Without a management layer to make it portable and reproducible, most teams stay with the simplest thing that survives copy-paste.

This is the gap tools like APM (Agent Package Manager) [3] are trying to close, by lifting the package-manager pattern (package.json, requirements.txt, Cargo.toml) onto agent userspace harnesses. You declare your userspace harness once in a manifest, a lockfile pins content hashes for byte-for-byte reproducibility, and one install command compiles the primitives out to whichever kernel harnesses your repo targets. In the vocabulary here: it's an attempt to allow the userspace harness a real distribution and lifecycle management, and to make the agent-agnostic path cheap enough that more teams take it. Moreover, and this is what I love about this approach, you can modularize the userspace harness with base modules and different bundles for different purposes, e.g. different stacks.

It's early, and it's worth being precise about what it does and doesn't solve. It addresses the management plane (distribution, versioning, reproducibility, policy), not the authoring plane. It won't write good instructions for you, and a compiled userspace harness is only as good as the primitives you put in. Its bet, that agent-agnostic authoring plus per-vendor compilation is the right shape, is a bet, not a settled fact. But it's the first serious attempt I've seen to treat the userspace harness as something you ship rather than something you copy, and that framing alone is progress.

Harness engineering as a discipline

None of this is speculative anymore. There's a growing body of empirical work on harness engineering, a Linux-Foundation-stewarded standard for at least one primitive, and a small ecosystem of tools forming around the management problem. The discipline is arriving whether or not our habits keep up.

So we should treat it like engineering. The userspace harness is the part you own, so give it what you give the rest of your codebase: version it, review it, and decide deliberately whether to bind it to one agent or keep it portable across several. Expect the ground to move, because the agent underneath will change and the interfaces it exposes are not stable; pin what you can, and build a way to notice when behavior drifts. And treat the whole setup as something you distribute and reproduce, not a folder of files you re-copy into the next project by hand. The kernel/userspace split is just the lens that makes those calls legible: it tells you which part is yours to engineer, and where portability is won or lost.

Further reading

[1] The mode41 sd-workflow at github.com/mode41/sd-workflow: apm harness package providing a spec-driven development workflow.

[2] Galster et al., Harness Engineering for Agentic AI Coding Tools: An Exploratory Study (arXiv:2602.14690, 2026): a cross-tool snapshot of repository-versioned configuration across five agentic tools and 2,853 open-source repositories (February 2026).

[3] APM (Agent Package Manager) at github.com/microsoft/apm: manifest, lockfile, and compile-to-every-harness for agent context.

Dr. Florian Patzer

Founder & Experienced Tech Lead

Dr. Florian Patzer

Dr. Florian Patzer is the founder and principal of mode41 — a practitioner with a strong background in agentic engineering, software architecture, and technology strategy, from conception through implementation. He is co-founder and CTO of nodeline GmbH, a former leading scientist at Fraunhofer, and an agentic engineering consultant at Bundesdruckerei. This is experience from doing agentic engineering in production, applying the mode41 methodology — not repackaging it secondhand.

Newsletter

Stay up to date

Don't miss out on the latest insights and updates regarding our content on agentic engineering. No hype, no spam.

By subscribing you agree to receive the mode41 newsletter. We use Keila (EU-hosted) to deliver it and you can unsubscribe at any time — see our privacy policy.