GVNR by Instruxi
io.gvnrPublished by gvnr.iov0.30.0Updated Oct 24, 2026
GVNR (gvnr.io): stops AI agents overspending and running dangerous commands before they act.
The publisher's own server: Gvnr
Overview
A local Claude Code governor that decides whether an agent action is allowed before it runs, enforcing spend limits and capability rules with a hash-chained…
- What you can do
- Runs as a local stdio process that intercepts agent tool calls and returns allow, deny, ask, or rewrite decisions. It enforces per-agent dollar spend limits, rate limits, loop detection, and capability rules such as refusing scripts piped into a shell or asking before destructive deletes, force-pushes, secret access, and deploys. Every decision is appended to a hash-chained receipt file that can be verified for tampering. Optional sign-in to an Enforcer workspace adds tenant policy checks and receipt shipping.
- When to use it
- Use it when running autonomous or long-running Claude Code agents that could overspend, loop, or run risky shell and git commands. It suits teams that want a local, auditable record of agent decisions and optional organization-wide policy enforcement.
- Requirements
- Runs locally via npx enforcer-governor as a Claude Code plugin; desktop only. Environment variables GOVERNOR_PORT (default 4000) and GVNR_AGENT (default random per session) configure it. Signing in to an Enforcer workspace is optional and requires credentials stored at ~/.enforcer/credentials.json.
Installation
In SourceWeft
- Open GVNR by Instruxi in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
Enforcer Governor
A Claude Code plugin that decides whether an agent action is allowed before it runs — and keeps a record you can prove.
Agents get stuck in loops, repeat work, and run scripts straight off the internet. Every other tool reports the damage afterwards. This one answers a question first:
May this agent do this, right now?
- allow — in budget and on task, carry on
- rewrite — run it, in a form the policy accepts
- deny — over budget, looping, or not permitted at all
- ask — pause and check with you
Every decision is appended to a hash-chained record. Edit or delete a single line and the chain visibly breaks. Until you sign in to an Enforcer workspace, everything stays on your machine — see What leaves your machine.
Install
Then restart Claude Code and sign in once with /enforcer:login. The enforcer plugin is the connection to your Enforcer workspace (its MCP server and the sign-in); the governor works without it, deciding and recording locally, but has no tenant policy to ask and nowhere to send receipts.
The governor brings the enforcement: the hooks, the capability rules, and the eight slash commands. /plugin disable enforcer-governor removes them just as cleanly. There is no daemon to start. The governor keeps its own state under ~/.enforcer-governor/ and a small shared file under ~/.enforcer/; it writes to your ~/.claude/settings.json only when you ask it to, with /enforcer-governor:telemetry on.
Two pieces cannot arrive that way, because Claude Code does not let a plugin ship either one: a plugin's settings.json honours only the agent and subagentStatusLine keys, and everything else is ignored without a word. Both are a single paste into your own ~/.claude/settings.json, and the governor enforces correctly without either.
The status line, which is the only always-on surface — the number you glance at instead of opening something:
The plugin's install directory changes with every version, so the status line does not name it: the governor records where it is running from in ~/.enforcer/plugin-root at every session start, and the command follows that. Until the first session after installing, it prints nothing.
The permission rules, which are belt to the hooks' braces. Copy the permissions block from this repo's settings.json into yours. The plugin cannot install it, so without this paste the hooks are doing the work alone — see How it works for exactly what that costs you, which is less than it sounds.
What you get
A number in your status line, which is also where the money figure comes from. · $3.40/$20 — live spend against the limit, always visible, no dashboard to open. It changes colour once, when something needs you.
It has a second job. Claude Code hands its own total_cost_usd to the status line and only to the status line — the hooks never see it. That figure can be computed at an organisation's contracted rates, so it beats anything a third-party price table can know. The status line records it and the gate reads it back on the next tool call. Without the paste in Install the governor still enforces; it just meters from the transcript instead, and every receipt says which of the two answered.
Capability rules that ship with the plugin. Piping a URL into a shell is refused outright. Deleting a tree, rewriting git history, reading credentials, publishing or deploying: those stop and ask. These are capability decisions, not spend ones, so they fire on a full budget — and they are checked without reading any state at all, so they hold even when the governor cannot read its own files. Deleting the state directory turns off the spend limit; it does not turn off the rules.
Your organisation's policy, not just ours. Sign in once with /enforcer:login and the rules above stop being the same six patterns for everyone. When a rule matches, the governor asks your Enforcer tenant policy about it: a resource of type agent_action whose id names the rule (fs.delete_tree, deploy.publish, git.force_push, git.rewrite_history, secrets.access, shell.pipe_to_shell). The policy is Rego, versioned, tested before it can go live, and rolled back by activating the previous version, so "agents here never delete a whole tree" or "publishing needs a person" is one change for the whole team.
Its answer composes with the local rule, and the direction matters:
A policy can make anything stricter and can waive a confirmation. It cannot lift a hard deny (curl | sh stays refused), and it cannot skip a rewrite. If Enforcer is slow, down, or you are signed out, the local rule decides alone, so losing the network never allows more. Only a matched command is asked about; ordinary tool calls never wait on the network. Answers are reused for policyTtlSec (30s), which is also how quickly a new policy version reaches each machine.
One sign-in for the governor and the Enforcer MCP server. The MCP server comes with the enforcer plugin from the same marketplace (/plugin install enforcer@instruxi), not with the governor; until 2.6.0 the governor shipped its own copy. Both read the same credential, ~/.enforcer/credentials.json (0600), so /enforcer:login and /enforcer-governor:login are the same sign-in: sign in once and both are signed in, sign out once and both stop sending a credential.
A spend limit that means dollars. /enforcer-governor:limit 40 sets $40 per agent. Claude prices each model at its own rate, so $40 is $40 whether the agent is on Opus 5 or Haiku 4.5. Where the harness figure is unavailable the cap falls back to cost-weighted effective tokens, because cached sessions re-read their whole context every turn and raw token counts explode while costing very little.
A word to the agent, not just to you. An agent that learns it is near the limit can land what it has instead of opening a new front. At roughly two thirds of the budget it is told once — one sentence, at the turn boundary, where it can still change its plan — and then the governor goes quiet until the situation changes. Warning at the limit itself is too late: the turn is already committed. Every word costs, because it joins the cached prefix and is billed on every later turn, which is why it is one sentence and why it is said once.
A safer command instead of a refused one. Some actions have a form that keeps the intent and drops the footgun. git push --force becomes git push --force-with-lease, which refuses only when someone else has pushed since your last fetch — the case that loses work. The rewrite is announced and recorded; a governor that edits commands silently would be an invisible actor in your transcript.
Rate limits, not just totals. The incidents that cost real money are rate incidents. Dollars per minute, new agents per minute, and errors per minute are each watched and each ask rather than block — and ask once, so an overnight run waits for you instead of dying or nagging.
A record an audit can read. /enforcer-governor:verify walks the file and names the first line that does not add up. Every receipt carries who the agent acted for, what it tried, which model answered, and which rule decided.
Commands
Getting out of the way
An agent stopped for spending is freed by raising the limit — /enforcer-governor:limit 40 — and carries on from where it stopped. An agent stopped for looping, or one you stopped yourself, needs /enforcer-governor:resume, because a raised limit is not consent to carry on doing the same thing.
To switch the governor off without uninstalling it, put any of these in ~/.enforcer-governor/config.json:
budgetOn covers the spend and rate checks, loopOn the loop check, rulesOn the capability rules. The three are independent: turning spend tracking off leaves curl | sh and rm -rf still guarded. All three off is fully inert — unless your organisation publishes a floor, below. Do not delete state.json to unstick something: it holds the head of the receipt chain, so the next receipt hashes against nothing and verify correctly reports the record as broken.
Settings your organisation sets
An Enforcer tenant can publish a set of these settings for every install it signs in (GET /api/v1/governance/settings, written by a tenant admin). They are a floor, not an override: for each setting the governor applies whichever of the two is stricter, so a managed $150 beats your $400 and your $40 beats both, and a check the organisation turns on cannot be turned off locally. /enforcer-governor:config marks them with ! and shows your own value beside them.
Nothing waits on the network to decide: the settings are fetched at session start, at most hourly, and cached. A machine that is signed out, or has never reached the control plane, runs on its own config alone. Identity settings (centralUrl, ingestUrl, operator) cannot be managed — being able to repoint an install is being able to redirect its receipts.
What leaves your machine
Nothing, until you sign in. The governor decides and records locally, and a machine that has never signed in (/enforcer:login) makes no network calls at all.
Once you sign in to an Enforcer workspace, these can leave, each under a switch:
Everything goes to the workspace you signed in to and nowhere else. /enforcer:login logout (or /enforcer-governor:login logout, the same command) stops all of them on this machine; what has already been sent stays in your workspace's records, which is the point of a record.
Files the governor writes: ~/.enforcer-governor/ (config, state, the receipt chain, per-session scratch that is swept after sweepDays), ~/.enforcer/credentials.json (your sign-in) and ~/.enforcer/plugin-root (where the installed plugin lives, so telemetry stays signed in across plugin updates).
Decisions and their codes
Every decision the governor makes, including "no objection", is one JSON record:
decisionisallow,denyorask(a rewrite is put to the person as anaskcarrying the safer command).codeis one of the codes below, defined once incore/codes.mjs. Codes are a published vocabulary: they are added, never renamed or reused.ruleis the rule's policy id (git.force_push), ornullwhen no rule decided.run_idis present only when the session holds an enforcer-graph run (ENFORCER_GRAPH_RUN_ID, or the run file enforcer-graph's hooks keep).
The record is written three places: as the decision field, last, on the hash-chained receipt in ~/.enforcer-governor/receipts.jsonl; as one line on the PreToolUse hook's stderr, prefixed enforcer-governor:decision ; and as the first line of the permission reason whenever the hook allows, denies or asks. A parent process (the graph dispatcher, a CI wrapper) parses that line instead of grepping the sentence under it.
Headless graph workers
A graph worker is a claude -p session the dispatcher starts in a git worktree on branch graph/<key>, with nobody to answer a prompt. The governor is the plugin that allows or denies its delivery steps (core/worker.mjs); jev-hooks and enforcer-graph no longer decide them. A session is headless when JEV_HOOKS_HEADLESS=1 or ENFORCER_HEADLESS=1 is set, or Claude Code reports the sdk-cli entrypoint (claude -p). The branch is read from the .git of the directory the command runs in (cwd, or git -C <dir>).
These are the only rules that allow (an affirmative grant that skips the prompt). They run before the capability rules, a tenant policy can still refuse what they allow, and rulesOn: false turns them off with the rest.
How it works
Seven hooks, no daemon, no port, nothing listening. State lives in ~/.enforcer-governor/ behind a lock, so parallel tool calls land in the record in the order they were decided.
That split is the architecture, and the two halves fail in opposite directions on purpose. Spend fails open: if the state is unreadable the hook allows the action and says in the reason line that it did not check, because a governor that blocks real work over a missing file of its own has failed at something more important than enforcing. Capability fails closed, because it can afford to — the rules are patterns matched against the action text and need no state, so an unreadable state directory does not reach them. A refusal decided that way is still written to the record, deliberately without a hash: there is no readable chain tail to hash against, and verify counts an unhashed line as unverifiable rather than as a break. Recording nothing would hide a real refusal, and forging a link would cry tampering on an honest file.
The transcript is read forward from where the last call stopped, so the cost of checking does not grow with the length of your session.
Run the tests
The bigger picture
The Governor is one idea applied to one resource. The idea is Enforcer, Instruxi's policy engine, and it asks a single question in front of every system it guards: may this identity do this, right now? — answered three ways, with a tamper-evident receipt for every answer. Here that identity is an AI agent and the resource is your money. instruxi.io
License
Functional Source License 1.1 (FSL-1.1-ALv2). Free to run on your own agents, in production, including commercially. You may not offer it as a competing commercial product or service. Becomes Apache 2.0 two years after each release. See LICENSE.
Source: README.md at commit 651ea83
Tools
0Version history
3- v0.30.0LatestSep 24, 2026
- v0.29.4Sep 23, 2026
- v0.29.0Sep 23, 2026
Score
40% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts
Declare a license in the repository or the registry entry.
