As large language models (LLMs) continue to advance in reasoning and code generation capabilities, development teams are discovering a puzzling paradox: an AI coding agent can write code that looks locally elegant, compiles cleanly and passes basic syntax checks, yet it could be wrong for the system as a whole.
When left unconstrained, agents optimize for the local context they have available. An agent asked to refactor a data model might rename a field in the service it is currently editing, completely unaware that two downstream microservices consume that exact field. The change is locally correct, but systemically destructive.
This persistent gap between raw model intelligence and reliable software delivery is not primarily a model-quality issue. What the model lacks is system-level visibility, architectural guardrails and automated feedback mechanisms. We can express this relationship as:
Agent = Model + Harness
While the model provides reasoning capacity, harness engineering supplies the structured environment, tool constraints, context boundaries and feedback loops that transforms raw intelligence into a safe, reliable and auditable delivery system.
A practical harness has two layers (and selective human gates)
To prevent both unconstrained AI drift and human review fatigue, a production-grade harness relies on two complementary enforcement layers, separated by targeted decision gates:
1. Guides (Pre-action steering): Mechanisms that constrain and direct the agent before it takes action or writes code.
2. Sensors (Post-action verification): Automated feedback loops that inspect and validate the output after the agent acts.
3. Selective human gates: Strategic checkpoints placed between guidance and sensors where human judgment or blast-radius sign-off is required.
By cleanly separating pre-action steering from post-action verification, teams avoid two common pitfalls: letting agents freelance without constraints or forcing humans to approve every trivial tool call.
Guides: Constraining before the agent acts
Guides establish the parameters within which an agent is permitted to explore, plan and write code. Effective guidance relies on four core patterns:
Scoped instructions and progressive disclosure
Loading monolithic instruction files into every session rapidly fills the context window, causing "attention dilution" and context rot. Instead, instructions should be scoped by file path or domain tree (e.g., loading database rules only when touching schema files). By using progressive disclosure, i.e., traversing documentation trees as needed rather than preloading everything, the agent maintains high attention on relevant team conventions.
Least-privilege tools
Relying on prompt text to ask an agent not to perform unauthorized actions (such as pushing code or editing configs) is inherently fragile. Least-privilege tools convert behavioral guidance into structural enforcement. For instance, a Q&A or code verification agent is provisioned with read-only tools, literally lacking file-writing capabilities.
Explicit defaults instead of guesses
When an agent encounters optional inputs during structured intake (such as an optional technical spec), it should avoid making unstated assumptions. The harness enforces an "ask before deciding" protocol. If the developer chooses to skip an optional step, the harness can explicitly record that decision. A default is visible and inspectable, a guess is hidden and risky.
Confirmation only for high-blast-radius decisions
To maintain high velocity without sacrificing safety, human confirmation gates are reserved for irreversible or high-blast-radius choices, such as multi-repository scope changes, schema migrations or public API modifications. Lower-risk decisions proceed with sensible defaults.
Sensors: Verifying after the agent acts
Even the best guides cannot catch every logic edge case or runtime error. Sensors operate after the agent acts, providing automated computational feedback to validate output.
Automated verification
Sensors wrap standard software engineering checks like unit tests, linters, static type checkers and architecture rules into the agent loop. When an agent finishes an implementation pass, sensors run automatically to evaluate correctness rather than relying on the agent's self-assessment.
Silent success, verbose failure
Sensors follow the "silent success, verbose failure" rule:
When checks pass: The sensor produces minimal output, preserving valuable context tokens and human attention.
When checks fail: The sensor generates verbose, actionable feedback (stack traces, linter error locations, failing test diffs), feeding the error directly back into the agent loop so it can self-correct without human intervention.
Promoting rules from prose into executable enforcement
If a team finds themselves repeatedly adding prose rules to prompt files because an agent ignores a convention, that rule should be promoted into a mechanical sensor (a custom linter rule, a type check or an architecture test). Prose is the starting point; where a rule can be reliably encoded, mechanical enforcement is the stronger option.
How the pattern works across repositories
To illustrate how a shared harness can help, consider a system with three microservices:
billing-service (owns a shared discount_rate field)
checkout-service (consumes discount_rate)
invoicing-service (consumes discount_rate)
This simplified example illustrates how the pattern can work when dependencies are known and accessible to the harness.
Unconstrained repository-level execution
When an agent is executed within billing-service without a multi-repo harness, a refactoring request causes the agent to rename discount_rate to promotional_discount in billing-service alone. The agent reports success because its local tests pass. However, checkout-service and invoicing-service silently drift out of sync, breaking production workflows.
Shared harness execution
When the same request is processed through a shared harness wrapping all three repositories:
Impact analysis: The agent scans dependency graphs across the shared workspace and identifies that changing billing-service affects checkout-service and invoicing-service.
Multi-repo confirmation gate: Recognizing a multi-repo blast radius, the harness pauses execution and presents a blocking confirmation gate to the developer.
3. Coordinated update: Upon human approval, the agent updates the contract and implementation across all three repositories, running multi-service test suites to verify the coordinated change.
The full delivery loop
One way to combine guides, sensors and selective human gates is through an end-to-end 6-phase delivery pipeline:
ANALYZE: Structured intake collects Jira tickets and technical context, enforcing explicit defaults for missing inputs.
BLUEPRINT: The architecture agent designs the cross-repo file plan. Detecting a multi-service blast radius, it pauses at a multi-repo confirmation gate for human sign-off.
RED: The test agent writes failing acceptance tests corresponding to requirements.
GREEN: The implementer agent writes minimal code until all RED tests pass.
REFACTOR: Code structure and adherence to team conventions are polished while maintaining passing test suites.
REVIEW: An automated review agent checks test coverage against acceptance criteria.
Within this pipeline, human and automated feedback serve different purposes:
Human feedback loop: Reserved for consequential, irreversible decisions (e.g., approving multi-repo architectural scope during BLUEPRINT).
Automated feedback loop: Handles mechanically correctable failures. If the REVIEW phase detects an untested acceptance criterion, it does not interrupt a human. Instead, it automatically routes the task back to RED/GREEN to generate the missing test and implementation, re-running REVIEW autonomously before opening a pull request.
Treat the harness itself as software
A harness is not a static set of configuration files or prompt snippets written once and forgotten. It must be managed with the same rigor as production software:
Version control and peer review: Store all agent definitions, skills, rules and workflows in version control. Submit harness edits through pull requests with peer review.
Earn every rule: Resist speculative rule bloat. Instructions in the harness should be purposeful and traceable to a concrete need, such as a past production failure, developer pain point, security requirement or established engineering constraint. Unearned rules add noise, dilute model attention and degrade output quality.
Continuous refactoring: As underlying LLM capabilities improve, revisit existing harness rules. Prune outdated constraints to ensure the harness remains lean and effective. This discipline also matters because the harness itself creates maintenance overhead: every rule, sensor and workflow becomes part of the engineering system teams must keep current.
Conclusion: Bounded autonomy and balanced control
Reliable agentic software development requires more than prompt engineering. Asking a model to be careful is fundamentally different from building an environment where violations are prevented or mechanically caught.
The key differentiator is not merely saying "use a harness," but mastering how to divide responsibility across the delivery lifecycle. By treating the harness as versioned, auditable software, development teams can use AI capabilities to accelerate delivery while protecting system integrity.
Disclaimer: The statements and opinions expressed in this article are those of the author(s) and do not necessarily reflect the positions of Thoughtworks.