Guardrails for AI coding agents
Your coding agent skips the failing test, or writes it to pass afterward — and a longer system prompt never quite makes it stop. You'll pull a ready-made TDD workflow from a Git repo, wire it into Claude Code or Cursor, and watch the rails make cheating not a move it can make — then layer your own rules on top.
Step 1
You've watched it in Claude Code or Cursor: the agent skips the failing test, or writes one that passes after the fact. The usual fix is a longer prompt — "always write a failing test first" — and it works until the next time pressure or a full context window lets the agent rationalize around it. The system prompt is a suggestion; it agrees, then does the other thing two turns later.
You're about to make that impossible — not by prompting harder, but by putting the agent on
rails. When the workflow doesn't offer write_implementation as a valid move,
the agent physically cannot jump to it. It's not blocked or discouraged — it's absent from the
menu, so no amount of persuasion brings it back. The right move appears only once it's earned.
Step 2
The cognitive-architectures repo — a repo of ready-made agent guardrails —
ships a TDD workflow you can use as-is. Clone it, point
gateway.yaml at it,
and run check to verify your guardrails loaded —
and that none of them clutter your agent's tool list.
git clone https://github.com/matt-cochran/cognitive-architectures ~/repos/cognitive-architectures
cat > gateway.yaml <<'EOF'
version: "1.0.0"
repos:
- path: ~/repos/cognitive-architectures
EOF
mcp-flowgate check --config gateway.yaml check lists every loaded guardrail — including the TDD workflow,
cognitive/tdd — each under its own namespace (a prefix that keeps ids from two
repos from colliding). None of them land in your agent's tool list: it still sees just two tools.
Step 3
Declare the agent role the workflow will delegate to. Because the rails carry the discipline —
not the model — they hold no matter what's behind them: even your frontier agent can't cheat the
order. A nice bonus: a commodity model (a cheaper, interchangeable one — say
claude-3.5-haiku) becomes safe to use on the bounded steps,
because the structure keeps it honest.
# the role the tdd workflow delegates to
agents:
tdd-agent:
model: anthropic/claude-3.5-haiku # commodity, via OpenRouter/OpenAI-compatible
Start the workflow by calling flowgate.command with
definitionId: "cognitive/tdd", and
ask the agent to implement a small function. The workflow forces the sequence:
red → green → refactor. When the agent tries to write the implementation before
a failing test exists, a guard — a precondition checked before a declared move runs —
rejects it with a distinct error code:
← { "error": { "code": "GUARD_REJECTED",
"message": "requires a failing test on record" } } Not "discouraged" — writing the implementation isn't a move the agent can make until a test is failing on record. The agent stays honest because the rails, not the model, enforce the order — and every attempt, including the refused one, lands in the audit trail.
Step 4
Add a second repo entry to your gateway.yaml.
Start with a rule from your own loop — say, your agent can't open a PR until CI is green, or it
can open one but a human merges it (a move marked actor: "human" — the agent
literally can't fire it, it just waits for you). And it also scales: the same repo can carry a
mandatory security review and a human deploy approval across the whole team, by adding one line.
version: "1.0.0"
repos:
- path: ~/repos/cognitive-architectures # proven baseline — ours
- path: ~/repos/acme-agent-policy # your gates — an example repo
Everything loads under its own namespace; if two repos define the same id, it fails loud at
check rather than one silently winning;
a deliberate override of a baseline guardrail is explicit and audited — no silent drift.
Note: acme-agent-policy is an illustrative name, not a real package — repos are mix-and-match; organize them however fits your team.
Step 5
Change a path: to a personal or company GitHub repo.
Same rails, your rules. That's the model — a dependency graph for agent behavior:
official, company, personal, and someday industry packs (HIPAA, SOC 2, fintech controls),
composed freely.
Like extending a base ESLint config or a Docker base image — but for what your agent is
allowed to do. Publish once, git pull to update everywhere.