Part 5: Governance — Declarative Rules for Autonomous Behavior
agents · architecture · governance · arbiter · series
*This is Part 5 of a six-part series on the layers of an autonomous coding agent. Start with the introduction.*
---
The drift problem
Every autonomous system we've built has drifted.
Not catastrophically. Not dramatically. Quietly. A research loop generates follow-ups that generate more follow-ups, each slightly more abstract than the last. A cost tracker accumulates charges that individually seem small but compound to $30 before anyone notices. A code agent keeps generating plausible output long after it should have escalated.
The drift is not a bug in any single component. It's an emergent property of systems that optimize for completion without external constraints on what completion means.
Governance is the layer that prevents drift. It sits between intention and execution, evaluating every autonomous action against a set of rules before it happens. Not after the fact — before.
Why hardcoded limits fail
The natural response to drift is to add an if statement. Check the budget in the main loop. Add a counter for follow-ups. Hardcode a cap.
We did this. It worked for about a week.
The problem is not that hardcoded limits are wrong. The problem is that they scatter. The research loop has its caps in Python. The code generation agent has its caps in a different Python file. The task spawner has limits in a config. The escalation threshold is a constant somewhere in a module nobody remembers writing.
When you need to change a limit — and you always need to change limits — you have to find it first. When you need to understand why a system stopped or why it didn't stop, you have to trace execution through five different files in three different languages to reconstruct which limit fired and which didn't.
Hardcoded limits also can't compose. You can't say "if the daily spend exceeds $30, halt everything" in a way that applies across the research loop, the code agent, and the task spawner simultaneously. Each system has its own implementation of "check the budget," and they don't coordinate.
This is the argument for declarative governance: separate the policy from the code.
What declarative governance looks like
A governance engine is a service that evaluates rules against context. The rules are written in a readable, editable format — not embedded in application code. The context is provided by the caller: what's the current task, what's the current spend, how deep is the backlog.
In our system, we use Arbiter — a Go-based declarative rules engine built for exactly this problem. A cost circuit breaker looks like this:
rule DailySpendCircuitBreaker priority 1 {
when { session.daily_spend_usd > 50.00 }
then HaltExecution {
reason: "daily_budget_exceeded",
alert: "discord",
}
}
This rule is not Python. It's not Go. It's a declarative policy statement in a .arb file that reads like what it does. Changing the threshold from $50 to $100 is a one-line edit. Publishing the updated rule to the running server takes one command. The research loop, the code agent, and every other autonomous process check this same rule before acting.
The engine runs as a gRPC service. Clients call it with a context payload — current spend, task type, backlog depth, whatever the rules need to evaluate. The engine returns which rules matched and what actions to take: proceed, throttle, deny, halt. Every decision is logged.
What we govern
Our governance layer manages rules across five bundles, each handling a different concern.
Cost governance. Daily spend caps, hourly token throttles, and warnings as limits approach. The system governs its own budget. We raised the daily halt threshold three times in our first week — from $20 to $30 to $50 — each time a one-line edit published in seconds. The point is not that the initial threshold was wrong. The point is that changing it was trivial. That's what makes governance sustainable.
Model routing. Which model handles which task. Code generation routes to GPT-5.4. Documentation routes to Claude Sonnet. Deep research routes to Claude Opus — but only when the local model's confidence falls below 0.4. Critical tasks get the most capable model. Routine work stays local and free. The routing is a strategy, not a series of if-else statements: the engine evaluates the task context and returns the model assignment.
Research governance. This is where governance proved most valuable. Our research loop runs autonomously every two minutes, pulling topics from a backlog, synthesizing briefs, and queuing follow-up topics. Without governance, it produced 1,700 briefs in a week, burned through 3,000 API credits in minutes, and spiraled into a self-reinforcing loop of increasingly abstract follow-ups.
Nine rules now govern research: daily caps on Firecrawl API calls (500), research cycles (300), and follow-up topics (30). Backlog depth limits prevent unbounded queue growth. Focus enforcement rejects follow-up topics that don't match the studio's research priorities. Escalation gates cap deep research to 10 per day with a confidence floor of 0.4. Source quality flags mark briefs where most URLs returned errors.
The research loop went from ungoverned chaos to a focused, predictable system producing actionable research — not by rewriting the loop, but by wrapping it in rules.
Approval gates. Some actions need a human. The engine can gate a commit, require Discord notification before a merge, or block file deletions and force pushes entirely. The rules define which actions are automatic, which are gated, and which are forbidden. This is where governance intersects with trust — the subject of Part 6.
Feature flags. Capabilities like autonomous task spawning, the agentic code generation loop, and auto-merge can be toggled on or off through the engine's flag system without touching code. This lets you turn capabilities on incrementally: enable the agentic loop for documentation tasks before enabling it for code generation, for example.
---
Reading this because you're trying to build?
>
For custom architecture and consulting, work with ResonanceWorks — Talk to Consulting. For a ready-made install, start with Torque Engineering.
---
The category of tooling
Declarative governance for autonomous agents is a category, not a feature. The industry is converging on it from multiple directions: Microsoft's research architecture describes governance as an infrastructure service alongside compute and storage. Amazon's 2026 AI agent policy formalizes rules for autonomous pricing and inventory decisions. Gartner projects that 80% of governments will deploy AI agents with governance frameworks by 2028.
For an agent system, the tooling needs to deliver:
- Declarative rules. Policy expressed in a readable format that non-engineers can understand and modify. Not code. Not configuration buried in YAML. Actual policy statements with conditions and actions.
- Runtime evaluation. The engine evaluates rules at the moment of action, not at build time. Context changes — spend accumulates, backlogs grow, confidence drops — and the engine's decisions change with it.
- Composability. New rules can be added without touching existing ones. Rules organized into bundles that can be published and versioned independently. Cost rules don't interfere with routing rules.
- Graceful degradation. If the governance engine is unavailable, the system should fail safe — deny by default, not proceed unchecked.
- Audit trail. Every rule evaluation, every denial, every routing decision logged with the full context. When something goes wrong, the log tells you exactly which rule fired and why.
The implementation we use — Arbiter, from the same pure-Go ecosystem referenced throughout this series — delivers all five. It runs as a gRPC service with rules organized into named bundles. Publishing a new bundle is atomic: compile the .arb file, push it to the server, activate it. The previous version is retained for rollback. Clients in any language call the service through generated stubs. Arbiter is part of a broader stack that includes gotreesitter for structural code intelligence, CorkScrewDB for vector search, and Manta for model inference — all pure Go, all designed to compose.
What we learned
Governance matters more than model selection. We spent weeks tuning prompts and evaluating models. The single most impactful change to our system's reliability was adding cost circuit breakers. Not better models — better limits.
Start with caps, not permissions. Our first rules were all circuit breakers: stop if spend exceeds X, stop if the backlog exceeds Y. These prevent the worst outcomes immediately. Sophisticated routing and quality gates came later, once we understood where the system actually drifted.
Rules should be tunable by non-engineers. The .arb format works because anyone can read it and understand what the system will do. When we needed to raise the Firecrawl daily cap from 20 to 500 after upgrading our plan, it was a one-line change published in seconds. No deploy, no code review, no waiting for a developer.
Log everything the engine decides. Every matched rule, every denial, every routing decision. When our research loop was burning Firecrawl credits, the deny logs showed 3,163 consecutive failures with "Insufficient credits." Without those logs, we would have assumed the loop was just slow.
The governance layer is for runtime, not design time. It doesn't tell agents how to do their work. It tells them when to start, when to stop, and which resources to use. The agents own execution. The governance layer owns policy.
Governance makes memory actionable. Part 4 covered how agents accumulate knowledge across sessions. Governance uses that knowledge. A rule like "don't modify shared components without review" is blunt. A rule like "escalate changes to modules modified more than 3 times in the last 30 days" is precise — and requires memory to evaluate.
Where governance fails
Over-governance kills throughput. If every action requires approval, the system stops being autonomous. The art is finding the threshold where governance catches drift without choking productive work. We started too conservative (20 research cycles/day) and had to triple it once we saw the system was spending most of its time waiting for the cap to reset.
Stale rules. A rule written for last month's architecture may not apply to this month's. Rules need maintenance — reviewing, updating, removing. This is easier with declarative rules than with hardcoded limits (at least you can read them all in one place), but it's still operational overhead.
False safety. A governance layer that's never tested in failure conditions gives false confidence. We discovered our cost circuit breaker was checking stale counters from April 1st while running on April 9th — eight days of ungovened operation because the date hadn't rolled over. The fix was simple, but the failure was invisible until we looked at the logs.
What this enables for the layer above
Trust — Part 6 — is the capstone. An agent that can be trusted to operate autonomously needs both memory (Part 4) and governance (Part 5). Memory provides the facts: what happened, what was decided, what worked. Governance provides the constraints: what's allowed, what costs too much, when to escalate.
Trust is the synthesis. An agent that knows its own accuracy (from memory) and operates within declared limits (from governance) can make calibrated decisions about when to proceed and when to ask for help. That calibration is what makes the difference between an agent that runs for five minutes and one that runs for five days.
Next: Trust
In Part 6 we'll look at the trust layer — confidence calibration, self-assessment, the economics of agent accuracy, and what it takes to build systems that earn trust rather than demanding it.
---
Get the rest in your inbox
The series lands roughly every week or two. Six parts in total, each standing alone and building on the last. Subscribe to get new parts the day they ship, plus occasional technical notes on what we're learning from running these systems in production.
Need custom help designing your stack?
ResonanceWorks works with founders and small teams on architecture, governance, and private AI system design. We take a small number of engagements at a time and work closely with founders and technical leads. Talk to Consulting.
Want a ready-made local-first system instead?
Torque Engineering installs performance-tuned private AI for independent operators. Explore Torque Engineering.
Exploring human-machine culture?
Entrainment House publishes music, art, and cultural works shaped through human-machine coordination. Enter the House.