← writing

The harness, the context, the flow

According to JetBrains’ developer survey from January 2026, 90% of developers were using at least one AI tool at work, a figure Google’s DORA report had already put at the same 90% a few months earlier, up 14 points in a single year (1) (2). However, that kind of growth comes with exactly the implications you would expect from a technology disruptive enough to reshape the whole development process and fast enough to make keeping up with it genuinely hard. DORA’s own report agrees on something sharper than raw adoption, pointing out that “AI amplifies the quality of the engineering system it operates within” (2): strong teams get stronger and the cracks in a struggling one only widen.

In my view the difference comes down to discipline and structure, the same gap engineers like Kent Beck have been describing: augmented coding, deliberate and test driven, against what he calls vibe coding, accepting whatever comes back without much scrutiny (3).

What software engineers can, and in my view should, focus on now more than in the pre-AI era is exactly the kind of work that gives real leverage: re-engineering how software actually gets built now, with a deep study of what gets called the harness, its context and a structured agentic workflow. Execution today can be delegated almost entirely to agents, so the time that frees up can and should go into understanding how those agents should execute.

AI does not ask us to throw out what we know about building software. The old principles do not die with agents in the loop, they get re-instantiated for a team that now includes them. What follows is my attempt at that re-instantiation, a structured method rather than a bag of habits, built on three pillars. The first is the harness itself, the material the rest is built from. The other two are the decisions that shape it most: what each agent gets to know (their context), and how the task flows end to end, agents doing their part and a human holding the gate at the points that matter. Some of it comes out of building Nesso day to day, where every one of these phases already runs, just informally. Closing that gap, from a flow that happens to work to one that is actually designed, is part of what pushed me to write this down.

What the harness is made of

Too many people still focus on the model itself, on what it can do in the abstract, and not nearly enough on what surrounds it: the infrastructure every major AI lab is now building to connect models to each other and to the world outside. That infrastructure, what people now call the harness, is mostly hidden complexity, invisible to the end user, and it already powers the products everyone uses every day. Even an ordinary chatbot today runs on infrastructure that lets it hold a conversation with the right expertise for whatever topic comes up, and reach for tools when it needs to touch its own memory or pull something from the web to keep its context current.

At work it cannot stay hidden. It has to be understood, and it has to be deliberately built and kept up by the people using it, so the AI stays tuned to whatever project it is actually working on. The evidence that it matters is not subtle. Artificial Analysis took a single model, Claude Opus 4.7, and ran it through three different coding harnesses (Opencode, Cursor CLI, and Claude Code), and its score on their agent index ranged from 65 down to 57, the same model doing clearly better or worse depending on nothing but the scaffolding around it (4).

The first step is understanding exactly what it is: it is not one setting you turn up or down, it is a handful of separate mechanisms, and each one controls a different lever over what the model knows or what it is allowed to do.

MCP

One of them sits apart from the rest. MCP, the Model Context Protocol, is not about organizing what the model already has, it is the wire it uses to reach anything outside itself: a tool, a database, another service. It is also the one piece of this list that has already become a real standard: Anthropic opened it, and OpenAI, Google, Microsoft and others now build to the same protocol. In practice a project rarely needs more than a couple that actually matter: one that pulls in current documentation for whatever libraries the code depends on, or others that let the agent talk to services the project already relies on directly: a database, a ticket tracker, a deployment API.

Persisted memory

Two of the rest sit in the background on every task, there to be read rather than rebuilt from scratch each time, though neither gets there the same way. One is what persists across sessions (most providers call it just memory), but it is mostly the provider’s own doing, whatever the model decided on its own was worth remembering, resurfacing later without anyone having to ask. The other persists too, but only because people, or AI instructed by people, put it there (rules on Cursor, or custom instructions on Copilot): the project’s own constraints, its architecture, its banned patterns, its idioms. That is arguably what keeps a project genuinely yours in the AI era, the intent no model can infer from the code alone, written down so an agent has to understand it rather than guess at it.

Repetitive tasks

Two more only show up at a specific moment instead of sitting in the background the whole time. Skills are procedures pulled in on demand, a written how-to for a recurring task, called up by a command or by the agent’s own judgment that this is the moment for it. Hooks are scripts that fire on a coded event instead, before or after a tool call, to check something, block it outright, or set off an action of its own, like an automatic commit.

As a rule, if a task keeps recurring and can be done by a model, write a skill for it. If the same task could run as a plain script with no AI involved, and it needs to fire on a specific event rather than be called up on demand, that is what a hook is for.

Agents

The last one is about where work happens rather than what happens in it. Sub-agents are separate instances, called by the main agent, each with its own context window and its own job, so the reviewer does not inherit the builder’s reasoning and the planner is not dragging the executor’s diff around with it. Isolating the box is the easy part, what goes inside each one is the harder question, and it gets its own pillar next.

The context each agent gets

The key to a good output is a good input, and the input that matters most is the quality of the context an agent has while executing a task, which does not need to be the same from one task to the next. When a person carries a change from idea to merge, they quietly switch hats. They think loosely while brainstorming, narrowly while implementing, and adversarially while reviewing. An agentic workflow should make those hats explicit too, and once it does the question stops being how much context to load and becomes which slice each one needs.

Every project ends up needing its own mix of agents depending on the task, but it helps to start from a simple base, listing the phases a workflow generally moves through today:

  • Brainstorming: the task gets explored, placed in the project’s context, challenged, checked against the project’s own requirements, and prioritized, usually the step that takes a backlog item from a rough draft to something structured enough to act on.
  • Planning: turns a settled task into an actual plan, which defines how it should be built given the codebase as it stands today and whatever constraints apply.
  • Execution: the plan turns into actual code, tested as it is written.
  • Internal review: the code gets checked from several angles at once, quality, correctness, bugs, security, before anyone outside the loop sees it.
  • Documentation: whatever explains the change gets updated, the harness’s own memory, the comments in the code, the docs on the site.
  • External review: the pull request opens and waits on whatever review still has to happen outside the loop.

Once the phases are identified, it helps to categorize the context agents actually need to work through them:

  • Task description: the GitHub issue, the specific ask for this task.
  • Plan: how the task will actually get built, written once the task description is settled, based on the current state of the codebase and its constraints.
  • Codebase: the code that already exists around the change, everything except the change itself.
  • Diff: that change, the part actually being built or reviewed.
  • Persisted memory: what the project already knows and carries forward, both what the model picked up on its own and what people wrote down as rules or instructions for that project.
  • History: why the code got to look the way it does, not what it is now but how it got there (a changelog, parts of the git log).

Put every phase and context category on one grid and what each phase might actually need becomes clear at a glance.

A grid of five workflow phases against six context layers. Each cell marks whether a phase reads a layer in full or in part, creates it, updates it, or has no relationship to it at all.
Five workflow phases against six context layers: full reads, scoped reads, created layers, updated layers, the shape of what each phase actually needs.

The matrix leaves out plenty of detail, but it gives us a framework for reasoning about which agents are worth creating, and with what context, a way of weighing different configurations against each other.

Some of these context categories do not need to be loaded in full, only the slice that matters for the task at hand. Working on a new React component only requires the part of the codebase around that component. In the same way, an agent should not load every rule or instruction, or read the project’s entire git history, only what is relevant to that specific task. Selecting the right slice can partly be left to the agent’s own judgment, and partly comes from how those instructions are set up in the first place. On Cursor, for instance, rules can attach conditionally: written once, then set to apply automatically only to files matching a given pattern, to be pulled in by the agent based on their own description, or invoked manually, instead of loading on every single task.

Some phases can be broken down further, into sub-phases with their own dedicated sub-agents. Internal review might split into security and code quality, each one benefiting from its own context, and even its own model and effort level.

Splitting work across agents by role does more than optimize context, it also lets each task run on a different model, saving tokens further and matching capability to what the task actually demands. A model good at planning is not necessarily the one best suited to execution. Claude Opus 4.8, or GLM 5.2, might handle brainstorming and planning, tasks that call for broad reasoning and weighing tradeoffs, while cheap, fast models like Cursor’s Composer 2.5, or the open-weight DeepSeek v4 Flash, handle execution.

Knowing what each phase needs and which model fits it is only half the picture. The other half is how these phases actually connect: what decides when one hands off to the next, and where a human needs to hold the gate rather than let the pipeline run on its own.

How the work actually flows

Not every phase should stop at the same kind of gate. Three usually show up across the pipeline, and telling them apart is what keeps the whole thing from feeling either too slow or too loose:

  • Human: a person looks at the output and decides whether to move on, worth the time only where a wrong turn is expensive to undo, typically brainstorming, planning, and documentation.
  • Automated checks: a hook, the same mechanism described earlier, firing a script such as a linter, a test suite, a formatter, or a quality check, checking the output against rules that need no judgment at all.
  • Agent verdict: another agent judges whether the work is good enough to continue, cheaper and faster than a person, but that verdict cannot be allowed to repeat forever, it needs a limit of its own. After enough failed attempts, the loop should hand off to a human instead of trying again.

Here is what that looks like end to end, the same five phases from the matrix above, each one now carrying a model, a context slice, and a gate.

A flow chart of five workflow phases in sequence: brainstorming, planning, execution, review, and documentation. Each step lists its model, the context it reads or writes, and its gate type, human, automated checks, or agent verdict. A branch from review loops back to planning for rework, or continues on to documentation once approved.
Five phases end to end, each carrying its own model, context slice, and gate. A failed review loops back to planning, an approved one moves forward to documentation.

Worth noticing where a failed review actually goes: back to planning, not back to execution. When the verdict comes back negative, the instinct is to send the diff straight back to execution for a quick patch on top of the last one. Ward Cunningham’s original idea of technical debt was a conscious trade off, ship the compromise now, know exactly what it costs, and pay it back on your own schedule (5). What builds up from patch after patch on a diff nobody but the AI ever rereads from scratch is a different kind of debt. Casserini et al. call it agentic entropy: a drift nobody chose, each fix correct enough on its own but slowly pulling the code away from the plan that was meant to shape it, until the diff stops reflecting any single coherent decision (6). It sits close to what I called understanding debt in an earlier post, both about what AI delegation quietly erodes when nobody pauses to look closely. Sending a failed review back to planning instead of patching execution again is what keeps that from happening.

The pipeline can move in more than one way. The loop back to planning is one, skipping phases entirely is another. Few tasks actually walk through all five phases in the first place, and deciding how much of the pipeline a given task needs is itself part of the job. A one line typo fix does not need brainstorming, or much of a plan either. In practice that decision, and every handoff that follows it, comes from one of three places: a person triggering each agent by hand, an orchestration layer that sizes up the task and fires each handoff on its own, or any mix of the two.

OpenCode already ships something close to this. Its agents declare which subagents they are allowed to hand work to through a permission map, not a single on or off switch:

{
  "agent": {
    "orchestrator": {
      "mode": "primary",
      "permission": {
        "task": {
          "*": "deny",
          "orchestrator-*": "allow",
          "code-reviewer": "ask"
        }
      }
    }
  }
}

Deny by default, allow a whole family of subagents that match a pattern, and still ask before invoking one specific case. Each subagent can get its own rule instead of one setting for all of them (7).

The architect behind the pipeline

Somewhere across these three pillars our job has changed shape. Not from writing code to prompting a model, but from writing code to designing the system that decides how code gets written, who gets to see what, and where a person still has to look before anything ships. That is an architect’s job, not a bricklayer’s: drawing the blueprint, choosing the materials, walking the site at the points that matter, without laying every brick by hand.

DORA’s line from the very start of this piece reads differently from here: “AI amplifies the quality of the engineering system it operates within” (2). At the start that sentence was about adoption. From this side of the argument it reads more like a job description. The actual measure of the work is no longer how fast an agent can produce a diff. It is how well the harness, the context, and the flow around it are put together.

Five phases, a context matrix, three kinds of gates: a starting shape, not a fixed one, worth redrawing as models and tools change and adapting to each project.

References

1.
JetBrains. Which AI Coding Tools Do Developers Actually Use at Work? [Internet]. 2026. Available from: https://blog.jetbrains.com/research/2026/04/which-ai-coding-tools-do-developers-actually-use-at-work/
2.
DORA. State of AI-assisted Software Development 2025 [Internet]. Google Cloud; 2025. Available from: https://dora.dev/dora-report-2025/
3.
Beck K. Augmented Coding: Beyond the Vibes [Internet]. 2025. Available from: https://tidyfirst.substack.com/p/augmented-coding-beyond-the-vibes
4.
Analysis A. Coding Agents: Harness Comparison [Internet]. 2026. Available from: https://artificialanalysis.ai/agents/coding-agents
5.
Cunningham W. The WyCash Portfolio Management System. In: Addendum to the Proceedings of OOPSLA 1992 [Internet]. 1992. Available from: https://doi.org/10.1145/157709.157715
6.
Casserini M, Facchini A, Ferrario A. Beyond the “Diff”: Addressing Agentic Entropy in Agentic Software Development. In: Human-Centered Explainable AI (HCXAI) Workshop at CHI 2026 [Internet]. 2026. Available from: https://arxiv.org/abs/2604.16323
7.
OpenCode. Agents [Internet]. 2026. Available from: https://opencode.ai/docs/agents