Agentic Engineering

How to Know When a Coding Agent Has Gone Rogue

Agent observability should connect intent, tool calls, state changes, verification, cost, and policy into one trace an operator can actually debug.

5 min read
A task trace connecting agent intent, tool actions, state changes, verification results, and stop decisions.

A rogue coding agent does not need to delete production.

It can make 84 tool calls, rewrite 37 files, spend most of its budget searching the wrong package, and still end with: “Implemented successfully. Tests pass.”

If your dashboard shows only tokens, latency, and HTTP errors, that run may look healthy.

Agent observability has to answer a different question: Did the system make sensible progress toward the task, within its authority, and prove the result?

Five questions every trace should answer

An operator investigating a run should not need to reconstruct it from a chat transcript, shell history, Git diff, and three provider dashboards.

The trace should answer:

  1. What was the agent trying to accomplish?
  2. What did it observe and decide?
  3. Which consequential actions did it take?
  4. What changed, and how was that change verified?
  5. Why did the task continue, stop, or escalate?

That creates a useful spine:

intent → observation → decision → action
→ state change → verification → next decision

Model calls are spans inside this trace. They are not the trace itself.

Instrument milestones, not private reasoning

You do not need to log hidden reasoning or every sentence the model considered. You do need the task-level decisions that explain behavior.

For each run, capture:

  • task type, goal, constraints, and starting revision
  • model route and configured budgets
  • current workflow stage
  • tools called, duration, outcome, and error class
  • files, records, or services changed
  • permission requests, grants, and denials
  • checkpoints and retries
  • verification commands and results
  • final status, stop reason, and review artifact

Use one task identifier across model, tool, Git, test, and deployment events. Without correlation, an incident becomes a scavenger hunt.

The OpenTelemetry project now defines semantic conventions for generative-AI operations. Those conventions are a useful starting vocabulary for model and agent spans, but a coding workflow still needs domain events such as patch_created, scope_expanded, test_failed, and review_required.

Activity is not progress

Agents are unusually good at looking busy.

Define progress using workflow milestones:

  • failure reproduced
  • owning module identified
  • patch created
  • focused check passed
  • behavior verified
  • review packet ready

Then detect runs that consume time or cost without crossing a milestone.

Useful signals include:

SignalWhat it may meanDefault response
Same command fails three timesRetry loop without a new hypothesisStop or require a changed plan
Search radius keeps expandingContext is wrong or task is underspecifiedRe-scope the task
Diff grows after acceptance passesUnrequested cleanup or driftFreeze edits and review
No verification after final mutationEvidence is staleMark incomplete
Subagent fan-out exceeds budgetOrchestration loopPrevent new delegation
New network domain appearsUnexpected boundary crossingDeny and alert

These are not universal thresholds. Calibrate them by task class. A repository migration legitimately touches more files than a typo fix.

Make mutations first-class

The consequential moment is often not the model response. It is the state change that followed.

A file edit, dependency update, message, database write, permission change, or deployment should carry:

  • the task and decision that caused it
  • the acting identity
  • the target and scope
  • the before/after reference when practical
  • the verification that followed
  • reversibility or rollback information

Now an operator can answer, “Why did this file change?” without reading the entire conversation.

It also exposes a subtle failure: the agent can make a correct decision and invoke a tool that behaves incorrectly. The trace must distinguish model failure from tool failure and environment failure.

The operator view should be a timeline

The default debugging interface should compress the run:

09:02  task accepted at commit a84c
09:04  pagination failure reproduced
09:07  2 files changed
09:08  focused test passed
09:10  browser check failed: stale API fixture
09:11  task blocked; fixture owner requested

Let the operator expand prompts, command output, retrieved context, and model responses when needed. Do not make raw text the primary interface.

Join the timeline with model route, token usage, tool latency, cache hits, and cost. A slowdown may come from a more expensive model, a much larger context bundle, a flaky service, or a test command that stopped using its cache. One “agent latency” metric cannot separate them.

Observability can become a privacy leak

Prompts, source files, screenshots, tool results, and internal documents may contain secrets or personal data. A trace system that copies all of it into a broadly accessible analytics store has increased the blast radius.

Log metadata and references by default. Capture raw content only when the diagnostic value justifies it. Apply access control, redaction, retention, and deletion rules to traces as deliberately as you apply them to the source system.

This is where observability and governance meet. OpenAI’s enterprise guidance separates aggregated workspace analytics from compliance and audit records; your own platform should likewise distinguish performance measurement from investigation evidence.

Define “rogue” as a policy violation, not a personality

An agent is not rogue because its prose sounds strange. It is rogue when behavior leaves the expected envelope:

  • it acts outside declared scope
  • it keeps spending without progress
  • it crosses a permission boundary
  • it mutates state without fresh verification
  • it hides failure behind a success status
  • it cannot produce a reviewable account of what happened

That definition is measurable, alertable, and fixable.

The goal is not to observe every token. It is to make every consequential action explainable.

Further reading