Claude Code in CI: Letting an Agent Fix the Build
Running a coding agent in your pipeline is easy. The engineering is in the guardrails: what it can touch, when it stops, and who reviews what it proposes.

Putting a coding agent in CI is a permissions design problem wearing a productivity costume. The mechanics are an afternoon's work: headless mode has shipped since Claude Code 2.0 in September 2025, and anthropics/claude-code-action@v1 wraps the whole thing in a GitHub Action. You can have an agent commenting on pull requests before lunch. Whether you should have it pushing commits is a different question, and it is the only one that matters.
The rule that keeps this safe is simple: an agent in CI proposes, it does not merge. Every pattern below is a variation on where you draw that line.
Headless mode, quickly
The -p (or --print) flag switches Claude Code out of the interactive REPL into a single batch invocation, which is what makes it scriptable. The flags that turn it from a demo into something you can run unattended are the constraining ones:
claude -p "Fix the failing unit tests. Do not change public APIs." \
--output-format json \
--max-turns 8 \
--allowedTools "Read,Edit,Bash(npm test)" \
--model claude-haiku-4-5
Each of those does real work. --output-format json returns an object with result, model, usage, and stop_reason, so your pipeline can branch on the outcome instead of grepping prose. --max-turns is your circuit breaker. --allowedTools is the allowlist, and it is the single most important flag on the line.
The three patterns, in ascending order of nerve
Teams land in one of three places. They are not equivalent, and most teams should stop at the second.
- Advisory. The agent reads the diff and comments. It has no write access to anything. Every finding costs a human thirty seconds to accept or dismiss. This is where to start, and for many teams it is where to stay.
- Proposing. The agent fixes something and opens a pull request against the branch. It writes code, but the merge button is human. The review gate you already trust does the work it was built for. This is the sweet spot.
- Autonomous. The agent commits to a branch that deploys. It is the pattern people demo and the one that generates incidents, because CI is the one place in your stack where a bad actor becomes a deployed artifact without a human in the loop.
Note what changes between them: not the agent's capability, only the blast radius of a mistake. The agent is equally likely to be wrong in all three. The difference is what happens next.
The failure mode nobody plans for
The obvious worry is the agent writing bad code. That one is handled: your tests and your reviewers catch bad code, which is what they are for.
The real failure is subtler. An agent told to make the build green has exactly one objective, and there is more than one way to reach it. Deleting the failing assertion makes the build green. Adding skip to the test makes the build green. Widening a type to any makes the type error go away. None of these are the agent malfunctioning. They are the agent doing precisely what you asked, in a way you did not intend, because your instruction described the symptom rather than the goal.
Two things help. Write the objective as a constraint, not a target: "fix the implementation so the existing tests pass, without modifying test files" is a different instruction from "fix the build". And enforce it structurally rather than trusting the prose, because prose is a request and a tool allowlist is a rule.
Guardrails that are actually load-bearing
- Scope the tool allowlist to the job. A test-fixing agent needs to read files, edit source, and run the test command. It does not need network access, it does not need to touch CI config, and it does not need the deploy credentials that happen to sit in the runner's environment.
- Protect the files that define correctness. Tests, lockfiles, CI workflows, and IAM policy belong on a path denylist. If the agent cannot edit the test, it cannot delete the test to pass it.
- Cap turns and cap tokens. A loop that cannot converge should stop and say so. An uncapped agent grinding at an impossible task is a bill and a queue of stuck jobs.
- Give the runner its own identity. Not a broad admin role that happens to be sitting there. The agent's job runs as a scoped role with the permissions that one task needs, so a confused agent cannot reach for something it was never meant to have.
- Treat agent commits as untrusted input. Same required checks, same review, same branch protection as any contributor. The agent gets no fast path, because the fast path is the vulnerability.
- Log the whole session. When an agent-authored change causes an incident at 3am, "what was it told and what did it do" needs an answer that is not a shrug. The JSON output plus the session transcript is your audit trail. Keep it.
The economics are genuinely good
Worth being fair to the idea: the numbers are favourable. An automated review pass on a mid-sized diff costs a few cents and finishes in under a minute. Against the cost of a reviewer's context switch, that arithmetic works out at almost any pull request volume, which is exactly why this pattern is spreading.
That is also the trap. Cheap enough to run on every PR is cheap enough to run without thinking about it, and the marginal cost of adding one more permission to the allowlist is always zero at the moment you add it. The cost arrives later, once. Decide the boundary while it is still theoretical.
The takeaway
An agent in your pipeline is a contributor with no judgment, infinite patience, and whatever credentials you handed the runner. Give it the narrow tools for one job, protect the files that encode what correct means, cap the loop, and make it open a pull request like everybody else. The productivity is real. It comes from the agent doing the tedious first pass, not from removing the human who says yes.
Read this next
- Evals Before Agents: You Can't Ship What You Can't Score, because an agent in CI without a scoreboard is a vibe check running on every commit.
- IAM for LLM Apps: Least Privilege When the Caller Is a Model, on scoping the role your pipeline agent actually runs as.
For the pipeline side of this, why automated tests are essential in your CI/CD pipeline covers the checks an agent's output has to clear, over at ercan.cloud. The hub is at ercanermis.com.
More from Ercan
Two more sites, same author, different ground.
Cloud, AWS, EKS, Terraform, platform engineering.
Field notes from production systems. EKS, IAM, Terraform at organization scale, observability, cost optimization.
Visit ercan.cloud →The hub. About, consulting, contact.
Personal hub for both writing tracks. Who I am, how the consulting works, how to reach me.
Visit ercanermis.com →