Get started
Node 20+. No account. No network calls. About fifteen minutes.
Install
npm install @senscheck/governance-core
npx @senscheck/governance-cli init
init writes a starter senscheck.config.json, an example wrapper, and a .gitignore entry for receipts.
Wrap a function
import { SensCheckGovernance, StaticAuthorityProvider } from "@senscheck/governance-core";
import { rm } from "node:fs/promises";
const governance = new SensCheckGovernance({
policies: [{
version: 1,
default: "FAIL_CLOSED",
rules: [
{ id: "deny-etc", when: { resource: "file:/etc/*" }, decision: "DENY" },
{ id: "allow-delete", when: { verb: "DELETE", resource: "file:*" }, decision: "ALLOW" },
],
}],
authorityProvider: new StaticAuthorityProvider([{
principalId: "coding-agent", verbs: ["*"], resources: ["*"],
expiresAt: new Date(Date.now() + 3600_000).toISOString(),
grantedBy: { id: "ops-oncall", type: "human" },
}]),
defaultPrincipal: { id: "coding-agent", type: "agent" },
});
export const safeDelete = governance.wrapFunction((path: string) => rm(path, { recursive: true }), {
verb: "DELETE",
resource: (path) => `file:${path}`,
risk: "HIGH",
});
Calling safeDelete("/srv/build") now throws GovernanceBlockedError with REQUIRE_APPROVAL, because HIGH risk needs a human and none has approved. rm is never called.
Add human approval
import { StaticApprovalProvider } from "@senscheck/governance-core";
const approvals = new StaticApprovalProvider();
// pass approvalProvider: approvals to SensCheckGovernance, then, from a human-facing surface only:
approvals.approve(effectDigest, { id: "alice@example.com", type: "human" });
The approval binds to that one effect, is checked for freshness, and works once. Keep approve() out of the agent's reach.
The CLI
npx @senscheck/governance-cli check # validate your policy file
npx @senscheck/governance-cli test # 21 fail-closed behavioural checks
npx @senscheck/governance-cli audit . # heuristic list of consequential operations
npx @senscheck/governance-cli explain .senscheck/receipts.jsonl
audit pattern-matches file writes, process execution, database writes, HTTP mutations and deployment commands. It lists candidates; it does not prove anything is safe.
Wrap more things
| Need | Use |
|---|---|
| Files, processes, fetch, SQL | @senscheck/generic-tools |
| MCP server tools | @senscheck/governance-mcp |
| OpenAI-style function tools | @senscheck/governance-openai |
| Review a repo, wrap tools with an agent | The plugins |
Next
Read why fail closed, then what it does not do. Source and full docs: GitHub.