The Four Engineerings of AI (and how I built the third one without knowing the industry was headed the same way)

The Four Engineerings of AI (and how I built the third one without knowing the industry was headed the same way)

The AI industry has just converged on the very same multi-agent architecture I've spent the last few weeks stumbling my way toward in my own code. I saw it all at once in two YouTube talks: one by Sally-Ann Delucia, from Arize, on how they solved context management in their agents; another by Luke Alvoeiro, from Factory, presenting a multi-agent architecture capable of building and shipping software for days on end.

I watched them with a strange mix of recognition and relief: the feeling of reading the design of something I had already built, and thinking "so I'm on the right track after all." Because I've spent the last few weeks writing a parallel-agent orchestration plugin —I call it parallel-work— and I built it by tripping over things, not by reading papers. And yet there they were, two people who don't know me at all, describing from their own trenches the same conclusions I had reached the long way around.

That's what this post is about: the four "engineerings" that are structuring how we work with AI —prompt, context, harness and loop engineering—, what those two talks say, and —at the end— a third speaker who talks not about architecture but about us: about the role left to the human when code becomes free. And why I believe that convergence is the most reliable signal that an idea is right — including one objection I'll raise against myself before you get the chance to.

The ladder: prompt → context → harness → loop

I owe the framework to Addy Osmani, who organizes work with models into four rungs, each one wrapping the previous:

  1. Prompt engineering. The model's native reasoning. You write the request well and trust what the model ships with. It's the rung we all started on, and the one the industry is already climbing out of.
  2. Context engineering. The agent fetches into its own window whatever it needs: tools, files, MCP results. The focus shifts from what you ask to what it sees while it works.
  3. Harness engineering. An external system manages context from the outside: it splits the requirement into a stable, structured task list, and survives the model's window instead of depending on it.
  4. Loop engineering. External scaffolding so the agent prompts itself and runs continuously, with the human out of the loop.
I'll also leave you a more visual, explanatory video on the topic: Loop Engineering Explained in 8 Minutes

The elegance of the model is that each rung doesn't replace the previous one — it wraps it. And if I had to pin my plugin to one point on that ladder, I'd say without hesitation that its center of gravity is the third: harness engineering. A wink I wasn't expecting: both speakers use that very word, each on their own —Sally-Ann calls her product "an AI harness"; Luke introduces himself as responsible for Factory's "core agent harness"—. When the vocabulary converges without anyone agreeing on it beforehand, it's usually because the concept was real. But to explain it properly, first the two talks.

Arize: "agents don't fail because of prompts, they fail because of context"

Sally-Ann Delucia's talk opens with an anecdote that's scary because it's so recognizable. At Arize they built an agent, Alyx, to analyze trace data from their own platform. The problem: every time Alyx ran, it generated more trace data, which bloated its context window, which made it hit the limit, which made it fail… and the failure's own trace added even more data to the next attempt. An agent drowning in its own data trail.

The line that stuck with me: "agents don't fail because of prompts, they fail because of context." It's the jump from rung 1 to rung 2 said in a single sentence.

The interesting part is what didn't work. The naive fix —truncating, keeping the beginning— produced amnesia: follow-up messages lost the thread. The "obvious" fix —asking an LLM to summarize— didn't work either: compression with no principle, no control over what got preserved. The two shortcuts we all think of first, ruled out with data.

What did work was a three-piece architecture:

  • Smart truncation: keep the head and tail of the conversation in the active context.
  • A retrievable memory store for the middle: it isn't thrown away, it's moved somewhere the agent can pull from when it needs to.
  • Sub-agents that take on the heavy operations (analyzing traces, searching) and return only the distilled result, keeping the main conversation light.

Her design principle sums it up perfectly: "context decides what the model sees, memory decides what survives." And the detail that surprised me: Delucia says Claude Code independently converged on the same truncation-and-compression strategy. She told it with a smile —when Anthropic published part of Claude Code's source, the Arize team read it "hoping to get a little bit of a secret from them," and found their own approach staring back—. It's not an Arize proprietary trick. It's a pattern that emerges when different people push against the same wall.

Factory: the multi-agent architecture that actually ships software

Luke Alvoeiro's talk goes one rung higher. His opening thesis is a good provocation: the bottleneck in software engineering is no longer model intelligence — it's human attention. We don't lack the capacity to generate code; we lack the capacity to supervise all the code being generated.

His answer is an architecture —they call it Missions— with three specialized roles:

  • Orchestrator: plans features and milestones and, crucially, writes the validation contract before a single line of code is written. It defines what "correct" means independently of how it will be implemented. It plays interlocutor, asks questions, closes requirements.
  • Worker: implements. And it does so with fresh context per feature —it inherits a "clean slate," without the accumulated baggage of previous tasks—, commits via Git and does a structured handoff.
  • Validator: verifies, and here's the refined part. There are actually two validators launched at the close of each milestone: one for scrutiny (a battery of tests, types, lints and a review agent per feature) and one for user testing that behaves like a human QA —it spins up the application and actually uses it: fills in forms, clicks buttons, checks that the flows work end to end—. Neither of them has seen the code before: validation is adversarial by design. And they often run on a different model provider, so that the same model that wrote the code isn't the one signing off on it.

A couple more decisions that strike me as the important ones. First, serial execution: a single worker or validator active at a time, because when you let agents run fully in parallel, "agents conflict, duplicate work, and make inconsistent architectural decisions." Second, model-agnostic design: minimal hardcoded logic —all the orchestration lives in about 700 lines of prompts and skills, not in a state machine—, so the system "improves with every model release rather than becoming obsolete." His way of putting it stuck with me: "missions ensure the discipline and the models provide the intelligence" —which is, word for word, how I think about my plugin: the machinery (hooks, skills, agents, commands and scripts) enforces the discipline, the model supplies the judgment—. The validation contract written before the code strikes me as the gem of the talk, because it inverts the usual vice: tests written after confirm the decisions you already made; they don't catch bugs.

The result they show: a Slack clone built in a sustained 16-day "mission," with 90% of the code covered by tests that, in the end, make up half the lines in the repository. And an honest data point from the talk itself: validation almost never passes on the first try —the system has to open corrective features over and over—, and the bulk of a mission's wall-clock time isn't spent generating code, but waiting for the user-testing validator to exercise the live application. That half the final code is tests, and that verification eats the clock, is not the system's toll: it is the system.

Where my plugin fits

And this is where I went back to my own notes with a mix of vertigo and relief. Because I wrote parallel-work without having seen either talk, tripping through real runs, and yet the correspondence is almost one to one.

parallel-work is a Claude Code plugin that encodes a coordinator-driven parallel-agent methodology: Intake → Design Lock → lanes in worktrees → a reviewer per PR → QA → architect audit → merge exactly once. Five roles.

Why a Claude Code plugin, and not a standalone system from scratch? Two reasons — one about design, one more prosaic. The design one fits everything above: Claude Code's harness is already very mature and very good —context management, tools, permissions, hooks, sub-agents—, so building my coordination layer on top of that harness, instead of reinventing the base, is the right engineering call. I bring the rung I care about —the multi-agent orchestration harness— and Claude Code supplies the ones underneath. The prosaic one: this way I leverage my own Claude Code subscription instead of standing up and paying for separate infrastructure. Less scaffolding to maintain, more time on the problem I actually want to solve.

And there's a sister question, the one I asked myself first: if Anthropic already offers Claude Code Teams —its own native multi-agent orchestration layer—, why build my own? Because I tried it before deciding. A while back I put Teams to work on a production NestJS service, with four Linear tickets that were the four layers of a single feature, and I wrote about it on the blog (in Spanish). The code came out solid, but the failures were the revealing part: the supervisor was too passive; the "team lead" approved plans on its own without escalating them to me, skipping protocols I had made explicit; and the agents worked in parallel even though the dependencies were sequential. Three cracks that, funnily enough, are exactly the three things parallel-work turns into hard invariants: the human pinned to the Design Lock and to the merge gate —the latter enforced by a hook, not by the model's good will—, the waves that order in time whatever depends on something else, and independent verification gates that don't rely on anyone remembering to look. It's not that Teams is bad —it's a solid foundation—; it's that I get out of the box what Teams gives me plus, on top, exactly the pieces its own trial showed me were missing. In the time I've been running the plugin it behaves much better for the way I work —with the usual caveat: it's my first-hand experience, not a benchmark, but it's precisely the experience that made me choose—.

If I put my vocabulary side by side with Factory's and Arize's, this is what comes out:

Industry concept parallel-work equivalent
Orchestrator (Factory) Coordinator — the persistent session, with the human
Worker with fresh context per task Builder in its own worktree — my central thesis
Validator that has never seen the code (creator ≠ verifier) Reviewer / QA / Architect — fresh context; reviewer and architect additionally read-only
Validation contract before the code Design Lock (glossary + ADRs before building)
Structured handoffs The handoff skill writing its HANDOFF.md
Context manager that survives the window STATE.md — always re-read, survives compaction
Sub-agents returning distilled results, not raw data Reviewer and architect return verdicts, not work
Human on the goal, agent on the execution The merge gate — the human-shaped hole
Model-agnostic scaffolding The discipline lives in prompts and skills, not a state machine — improves with every model
Two confessions about that table, so you don't buy it wholesale. First: the Factory piece I don't have yet is validator model diversity —having the verifier run on a different provider than the one that wrote the code—. My independence is built with a different mechanism: fresh context (the reviewer never watched the builder reason, so it can't rationalize its decisions) plus read-only enforced in the agent's definition. I stand by that mechanism, but it's not the same axis, and adding model diversity is in my backlog, not in my code. Second: "model-agnostic" does not mean executor-agnostic. The plugin is deliberately coupled to Claude Code, because its enforcement layer —the hooks that make it physically impossible for a builder to merge— is precisely the part that wouldn't port cleanly to another platform, and it's also the differentiating asset. The discipline survives every model release; it doesn't pretend to survive a change of executor, and that's a decision, not an oversight.

Osmani's definition of "harness" —"an external system that manages context from outside, dividing the requirement into a stable, structured task list"— is, literally, my STATE.md plus the coordinator. It survives compaction, splits the epic into lanes and waves, and gives every role fresh context instead of a self-summarized context that leaks. Arize's answer to the context problem is retrievable memory; my answer to the same problem is to never let the context get dirty in the first place —every role starts clean—. Different paths, same mountain.

There's another coincidence I especially liked. Luke lists five multi-agent communication patterns, and Missions uses four: it deliberately discards direct communication between agents, because without a coordinator the state fragments and the single source of truth disappears. In parallel-work the builders never talk to each other either: everything goes through the coordinator and through STATE.md, which is the single source of truth. Two systems landing on the same rule without knowing each other —agents don't coordinate peer-to-peer, they coordinate against a central state— is exactly the kind of coincidence that made me write this post.

The honest divergence: serial vs parallel

Not everything fits, and the point where it doesn't is the most interesting one to tell. Factory serializes features to keep agents from colliding. I do exactly the opposite: I parallelize the lanes. It's the word that gives the plugin its name.

A contradiction? Not if you look at how the conflict is resolved in each case. Factory avoids the collision by executing one at a time. I avoid the same collision with worktree isolation (each builder works in a separate git tree), a shared integration branch every PR targets, and a single merge once the epic is whole. Same problem —agents stepping on each other, inconsistent architectural decisions—, two valid solutions: they solve it in time (serial), I solve it in space (worktrees). That two designs arrive at different answers to the same risk doesn't weaken either one; it delineates when to choose each.

And here is where anyone who has suffered through concurrency raises an eyebrow, rightly: the worktree only solves the physical clash —two agents editing the same file—. What about the logical one, when lane A changes a method signature or a schema that lane B depends on? The worktree doesn't touch that one; it's governed by three other layers:

  • The Design Lock pins the shared contracts before a single lane opens: the glossary and the ADRs close off shared signatures, schemas and architectural decisions. Builders don't invent divergent interfaces; they start from the ones already sealed.
  • The waves order dependencies in time. The coordinator only parallelizes deliberately independent lanes; whatever touches a shared surface goes in an earlier wave, so the dependents already inherit the change. The parallelism is within the wave, not indiscriminate.
  • QA and the architect's audit at the seams catch whatever drift slipped through anyway: the architect reads the converged whole —not each lane separately— looking precisely for cross-lane inconsistency; QA tests the joints. And all of that happens before the single merge.

What if the contract itself turns out to be unworkable mid-execution —lane A discovers that the agreed signature doesn't hold? That's where isolation doesn't mean losing the ability to speak up. Every role still runs inside interactive Claude Code sessions, so a builder that sees the contract collide with reality doesn't keep building on something broken: it raises an alert, and the user —or even the coordinator, which also has the ability to look at the builders' state— can decide whether to pause the wave and go back to the design table with the human, to update the Design Lock and STATE.md before resuming or redirecting the builders. The plugin automates and parallelizes everything it can, but it puts the human in the loop exactly when reality breaks the plan. A Design Lock that couldn't be renegotiated would be dogma; this one gets renegotiated when it has to.

In one sentence: Factory avoids the logical conflict by never giving it the chance —one agent at a time—; I avoid it by bounding the shared surface up front and auditing it at convergence. Without those three layers, parallelizing would be reckless; with them, the worktree becomes the most visible of the defenses, not the only one.

The line I don't cross

The fourth rung, loop engineering, is where I choose to stop on purpose. The move that defines loop engineering is the agent prompting itself in a closed loop, with no human. My plugin has the machinery for that —a watch loop in which the coordinator re-prompts itself to detect finished lanes— but it keeps the human pinned to two anchors:

  1. Triggering the epic and the Design Lock decisions.
  2. The merge gate. Only the coordinator can merge, and since a recent version not even the coordinator can do it while the watch loop is active: a marker file the loop drops blocks merging until the loop ends. Merging went back to being a deliberate act, not something the loop does on its own.

Osmani breaks that loop rung down into six components. Doing the tally against the plugin is the part that surprised me most when watching the videos, because it comes out at five and a half out of six:

Loop component (Osmani) In parallel-work Match?
Worktree Self-provisioned lanes under .worktrees/, in parallel, never contaminating the main tree ✅ Full
Sub-agents Reviewer, architect and QA: agents that verify and audit before anything is called done ✅ Full — and it's the thesis of the plugin
State STATE.md / HANDOFF.md / DEBT.md, per-epic source of truth, survives compaction ✅ Full
Skills The plugin ships as modular skills (coordinator, builder, qa, guide, harness, backlog, steward) ✅ Full
Plugins & Connectors It is a Claude Code plugin; it connects herdr, gh, trackers and the GitNexus MCP ✅ Full
Automation The /loop is a watch heartbeat, not a cron writing code alone and unsupervised ⚠️ Partial — on purpose

And here's the beautiful part: the only component I leave half-done —Automation— is exactly the one that would be needed to close the loop entirely, the one that would hand the irreversible step to the machine. It's not a box I forgot to tick; it's the same line as before, seen from another angle. I have the whole ladder assembled except the last rung, and that gap is person-shaped on purpose.

This connects with the part of Alvoeiro's talk that resonates with me most: if the bottleneck is human attention, the right design isn't to remove the human — it's to place them where their attention yields the most —on the goal and on the irreversible step— and remove them from everything else. My bet is that the value is in the scaffolding —parallel isolation, independent verification, durable state—, not in taking the human out of the last step. It's loop-engineering machinery with a person-shaped hole in exactly the right place.

And so this doesn't stay a pose: the plugin carries an evidence instrument that measures precisely this. In the first epic it ran on itself, the independent gates —reviewer, QA, architect— produced 18 findings: none critical —15 low and 3 medium—, but 17 of them would have shipped to production without those gates, and one of the mediums was against the coordinator itself — exactly the kind of failure a monolithic system cannot see in itself. With the honest caveat that this number is n=1, on a shell-and-documentation repo —the real stress test, unleashing the five roles on a decoupled, strictly-typed backend, is still to come—. Since that first epic the plugin has already driven several more, real ones, which have been hardening it into today's version: it's not a weekend experiment. But I'm not going to sell you that it competes in maturity with Arize or Factory — far more consolidated, far better-backed products than mine. And maybe that's the most revealing part: arriving at their same shape in barely a few weeks, working side by side with very capable models (Opus 4.8 and Fable 5), says less about my merit than about how hard the convergence pushes.

Why the convergence matters to me

I could tell all of this as "look, I'd already done it." But that's not the interesting part. The interesting part is something else: how can you come to know a design decision is right when you make it alone, with nobody pushing back?

When you build something alone, your greatest fear is being in love with an idea that only works inside your head. Convergent evolution is the antidote: when people who don't know each other, working on different problems, with different incentives, land on the same shape —fresh context per unit of work, verification by an independent agent, an external state manager that survives the context window, and a human guarding the irreversible step— that stops being an opinion and starts looking like a constraint of the problem.

Now, the objection I promised to raise against myself before you do: what if the convergence isn't about the problem, but about the substrate? I built on top of Claude Code, whose primitives —sub-agents, compaction, worktrees, skills— already channel you toward this shape; Arize says they read Claude Code's source; and these talks circulate on the same conference circuit. Maybe it's not that we were all pushing against the same wall, but that we were all walking down the same corridor. It's a serious rebuttal, and it lowers the degree of independence I can honestly claim: from "three separate paths" to "three paths sharing a landscape." But it only moves the question up one level — it doesn't dissolve it: someone designed that corridor, and got there on their own — Delucia herself tells how Arize and Anthropic converged on the same context strategy without copying each other, each against their own wall. That the substrate channels you toward a shape is also evidence that the shape is a real constraint; it's just that the evidence is worth somewhat less than it appears at first glance, and I'd rather discount it myself than have you discount it for me.

None of the three of us has to be right. But that all three of us point at the same place, along paths that are at least partly separate, is the best clue I have that the place exists.

finally { }: and still, someone has to read the code

And here comes the third speaker I promised, the one who isn't about architecture but about us. Alex Volkov describes the debate running through the profession: at one end, "code is free… not a thing to get hung up on anymore"; at the other, "slow down… read every line." His twist is that the question is badly framed: it's not about the people, it's about the tasks. The same engineer reads every line of the payments code and waves through the non-critical stuff without looking. You route each change to the scrutiny it needs.

What made me smile is that his "routing table" includes, without knowing it, two rules I had already turned into code. One: separate. Don't let the same agent write, inspect, and grade itself —"it's like if I came up with an exam and then I took the exam and I scored myself on it"—. That is, exactly, the reason my reviewer and my architect start with fresh context and read-only. And two: build a system that builds the system; reading spends your attention once, but designing makes the system remember it. That's the entire plugin: the machinery that enforces the rules and executes the method so I don't have to police everything by hand.

The other two videos validated my architecture; this one validates my decision to leave a person-shaped hole. Because, as he says, "loops don't remove judgment, but they do raise the stakes on where you put it" — and that's why I leave that hole where I leave it: not on every line —that no longer scales—, but on the goal and on the merge, the one place where my judgment still earns its keep. Not every line of 2026 needs your eyes; every system still needs your judgment.

And with that I throw down the gauntlet, because these are debatable decisions and I want you to debate them. Parallelizing instead of serializing; forbidding agents from talking to each other and forcing them to coordinate against a central state; putting the human-shaped hole exactly at the merge and nowhere else. The plugin is still private —I can't show you the code, but I can show you the design, which is precisely what I've dissected here—, so what I'm offering is the conversation: where do you draw the line? How do you avoid logical collisions when several agents work at once? Have you already hit the context wall, and how did you get out? Tell me in the comments. This is a field we're all sketching out together, and I'd rather you push back than nod and close the tab.


Talks cited:

  • Sally-Ann Delucia — How we solved Context Management in Agents
  • Luke Alvoeiro — The Multi-Agent Architecture That Actually Ships
  • Alex Volkov — should we still be reading code in 2026? (the ZL continuum, AI Engineer)
  • The four-engineerings framework: Addy Osmani's writing on loop engineering
You've successfully subscribed to The Dave Stack
Great! Next, complete checkout for full access to The Dave Stack
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info is updated.
Billing info update failed.