Two runtimes. One verdict.
The Node and Python evaluators are held to a shared conformance fixture, so an SDK and the gateway cannot quietly disagree about whether an action is allowed.
Node
The common pattern is guard.wrap: put the decision in front of the function you want governed, and leave the function itself alone.
import { guard } from "@cirvix_ai/agent-control"; const readFile = guard.wrap( { action: "read:file", agent_id: "agent-01" }, async (path) => fs.readFile(path, "utf8") ); // Denied calls throw before the body runs. // The decision is recorded either way. await readFile(".env"); // CirvixDenied: deny-dotenv-read
The gateway and the SDK share one decision core, so wrapping a call locally and routing it through the gateway produce the same verdict for the same request.
Python
The Python package ships a native evaluator rather than a thin HTTP client, so a local decision does not require a round trip.
from cirvix import Guard guard = Guard(org_id="acme-42") @guard.wrap(action="read:file", agent_id="agent-01") def read_file(path: str) -> str: return open(path).read() read_file(".env") # CirvixDenied: deny-dotenv-read
Pre-built Ecosystem Plugins (10-Second Setup)
Drop Cirvix governance into leading developer tooling and multi-agent frameworks with zero architectural overhaul.
Custom MCP Gateway Flag
Register the Cirvix gateway as a Model Context Protocol tool provider in one terminal command:
# Auto-registers into Claude Code MCP registry
claude mcp add cirvix -- cirvix gateway --strict
All tool execution requests (bash, file edit, web access) pass through kernel and policy verification before reaching execution.
Silent Background Daemon
Install the official extension from the marketplace (cirvix.agentcontrol) or enable silent daemon boot in settings:
// .vscode/settings.json { "cirvix.daemon.autoStart": true, "cirvix.enforcePolicies": "strict", "cirvix.ipcSocket": "unix:///var/run/cirvix/ipc.sock" }
1-Line Python Middleware
Intercept tool calls, API egress, and state mutations across any Python agent framework with Guard.wrap():
from cirvix import Guard # 1-line wrap for LangChain, LlamaIndex, or CrewAI agents agent = Guard.wrap(raw_agent, agent_id="autonomous-analyst")
Framework Examples
from cirvix import Guard from crewai import Agent, Crew, Task from langchain.agents import create_openai_tools_agent # 1. Wrap LangChain Agent langchain_agent = create_openai_tools_agent(llm, tools, prompt) governed_agent = Guard.wrap(langchain_agent, agent_id="triage-agent") # 2. Wrap CrewAI Crew crew = Crew(agents=[dev_agent], tasks=[refactor_task]) governed_crew = Guard.wrap(crew, agent_id="dev-crew") # Any tool invocation that violates policy throws CirvixDenied # and records a hash-chained (unsigned) entry in the audit log.
Why a shared fixture
Two implementations of the same rule language will drift. The conformance fixture is the thing that stops that: a corpus of requests and expected verdicts that both engines must reproduce exactly.
It earns its keep. When the fixture was first run across both engines it immediately surfaced a real path-canonicalization difference on Windows — a case where the two evaluators would have disagreed about whether a resource matched.
| Guarantee | Enforced by |
|---|---|
| Same request, same verdict, either language | Shared conformance fixture, run in CI |
| SDK and gateway cannot disagree | One decision core, shared by both paths |
audit_only never authorizes | Evaluator, not policy convention |
| Glob patterns stay inside their segment | Literal matcher, covered by the fixture |
Not available
There is no Go, Java, or Ruby SDK today. If your runtime is not Node or Python, use the HTTP gateway or the Single-Binary Daemon — it is the same decision core behind a network boundary. We would rather say this plainly than list a language we have not built.
Bring every agent
under control.
Set durable policy, preserve a verifiable record, and give teams a safer way to put intelligent systems to work.