The Second Axis Approach to Agent Guardrails

Date: July 8, 2026 • Author: Second Axis • Category: Engineering

Landscape event photo

Your agent runs at 3 AM. It reads your standup notes, finds a bug report, and files a ticket in Jira. Helpful. Except it filed the ticket in the wrong epic, and it posted the summary in #general instead of #engineering.

Nobody was awake to stop it. That is the whole problem with autonomous agents in one sentence: the more useful they are, the less often a human is watching when they act.

Chat tools solved this with a popup. The agent wants to do something, you click Allow or Deny. That works great when you are sitting there. It is useless for an agent that runs on a schedule. You cannot approve an action in your sleep.

So we built something else. In Second Axis, you tell the agent the rules in plain English. The agent turns your words into real code rules. And from then on, every action it takes is checked against those rules, by code, not by AI.

This post explains how it works, and what we found when we checked whether anyone else had built it.

First, everything goes through one door

You cannot enforce rules if actions can sneak around them. So the first step had nothing to do with policies at all.

Second Axis agents connect to a lot of tools: Slack, Jira, Linear, Notion, Gmail, GitHub, and about 40 more. Until recently each of those was its own separate connection. Rules would have needed to live in 20 different places, and a new integration could forget them entirely.

So we collapsed everything into a single MCP server. (MCP is the open standard AI agents use to call tools.) Every tool the agent can touch, whether it is our own or a third party's, is now served through one server with one dispatch function.

That one function is the door. Every action passes through it, by construction. There is no second path. Which means a rule enforced at that door cannot be skipped, forgotten, or worked around.

Not every tool needs a gate

Once every call goes through one door, the lazy answer is to check everything. That would be miserable. Most of what an agent does is harmless, and asking about it would train you to click Allow without reading.

So the policy layer first sorts every tool into one of three classes:

The three classes of tools: read, write inside Second Axis, and write outside

The sorting is based on what a tool touches, not where it lives. Creating a Jira ticket runs in our own code, but it changes something in your Jira, so it counts as an outside write. A web search calls an outside service, but it only reads, so it runs freely.

Reads run freely. Writes inside Second Axis run freely, because they stay in your workspace and are easy to undo. Writes to your outside tools are the only class that can actually hurt you, so that is the only class we gate. And when we cannot tell what an unfamiliar tool does, we treat it as an outside write. Unknown means gated, not ignored.

The interesting part: the agent writes the rules

Here is the moment that made us want to write this post.

When you set up a scheduled agent in Second Axis, you describe the boundaries the same way you would brief a new teammate:

Only create tickets in the Mobile epic. Only post in #engineering. Never email anyone outside the company.

That sentence is not a hint. It becomes law. The agent reads the actual definition of each tool it will use, finds the exact field your rule is about, and compiles your sentence into a small, precise check. "Only post in #engineering" becomes a rule on the channel field of the Slack tool. The rule is validated against the tool's real schema before it is saved, so a rule about a field that does not exist fails right away instead of silently doing nothing.

How it works: you state the rule, the agent compiles it, and every action is checked at the door

Then, every time the agent acts, the door checks the real arguments of the real call against the saved rules. Ticket in the Mobile epic: passes. Post to #general: blocked, with the exact rule that blocked it.

The same agent that will be governed by the rules is the one that writes them. It writes them once, in conversation with you. After that, it lives inside them.

Why AI never makes the final call

There is a popular way to build guardrails right now: put a second AI in charge of judging the first one. Every action goes to a judge model that decides if it looks safe.

We decided against it, and this is probably our strongest opinion in the whole design.

A tool call is structured data. The Slack call literally contains channel: "#general". You do not need intelligence to check whether that equals "#engineering". You need an equality check. Using a model to answer a question that code can answer buys you four problems for free: it can be wrong, it costs money on every call, it adds seconds of delay, and you can never fully explain its decision afterward.

The deterministic version has none of those. Same input, same answer, every time. It costs nothing and runs instantly. And when something is blocked, we can show you the exact rule that fired, which is the difference between an audit log and a shrug.

So the AI in this system has exactly one job: translating your English into a rule, once, while you are there to confirm it. At runtime, when nobody is watching, there is no model in the decision path at all. The clever part happens while you are in the room. The boring, reliable part runs at 3 AM.

Didn't someone already build this?

We asked ourselves the same question, and the honest answer is: the pieces exist, the loop does not.

Checking structured requests against code rules is a decade-old idea called policy as code. Open Policy Agent and Cedar do it for APIs and infrastructure. It is proven, which is exactly why we trust the approach.

The agent world is catching up fast. AWS Bedrock AgentCore Policy intercepts agent tool calls at a gateway with Cedar rules, and it can even help a developer draft those rules from English in the AWS console. A wave of MCP gateways like Invariant, Lasso, and Pomerium let security teams write rule files for agent traffic. Researchers have gone further: Progent and Conseca both showed that an LLM can generate tool-call policies that are then enforced deterministically.

Here is what we could not find anywhere: a shipped product where the end user sets the boundary in one plain sentence, the agent itself compiles that sentence into a deterministic rule by reading its own tools, and the rule then governs that same agent at a door it cannot go around. In every product we found, a developer or a security engineer writes the policy in a console or a config file. The research systems generate policies automatically from task context, not from a user's stated intent. The full loop, from your sentence to enforced code, inside one product, written by the agent it governs, is the part we had to build ourselves.

Who writes the ruleWhere it is writtenEnforced by
Cloud policy enginesDeveloper or security teamConsole, Cedar codeCode at a gateway
MCP gatewaysSecurity engineerRule files, YAMLCode in a proxy
Research prototypesAn LLM, from task contextInside the frameworkCode in the harness
Second AxisThe agent, from your sentenceIn conversationCode at one door

What we are still working on

A few honest open questions, because a system like this is never finished.

Rules can conflict, and we need clearer behavior when they do. Some boundaries are easy to state and hard to compile, like "never message anyone outside the company," which needs to know what "outside" means. And the authoring step itself deserves scrutiny: if a prompt injection can trick the agent while it is writing a rule, the rule inherits the trick, which is why rules are written once, shown to you, and confirmed before they ever run.

We would rather name these now than have you find them later.

Where this lands

The approval popup was built for a world where you watch your agent work. That world is ending. Agents increasingly act on schedules, on triggers, and overnight, and the security model has to work when the human is asleep.

Our answer is a simple split. Let the model be clever exactly once, with you in the room, turning your words into rules. Then let plain, boring, auditable code hold the line every time after that, at a single door every action must pass through.

You describe the boundary. The agent writes the rule. The rule runs as code. That is the whole idea, and we think it is how autonomous agents earn the right to act unattended.