Coding agents are crossing an important boundary. They are no longer limited to suggesting the next line of code. They can inspect repositories, edit files, run shell commands, install packages, call external tools, change infrastructure, and prepare software for production.
That’s a major productivity shift. It’s also a governance shift.
The question is no longer just can the agent write good code? It’s also: what is the agent allowed to do, who granted that authority, what actually happened, and what proof is required before the result can be trusted?
Most teams still answer those questions with prompts, repository instructions, and manual review. Those mechanisms are useful, but they aren’t a control plane. Guidance can shape what an agent tries to do. Governance determines what it may do.
This article presents a reference architecture for a standalone, local-first governance layer for Claude Code. It’s designed to preserve the speed of agentic development while adding deterministic policy enforcement, least-privilege execution, risk-sensitive evidence, and human authority where consequences are high.
The goal isn’t to make Claude Code less autonomous. It’s to make autonomy safe enough to use seriously.
CLAUDE.md is excellent for coding standards, architectural preferences, preferred libraries, and review checklists. But an instruction file shouldn’t be treated as a security boundary.
A useful separation looks like this:
This distinction matters because repository content is also part of the agent’s context. A README may tell the agent to run an installation command. A code comment may contain outdated deployment instructions. Tool output or an external MCP response may contain text designed to trigger actions.
Information entering context doesn’t automatically deserve authority. That’s the first foundational rule:
Information may influence the agent without granting it permission.
The proposed control plane lives with the software project under one authoritative root:
.ai-governance/
It’s versioned, inspectable, testable, portable, and available offline. It doesn’t require a remote policy server, a central authorization service, or another agent framework.
Claude Code already provides the extension points needed to make this architecture practical. Its hooks can run deterministic checks at defined lifecycle events, and PreToolUse can evaluate a tool call before it proceeds. Claude Code’s permission system separately applies deny, ask, and allow rules, with restrictive rules retaining precedence. Importantly, these controls are implemented by the runtime — not by asking the model to police itself. (See the official documentation for hooks, permissions, and plugins.)
The result is a compact operating model:
That simple model hides sophisticated mechanics inside the plugin, where they belong.
Raw tool calls are too inconsistent for reliable policy. Consider:
git push --force origin main
The governance layer shouldn’t match this as an arbitrary string. It should normalize it into a canonical action:
category: gitoperation: pushresource: maineffects: - external_write - destructiverisk: high
Now policy can reason about meaning rather than syntax.
This is also where security hardening becomes real engineering. A naive policy that only blocks --force can miss -f, --force-with-lease, --mirror, or Git’s +refspec form. A naive path rule can be bypassed with symlinks, .., or alternate path representations. A shell command may combine safe and destructive operations with pipes, conditionals, or command substitution.
The adapter must therefore:
Deterministic governance succeeds or fails at this normalization layer. If two equivalent actions produce different policy outcomes, the control isn’t dependable.
An available tool is a capability. It isn’t authorization.
The proposed architecture gives each session a privilege envelope: the maximum set of operations, resources, destinations, and environments the agent may use without expanding its authority.
For example, a development session may be able to:
The same session may need explicit approval to:
This yields an important distinction: policy approval asks whether an action may happen. Privilege expansion asks whether the session may become more powerful. Those aren’t the same event, and they shouldn’t share the same approval semantics.
Authority also depends on provenance. A direct human instruction, approved project configuration, repository text, tool output, and external content shouldn’t carry equal weight. Users don’t need to manage a complicated authority lattice — the interface can expose three understandable trust classes:
Only authority-bearing arguments, such as a command, URL, branch, package, destination, or deployment environment — need targeted provenance tracking. Full taint tracking would add enormous complexity for little MVP value.
Mandatory controls should rely on exact operations, effects, canonical paths, branches, environments, argument patterns, risk thresholds, and policy precedence.
The runtime decision itself can stay small:
ALLOW · WARN · REQUIRE APPROVAL · DENY
But the decision should carry a structured explanation, including:
This produces a governance judgment, not just a boolean result.
Independent checks should compose conservatively. If one policy allows an action but another identifies a protected resource, the more restrictive judgment wins. If a compound shell command contains one dangerous segment, the entire command is judged by that segment.
LLMs can later provide advisory classification or help draft policy, but they shouldn’t override mandatory deterministic controls. The model is the actor being governed, it shouldn’t also be the final enforcement authority.
This is the architectural distinction many agent-governance approaches miss.
Action governance asks: may this tool call execute now?
Change governance asks: is the accumulated software change ready to be accepted?
A sequence of individually permitted actions can still produce a high-risk change. Editing an authentication flow, a database migration, a CI workflow, or Terraform configuration may be legitimate — but it should create stronger evidence obligations than editing documentation.
The changed files determine the risk zone. The risk zone determines what evidence is required:
This produces a change-state machine such as:
READY → NEEDS_EVIDENCE → PENDING_HUMAN_REVIEW → HUMAN_REVIEWEDany state → BLOCKED
The agent may complete its technical work and still be unable to declare the change governance-ready. That’s a feature, not a failure.
The system shouldn’t store hidden reasoning or unrestricted prompt history. It should record observable events:
For consequential actions, the plugin creates a lightweight receipt. Receipts are linked to append-only evidence and can be hash-chained so silent rewriting is detectable. Sensitive values are redacted; chain-of-thought is never captured.
This changes the review conversation. Instead of asking “did the agent test this?”, a reviewer can see which test command ran, whether it succeeded, which change it relates to, and whether the evidence satisfies the applicable obligation.
Evidence doesn’t eliminate human judgment. It makes human judgment faster and better grounded.
A powerful policy engine with a painful setup experience will fail socially before it fails technically.
The right first-use flow isn’t “author six YAML files.” It’s:
Install plugin→ Run onboarding→ Inspect the repository automatically→ Ask only unresolved, high-value questions→ Generate configuration and scenario tests→ Validate and synchronize native permissions→ Start in OBSERVE mode
The onboarding experience should identify languages, frameworks, package managers, infrastructure, CI, sensitive directories, protected branches, secret locations, and production-capable operations. A normal repository should require only a handful of meaningful questions.
Configuration should scale progressively:
The engine can be sophisticated without forcing every user to become a governance specialist.
Governance should earn trust before it blocks work. The recommended adoption path is:
OBSERVE → WARN → ENFORCE
In Observe, every policy is evaluated and evidence is collected, but no action is blocked. This reveals false positives and missing rules.
In Warn, developers see conflicts while most work continues. The team can measure friction and tune policy.
In Enforce, denials are blocked, approval-required actions must be approved, and invalid mandatory configuration fails closed.
A balanced profile keeps ordinary development nearly invisible: routine work proceeds, unusual privilege expansion triggers a question, and genuinely prohibited behavior stops. The design target isn’t maximum control — it’s minimum unnecessary friction with no silent degradation.
A governance system that can be edited by the process it governs is only theater.
The monitor needs a built-in self-protection set covering at least:
It also needs adversarial tests for bypass variants not just happy-path policy tests: force-push aliases, symlink escapes, encoded shell commands, indirect destructive operations, prompt injection in repository content, forged test evidence, governance tampering, privilege expansion, unknown tools, and MCP actions.
The most dangerous failure mode isn’t a visible denial. It’s an ungoverned session that everyone believes is governed. Therefore: never degrade silently. If mandatory policy can’t load, evidence integrity fails, or a critical action can’t be classified, the system must make the degradation visible and react conservatively.
Enterprise governance discussions often jump straight to centralized authorization services, remote approval workflows, signed identities, and global audit ledgers. Those may become valuable extensions. They aren’t required to prove the core product.
A repository-attached, standalone plugin has three advantages:
If you already run coding agents with production-capable permissions, the question worth answering is narrow: what actually stops a bad action today deterministic policy, or review after the fact?
Next in this series: the code.
Follow if you want the repo the day it lands.
A Practical Architecture for Governing AI Coding Agents, Without Slowing Developers Down was originally published in Towards AI on Medium, where people are continuing the conversation by highlighting and responding to this story.