Anthony Dominguez

Four terms have arrived in AI engineering in the last year, and three of them arrived in the last six months. Prompt engineering. Context engineering. Harness engineering. Loop engineering. Loop engineering is the newest, coined by Addy Osmani at Google on June 7, 2026, days after a widely shared comment from Boris Cherny, who built Claude Code.
Every explanation of these terms is written about coding agents. That is where the money and the attention are, and it is also where the ideas are easiest to demonstrate, for a reason that turns out to matter enormously in real estate.
Nobody has written what any of this means when the input is not a codebase but an offering memorandum, a rent roll and a trailing twelve. That is the gap this is meant to fill, because the architecture that works for a coding agent does not transfer cleanly, and the place it breaks is the most important design decision you will make.
These are not synonyms or competing schools of thought. Each one exists because the layer below it ran out of room. The fastest way to see the difference is to take one ordinary question and make it bigger.
| Layer | What you ask | What has to happen |
|---|---|---|
| Prompt | Find the lease expiration date in this lease | One call. Everything it needs is already in front of it |
| Context | Find every lease expiration date in my portfolio | The agent has to go get the leases before it can answer |
| Harness | Read all four hundred leases in the data room and build the expiration schedule |
Too big for one sitting. Needs chunking, state and retries |
| Loop | You gave it a goal of portfolio optimization | The system decides the work and writes itsown prompts. On its own it decides it needs a rollover schedule |
If you want the business version of this same progression rather than the engineering one, we wrote that separately as the five levels of AI in commercial real estate.
Prompt engineering. Find the lease expiration date in this lease. You paste the lease, you ask, you get a date. One model call, nothing outside it, and the quality of the answer depends almost entirely on how you asked. That is prompt engineering, and for a single document it is often all you need.
Context engineering. Now find every lease expiration date in my portfolio. Nothing changed about the question and everything changed about the work, because the agent has to go get the leases first. It queries your system, opens files, hits an API or an MCP server. Context engineering is deciding what fills the model’s window and letting the model fill it itself. By early 2026 this had largely absorbed what people called prompt engineering, because on any real task the harder question is what goes in the window rather than how you word the request.
If you are already using a modern AI chat with tool access and connectors, a lot of this is happening without you building anything, which is why this layer often feels like it came free. You cross into the next one the moment the job stops fitting in a single sitting.
Harness engineering. Now read all four hundred leases in the data room and build me the expiration schedule. This one breaks. Four hundred leases do not fit in a context window, and letting the model summarize as it goes leaks, so details that mattered quietly degrade. What you need is something outside the model that splits the work, tracks which leases are done, retries the three that failed, and holds the running answer. That is the harness, and it is everything that is not the model. Tool execution, parsing what comes back, retrying on failure, routing work to sub agents, and holding state. Martin Fowler’s write up is the clearest general treatment.
A harness also draws the bounds of the job, and in real estate that is the part with teeth. The harness is what says this agent may read the rent roll and write to the deal record, and may not email the broker, may not alter the underwriting model, and may not touch any deal other than the one in front of it. Those limits are not a safety afterthought bolted on at the end. They are most of the design.
You will not write most of the machinery yourself. Retries, sub agent routing, permission systems and state all ship inside the agent frameworks now, and configuring one is a different job from building one. What does not come in the box is the part that is actually yours. Which bounds apply to your deals, which checks have to pass before anything moves, and what the system is allowed to remember.
The same failure happens on a single document once it gets ugly enough. Normalize a four hundred row rent roll where the header block repeats every page, thirty of the rows are duplicates of units already listed, and the status column uses a vocabulary this particular property management system invented. No amount of prompt wording fixes that, because the failure is not comprehension. The failure is that the work does not fit in one sitting.
Loop engineering. Nobody asks the AI chat anything. You give it one standing goal, optimize the portfolio, which is too vague for anyone to answer in a single request. It runs Monday morning, checks which leases roll in the next ninety days, pulls comps for those units, and flags where you are under market. Every example above started with a person typing. A loop is the scaffolding that lets the system decide the work and write its own prompts toward a goal you set once. In acquisitions the same shape reads as watch the inbox for new offering memoranda, screen each one against the buy box, and have three deals worth opening on my desk Monday morning.
Osmani’s version has six components: automation, worktrees, skills, plugins and connectors, sub agents, and state. Worth knowing that plenty of serious people think loop engineering is a buzzword that mostly encourages burning tokens, and there is not much of it working in production yet. There is now an academic study of harness engineering in agentic coding tools if you want the research view. The skepticism is fair and the layer is still real.
These four layers show up anywhere the work starts with documents, which is most of this industry. The rest of this uses acquisitions, because that is where the documents are worst and the deadline is real.
This is the question everyone asks second, and the answer is that a harness has a boundary, and choosing the boundary is the design decision.
A rent roll normalizer with retries, validation and state is a harness. An underwriting orchestrator that calls that rent roll normalizer as one of its tools is also a harness. Both are legitimate and they nest.
What tells you which one you are looking at is the exit condition. If the thing stops when a single document has been extracted and verified, that is a document harness. If it stops when a deal has been screened, the document harness was a tool inside it.
Here is the shape, using the most common real job in acquisitions. An offering memorandum, a rent roll and a trailing twelve on a 312 unit garden style deal arrive by email, and you want it screened by morning.
The orchestrator owns the goal and owns memory. Memory is what makes the second cycle better than the first.
A rent roll agent turns the export into normalized rows. Units, leases, rents, charges, dates, status.
A financials agent maps the trailing twelve to your chart of accounts.
A market research agent gathers comps and submarket context, which is a context engineering problem rather than a harness problem, since it is mostly retrieval.
A validator agent checks the work of the other three. In real estate it is the most important agent in the fleet, and it does not appear in any coding architecture diagram.
The orchestrator reads the validator’s report, decides whether the deal is screened or whether something needs another pass, writes what it learned to memory, and either delivers or iterates.

Memory is not one thing, and the three kinds behave differently enough that confusing them is how systems get slow and expensive.
Procedural memory is how your firm works. Your underwriting standards, your buy box, how you treat a charge code, which format the quarterly LP report has to land in. This is usually plain text or files, which is why the industry started calling them skills. It changes rarely and it is the cheapest thing to get right.
Semantic memory is durable facts. Your portfolio, your conventions, your chart of accounts, and the answers to questions that have already been settled. This is where an escalation goes to live. When a person tells the system that a particular status value on a particular property management system means empty with a signed lease, that answer belongs here, and the next run reads it instead of asking again.
Episodic memory is what happened. A time ordered record of past runs and past deals. Which deals you screened, what the validator flagged, what you passed on and why.
The retrieval patterns differ. Semantic memory is fetched by meaning, which is what retrieval augmented generation is for. Episodic memory is mostly a query, give me the last twenty deals in this submarket, and only needs semantic search when the question is fuzzy, such as which deals did we pass on for reasons that turned out to be wrong.
One honest note on scale. General agent architecture spends a lot of time on consolidating episodic memory into semantic facts before it grows unbounded, because a consumer support desk handles millions of conversations. A firm screening three hundred deals a year does not have that problem for a long time. Build the three stores, and do not build the compaction machinery until volume actually demands it.
The rent roll agent and the financials agent share no inputs, so they run concurrently. The market research agent depends on neither and can start immediately. The validator depends on all three and cannot start until they finish, which makes it the natural synchronization point and the natural place to spend money on a stronger model.
That ordering is not a performance detail. On a 312 unit deal the rent roll agent is the long pole and the market research agent is done in seconds, so sequencing them badly means you pay for that agent to sit idle on every deal you screen. Fan out is the main reason an agent fleet beats one long conversation, and a badly ordered pipeline gives most of that back.
Here is why the coding architecture does not transfer.
A coding agent gets its verification for free. The compiler either accepts the program or it does not, and the test suite either passes or it fails. That is an oracle, an external judge that answers correct or incorrect with no human involved, and it is the only reason autonomous coding loops work at all. The loop can run unattended because something other than the model decides when it is done.
Underwriting has no compiler. Nothing tells you that a 312 unit rent roll came back right. The ground truth is not in a test file, it is buried inside the document you are trying to read, which means the entire architecture problem is manufacturing an oracle out of the document itself.
That is what the validator agent is for, and the checks are deterministic rather than model driven. A model should not be grading a model here. Here is an example for a residential rent roll loop:
None of these require knowing the correct answer in advance. They are invariants, and that is what makes them usable as an exit condition. The loop stops when the invariants hold and escalates when they do not.
In a domain without a compiler, you have to build the compiler, and in real estate the compiler is a set of arithmetic identities the document has to satisfy against itself.
The validator should emit something structured that the orchestrator can act on without reading prose. The useful minimum is what was checked, what the document claimed, what you produced, the size of the gap, and what should happen next.
check: unit_count_vs_source_summary
expected: 312 (stated on source summary)
actual: 319 (distinct unit identifiers extracted)
delta: 7
severity: blocking
action: escalate
check: charges_cross_check
expected: sum of line items
actual: matches on 317 of 319 units
delta: 2 units
severity: warn
action: retry_extraction
check: status_vocabulary
expected: all values within known set
actual: 4 values unrecognized
delta: 4
severity: blocking
action: escalate_with_samples
Three severities are enough. Pass means move on. Warn means the run continues and the gap is reported alongside the output. Blocking means the loop cannot call itself finished.
This is the actual hard problem. A loop is only as good as its failure policy, because an agent that retries forever burns money and an agent that halts on everything is just a slower human.
Three failure classes, three different responses.
Mechanical failures retry. The parse drifted, a column landed in the wrong place, a page was skipped. The input has not changed and the work is deterministic, so run it again. Cap the retries at two. A third identical failure is not mechanical, it is structural, and retrying is throwing money at a bug.
Ambiguous failures escalate. An unrecognized status value, a charge code nobody has mapped, two rows for one unit where the correct treatment depends on which system produced the file. The agent cannot resolve these and should not try. Escalation means surfacing the specific rows with enough context for a person to answer in under a minute, and then writing that answer to semantic memory so the next run does not ask again. That last part is what turns escalation from a tax into an asset.
Structural failures halt. The document contradicts itself. Its own printed unit count does not match its own rows. When the source is internally inconsistent there is no correct extraction and no amount of iteration produces one. Stop, report, and hand the whole thing to a person.
None of these decisions belong to the agent that did the work. The agent reports, the validator classifies, and the orchestrator decides. Keeping those three roles separate is what stops a fleet from talking itself into a wrong answer.
There are two kinds of loop and the distinction matters more here than it does in software.
An open loop is given a broad goal and allowed to decide what to do about it. It discovers work you would not have thought of, and it burns tokens in every direction, including directions you did not want.
A closed loop starts from a bounded goal with an explicit evaluation at each step. You know roughly what the path looks like before it runs.
Screening a deal should always be a closed loop. The goal is bounded, the evaluation is the validator, and an open loop turned loose on a live pipeline produces confident output nobody checked. In software a wrong turn shows up as a failing test. In underwriting it shows up as a number in a memo.
A loop needs a guardrail that ends it, and the guardrail worth arguing about is not technical. Decide at planning time whether this loop screens and reports, or screens and acts.
Those are different products. Screen and report means the system hands you three deals and a list of what it could not resolve. Screen and act means it registers the deal, assigns it, and emails the broker. Both are reasonable. Discovering which one you built after it emailed the broker is not.
The second guardrail is about silence. A loop must be able to tell you it is stuck. An agent sitting quietly for forty minutes waiting on an approval nobody knew it wanted has failed just as completely as one that produced a wrong number, and it fails in a way you will not notice until you go looking.
Validators tell you whether one deal was screened correctly. Nothing so far tells you whether the system did better across the two hundred deals you screened last quarter than it did the quarter before, and without that you are tuning prompts on vibes.
The fix is to record every run as a tree of events. What was asked, which documents were pulled, which tools were called and how many times, which checks failed, how long it took, how many tokens it burned. Software calls this tracing and has tools for it, Langfuse and LangSmith among them, but the principle is older than any of that. A run you did not record is a run you cannot learn from.
Then ask two separate questions of that record. Was it correct, and was it healthy. Correctness you already have, because the validators answer it deterministically. Health is turnaround time, cost per deal, and above all escalation rate.
Escalation rate is the number to watch in real estate, and it should be sliced by source system rather than reported as one figure. Four percent of files escalating sounds tolerable until you notice every one of them came out of the same property management system. That is not an agent problem and no prompt change will fix it. That is a mapping gap, and it tells you exactly where the next day of work goes.
Then ship the fix and watch the same numbers. Sometimes that is a prompt revision or a model swap. More often, and more valuably, it is a new validator, because every check you add is permanent and every check you add makes the next rent roll safer. The validators are the part that compounds.
One caution. It is fashionable to use a model as a judge to score agent output, and for anything numeric that is a mistake here. You have arithmetic truth available. Do not replace a fact with an opinion. Save the judges for the genuinely subjective things, like whether the memo reads the way your investment committee expects.
Anything that requires judgment about what a number should be, rather than whether a number ties.
Some property management systems export status codes as single letters with no legend, and no honest reader can tell you what they mean. Market rent in a market with no comparable sales is a triangulation problem that experienced people disagree about. Whether a given expense is a capital item or an operating one is frequently a real argument rather than a lookup.
An agent should surface all three and route them to a person. A harness that tries to resolve them is not automating judgment, it is hiding it.
The harness is the durable part. Models are becoming interchangeable reasoning engines, good ones arrive every few months, and swapping one for another should not require rebuilding the system around it. What does not get commoditized is the orchestration, the domain validators, and the accumulated state.
In real estate that lands differently than it does in software, because the validators are not generic. They are arithmetic identities specific to how these documents work, and the firms that write them down are going to be able to keep changing models underneath while everyone else rebuilds their prompts every time something ships.
There is a catch. Everything above is buildable, and none of it is free to keep running. Harnesses need maintenance every time a property management system changes an export, a model deprecates, or someone finds a status value nobody had seen. If that is the work you want to own, own it. If it is not, that is the argument we made in build versus buy, and it is worth a conversation with us before you staff it.
