You do not need
to replace your agent.
You place an independent execution-control boundary before state-changing actions. One synchronous call at the plan → act boundary returns a deterministic verdict before anything is issued.
The service never executes your tools. It evaluates the proposed call as JSON and returns an authorization decision.
One endpoint. One decision.
POST {GOVERNANCE_URL}/v1/evaluate
Authorization: Bearer {GOVERNANCE_TOKEN}
Content-Type: application/json
{
"trajectory": [
{ "tool": "transfer_funds",
"args": { "amount": 50000, "to": "acct_991" } }
],
"domains": ["finance"]
}{
"verdict": "BLOCK", // PERMIT | ESCALATE | BLOCK
"permitted": false, // execute only when true
"layer": "V5+",
"reason": "Ω violation: finance_high_value_unverified_transfer",
"omega_domain": "finance",
"trajectory_hash": "9f3c1a8e7b22",
"attestation": {
"engine_commit": "96ecd39…",
"ruleset_hash": "7b1f…"
}
}trajectory is the sequence about to run — one call or several. The response carries the governing rule, the Ω domain, a replayable trajectory_hash, and an attestation tying the verdict to the exact engine commit and ruleset.
The same six steps
in every deployment profile.
The calling identity and the authority it actually holds are resolved first.
The envelope and Ω definitions in force are loaded and verified by signature.
The proposed trajectory is evaluated deterministically. Permit, escalate or block.
Where escalation applies, an independent approver decides. Nothing executes while held.
Only an authorized transition is issued to the downstream system.
The proposal, policy state, verdict, approval and result are recorded and hash-linked.
Three branches.
One of them issues the call.
import { guardedDispatch, GovernanceBlocked } from "./governanceGuard";
// The boundary sits at plan -> act. Nothing above it changes.
try {
await guardedDispatch(
{ tool: "transfer_funds", args: { amount: 50000, to: "acct_991" } },
(call) => runTool(call), // PERMIT -> issue the call
(v) => routeToApprover(v.review), // ESCALATE -> independent approval
{ domains: ["finance"] },
);
} catch (e) {
if (e instanceof GovernanceBlocked) deny(e.result.reason); // BLOCK -> never issued
}from governance_guard import guard, GovernanceBlocked, GovernanceEscalation
try:
guard("transfer_funds", {"amount": 50000, "to": "acct_991"},
domains=["finance"])
run_tool(...) # PERMIT -> issue the call
except GovernanceEscalation as e:
route_to_approver(e.review) # ESCALATE -> independent approval
except GovernanceBlocked as e:
deny(str(e)) # BLOCK -> never issuedOn ESCALATE the response carries a review record you can render or forward to an approver:
{
"verdict": "ESCALATE",
"permitted": false, // held — not issued
"requires_human_review": true,
"omega_domain": "healthcare",
"review": {
"reason": "Clinical recommendation generated.",
"required_action": "Oncology consultant review.",
"decision_authority": "Oncology consultant",
"execution_status": "HELD FOR HUMAN REVIEW"
}
}The absence of an authorization
is not an authorization.
An unreachable evaluator, an unverifiable policy bundle, a tampered signature or a timeout all resolve the same way: the transition is not authorized, so the call is not issued.
# Fail-closed is the default and is not configurable away.
# An unreachable evaluator, an unverifiable policy bundle or a
# timeout all resolve to "not authorized" — never to "proceed".
except GovernanceUnavailable:
deny("authorization unavailable") # the call is not issuedThe adapter changes.
The contract does not.
Every verdict is replayable.
Where enforcement runs
is your decision.
One call, before the call.
Copy the guard, point it at an endpoint, and run a trajectory through it.