Maxxwell by Rindler
Writing

Policy checks and guardrails for AI coding agents

2026-09-21

You already know your AI coding agents can write code. The hard part is stopping them from merging unsafe or non-compliant changes while you’re juggling ten.


You already know your AI coding agents can write code. The hard part is stopping them from merging unsafe or non-compliant changes while you’re juggling ten sessions at once.

This walkthrough shows how to turn coding standards, security rules, and compliance constraints into policy checks that every agent must pass before anything lands.

It’s a companion to the broader pillar: AI coding agent orchestration: the complete guide for multi-agent development.


What we’re actually building

You’ll set up an orchestration layer that enforces:

Concretely, you’ll:

  1. Define policy-as-code for your AI agents
  2. Wire it into your orchestrator (Maxxwell, homegrown, or another platform)
  3. Gate agent changes with CI/CD checks and protected branches
  4. Add audit logs so you can explain why the agent was blocked

All examples assume:


Step 1: Decide which decisions belong to policy, not the agent

Agents are good at “how to implement X”. Policies are for “whether X is allowed.”

Start by writing down specific guardrails:

Then assign each guardrail to one of three buckets:

Write this down as a simple table before touching code. This is your policy spec.


Step 2: Encode guardrails as policy-as-code

Now turn the spec into something the orchestrator and CI can execute.

The practical pattern is: OPA (Open Policy Agent) + Rego as a decision engine, fed by CI and the orchestrator.

2.1 Define the input shape

Decisions need structured input. For an AI agent change, you typically have:

{
  "repo": "payments-service",
  "branch": "feature/agent-update-123",
  "author": "ai-agent-claude",
  "files": [
    { "path": "src/payments/handler.py", "changed_lines": 42 },
    { "path": "src/payments/sql_queries.sql", "changed_lines": 10 }
  ],
  "tests": {
    "passed": true,
    "coverage_delta": -2.5
  },
  "security_scan": {
    "status": "fail",
    "critical_vulns": 1,
    "xss_findings": 2
  },
  "license_scan": {
    "status": "pass"
  },
  "agent": {
    "id": "claude-code-1",
    "role": "worker",
    "orchestrator_session": "orchestrator-42"
  }
}

Your job: make sure your CI pipeline can produce this JSON and hand it to OPA.

2.2 Write Rego policies for AI agent changes

Create policy/agent-change.rego:

package ai.agent.change

# Entry point: should this change be allowed to merge?

default allow := false

# Hard blocks

deny[reason] {
  input.security_scan.status == "fail"
  reason := "security_scan_failed"
}

deny[reason] {
  input.security_scan.xss_findings > 0
  reason := "xss_vulnerabilities_present"
}

deny[reason] {
  input.tests.passed == false
  reason := "tests_failed"
}

deny[reason] {
  input.tests.coverage_delta < -5
  reason := "code_coverage_regression_too_high"
}

# Soft warnings

warn[reason] {
  input.agent.author == "ai-agent-claude"
  reason := "change_authored_by_ai_agent"
}

warn[reason] {
  some f
  f := input.files[_]
  endswith(f.path, "sql")
  reason := "sql_file_modified_require_manual_review"
}

allow {
  not deny[_]
}

This one file:

You can extend this with coding standards, PII rules, or license checks.


Step 3: Plug policy checks into CI/CD and protected branches

You now need the policy decision to be merge-blocking, not just advisory.

3.1 GitHub Actions example

A minimal workflow to enforce AI agent policies:

# .github/workflows/ai-agent-policy.yml
name: AI Agent Policy Check

on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  policy-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run tests
        run: |
          pytest --maxfail=1 --disable-warnings -q

      - name: Run security scan
        run: |
          ./scripts/run_security_scan.sh --format json > security.json

      - name: Build policy input
        run: |
          python scripts/build_policy_input.py \
            --security security.json \
            --output policy-input.json

      - name: Evaluate OPA policy
        run: |
          opa eval \
            --format=json \
            --data policy \
            --input policy-input.json \
            "data.ai.agent.change" > decision.json

      - name: Fail if policy denies
        run: |
          python scripts/enforce_policy.py decision.json

enforce_policy.py can be straightforward:

import json
import sys

with open(sys.argv[1]) as f:
    decision = json.load(f)

result = decision["result"][0]["expressions"][0]["value"]

allow = result.get("allow", False)

if not allow:
    reasons = result.get("deny", [])
    print("Policy denied change. Reasons:")
    for r in reasons:
        print("-", r)
    sys.exit(1)

warnings = result.get("warn", [])
if warnings:
    print("Policy warnings:")
    for w in warnings:
        print("-", w)

3.2 Enforce via protected branches / rulesets

On GitHub:

On GitLab:

This implements OWASP’s pattern: least privilege + required checks + protected merge paths.

Most orgs deploy AI agents before governance: 69% are in production, yet only 21% track agents and MCP connections, and 79% lack monitoring policies.


Step 4: Teach your orchestrator to respect policies

CI stops bad merges. Your orchestration layer should stop pointless work and give you signal earlier.

You want three behaviors:

  1. Agents know the policy
  2. Sessions surface policy failures and warnings in their state
  3. Orchestrator doesn’t act; it drafts requests that you send

4.1 Brief the orchestrator seat with policy context

If you use Maxxwell, the orchestrator seat is just another coding-agent session started from a brief.

Create a short policy brief:

You are the orchestrator for multiple coding agents.

Before asking any worker to implement a change, enforce these rules:
- No change should proceed without a test plan.
- If a change touches auth, payments, or PII, require explicit human review.
- If CI policy denies a change, stop that worker and report back.

Summarise for me:
- What landed (merged to main)
- What is blocked by policy
- What needs my decision

Do not run git or CI commands yourself. Only draft instructions for workers.

In Maxxwell, that brief is what the orchestrator seat is started from.

4.2 Mark session state with policy results

Your orchestrator should treat policy status as part of session state visibility.

Example states:

In Maxxwell, session tiles already show a readable state per session. Tracking policy status alongside that state gives you:

4.3 Draft, don’t act, on policy-driven fleet changes

One subtle but important guardrail: controls draft rather than act.

In Maxxwell, any fleet control that would:

…writes a fully formed, unsent sentence into the composer. It never runs the command.

This matters for policy:

The human stays the one who commits and merges. Policy helps you decide; it doesn’t secretly override you.


Step 5: Add audit logs and explainability

NIST and OWASP both care about traceability: you need to explain why the agent was allowed or blocked.

Make sure your stack writes:

OPA already supports decision logs. Turn them on:

opa run \
  --server \
  --log-level debug \
  --set=decision_logs.console=true

And pipe them somewhere with retention.

This gives you a story you can tell:


Step 6: Wire security and compliance deeper into the workflow

The data says the raw AI output needs guardrails: Veracode saw 45% of generated samples fail security tests; XSS showed up in 86% of relevant samples.

Use policy to push checks earlier:

Your orchestrator doesn’t need to understand each tool. It needs to:

Maxxwell’s role here is simple: it keeps all sessions visible, with a readable state for each one, and never pretends a missing signal is fine.


Step 7: Start small, then tighten

You don’t have to build the full NIST AI RMF stack on day one.

Practical rollout:

  1. Week 1-2: Require tests + basic security scan for all AI-authored changes; block merges when they fail.
  2. Week 3-4: Add language-specific rules (e.g. SQL, auth, payments) as soft warnings; require human review.
  3. Week 5+: Bring in license and PII policies; add audit logging and reporting.

Each step gives you more control without breaking developer flow.

If you’re coordinating many agents by hand today, Maxxwell is a reasonable orchestration layer to start with: it runs locally, keeps your agents in real terminals you control, and adds visibility and drafting without trying to be another copilot.


FAQ

How do I enforce coding standards for AI agents without slowing humans down?

Scope policies to author identity and branch patterns.

Example:

Use labels (ai-generated, agent:claude) and Rego conditions (input.agent.author) to apply stricter rules to AI changes.

What’s the minimum viable policy to stop really bad AI code from merging?

A reasonable baseline:

Encode that in OPA and make the CI job a required check on protected branches.

This alone filters out a large chunk of the 45% of AI-generated samples that would fail basic security tests.

Do I need OPA, or can I just script this in CI?

You can start with scripts, but OPA helps when:

Scripted checks are fine early; migrate to OPA when you find yourself copying the same logic into five different workflows.

How does Maxxwell fit into this guardrail setup?

Maxxwell doesn’t replace your AI coding agents or your CI.

It:

With policy hooked into CI, Maxxwell becomes the place you see which agent sessions are blocked by guardrails and draft what happens next - without giving it permission to act on its own.

How do I prevent agent drift in multi-agent workflows?

You won’t get automatic drift correction out-of-the-box.

Use policy and orchestration together:

Policy keeps bad code out of main; the orchestrator keeps agents pointed roughly at the right goal. The human still decides when to re-aim or kill a session.