The reflex that fixes the wrong layer
An agent system misbehaves and almost everyone reaches for the same tool first: the prompt. Reword the instruction, add an example, pin down the output format, run it again. Sometimes that works. When it doesn't, the failure returns in the same shape, which means the wording was never the problem.
Three practices have grown up around the problem, used as if they were three labels for one job.
Prompt engineering is the wording of what you ask.
Context engineering is what the model actually sees at runtime: what gets retrieved, what gets injected before it reads anything, what gets compressed, what is deliberately kept out.
Harness engineering is the practice of shaping the scaffold around all of it: which agent runs, which files it may read, which artifact it has to produce, which gate checks the result, and what happens when that gate fails.
The ladder is worth drawing as a teaching device. It is not a true picture, and the last part of this piece is the case that showed me where it stops being true. Start with the boundaries: what each rung can fix, and what it provably cannot.
Prompt engineering fixes wording, not architecture
Prompt engineering earns its reputation on a narrow class of failure. The model already has everything it needs and still returns the wrong shape of answer: an ambiguous instruction, a missing format spec, a task framed loosely enough that the model guesses. Reword it and it lands. That is a real fix, and there is no shame in reaching for it first.
Some of those fixes even last. Look at why: a prompt change survives into next month because somebody wrote it into a persona file or a checklist the next run reads. What makes it durable is a file.
What the wording cannot do is produce a fact that was never in front of the model. And it cannot touch an architecture problem, which is the failure The harness is the product opens with.
The setup there is one person and three chat sessions. One session drafts a spec. He pastes it into a second, which argues architecture. He pastes the plan into a third, and code appears. Then he diffs it by hand and finds three contradictions the model had forgotten since page one, and starts over.
Read that as a wording problem and the repairs write themselves: a better handoff template, an instruction to re-read the spec first. None of them touch it, and the essay is exact about why: the harness in that setup was the person, tired, holding the whole context in his head, deciding which answer counted. "Nothing on disk was authoritative. Nothing outside my own attention enforced the workflow."
A better-worded handoff still gets relayed by someone who has to remember what the last one said. The fix was to make something other than a person authoritative, and that is not a sentence you can write into a prompt.
Context engineering: two designs, opposite advice
Move up a rung and the failures change character. Context engineering fixes recall: "it forgot," or the more dangerous version, a confidently wrong answer produced because the fact the model needed had scrolled out of range.
It has hard edges of its own. Perfect context plus an ambiguous instruction still gets a wrong-shaped answer, and the right facts in the window guarantee nothing about whether anyone checks the output before it ships.
The awkward part is that inside this one rung, two serious designs give opposite advice.
Boot-time injection: stop trusting retrieval
Memory is easy. Retrieval is hard. is a production report from Rheo, an assistant running headless on a server. A user would send a message, follow up ten minutes later with "Can you continue from where we left off?", and get back "I don't have context for what you shared."
The tools were all there: a conversation ledger, chat_recent, chat_search, a memory API. The model just didn't call them. The diagnosis is one sentence: "The model doesn't notice what's missing." A prompt with no recent history looks almost identical to a brand-new conversation, so the model treats it like one. It answers. It doesn't go hunting. The team had been treating "the tool exists" as "the tool gets used."
So they stopped trusting retrieval and switched to boot-time injection: every request now builds the prompt from open tickets, episodic digests, durable memory and the recent session turns before Claude ever sees the user's message. The bill is stated plainly, a few hundred milliseconds and roughly 1,000 to 2,000 tokens per turn.
Tool-driven retrieval: hand over the tools and wait
Give the model the tools, not the context argues the other way, and the naive move it defines itself against is front-loading the window with recent turns.
Its case is concrete. Persist the turns, inject the last N on every prompt, and you hit two walls. Tokens, because most of what you inject has nothing to do with the question on the table. Then coherence: past roughly twenty turns the signal-to-noise ratio drops and the model starts losing the thread. That is context stuffing, a payload sized by how long the conversation happened to run.
Its fix is to change the question. Asking how much recent context to inject assumes the harness must guess what the model will need before the model has read anything. Ask instead who decides what to retrieve: the model does, after it has seen the request.
Both correct, and I am not going to resolve it
Two designs, same layer, opposite prescriptions, each right about the failure it was built against. Boot-time injection wins where the model provably will not call the tool. Tool-driven retrieval wins where front-loading is bloating the window with material nobody asked for.
That is a clean partition only if you can tell which regime you are in. The push case announces itself as a tool that exists and doesn't get called: Rheo's symptom was a follow-up answered confidently with chat_recent sitting right there, unused. The pull case shows from the other side, in how much of what you inject the answer never touches. Both are countable in your own logs. A tool going uncalled on turns that need it does not get fixed by better wording, and a window full of turns nobody asked about does not get fixed by injecting more.
It would be tidy to declare one of them the best practice. What happened next makes that harder. Semantic search landed over the same SQLite file in July 2026 and did not flip the production choice: memory_context, the bundle assembled at session start, stayed keyword-only in v1. Better retrieval arrived and the injection still fired.
Notice who both sides say is making the call. The tool-driven piece lands on a four-word summary of its architecture: "The harness stopped guessing." That deserves unpacking, because "we stopped guessing" is also what people say after rewriting a prompt. Nothing was reworded there. The harness stopped injecting the last N turns and started exposing retrieval as tools the model calls once it has read the request: a payload fixed before the question was known, replaced by a decision taken after. Push or pull, that decision belongs to the same place.
Harness engineering: where enforcement finally lives
That place is the rung above, and it reaches a class of problem the two below it cannot. Routing first: which agent or tier handles which job. That is the orchestrator's work; in the Bureau it writes no specs and no code, it triages and spawns specialists into fresh contexts. A cold reviewer is only cold if it never watched the plan get argued into shape.
Then enforcement, which is the part with teeth. Gate the flow, not the judgment builds a gatekeeper that emits exactly three outcomes, proceed, revise or escalate, each bound to the hash of the artifact it judged. Nobody ships version two on version one's approval.
The isolation there is not a prompt instruction. The gatekeeper is spawned headless and reads only a staged per-checkpoint directory: the artifact, a bounded slice of the log, the state file, the conventions doc, its own persona file. The full run history is physically outside its read scope. Nobody copied it in. "The wall is made of what is on disk, not what the prompt asks for."
That is the strongest thing here, and it is a property rather than a story. Choosing what goes in the window is a context decision. Making a role structurally unable to reach the rest of the record is not; there is no prompt you can write that gets you a file that was never staged. You do not have to take my word for it: read the staging code, the file is in the directory or it isn't.
The harness has its own hard limit, and the gate essay states it rather than hiding it: "A gate is exactly as sharp as the list behind it, and that list needs tending." A well-built harness enforces a bad checklist perfectly, and its routing and gating work just as flawlessly whether the prompt is badly phrased or the context is wrong, shipping the bad answer faster with better paperwork. A bad routing rule is the one to fear, because it is the quietest: a bad prompt produces a visibly wrong answer, while a bad route produces a confident, well-documented approval from a reviewer who could not have known better.
Where the ladder bends
Here is the case that made me stop drawing three boxes at even weight. It is the same delegate, earlier, when it was still a design document.
Before building it, its author stress-tested the design against five general-purpose models: Claude, Grok, ChatGPT, DeepSeek, Mistral. The feedback was genuinely useful. One caught fused responsibilities, one sharpened the audit trail, one pushed to separate two concerns. By the fifth review the returns had collapsed into agreement, and the agreement felt earned.
It was also wrong, and one measurement is what showed it. The run had 52M input tokens. 50.2M were cached, roughly 96%. The claim all five had been improving was that the cost came from the growing orchestrator transcript. The cache figure ends that argument: the transcript was never the sink. Codex, running in the actual repository with the relay telemetry in front of it, found it elsewhere, in 126 terminal round-trips, redraw noise, the same artifacts re-verified over and over, and one resumed session that spun for eight minutes producing nothing. It also falsified two design claims that had been treated as facts, by reading the rules and tracing the workflows.
Notice what the five already had. Each read the design cold, none had sat through it being argued into shape, and that is exactly the isolation a fresh reviewer buys you. It was not enough. They could judge whether the design was plausible. Truth needed seeing the system itself, and none of them could. The reasoners weren't worse; they were routed with the wrong context, and who gets assigned to a review is a harness-level decision.
The obvious objection is that this dresses up a plumbing detail: the variable was data access. One reviewer could read the repository and five could not; no policy was involved. That is the point. At the harness layer they are one decision: declaring a role and declaring what it may read happen in the same file. The gatekeeper is the clean version: its isolation is not a rule it obeys, it is a directory somebody staged. The rule the framework took from the episode doesn't mention prompts either: "Route to ground truth, not to a vote."
The site's glossary states the general version, and files it under context engineering rather than under the harness: deciding what the model sees is one of the concerns a harness has to handle, alongside routing, permissions, and gates, not a peer layer standing beside it. So the ladder stops being true at the top: harness engineering shapes an outer scaffold that owns context flow as one of its own decisions, and prompt engineering is the narrowest lever in the set, operating on whatever context and framing the harness already handed over.
One case is one case (I know how that sounds), and I am not claiming a single design review settles a hierarchy. The load-bearing argument is the staged directory, which holds with no story attached to it. What would change my mind is a review where everyone had equal access to ground truth and the wording of the request is what separated the true answer from the plausible one. I haven't seen that one.
Diagnose the layer, not just the symptom
The practical version is one question, asked before you rewrite anything: what would have to be different for this failure to be impossible?
If the answer is clearer wording, rewrite the prompt. If it is a fact that was never in the window, you have a context problem, and then you get to argue about push versus pull. If the answer is that someone would have to remember to re-apply the fix next run, or that the reviewer could not have caught it from where it was sitting, no prompt and no retrieval strategy holds that. It is wiring.
Be careful with the middle case: "is this a context problem or a harness problem" is usually a false choice. The harness is what decided the context. What separated five capable models from the one reviewer who got it right was not how any of them were asked. It was who had been handed the repo.