The agentic loop, a reminder #
The engine has not changed since the previous article: an agent captures an intent, plans the steps, acts through tools, and observes the results. When the observation is unsatisfactory, the agent re-plans and iterates: the loop is self-correcting.
This loop is the delivery engine of modern software. Everything that follows in this article is about one question: where does governance live in this loop?
The status quo: everything is front-loaded #
Look at how we steer agents today. Governance rules, architecture context, security policies: everything is injected before the loop starts, through the initial prompt and global instruction files ( CLAUDE.md,
.cursorrules
copilot-instructions.md
Capture, once, and everything the stack dumps up-front lands in it.
The interaction is asymmetric: all the control is spent up-front. Once the loop starts spinning, the agent is on its own. Nothing guides it while it plans, while it executes, while it observes. We write two hundred lines of instructions and then hope.
The late gate: control after the work is done #
The remaining control arrives at the worst possible moment: the end. The commit that breaks the CI is rejected. The forbidden API is flagged in code review. The non-compliant color ships to staging and bounces back.
These late gates do their job (nothing broken reaches production), but look at the cost. The agent has already burned its tokens. The work is done and must be redone. Each bounce is a full trip around the loop, plus a human interruption. This is the opposite of what the industry calls shift-left (moving verification as early as possible in the delivery process), and it frustrates the very flow the agent was supposed to accelerate.
But wait: is self-correction not precisely the loop’s job? It is. The red arrow on the diagram has been doing exactly that since the first phase. The nuance is that the loop can only correct what its Observe step can see. The late gate delivers its verdict after the loop has exited, outside the agent’s observation horizon. So the rejection cannot be absorbed as one more iteration; it re-enters at the top, as a new intent, usually carried by a frustrated human. Same information, wrong side of the loop boundary.
The failure is architectural, not technical: the control exists, it is just in the wrong place. It sits outside the loop, when the loop is where the work happens.
The pivot: distribute governance inside the loop #
Here is the shift this article proposes. Instead of concentrating everything at the start and controlling at the end, the platform injects governance inside each step of the loop:
- at planning time, the agent receives the architecture patterns, the critical dependencies, and the valid options, before it commits to a strategy; - at execution time, the tools themselves carry the rules and validate state in real time; - at observation time, the platform measures the gap between the result and the original intent and feeds it back, structured.
The initial context becomes light again: the intent, and little else. Everything the agent used to receive as a wall of up-front text is now delivered just in time, by the step that needs it.
Who builds this? The platform team, and this is Platform Engineering by the book: these mechanisms are designed, versioned, and served as internal products that stream-aligned teams and their agents consume without friction.
Pillar 1 — Amplified planning #
Do not let the agent plan in the void. At the exact moment it designs its strategy, the platform provides the enterprise architecture patterns, the critical dependencies, and the valid options.
The industry has a name for the shape of this guidance: the Golden Path, the paved road, the supported and blessed way of building something, popularized by Spotify and productized by tools like Backstage. But today’s golden paths are documentation for humans. Here, they become a planning input for the agent: instead of discovering conventions by reading thousands of lines of code (or worse, by violating them), the agent receives the map of the terrain before it starts walking.
The nature of the guardrail changes: it guides toward the paved road at planning time, instead of saying “no” at the end.
Pillar 2 — Contextual in-tool execution #
The tools the platform hands to the agent (CLIs, APIs, refactoring scripts) must not be passive executors that return exit 1
and a stack trace. They must be smart: encapsulate the business rules, validate state in real time, and, when something goes wrong, answer with an actionable, semantic error.
Compare the two experiences. A passive tool says:
Error: migration failed near line 12. SQLSTATE 42P07. Exit status 1.
A smart platform tool says:
{
"error_category": "DATABASE_SCHEMA_CONFLICT",
"message": "Table 'payments' already exists in staging.",
"remediation_guidance": {
"allowed_actions": [
"Use 'get_db_schema' to inspect the current structure.",
"Add an 'IF NOT EXISTS' clause or rename the table."
],
"context_update": "Current staging schema version: v2.4.1"
}
}
The first output sends a weak model into a panic loop. The second one turns the failure into an immediate, guided self-correction: the tool behaves like a deterministic mentor.
Pillar 3 — Retroactive observation #
Start with the question this phase usually raises: where does the observation get its yardstick? Not from a side channel; the loop does not need one. The context is born at Capture, and nowhere else. That is what the capture step is: the moment the loop’s working context is created and filled (the declared intent, the injected invariants). Every subsequent step appends to that same context: the plan, the tool calls, the raw results. By the time execution reaches Observation, the original intent is still sitting at the top of it. The context chip on the diagram shows exactly that: the yardstick flows from the captured context into the comparator, not from outside the loop.
Pillar 3 is about what observation does with that yardstick. It must not exist only to produce logs for humans. Its job is to measure the gap between the execution result and the captured intent, and to report it structured: which invariant was missed, by how much, what context changed. Not a raw “unsatisfactory result, try again”.
And observation does not complete the intent by itself; nor does an intent gap short-cut back to planning. That inner arrow is reserved for execution-level errors: a tool was called wrong, the how failed, re-plan the step (pillar 2). An intent-level gap is something else entirely. It is new knowledge (the measured gap, the facts discovered along the way), and knowledge belongs in the context. So the feedback flows back to Capture, where the context gains those new elements, and the loop runs another full cycle (capture, plan, act, observe) on the enriched context, until the gap closes or a budget guardrail fires. Watch the diagram: the green feedback travels the loop’s own path back to Capture, and the context chip lights up as it lands. The intent is completed by cycling the loop; pillar 3 only sharpens the signal each cycle converges on.
To be precise about what changed: none of this invents a new mechanism; it routes the existing signals to the right re-entry point. A tool-level error re-enters at Plan: fix the how, same cycle. An intent-level gap re-enters at Capture: enrich the what, new cycle. And the late gate of phase 3 re-enters nowhere: its verdict lands outside the loop’s sight entirely. The difference between the three is not the arrow; it is what the signal is, and where it gets to re-enter the loop.
(This pillar opens onto agentic telemetry: measuring guardrail efficiency across thousands of loop executions and feeding the next planning phases. That is the subject of a future article; the proof of concept below deliberately stops at pillars 1 and 2.)
The vision: guardrails as accelerators #
Put the three pillars together and the paradigm has flipped. The platform validates the agent’s assumptions at every step, which gives it the confidence (the super-powers) to execute complex modifications safely. The result exits the loop already compliant: there is no gate at the exit because the gates did their work inside.
This is the philosophical core of the article: a well-placed guardrail is not a brake, it is an accelerator. Formula One cars corner faster because the track has barriers and the car has traction control. Remove them and every lap gets slower and more careful, not freer.
A fair objection at this point: “you have just described more scaffolding around the model — will any of it survive the next model generation?” That objection deserves a precise answer, and it needs a grid.
Two orthogonal axes: durable assets vs. scaffolding #
In See, Act, Correct I introduced the distinction between compensatory systems, which work around the current limitations of a model and lose value as models improve, and amplifier systems, which build on the model’s strengths and gain value as models improve. The test is one question: would this artifact be more useful, or useless, if the model were twice as intelligent tomorrow?
Cross it with the implementation axis, declarative (text, simple, fragile) versus programmatic (code, deterministic, robust), and you get the grid on the left. Read it as a decision tool, not a taxonomy: take the artifact you are about to build, ask the 2× question, route it into its column, and act on the verdict at the bottom (fund the right column; tag the left one and give it a sunset date).
The crucial insight, and the one I initially got wrong when designing what follows: whether a mechanism blocks or guides has nothing to do with whether it is compensatory or amplifying. A 200-line prompt enumerating forbidden files is guidance, and it is pure compensatory debt: it fights the model and rots as models improve. A hard gate that verifies a semantic invariant (“a schema migration precedes the code that uses it”) is a blocker, and it is a durable amplifier: a smarter model satisfies it more elegantly, and never makes it useless.
So the question for every platform investment below is never “does it constrain the agent?” but “does it age well?”. The bottom-right cell (programmatic amplifiers) is where the next three sections live.
Materializing Pillar 1: the Platform Planning Gateway #
This is the first concrete proposal of this article. The Platform Planning Gateway (PPG) intercepts the planning step with two moves: one soft, one hard.
The soft move, enrich(): fetch the rules that apply, before planning. Think of the fifteen-minute conversation with the staff architect before you start a piece of work (
“anything I should know before touching the payment code?”), automated. Before planning, the agent asks the platform exactly that question: it sends its
intent and its
repository context, and the gateway answers with the
architectural invariants that apply, retrieved from the organization’s
Architecture Decision Records. Concretely:
// agent → platform
{ "intent": "Add the Seka payment method to checkout",
"repository_context": { "name": "checkout-service", "tech_stack": ["Go"] } }
// platform → agent
{ "amplifier_context": { "architectural_invariants": [ {
"adr_id": "ADR-042",
"invariant": "Every outbound call to a third-party service MUST go
through the corporate security egress proxy." } ] } }
How did the gateway know ADR-042 was relevant? Each ADR declares its own scope selectors (here, the keyword payment
matched the intent): keyword matching in the PoC, semantic retrieval in production. The agent injects the returned invariants into its planning context and reasons over them: its plan now includes the proxy step before a single line is written.
Note the two things enrich()
deliberately does not do. It does not enforce anything: it advises. Enforcement comes next, in the hard move. And it returns no recipe (“modify file X at line Y”), only semantic invariants: the recipes are exactly what a better model derives on its own. Architects write the invariants and the selectors in the ADRs; the gateway only retrieves. That division of labor is what makes enrich()
a declarative amplifier: a smarter model exploits the same invariants better.
The hard move: lock_in_plan(). The agent must materialize its plan as a structured document (a JSON contract, not free text) and submit it. The gateway runs a
plan linter: deterministic code, deliberately
notan LLM, in the spirit of policy-as-code engines like
Open Policy Agent. A non-conforming plan is rejected 100% of the time, reproducibly, with semantic violations:
{
"status": "PLAN_REJECTED",
"violations": [{
"policy_id": "go_tests_present",
"message": "The plan must contain a 'go test' step for a Go stack.",
"nature": "amplifier"
}]
}
The agent self-corrects, in practice in one or two iterations even with a small model: the linter redresses it like a compiler would.
When the plan passes, the gateway issues the capability ticket: an ephemeral signed JWT embedding the plan’s fingerprint and the least-privilege scope derived from it (which files may be modified, which tools may be called). This is capability-based security applied to the agentic loop, and it is the key that unlocks the next phase.
Materializing Pillar 2: Smart Tools honor the ticket #
The ticket would be theater if the tools did not check it. So every Smart Platform Tool starts with the same three-step contract:
Verify the ticket, in-tool. Agentic drift happensduringexecution: the agent decides mid-flight to touch a file it never planned to touch. The tool decodes the ticket, compares the requested action to the locked scope, and refuses deterministically:OUT_OF_PLAN_SCOPE
, nothing executed, no damage done, no cleanup. The check lives inside the tool because that is the last line of defense that no prompt drift can bypass.Execute in a sandbox. Dry-run first, isolated copy, never directly on the target.Analyze semantically. On failure, the tool returns the structured, actionable payload from pillar 2: the error category, the remediation guidance, and thecontext the model cannot guess(the staging schema version, the interface definition, the violated ADR).
Note what the ticket refusal is not: it is not a punishment, and, matrix in hand, it is not compensatory. It addresses the symmetric risk of amplifiers: an ungoverned amplifier amplifies systemic errors at the same scale as successes. Least privilege stays relevant even against a perfect model, because it protects the organization, not the model.
Governing the transition debt #
One piece is missing, and it is the one platform teams forget: the exit plan for the scaffolding.
Some of what we just built is compensatory, knowingly. The exhaustive enumeration of frozen legacy files exists because today’s models cannot reliably infer “deprecated, do not touch” from annotations. The raw-stack-trace-to-JSON translator exists because today’s models digest structured errors better than raw ones. Both will become dead weight as models improve — that is fine, if we can find them again.
So the proposal is to make the durability axis a first-class attribute of every rule: each policy, booster, and translator is tagged amplifier
or compensatory
, and every compensatory artifact must carry a measurable sunset condition (“model honors @deprecated
semantically on >95% of our benchmark”). The platform exposes a transition-debt report: the compensatory ratio, and the list of pending sunsets. That ratio must trend toward zero across model generations: it is the health indicator of the platform investment.
For the record, the alternatives considered and rejected: putting everything in the system prompt (fragile, unverifiable, compensatory-declarative); gating only in CI (the late gate of phase 3: feedback arrives too late for self-correction); using an LLM to validate the plan (non-deterministic; we want a linter, not a judge).
The amplified loop, materialized #
Here is the full picture, with everything in place.
The intent enters light. The plan is enriched by ADR invariants, linted deterministically, and locked into a capability ticket. The tools verify the ticket at their door, execute in sandboxes, and answer failures with semantic guidance. The observation measures the gap against the original intent and feeds the loop. Every artifact along the way is tagged on the durability axis, and the scaffolding has a scheduled exit.
The result flows out of the loop with no gate at the exit: not because control was removed, but because it was relocated to where the work happens. The stream-aligned team and its agents ship faster because the platform constrains them well.