Cinqa/Field Notes/Automations
Automations · 4 min read · Updated

Claude Code automation: the guardrails that stop it breaking production

Scoped permissions, plan mode, hooks and the prompt-as-spec pattern we use to run Claude Code on client codebases without it rewriting production.

Tarun Chelumalla
Tarun Chelumalla
CTO · Workflows & AI
A developer typing at a desk at night in front of two monitors showing code

Where codebase automation goes wrong

Someone wires Claude Code into a workflow. It passes every test on Tuesday, and on Friday it quietly changes something in production nobody asked it to touch. When we trace failures like this back, it's almost always the same three causes: the agent could see and edit too much, nothing stopped it before the risky step, and nobody had written down what "done" meant.

This is the setup we use on client codebases to prevent that.

1. Scope the agent, not the model

The common mistake is giving Claude Code the whole repository and hoping the prompt keeps it in line. Prompts are advice. Permissions are rules.

In practice that means four things:

  • Put the agent's rules in the project's CLAUDE.md file: which folders are in scope, which commands it may run, which files it must never edit.
  • Back those rules with allow and deny lists in the project's Claude Code settings, so a write outside the allowed paths is refused, not just discouraged.
  • Run automated work on its own branch, ideally in a separate git worktree, so a bad run never touches the branch people are working on.
  • Put anything destructive (deleting files, dropping tables, force pushes) behind an explicit confirmation.

An agent that can only edit the components folder can't drop your database migrations by accident.

2. Prompt as spec, not prompt as wish

"Refactor the auth module to be cleaner" is a Slack message. Agents need tickets.

A useful spec has three parts.

Input. Exactly what's in scope: "the session validation block in the auth middleware, lines 45 to 120".

Constraints. What must not change: "don't change the public API, all existing tests pass, no new dependencies".

Acceptance criteria. How you'll know it worked: "each function has one job, and none is longer than 40 lines".

Written like this, you review the diff against the spec instead of guessing what the agent intended. We go deeper on the method in prompt-as-spec.

3. Two checkpoints with a person in them

Fully autonomous pipelines are tempting, and they're where the expensive mistakes come from. Every Claude Code workflow we ship has two gates.

  1. After the plan. Claude Code's plan mode makes the agent set out what it intends to change before it touches a file. A person approves or rejects the plan. It takes two minutes.
  1. After staging, before the commit. The agent stages its changes and summarises the diff, and a person reviews it.

The second gate doesn't always need a person. A hook can run a checklist against the diff and block the commit if a file outside the allowlist changed. But there has to be a gate.

4. Make every run idempotent

Running the workflow twice should give the same result as running it once. That sounds obvious until a pipeline adds a duplicate function on its second run because it never checked whether the first run had already done the job.

So every automation starts with a state check. Read the current state of the target files and confirm the change hasn't already been made, before writing anything.

5. Always keep a dry run

Every pipeline we hand over can run in a mode that shows the intended changes without making them. That's how you demo it to the people who will own it, how you run it in CI as a check, and how you debug it when it misbehaves.

With Claude Code, the simplest version is running it headless with permissions that allow reading but not writing, and asking for the proposed diff as the output. Review it, then run it for real.

The stack

  • Claude Code, using Claude's Sonnet models for most code steps and Opus for planning larger changes
  • n8n for the orchestration around it: triggers, branching, checkpoints and notifications
  • A dedicated git user for automated commits, so they stand out in the history
  • Conventional commit messages, written by the agent, so the changelog writes itself

What breaks, and how we catch it

Imports that don't exist. The agent imports a module that isn't there. Caught by running the type checker and the build as a required step after every change.

Scope creep. The agent "helpfully" tidies code next to the code it was asked to change. Caught by comparing the changed files against the allowlist and rejecting anything outside it.

Losing the thread on big files. On very long files, changes drift out of step with each other. Caught by asking for one function or block at a time and checking each change before the next.

Set it up once

Treat Claude Code like a talented engineer in their first week: fast, keen, and in need of a clear ticket, limited access and a review before anything ships. Set that up once and it does real work. If you want it built into your own repository and workflows, that's part of our AI automation work.

← Back to Field NotesStart a Project →