TL;DR: As agents get better at writing code, the system around them become more important. The developer’s role shifts toward designing the feedback loop: giving the agent enough context to be useful, enough freedom to move quickly, and enough boundaries to remain safe.
I do the vast majority of my day-to-day work with AI coding agents. Whether the tool is Codex, Claude Code, OpenCode, or something similar, the workflow has become familiar: give the agent a task, let it work, review the result, and iterate.
But I’ve recently started to think of this as two nested loops.
The two loops
The inner loop belongs to the agent itself: plan, act, observe. It forms a hypothesis, makes changes, runs commands, inspects the results, and adjusts its approach. Modern coding agents are effective largely because they can run this cycle quickly and repeatedly.
The outer loop belongs to the developer: define the task, provide context, review the outcome, and decide what happens next.
The trouble is that these two loops often run on different information.
Real projects are never fully represented by the codebase. The repository holds source code, tests, configuration, and documentation, but a lot of what actually matters lives elsewhere: cloud resources, job runs, workspace configuration, logs, the rendered UI, browser state, and other operational signals. As developers, we fold all of this into our decisions without thinking twice. Most agents, by default, have no way to see any of it.
When that happens, this outside information only reaches the agent through the developer’s outer loop, and only intermittently. The agent works from an incomplete picture, produces a solution, and only afterward, during review, does it learn what it was missing. The result is often another round of changes, not because the agent reasoned poorly, but because it was working from less information than the developer had.
This is, I think, one of the central jobs of an AI-assisted developer: designing systems that let the agent see as much of this surrounding world as possible, and pulling that information into its own plan-act-observe cycle rather than leaving it for the outer loop to supply after the fact. The more of the inner loop the agent can run on real, current evidence, the fewer trips back through the outer loop are needed.
Evidence beyond the repository
For cloud and data projects, this matters almost immediately. In an AWS or Databricks environment, the current state of the system can be just as important as anything in the repository, even when that repository is Terraform-backed. An agent has no inherent way to know which resources actually exist, how jobs are configured, or what recent runs have done, and without that, its inner loop is built on assumptions rather than evidence.
A well-scoped CLI command, made available inside that loop, can be the difference between an agent guessing from static files and working from the same evidence a developer would reach for.
The same principle holds for frontend work. An agent editing a UI without ever seeing the rendered page is effectively working blind, its inner loop missing an observation step worth the name. A small Playwright setup that starts the application, opens the relevant page, takes a screenshot, and reports console errors gives that loop something to look at. It lets the agent compare what it intended against what actually rendered, instead of reasoning from code and descriptions alone.
Boundaries matter
None of this means giving agents unrestricted access to the systems around the codebase. When an inner loop reaches into cloud infrastructure, it should be scoped to read-only wherever possible. The point is not to let the agent change infrastructure directly, but to let it observe the state of the systems that shape the code it’s working on. Where role-based access controls exist, use them; they’re the simplest way to get this right.
Where RBAC isn’t available, the guardrails have to be designed by hand. Rather than handing an agent unrestricted CLI access, it’s worth exposing a small, deliberate set of safe, read-only operations through a thin wrapper. That wrapper effectively defines the boundary of the agent’s inner loop: wide enough to be useful, narrow enough to stay safe.
Git and the usual file-based workflow already give agents working on code a degree of protection, since changes are visible, reversible, and reviewable before they land. That safety net doesn’t automatically extend to the outer systems an agent starts to touch, which is exactly why it has to be built deliberately rather than assumed.
None of this requires much infrastructure. A well-written AGENTS.md and a handful of reusable skills are often enough to give an agent’s inner loop access to the same context and feedback that a developer relies on every day.
That is still engineering work. It’s just a different kind of engineering work.