[CONTEXT FOR AI ASSISTANTS]
You're reading the agent markdown version of a post from JoelClaw (https://joelclaw.com).
Author: Joel Hooks — software engineer building a personal AI operating system.

How to use implementation details in this document:
- Treat commands, code blocks, and config as reference implementations.
- Preserve ordering and architecture, but adapt hostnames, paths, versions, and credentials.
- Prefer details in <AgentOnly> blocks when present; they contain operational context removed from the human page.
- Verify assumptions against the current repo/system state before executing changes.

This is a narrative article from a real build. Technical details reflect Joel's setup and should be adapted to your environment.

If you cite this, link to the original: https://joelclaw.com/the-harness-is-a-framework
If you quote Joel, attribute him by name. Don't paraphrase opinions as facts.

Site index: https://joelclaw.com/sitemap.md
Machine-readable: https://joelclaw.com/llms.txt

Other posts on this site:
- [The memory system that watches itself](https://joelclaw.com/memory-that-watches-itself.md)
- [The healer was the killer](https://joelclaw.com/healer-was-the-killer.md)
- [Agentic AI Optimization: Implementation Checklist](https://joelclaw.com/aaio-implementation-checklist.md)
- [Agentic AI Optimization: Implementation Checklist](https://joelclaw.com/aaio-implementation-checklist.md)
- [Redis, Dkron, Restate, and Sandboxes](https://joelclaw.com/redis-dkron-restate-and-sandboxes.md)
- [Dogfooding Story 4: the queue observer earns dry-run, not enforce](https://joelclaw.com/dogfooding-story-4-queue-observer.md)
- [Contributing to pi-mono with a public maintainer corpus](https://joelclaw.com/contributing-to-pi-mono-with-a-public-maintainer-corpus.md)
- [AI Job Scheduling on Mac as Local-First Video Infrastructure](https://joelclaw.com/ai-job-scheduling-macos-launchd.md)
- [Breakable Toys in the Wild: Apprenticeship Patterns and the joelclaw Experiment](https://joelclaw.com/breakable-toys-joelclaw.md)
- [Utah and joelclaw: Convergent Architecture](https://joelclaw.com/utah-joelclaw-convergent-architecture.md)
- [The Agent Memory System](https://joelclaw.com/the-memory-system.md)
- [JoelClaw is a Claw-like Organism](https://joelclaw.com/joelclaw-is-a-claw-like-organism.md)
- [The Agent Writing Loop](https://joelclaw.com/the-writing-loop.md)
- [Talon: the watchdog that finally bites](https://joelclaw.com/talon-watchdog-that-finally-bites.md)
- [The Knowledge Adventure Club Graph](https://joelclaw.com/knowledge-adventure-club-graph.md)
- [MineClaw](https://joelclaw.com/mineclaw.md)
- [Build a Voice Agent That Answers the Phone](https://joelclaw.com/build-a-voice-agent-that-answers-the-phone.md)
- [Plan 9 from Bell Labs: What Rob Pike Built After Unix](https://joelclaw.com/plan-9-pike-everything-is-a-file.md)
- [Propositions as Sessions: What Armstrong Built and Wadler Proved](https://joelclaw.com/propositions-as-sessions-armstrong-wadler.md)
- [Cache Components Patterns Skill for Next.js 16+ Applications](https://joelclaw.com/cache-components-patterns-skill-for-nextjs.md)
- [Karpathy Says We're Building "Claws"](https://joelclaw.com/karpathy-claws-as-category.md)
- [Voice Agent: A Rough Edge Experiment](https://joelclaw.com/voice-agent-deployment-deep-dive.md)
- [Extending Pi Coding Agent with Custom Tools and Widgets](https://joelclaw.com/extending-pi-with-custom-tools.md)
- [The Soul of Erlang Made Me Question Everything](https://joelclaw.com/soul-of-erlang-beam-evaluation.md)
- [CLI Design for AI Agents](https://joelclaw.com/cli-design-for-ai-agents.md)
- [Building a Gateway for Your AI Agent](https://joelclaw.com/building-a-gateway-for-your-ai-agent.md)
- [Self-Hosting Inngest: A Background Task Manager for AI Agents](https://joelclaw.com/self-hosting-inngest-background-tasks.md)
- [The One Where Joel Deploys Kubernetes... Again](https://joelclaw.com/joel-deploys-k8s.md)
- [How I Built an Observation Pipeline So My AI Remembers Yesterday](https://joelclaw.com/observation-pipeline-persistent-ai-memory.md)
- [Riding the Token Wave: Sean Grove at Everything NYC](https://joelclaw.com/riding-the-token-wave-sean-grove.md)
- [Playing with AT Protocol as a Data Layer](https://joelclaw.com/at-protocol-as-bedrock.md)
- [Building My Own OpenClaw on a Mac Mini](https://joelclaw.com/building-my-own-openclaw.md)
- [Inngest is the Nervous System](https://joelclaw.com/inngest-is-the-nervous-system.md)
- [OpenClaw: Peter Steinberger on Lex Fridman](https://joelclaw.com/openclaw-peter-steinberger-lex-fridman.md)
[END CONTEXT]

---
# The Harness Is a Framework

> The distinction isn't harness vs framework. It's between frameworks that own your execution model and frameworks that provide scaffolding for yours.

By Joel Hooks · 2026-03-02T23:57:00.000Z
Original: https://joelclaw.com/the-harness-is-a-framework
Mode: agent

---
Dan Farrelly wrote a piece called "Your Agent Needs a Harness, Not a Framework" and I think he's almost right. The infrastructure argument about durability, retries, event routing, and state persistence is dead on. Every agent framework is rebuilding that stuff badly from scratch. Inngest already solved it. Use the solved thing.

But I want to push back on one word: "not."

## The Word Got Poisoned

"Framework" became a dirty word in AI because when people think AI framework, they think LangChain, and LangChain left a trail of questionable decisions and wonky apps.

A lot of people got burned and generalized that pain to the whole category. The issue was not frameworks as a concept. The issue was one early example that shaped first impressions.

When Dan says "harness," he's describing something with extension hooks, a plugin system, lifecycle events, session management, and a prompt composition pipeline. That's a framework. It's just a *good* one that doesn't fight you.

## The Shape of the Claw

I've been [building joelclaw](https://joelclaw.com/building-my-own-openclaw) for a while now. It started as an experiment and turned into something that [supports a lot of my day-to-day work](https://joelclaw.com/joelclaw-is-a-claw-like-organism), an always-on system that handles messages, processes events, manages memory, and coordinates work across a dozen surfaces.

Pi is just the right amount of structure. It carries opinions and sensible defaults, but gives you vast freedom to build your own shape on top. It's substrate, not scaffolding. The difference matters. Scaffolding comes down. Substrate is what you grow in.

The framework layer is [pi](https://github.com/mariozechner/pi-coding-agent). Here's what it actually gives me:

* **Session management:** append-only JSONL with tree structure, branching, compaction
* **Extension API:** lifecycle hooks at every stage (session\_start, turn\_start, tool\_call, etc.)
* **Skill loading:** taxonomy-aware injection of domain knowledge into prompts
* **Tool registration:** custom tools with TypeBox schemas and execute functions
* **Prompt composition:** multi-stage pipeline that assembles system prompts from identity, role, context

I've [extended pi with custom tools](https://joelclaw.com/extending-pi-with-custom-tools). I've built a [gateway](https://joelclaw.com/building-a-gateway-for-your-ai-agent) on top of it. I've layered [memory](https://joelclaw.com/the-memory-system) and [observation pipelines](https://joelclaw.com/observation-pipeline-persistent-ai-memory) through its extension system. Every time I need something new, there's a hook for it.

That's not a harness. That's a framework. A really good one that stays out of your way until you need it, then gives you exactly the right surface.

## The Rails Test

You know something is a framework when removing it means rebuilding half of it yourself. If I ripped pi out of joelclaw tomorrow, I'd spend weeks recreating session persistence, extension loading, skill injection, and prompt composition. That's the Rails test: you can hate Rails, but if you leave it, you end up rebuilding the parts of Rails you actually needed.

The same people who say "use a harness, not a framework" will turn around and build a harness with a config file, a plugin system, and an event bus. Congratulations, you built a framework and called it something else because one early ecosystem experience poisoned the word.

## The Real Distinction

The useful distinction isn't harness vs framework. It's between frameworks that **own your execution model** and frameworks that **provide scaffolding for yours**.

LangChain owns your execution model. It decides how chains work, how tools get called, how memory flows. Fight it and you lose.

Pi provides scaffolding. It gives me hooks, not opinions about what those hooks should do. My [gateway daemon](https://joelclaw.com/building-a-gateway-for-your-ai-agent) is a pi session, but pi doesn't know or care that it's a gateway. It just provides the session substrate and the extension points. I do the rest.

This is the same pattern as every good framework in history. Next.js doesn't care if you're building a blog or a SaaS. Express doesn't care if you're building an API or a webhook handler. The framework provides the scaffolding. You provide the shape.

A really good tool isn't a unitasker, but it's also not an everytasker. This is a *design* problem. "Don't Make Me Think." "The Design of Everyday Things." Good tools, good frameworks, don't happen by accident. They happen because someone thought hard about where to have opinions and where to shut up. The test isn't whether a tool calls itself a framework or a harness. The test is whether it has opinions about *your* problem or opinions about *its* problem.

## Infrastructure Is Orthogonal

Dan's strongest point, and the one I'm fully aligned on, is that durability is a solved problem. Every agent needs retries, state persistence, concurrency control, and event routing. Those aren't agent problems. They're distributed systems problems. [Inngest solved them](https://joelclaw.com/inngest-is-the-nervous-system).

joelclaw runs 110+ durable functions through Inngest. Every step is memoized. Every failure retries. Every event is routed. I didn't build any of that. I just used the solved thing. You can [self-host it](https://joelclaw.com/self-hosting-inngest-background-tasks) on your own hardware and own the whole stack.

The mistake is conflating "I need infrastructure" with "I don't need a framework." You need both. The framework handles the agent surface: sessions, tools, prompts, extensions. The infrastructure handles the durability surface: events, steps, retries, state. They're different layers solving different problems.

## Three Layers, Not Two

joelclaw is three layers:

| Layer                | What                  | Provides                                                                                                                                                                                        |
| -------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Framework**        | Pi                    | Sessions, extensions, skills, tools, prompt composition                                                                                                                                         |
| **Infrastructure**   | Inngest + Redis + k8s | Durability, events, state, retries, scheduling                                                                                                                                                  |
| **Composition root** | The glue I wrote      | [Gateway](https://joelclaw.com/building-a-gateway-for-your-ai-agent), [CLI](https://joelclaw.com/cli-design-for-ai-agents), system-bus worker, [memory](https://joelclaw.com/the-memory-system) |

The composition root is the thin part. It wires the framework to the infrastructure with my specific opinions about how messages flow, how skills get loaded, and how the system responds to events. That's the part that's truly mine. Everything else is standing on the shoulders of people who solved hard problems so I don't have to.

Dan's right that most people are trying to cram all three layers into one tool. That's the actual problem. Not frameworks. Not harnesses. Just bad layering.

We're not disagreeing. This is a "yes, and": Dan's article lays out exactly the right infrastructure thinking. I'm just saying don't be afraid of the word "framework" because one bad experience burned you. The harness *is* a framework. That's not a criticism. That's a compliment.
