TAOS
← White Papers
AI Engineering

Change a Policy. Don't Restart the Agent.

May 1, 2026Taos Team
Policy-as-CodeHot ReloadDevOps

Change a Policy. Don't Restart the Agent.

Category: AI Engineering | Reading time: 5 min


The Deployment Tax on Policy Changes

Every time a compliance requirement changes, a finance team raises the approval threshold, or a new vendor category needs different treatment, your engineering team faces a familiar sequence:

  1. Write a Jira ticket
  2. Developer interprets the requirement, modifies if-else logic in application code
  3. Code review
  4. Testing
  5. Deployment (with all associated CI/CD latency and downtime risk)
  6. Verification

A policy change that should take 10 minutes takes 2–4 weeks. The compliance team waits. The control is temporarily inconsistent — old code, new requirement. And the next change starts the cycle again.

This is the deployment tax on policy changes. It exists because policy is embedded in application code rather than managed as a first-class artifact.

The Taos governance kernel eliminates this tax by separating policy from code. Here's how it works.


Policy as a File, Not a Function

In a traditional payment application, the approval matrix looks like this:

def requires_approval(amount: float, vendor_status: str) -> str | None:
    if vendor_status == "blocked":
        raise PolicyError("Vendor blocked")
    if amount < 1000:
        return None  # auto-approve
    elif amount < 25000:
        return "manager"
    elif amount < 250000:
        return "vp_finance"
    else:
        return "cfo"

This is application code. Changing the thresholds means changing the code, testing it, deploying it. The compliance team can't touch it. Only engineers can.

In Taos, the same logic lives in policy.rego:

tier_auto_approve { input.amount < 1000 }
tier_manager      { input.amount >= 1000; input.amount < 25000 }
tier_vp_finance   { input.amount >= 25000; input.amount < 250000 }
tier_cfo          { input.amount >= 250000 }

required_role = "manager"    { tier_manager }
required_role = "vp_finance" { tier_vp_finance }
required_role = "cfo"        { tier_cfo }

This is not application code. It's a policy document. It lives in the Taos control plane, not in the application repository. The compliance team owns it.


The Live Reload Mechanism

When the compliance team edits the policy in the Taos UI and publishes a new version, the change needs to reach the running agent without a restart.

Taos solves this with the PolicySyncManager — a background task that polls the control plane for policy bundle updates:

class PolicySyncManager:
    async def _sync_once(self) -> None:
        bundle = await self._fetch_bundle(token)
        if bundle["version"] != self._last_version:
            # Rebuild the Rego engine with new source
            _reload_engine_from_source(bundle["rego_source"])
            self._last_version = bundle["version"]
            logger.info("Policy reloaded — version %s", bundle["version"])

Every 30 seconds (configurable), the manager checks if the policy version has changed. If it has, it rebuilds the regopy.Interpreter in-place — replacing the module-level engine that all subsequent check_policy() calls use. No restart. No redeployment. The new rules are effective on the next policy evaluation.


The Full Change Cycle: 10 Minutes

With live policy reload, the workflow for a policy change becomes:

Compliance team:

  1. Opens Policy Bundles in Taos control plane (2 min)
  2. Edits the Rego rule — e.g., changes input.amount < 1000 to input.amount < 2000 (2 min)
  3. Adds a note: "Q2 threshold increase per CFO directive ref. CFO-2024-Q2-001" (1 min)
  4. Publishes new version (30 seconds)
  5. Calls POST /api/policy/reload to force immediate pickup (optional — otherwise waits ≤30s) (30 seconds)

Total time: under 10 minutes. Zero engineering involvement. Zero deployment.

The change is versioned, attributed to the person who made it, and immediately active in all running agent instances.


PolicyTestPanel: Test in the Browser Before Going Live

Taos ships a PolicyTestPanel directly in the control plane UI. Before publishing a new policy version, you can test it interactively without touching the running agent:

  1. Open Policies → [your bundle] → Test tab in the control plane
  2. Pick the entity to test against (tool, step, or freeform JSON input)
  3. Fill in principal fields (role, attributes) and the relevant parameters
  4. Click Run Test — Regorus evaluates the bundle in the browser via WASM (no kernel round-trip)
  5. See the result instantly: outcome, reason, rule_fired, approver_role, denial_mode

The Test tab runs evalBundleFull() — the same deny-wins composition logic the kernel uses, implemented in WebAssembly Regorus so it runs in your browser at microsecond speed. The test reflects exactly what the kernel will do on the next real call.

After publishing and before relying on the live reload polling interval, you can also force an immediate reload:

Verifying the Change Took Effect

After publishing a new policy version, you can verify it's active:

# Check current policy version loaded in the agent
curl -H "Authorization: Bearer $TOKEN" \
     http://localhost:3502/api/policy/status

# Response:
{
  "sync_enabled": true,
  "current_version": 7,
  "refresh_interval_seconds": 30,
  "local_policy_path": "/app/workflows/vendor_payment/policy.rego"
}

And you can test the new threshold immediately:

# Submit a test payment at the new boundary
curl -X POST http://localhost:3502/api/payments \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"invoice_id": "TEST-1500", "mode": "governed"}'

# Check the policy_log in the response
# rule_fired should now be "tier_auto_approve" for amounts < $2,000

What Happens to In-Flight Workflows

A natural question: if a workflow starts under policy version 6 and the policy updates to version 7 while the workflow is running, which version applies to each step?

Taos evaluates policy at step execution time using the current engine. This means:

  • Steps that executed before the reload used version 6
  • Steps that execute after the reload use version 7

For most policy changes (threshold adjustments, role changes), this is fine — the change is incremental and any in-flight workflow will complete cleanly under either version.

For breaking changes (a new hard deny rule), you can use the TAOS_POLICY_REFRESH_INTERVAL to control when the reload happens — setting it to fire at a low-traffic window.

The policy log in the audit trail records which version was active at each policy evaluation, so you always know which rules governed each decision.


The Compliance Team as Policy Owner

The most important organisational shift that live policy reload enables is changing who owns the policy.

Before: Engineers own the approval thresholds, OFAC rules, and vendor categories because they're in code. Compliance describes requirements; engineering implements them.

After: Compliance owns the policy. They write the Rego (or work with a governance engineer to write it once), publish updates directly, and see the results immediately.

The engineering team maintains the kernel and the application infrastructure. The compliance team maintains the rules. These are appropriately different roles.


The Bottom Line

Policy changes shouldn't require engineering tickets. Threshold updates shouldn't require deployments. OFAC rule additions shouldn't wait for the next sprint.

Live policy reload — powered by regopy, PolicySyncManager, and the Taos control plane — makes policy changes a compliance team operation. The deployment tax disappears.

Change the policy. Don't restart the agent.


Tags: live policy reload, policy-as-code, AI governance, Rego, compliance automation, regopy, Regorus