Skip to content

Governance patterns: branch protection as agent gate, CODEOWNERS

Governance patterns: branch protection as agent gate, CODEOWNERS

Section titled “Governance patterns: branch protection as agent gate, CODEOWNERS”

Autonomous agents need constraints. But those constraints must be:

  • Enforceable — the agent can’t opt out
  • Configurable — operators can adjust without redeploying agents
  • Auditable — every approval and bypass is logged
  • Granular — “require human review for infra changes” != “require human review for everything”

The rig’s answer: use GitHub’s existing branch protection and CODEOWNERS system as the enforcement layer. Agents work within these constraints because they can’t merge without satisfying them — the GitHub API enforces it, not the agent’s self-discipline.

Every dashecorp/* production repo has a protected main branch with:

Required status checks:
- ci (build + lint + test)
- conductor-gate (Closes #N check)
Required reviews: 1
- Dismiss stale reviews on new commits: true
- Require review from CODEOWNERS: see CODEOWNERS section
Restrictions:
- No direct push to main (agents included)
- No force push
- No branch deletion

The “1 required review” is satisfied by Review-E’s approval (she’s in the GitHub org as review-e-bot). For repos without CODEOWNERS, Review-E’s approval + CI green = auto-merge eligible.

Rig-conductor registers a GitHub App that posts a required status check conductor-gate on every PR. The check passes only if:

  1. PR body contains Closes #N or Closes owner/repo#N
  2. No unresolved review threads
  3. Issue is in ISSUE_ASSIGNED state (not closed, not stuck)

This prevents:

  • PRs that don’t close an issue (orphaned work)
  • PRs merged before Review-E resolves her comments
  • PRs for issues that were already closed by another agent

The conductor gate is separate from CI. It runs independently via webhook and can pass or fail without blocking the CI queue.

CODEOWNERS files give operators surgical control over which paths require human approval. The pattern:

# .github/CODEOWNERS in dashecorp/rig-gitops
# Anyone can review most content
* @review-e-bot
# Infrastructure changes require a human
/apps/** @<the-operator>
/clusters/** @<the-operator>
/infrastructure/** @<the-operator>
# Agent character files require human review
/apps/*/character.yaml @<the-operator>

With this CODEOWNERS file:

  • A PR changing apps/dev-e/rig-agent-helmrelease.yaml requires the operator’s approval even if Review-E already approved it
  • A PR changing src/content/docs/research/new-doc.md only needs Review-E

This creates a two-tier governance model:

Path typeRequired approverHuman involved?
Application code / docsReview-E botNo
Infrastructure / Helm configsHuman ownerYes
Agent character filesHuman ownerYes
Security-sensitive filesHuman ownerYes

No model changes required. When the operator wants to add a new sensitive path to human review, they edit .github/CODEOWNERS. They don’t retrain a model, don’t update agent prompts, don’t redeploy. The enforcement is in GitHub’s infrastructure, not in the agent’s reasoning.

Audit trail is automatic. Every PR approval, dismiss, and bypass is logged in GitHub’s audit log. The operator can answer “who approved the HelmRelease change on April 21?” from the GitHub UI.

Agents can’t bypass it. A Dev-E pod cannot merge a PR against a CODEOWNERS-protected path even if it somehow generated an approval token — GitHub’s merge API enforces CODEOWNERS before accepting the merge request.

As the rig matures, governance tiers can evolve:

PhaseTrust model
EarlyEvery PR needs human approval
CurrentReview-E approves code; human approves infra
FutureReview-E approves most things; human reviews only cost-threshold or security-classified changes

This evolution happens by changing CODEOWNERS and branch protection rules — not by changing the agents. The governance layer is intentionally decoupled from the agents so trust can be incrementally extended as the rig proves reliability.