In April 2026, Ryan Lopopolo from OpenAI gave a keynote at the AI Engineer Conference called "Harness Engineering: How to Build Software When Humans Steer, Agents Execute."

The talk, and the accompanying blog post, describe how his team built a real product with zero lines of manually written code.

The numbers: ~1M LOC, ~1,500 PRs and an average of 3.5 PRs per engineer per day.

In this post, I'll go through the main patterns for building an agent that takes a development task and delivers a Pull Request.

Philosophy

The idea behind everything is simple:

Humans steer. Agents execute.

Code is no longer the scarce resource. Human time, attention and the model's context window are.

Every engineer is effectively a Staff Engineer leading an infinite team of agents.

The job is not to implement. It's to design systems, specify intent and build feedback loops.

Agent loop

Lopopolo calls this pattern the "Ralph Wiggum Loop". It's an iterative cycle where the agent:

  1. Reads AGENTS.md to discover relevant context
  2. Navigates to deeper docs and execution plans
  3. Implements the solution
  4. Runs linters and tests locally
  5. Performs self-review
  6. Opens a Pull Request
  7. Requests reviews from specialized agent reviewers
  8. Addresses feedback and iterates
  9. Repeats until all reviewers approve

Single runs were observed working for more than 6 hours on a single task. Often while the engineers slept.

Progressive disclosure

The first instinct was to write one comprehensive AGENTS.md.

It failed, for a few reasons:

  • A giant file crowds out the task and the relevant code from context
  • When everything is "important", nothing is, and the agent pattern-matches locally
  • It rots instantly and is hard to verify mechanically

The solution was to treat AGENTS.md as a table of contents (~100 lines), pointing to a structured docs/ directory:

AGENTS.md              ← ~100 lines, pointers only
ARCHITECTURE.md
docs/
├── design-docs/
│   ├── index.md
│   └── core-beliefs.md
├── exec-plans/
│   ├── active/
│   ├── completed/
│   └── tech-debt-tracker.md
├── product-specs/
│   └── index.md
├── references/
│   └── design-system-reference-llms.txt
├── QUALITY_SCORE.md
├── RELIABILITY.md
└── SECURITY.md

Agents start with a small, stable entry point and are taught where to look next.

Mechanical enforcement

Architecture rules must be enforced, not just documented.

The team uses:

  • Custom linters (themselves generated by Codex) that validate dependency directions
  • Structural tests that check import boundaries between layers
  • CI jobs that block PRs violating architectural constraints

Lint error messages end up working as prompts. When the agent hits a lint failure, the error message becomes part of its context.

So the message should tell the agent what to do:

// Bad: "Error: Invalid import"
// Good: "Error: Service layer cannot import from UI layer.
//        Move this logic to a Provider or restructure
//        the dependency. See docs/ARCHITECTURE.md#layers"

Agents replicate patterns that already exist, even suboptimal ones.

Without mechanical enforcement, bad patterns compound exponentially.

Repository as the source of truth

From the agent's point of view, anything it can't access in-context while running effectively doesn't exist.

Take a Slack thread where the team aligned on an architectural pattern. If it's not in the repo, the agent doesn't know about it.

Everything must go into versioned, repository-local artifacts:

  • Design decisions → versioned markdown
  • Execution plans → checked in with progress logs
  • Product specs → indexed and navigable
  • Technical debt → tracked alongside code

Feedback loops

As throughput increased, the bottleneck moved from writing code to validating it.

The solution was to make the application directly legible to the agent.

They wired the Chrome DevTools Protocol into the agent runtime, so it could:

  1. Launch an isolated app instance per git worktree
  2. Snapshot DOM state before and after interactions
  3. Capture screenshots for visual regression
  4. Query logs via LogQL and metrics via PromQL
  5. Loop until clean: fix → restart → revalidate

This works because it replaces a subjective "does this look right?" with a mechanical "does this pass?".

Closing the loop

If the agent fails, the solution is NOT to fix it manually. It's to encode the correction into the repository to prevent future occurrences.

The cycle is:

  1. Observe: the agent makes repeated errors of the same class
  2. Diagnose: find the underlying pattern
  3. Codify: write a lint rule, guardrail or documentation
  4. Enforce: CI blocks the undesired pattern
  5. Result: that class of error is eliminated permanently

It costs some velocity in the short term, in exchange for long-term exponential gains.

Skills

Skills are executable instructions that teach the agent how to operate in a specific repository:

  • How to launch the app (boot, verify health)
  • How to run tests (correct commands, environment setup)
  • How to review (what to check before submitting a PR)
  • How to use observability (connect to local metrics and logs)

Codex, or any coding agent, should be the entry point to development.

Tools are designed for the agent to invoke first, and for humans second.

Agent reviewers

Instead of mandatory human review, the team uses specialized reviewer agents:

Reviewer Focus
Security Vulnerabilities, exposed secrets, injection vectors
Architecture Layer boundary conformance
Reliability Retry policies, timeouts, circuit breakers
Product Implementation matches spec

The dev agent opens a PR, requests agent reviews, iterates on the feedback and merges when all of them approve.

Humans may review, but aren't required to.

Conclusion

The role of the engineer is shifting from writing code to building systems that let agents write code reliably.

The investment goes into:

  • Documentation that agents can consume
  • Guardrails that mechanically prevent drift
  • Feedback loops that allow autonomous validation
  • Skills that encode tribal knowledge into executable instructions

In Lopopolo's words:

"You can simply say 'do not produce slop, don't accept slop' and you won't get slop in your codebase. But to do that requires taking short-term velocity hits to figure out what the agents are struggling with, put guardrails in place, then step back and spend your time on higher-leverage activities."

References

Thanks!