nod_
An agent governor that decides what an AI agent may do, driven by declarative policy rules written in Nodora.
- Go
- AI Agents
- CLI
nod exists because I started letting AI agents work in my codebases, and the
control I had over them was all or nothing. An agent like Claude Code proposes
a tool call (a shell command, a file write, a network fetch) and I either
approve everything by hand, which defeats the point of automation, or I turn on
auto-approve and hope it never decides rm -rf is a good idea. What I actually
wanted was a policy layer in between: my rules, written down once, deciding
which calls are fine, which need my eyes, and which never run with a reason
attached to every decision.
That’s what nod is. You give it a proposed action as JSON and a policy written
as rules; it answers allow, ask, or deny, and shows which rule decided
and why. The rules are written in Nodora, my declarative
rule language, so each rule is a pure, type-checked function from input to
verdict: the same idea that made business rules maintainable, pointed at agent
governance. A hook adapter converts an agent’s tool call into that JSON and
returns the decision to the agent’s host to enforce; Claude Code works today
via its PreToolUse hook.
Governing an untrusted, tireless actor forces some design decisions, and they all trace back to that:
- Deny wins, always. Signals from every rule file are merged so that one
Denyoutranks any number ofAllows. Adding a rule file can only make the policy stricter for a call another rule denies so that a misbehaving rule can’t override a safety rule. - Local policy can tighten, never loosen. A project can ship its own
.nod/rules folder, but because that folder may arrive with a cloned repo, itsAllowsignals are suppressed by default. Cloned code can forbid things further; it can’t auto-approve its way past my global policy. - Fail closed. When nod gates a command, a policy block and a crashed run land on the same non-zero exit. If the governor can’t say yes, the answer is no.
- Every decision is auditable and replayable. Each verdict is appended to a JSON log with its provenance. Because evaluation is pure, that log doubles as a regression corpus: replay it against an edited policy and see exactly which past decisions would flip before adopting the change.
The end state is that the agent keeps its speed and I keep the final word: dangerous calls are blocked with a named rule and a reason, sensitive ones come back to me, and everything else flows, governed by a policy I can read, diff, and test like any other code.