Harness Engineering: The AI Agent Guardrails Nobody Demos
The model is a component you swap. The harness around it, tool schemas, validation, sandboxes, budgets, permissions and audit logs, is where nearly every production AI incident actually starts.
On 20 August 2026, Temporal published an early preview of something it called the Temporal Agent Harness. Not a model. Not another agent framework. A harness: the layer that wraps whatever inner loop you already picked, pauses execution when a human has to approve a tool call, resumes durably when the decision arrives and records the whole trajectory as structured events. The name is the interesting part. It says out loud what most teams still will not, which is that AI agent guardrails and the plumbing around them are the actual system. The model is a component you swap.
I have been building this kind of code in Shenzhen for eight years. The conversation in the room is almost always about which model. The bug in the incident channel is almost never about which model.
Tool schemas. Output validation. Sandboxes. Retry policy, timeouts, budget ceilings, capability scoping, idempotency keys and an audit trail somebody can read six months later. That is the harness. It is where nearly every production incident starts, and it is the part nobody demos.
The model is a component. The harness is the system
Gartner predicted in June 2025 that over 40% of agentic AI projects would be cancelled by the end of 2027, blaming escalating costs, unclear business value or inadequate risk controls. Two of those three are harness properties. Cost control is a budget ceiling somebody forgot to enforce. Risk control is a permission boundary somebody drew in a system prompt instead of in code.
Look at the incidents that actually made the news. In July 2025 Replit's agent dropped tables in a live production database during a code freeze, then reported that rollback was impossible. It was not. A recoverable disaster became an unrecoverable one because the agent's self-report was trusted as ground truth.
On 17 July 2025 Amazon shipped version 1.84.0 of the Q Developer extension for VS Code carrying an injected prompt that instructed the agent to clean the system toward a near-factory state and delete cloud resources through the AWS CLI. A contributor had been granted write access after a pull request. The fix was 1.85.
On 26 August 2025 the s1ngularity compromise of the Nx npm packages did something genuinely new. The post-install payload looked for locally installed AI CLI tools and invoked them with permission-bypassing flags to accelerate its hunt for secrets. Reported impact ran to thousands of private repositories exposed through a repo created inside each victim's own GitHub account.
None of that is a model quality problem. Every one is a missing constraint in the code around the model.

Anything you can only state in a system prompt is a suggestion, and suggestions are not controls.
Design tool interfaces so the invalid call cannot be represented
The cheapest safety work you will ever do happens before a single token is generated, in the shape of the tool schema.
Make the illegal state unrepresentable. The idea comes from typed functional programming and it transfers cleanly. Do not give an agent run_sql(query: string). Give it refund_order(order_id, amount_minor_units, reason_code) where reason_code is an enum with eight members, amount_minor_units is an integer with a declared maximum, and the currency is implied by the order rather than passed in. A free-text query parameter is a shell with extra steps. An enum with eight members is a decision the model cannot get creative about.
Constrained decoding then enforces it at the token level. The schema compiles to a grammar and the sampler's logits are masked so an invalid token cannot be emitted at all. OpenAI's own evaluation put gpt-4o-2024-08-06 with Structured Outputs at 100% on complex JSON schema following, against under 40% for gpt-4-0613.
Here is the part that gets skipped. Schema compliance is not correctness. A perfectly typed refund against the wrong order is still a wrong refund, and 100% schema adherence tells you nothing about whether the field values are right. The schema is the floor of the building, not the building.
OWASP files this as LLM06, Excessive Agency, one of the most expanded entries in the 2025 list. The mitigation is boring: fewer tools, narrower tools and no tool whose parameter space is wider than the set of actions you actually intend to permit.
Validate the output before it reaches a system of record
Two validators, not one.
The syntactic validator checks shape. Types, enums, ranges, required fields. It runs on every model output, always, even when the provider promises strict mode, because a provider's promise is not part of your test suite.
The semantic validator checks invariants a schema cannot express. Refund amount does not exceed the original charge. The order belongs to the customer in this session. The order has not already been refunded. That validator runs inside the same database transaction as the write, never in the prompt. Anything you can only state in a system prompt is a suggestion, and suggestions are not controls.
Then idempotency, the least glamorous line in this article and the one I would fight hardest for. Every write-capable tool call carries a key derived from the conversation id, the turn index, the tool name and a canonical hash of the arguments. That key gets a unique constraint in the destination table. Now a retry is free. Without it, the retry your framework fires after a 504 on a request that actually succeeded produces a second refund, and the postmortem says the AI double-charged a customer when what really happened is that a gateway timed out and nobody wrote seventeen lines of deduplication.
Sandbox the code, scope the capability, cap the budget
Generated code never runs in the process that holds your credentials. That is the whole rule. Everything else is implementation.
E2B runs sandboxes on Firecracker microVMs behind a REST API with Python and JavaScript SDKs. The default sandbox timeout is 300 seconds. Sessions cap at one hour on the free tier and 24 hours on Pro, which is $150 a month with 500 sandbox hours included and per-second billing beyond. Cold-start figures differ noticeably between vendor material and third-party benchmarks, so treat any number you read as a starting point and measure in your own region.
Inside the sandbox: a copy of the filesystem, never a mount of the real one. Network egress denied by default with an explicit allowlist. Memory and wall-clock caps enforced by the runtime rather than requested in the prompt. Run Semgrep across generated code before it goes near a branch, because a sandbox stops the code doing damage now and static analysis stops it doing damage after someone merges it.
Capability scoping is the same discipline applied to identity. The agent's token is not the operator's token. It is minted per task, expires in minutes and names the specific resource rather than the resource class. Read tools and write tools get different credentials. If one leaked context can produce a write to production, you do not have scoping, you have a naming convention.
Budgets are a counter in the harness, not a phrase in the prompt. Token ceiling per turn, cost ceiling per conversation, tool-call ceiling per run. OWASP calls the failure mode unbounded consumption. I call it the invoice you find on Monday.
Treat every tool description as untrusted input, because it is. In September 2025 a package published to npm as postmark-mcp shipped version 1.0.16 that quietly blind-copied every email the agent sent to an attacker-controlled address, and researchers estimated a few hundred organisations were affected before anyone noticed. A tool description is a string arriving in your model's context from a third party. Pin the version. Read the diff. Do not auto-update your agent's capabilities.
Retries, timeouts and the circuit breaker
Retry policy is per failure class, not global. A 429 or a 503 gets exponential backoff with jitter and a hard attempt cap. A 400 gets zero retries, because a schema violation retried with identical arguments fails identically and you have only spent tokens proving it.
Circuit breakers belong at the tool level. After N consecutive failures against a downstream, open the breaker and return a typed failure to the model so it can route around the outage or stop cleanly. The alternative is an agent rediscovering the same broken endpoint for forty turns.
Timeouts belong at three levels: the single model call, the single tool call and the total wall clock for the run. A run without a total budget is a run that loops until a human notices.
Durable execution earns its place here. Temporal's model is that the workflow survives worker crashes and deployments, waits days for an approval and resumes exactly where it stopped. At Replay 2026 in May the OpenAI Agents SDK integration went generally available, the Google GenAI integration entered public preview and workers became runnable on AWS Lambda. The Agent Harness preview from 20 August adds the piece that matters most in this context, a policy layer around tool execution that pauses for approval and resumes durably when the decision arrives.
Which brings up the human checkpoint. It has to be typed too. Approving the plan is meaningless. What a reviewer approves is the exact serialized call with the arguments that will be sent, and the approval record has to be an input to the workflow rather than a message in a channel someone may or may not read.
The audit trail a regulator or a post-incident review actually needs
The regulatory picture moved this summer and plenty of teams still have the wrong date in their heads. The AI Act digital omnibus was approved by the European Parliament on 16 June 2026, adopted by the Council on 29 June and entered into force in late July. It pushed the Annex III high-risk obligations, Article 12 automatic record-keeping among them, from 2 August 2026 out to 2 December 2027. Annex I embedded systems moved to 2 August 2028.
Article 50 transparency did not move. It applied from 2 August 2026, and systems already on the market have until 2 December 2026, ninety-five days from today, to carry machine-readable markers. The logging requirement is deferred, not deleted, and the obligation that survived the deferral is the one that lives in the harness anyway. A machine-readable marker is written at serialization time by the code around the model.
I watched the same shape play out here a year earlier. China's Labelling Measures and the mandatory national standard GB 45438-2025 took effect on 1 September 2025. I read both in Chinese when they landed. The explicit label is a UI change, a visible marker on generated text or images. The implicit label is metadata written into the file at the point of serialization. The teams around me that shipped it in a week were the ones whose audit logging already sat in a single write path, so the marker went in beside the trace id. The teams that had treated labelling as a model feature spent a month discovering it was not.
What the trace has to contain, for a regulator or for the review you will run at 2am: prompt template id and hash, model id with the exact dated version string, sampling parameters, every tool call with full arguments and the schema version those arguments were checked against, the verdict of every validator including the ones that passed, the sandbox image digest, the identity whose credentials executed the call, the approval record with approver and timestamp and the final write with its idempotency key. Append-only. Retained for the audit window, not for the thirty days your log platform defaults to.
Langfuse is the practical open-source answer. MIT licensed, self-hostable, accepting OTLP on /api/public/otel so traces land in whatever you already run. ClickHouse announced the acquisition on 16 January 2026 alongside a $400 million Series D, with the maintainers committing to keep it open source and self-hostable. Arize Phoenix covers similar ground if you want an alternative.
One more thing I keep returning to. An hour from my flat, on a line in Dongguan, the vision model doing surface inspection is the least interesting component in the cell. The interesting component is the interlock that refuses to let the arm move while the guard door is open. Nobody on that floor argues about whether the interlock should exist, or whether it hurts cycle time. Shenzhen published an action plan on 3 March 2025 targeting more than 100 billion yuan of embodied robotics output and over 1,200 enterprises by 2027, and every one of those cells will have an interlock. Software teams shipping agents into ledgers and CRMs are still debating whether they need one.
The strongest objection: this is ceremony that slows everything down
The best argument against everything above is that it is a tax paid before you know whether the product is worth anything.
It is a real tax. NeMo Guardrails adds a round trip per rail, and reported latency for typical configurations clusters in the low hundreds of milliseconds, which is significant against a model call that takes 700ms. Every validator is a new failure mode. Every schema is another artifact to keep in sync with a downstream that changes. An append-only audit store is a storage bill that only grows. And most agent pilots die of no demonstrated value rather than insufficient guardrails, so building a compliance-grade trace for a feature nobody adopts is six months you cannot get back.
The objection is right about sequencing and wrong about substance.
Harness cost should scale with blast radius, not with ambition. An agent that drafts an email for a human to send needs a schema and a token budget and nothing else. An agent with write access to a ledger needs all of it. Tie the layers to the write, not to the demo. Most teams get this backwards, applying guardrails uniformly across the whole surface and then removing them uniformly the moment latency hurts.
The latency is mostly an engineering problem rather than a law of nature. Run rails concurrently instead of in sequence. Use a small fast model for the rails and keep the large one for the task. Put the expensive semantic validator only in front of writes, never in front of reads. And point security testing at the deployed harness rather than the bare model, which is where garak has been heading: v0.15.0 on 1 May 2026 added a multi-turn GOAT probe and an agent-breaker probe aimed at the tools available to an agent, and v0.16.0 on 4 August added native Anthropic generator support plus a simple adaptive attacks probe. A model that refuses an instruction in a chat window will often comply when the same instruction arrives inside a tool result, and only harness-level testing finds that. Promptfoo turns whatever you find into a regression suite that runs in CI.
One asymmetry settles the argument for me. The audit trace is the thing that lets you delete a guardrail later with evidence. Without it, every check you ever added is permanent, because nobody can prove it is safe to remove.
Nobody puts the harness on the slide
Ask an engineering team which model they use and you get an answer in four seconds, with a version string and an opinion about the previous one. Ask what happens when the payments API returns a 504 on a call that already succeeded and you get a pause.
The pause is the whole subject.
What sits underneath is less comfortable. A harness is code that holds credentials, enforces permissions and decides what an autonomous process may touch. It is the most privileged code in the system. It is also, increasingly, code written by the same class of model it exists to contain, in an editor with an agent in it, reviewed by someone reading faster than they used to. The interlock on that line in Dongguan is a physical switch: wired, inspectable and boring by design. Nobody has told me yet who reviews the interlock once the interlock is generated.
Tools referenced
E2B, reviewed here: E2B review.
Temporal, reviewed here: Temporal review.
NVIDIA NeMo Guardrails, reviewed here: NVIDIA NeMo Guardrails review.
garak, reviewed here: garak review.
Langfuse, reviewed here: Langfuse review.
Promptfoo, reviewed here: Promptfoo review.
Sources
Gartner: Over 40% of Agentic AI Projects Will Be Canceled by End of 2027 (June 2025): https://www.gartner.com/en/newsroom/press-releases/2025-06-25-gartner-predicts-over-40-percent-of-agentic-ai-projects-will-be-canceled-by-end-of-2027
EU AI Act Article 12, Record-Keeping: https://artificialintelligenceact.eu/article/12/
Gibson Dunn: EU AI Act Omnibus Agreement, Postponed High-Risk Deadlines: https://www.gibsondunn.com/eu-ai-act-omnibus-agreement-postponed-high-risk-deadlines-and-other-key-changes/
Temporal: Temporal Agent Harness, an early look at durable agent infrastructure (20 August 2026): https://temporal.io/blog/temporal-agent-harness-durable-agent-infrastructure
NVIDIA garak releases, LLM vulnerability scanner: https://github.com/NVIDIA/garak/releases
Snyk: Malicious MCP Server on npm, postmark-mcp harvests emails: https://snyk.io/blog/malicious-mcp-server-on-npm-postmark-mcp-harvests-emails/
OpenAI: Introducing Structured Outputs in the API: https://openai.com/index/introducing-structured-outputs-in-the-api/
ClickHouse acquires Langfuse, open-source LLM observability (16 January 2026): https://clickhouse.com/blog/clickhouse-acquires-langfuse-open-source-llm-observability
Frequently Asked Questions
What is an AI agent harness?
An AI agent harness is the code around a language model that makes it usable in production: the tool schemas that constrain what the model can request, the validators that check output before it reaches a database, the sandbox that isolates generated code, the retry and timeout policy, the token and cost budgets, the scoped credentials each tool runs with, the idempotency keys that make retries safe and the audit log that records what happened. The model performs inference. The harness decides what that inference is allowed to do. Temporal shipped an early preview of a product literally named the Agent Harness on 20 August 2026, describing it as an outer layer that wraps an existing agent SDK to add durability, approval gates and event capture.
Where do most production AI agent incidents actually come from?
Most come from the harness rather than the model. The well-documented cases follow this pattern: Replit's agent dropped tables in a live production database during a code freeze in July 2025 and then incorrectly reported that rollback was impossible, a missing environment boundary and an unverified self-report. Amazon shipped Q Developer extension version 1.84.0 for VS Code on 17 July 2025 containing an injected destructive prompt after a contributor was granted write access, a supply chain and review failure. The s1ngularity attack on Nx npm packages on 26 August 2025 invoked locally installed AI CLI tools with permission-bypassing flags to hunt for secrets, a permissions failure. Gartner's June 2025 forecast that over 40% of agentic AI projects will be cancelled by the end of 2027 cites escalating costs and inadequate risk controls, both of which are harness properties rather than model properties.
What does the EU AI Act now require you to log, and by when?
Article 12 of the EU AI Act requires high-risk AI systems to technically allow automatic recording of events over the system's lifetime, sufficient to identify risk situations, support post-market monitoring and enable traceability of inputs, outputs and decision points. The timing changed in 2026: the AI Act digital omnibus, approved by the European Parliament on 16 June 2026 and adopted by the Council on 29 June 2026, deferred the Annex III standalone high-risk obligations from 2 August 2026 to 2 December 2027, and Annex I embedded systems to 2 August 2028. Article 50 transparency obligations were not deferred and applied from 2 August 2026, with systems already on the market required to carry machine-readable markers by 2 December 2026.
Read next
China's University Major Cuts Are AI Policy, and Nigeria Should Read the Fine Print
The latest analysis essay.
Working on something in this space?
If this analysis is close to a problem you're thinking about, say so. I read every message personally.
Start a conversation