GVNR by Instruxi
io.gvnr由 gvnr.io 發布v0.30.0更新於 Oct 24, 2026
GVNR (gvnr.io): stops AI agents overspending and running dangerous commands before they act.
發布方自己的服務:Gvnr
概覽
一個本機 Claude Code 治理外掛,在代理動作執行前決定是否放行,執行支出上限與能力規則,並保留雜湊鏈式憑證紀錄。
- 可以做什麼
- 以本機 stdio 程序執行,攔截代理的工具呼叫並回傳允許、拒絕、詢問或改寫決定。它執行每個代理的美元支出上限、速率限制、迴圈偵測與能力規則,例如拒絕將指令碼透過管線送入 shell,或在破壞性刪除、強制推送、存取密鑰與部署前詢問。每個決定都會附加到可驗證竄改的雜湊鏈式憑證檔案中。可選登入 Enforcer 工作區以增加租戶政策檢查與憑證上報。
- 適用情境
- 適用於執行自主或長時間執行的 Claude Code 代理,這些代理可能超支、陷入迴圈或執行有風險的 shell 與 git 指令。也適合希望取得本機可稽核的代理決定紀錄並可選執行組織級政策的團隊。
- 執行需求
- 透過 npx enforcer-governor 作為 Claude Code 外掛在本機執行,僅限桌面端。環境變數 GOVERNOR_PORT(預設 4000)與 GVNR_AGENT(預設每次工作階段隨機)用於設定。登入 Enforcer 工作區是可選的,需要憑證檔案 ~/.enforcer/credentials.json。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 GVNR by Instruxi,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
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.
來源:README.md,提交 651ea83
工具
0版本歷史
3- v0.30.0最新Sep 24, 2026
- v0.29.4Sep 23, 2026
- v0.29.0Sep 23, 2026
評分
已滿足適用檢查項的 40%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分
請在儲存庫或註冊中心條目中宣告授權條款。
