Tools

AI-generated text

Pick a Coding Harness by the Control It Gives You, Not Its Vendor

Coding harnesses differ less by brand and more by which layers of control they expose.

Pick a Coding Harness by the Control It Gives You, Not Its Vendor

The world of 2019 — when only a few language models existed with small context windows — is gone. Today flagship vendors and open-source projects compete across model families, sizes, capabilities, and deployment options. Coding harnesses are following a similar expansion.

At first glance Claude Code, Codex, Pi, DeepSeek Harness and the other coding harnesses all appear to do the same job: help you build software with models. Look closer and each harness gives you control over different parts: what the model can see and change, how it uses tools, where it runs, and what happens on failure. So instead of asking which harness is best overall, ask:

Which layer of the harness does your project need to own?

What a harness provides — and what remains your responsibility

Picking a harness is not just about which model writes the best code. You are also choosing what the harness enforces for you, what you can customize, and what you must implement yourself. If the harness doesn’t provide verification, durable state, repair routing, or an enforced execution boundary, those responsibilities stay with you. You remain accountable for the workflow’s reliability and governance.

Each harness tends to have a center of gravity: a layer where it gives you the most direct leverage. The following descriptions are deliberately high level; boundaries overlap and the products change quickly. The point is to show where each harness typically gives you default control, and where the engineering work is likely to remain yours.

Claude Code — control inside the run

Claude Code buys you fine-grained control over how an implementation unfolds. CLAUDE.md provides standing instructions, skills add task-specific playbooks, subagents divide work, and hooks intercept actions before and after tool calls. A hook can do more than refuse an operation: it can explain the refusal or immediately return a compiler or policy failure to the agent.

These features let you steer the coding loop extensively, but they operate inside Claude Code’s existing lifecycle. If you need to control the outer lifecycle itself, you need an additional layer.

Codex — control through separation

Codex provides separation between a coding task and its execution environment. A noninteractive codex exec run can work on a narrow task in a specified repository, under an OS-enforced sandbox, and return a schema-constrained result.

This separation is useful for independent verification. You can give Codex a clean checkout, exclude builder instructions, restrict writable paths, and run separate reviews for code quality, test gaps, persistence, or user-visible behavior. The sandbox depends on the operating system, but it moves scope enforcement out of the prompt and into the execution boundary.

Pi — control over the loop

Pi gives control over the coding loop itself. Its tools, commands, event handlers, context, models, and session state can be extended or replaced. That allows you to decide which steps remain agentic and which follow deterministic policy.

For example, a local defect can return to implementation, a repeated defect can force replanning, and conflicting findings can trigger a recheck or human review. Pi can also run agents inside this lifecycle, so it’s more than a simple deterministic orchestrator. In the author’s example, programmability in Pi was used to make the outer decisions deterministic — that was a design choice, not Pi’s definition.

DeepSeek’s harness — control through composition

DeepSeek’s harness is valuable when you want to swap whole parts of the harness rather than wrap or steer them. Tools, sessions, lifecycle behavior, verification, governance — and even the loop itself — are composable plug-ins. This lets you replace one component without rebuilding the rest.

The trade-off is that your control is only as good as the plug-ins you assemble. Where Pi gives you a minimal core to build on, DeepSeek’s harness presents a set of parts to compose.

A practical example: migrating Python 2.7

The real problem the author wanted to solve was migrating a legacy Python 2.7 application reliably without changing accumulated behavior or corrupting persisted data. Getting the code to run on Python 3 was only part of the job. The author also needed to preserve behavior, verify data across both runtimes, control what coding agents could change, and define what should happen when a test or verification failed.

So the harness choice was approached through the lens of control, isolation, and lifecycle management. The result was a composition of multiple harnesses:

  • Claude Code built the port, because the author wanted internal steering, specialized skills, hooks, and a factory of implementation and review subagents.
  • Codex verified the port in isolated runs, because an independent model context, clean workspaces, constrained writes, and structured findings were needed.
  • Pi owned the outer lifecycle, because durable state, evidence validation, bounded repairs, replanning rules, and human escalation were required.
  • Frozen acceptance checks, including Playwright and Python 2/3 differential checks, ran outside agents so neither the builder nor the verifier could redefine success.

DeepSeek’s harness was not used in this case, not because it couldn’t do the job, but because the author wanted a very small outer lifecycle they could read end to end.

To test the setup, the author created a small Python 2 application with similar traps and compared the composed configuration with a single Claude Code session in which Claude verified and tested its own code.

Both setups passed all 25 hidden behavior tests. Yet the single-session setup silently collapsed two distinct Python 2 dictionary keys — the Unicode u'é' and the byte string 'é' — into one Python 3 string, and after the data was saved one entry was permanently lost. The single-session setup also changed a Python 2 Unicode value into bytes without documenting it. The test suite, Claude’s own tests, and hundreds of recorded behavior comparisons missed it.

Two isolated Codex verifiers independently reproduced the defect. Claude did not simply accept the finding; it contested it. Pi launched a fresh Codex run that received only the finding and Claude’s argument. The independent recheck upheld the finding, Claude accepted it, Pi routed the defect into a bounded repair, and the next verification round confirmed that both keys and their original types now survived.

This illustrates an important point: models can be self-reinforcing within a session. Independent verification matters because a separate verification is not anchored to the same implementation history; it can break the feedback loop.

The improved outcome came from combining the controls needed: internal steering, independent execution, frozen behavioral evidence, and deterministic lifecycle policy — not from any single harness alone.

How to pick a harness

Start by identifying the level of control you need and how much of the remaining harness you are prepared to implement yourself. Helpful starter questions:

  • Do I want to configure an existing coding loop, extend it, or replace parts of it?
  • Can I control tools, context, memory, and model selection at the level my project requires?
  • Where are permissions, allow lists, and policies enforced: in instructions, application logic, or the operating system?
  • Can I intercept actions and lifecycle events before and after they happen?
  • How much of the orchestration, state management, and session lifecycle can I change or orchestrate?
  • What does the harness expose for observability, verification, and structured evidence?
  • Which reliability and governance controls does the harness provide, and which remain mine to build?
  • Can the harness work with other tools and harnesses if my requirements span several control layers?

These questions are examples, not an exhaustive checklist. The right tool depends on what you are building, how much autonomy you give the coding agent, and what you remain accountable for when it fails.

Your answers might lead you to Claude Code, Codex, Pi, DeepSeek’s harness, or another harness entirely. Ultimately the vendor’s name only tells you who packaged the runtime, not where your guarantees live. Whether you choose a single harness or orchestrate multiple, the principle is the same: pick the tool by the boundary of control it gives you, and decide whether you want the agent to define the terms of its own success.