Skip to main content
Glama

safe-autonomy

A fence and a shadow for autonomous coding agents. Decide what an AI is allowed to ship without a human, watch it reason before you trust it, and keep the dangerous stuff in your hands.

The hard problem in AI operations isn't making the agent smarter. It's being disciplined about what it is never allowed to touch. safe-autonomy is that discipline as ~150 lines of pure, dependency-free, unit-tested code you can drop into any agent pipeline.

The idea

Autonomy is only safe where "the AI was wrong" cannot hurt anyone. Additive observability is worst-case noise. A revert goes to a known-good state. The changes that matter most — money, product, user-facing truth, the database — are exactly the ones that stay human. Not from fear, from fallibility: agents make real mistakes, and the value of a human in the loop is catching them.

So this library does two small things:

  1. The fence (classifyChange) — one pure function that routes a proposed change to auto or human. Default is human. auto only when the change touches no sensitive path, is reversible, and is an additive/reversible kind (a monitor, a test, a revert). One sensitive file drags the whole change to human.

  2. Shadow mode (shadowClassify) — run the fence over your real backlog and log exactly how each change would be routed, shipping nothing. You read the shadow log for as long as you want before enabling any autonomy.

Related MCP server: CHIM MCP Server

Use it

import { classifyChange } from "safe-autonomy/gate";

classifyChange({ files: ["src/lib/metrics.ts"], kind: "add_monitor", reversible: true });
// → { lane: "auto",  reasons: ["additive/reversible \"add_monitor\", no sensitive paths"] }

classifyChange({ files: ["src/api/stripe/webhook.ts"], kind: "add_monitor", reversible: true });
// → { lane: "human", reasons: ["touches human-only path(s): src/api/stripe/webhook.ts"] }

Bring your own denylist and allowlist; the defaults cover money, auth, schema, sending, deletion, webhooks, and secrets:

import { classifyChange, DEFAULT_CONFIG } from "safe-autonomy/gate";

const config = {
  ...DEFAULT_CONFIG,
  humanOnlyPaths: [...DEFAULT_CONFIG.humanOnlyPaths, /\/pricing\//],
};
classifyChange(change, config);

Shadow a whole backlog before you enable anything:

import { shadowClassify, formatShadowLog } from "safe-autonomy/shadow";

const report = shadowClassify(proposals, deriveChange); // deriveChange: your proposal → a ChangeDescriptor
console.log(formatShadowLog(report, (p) => p.title));
// Autonomous shadow — 3 proposal(s): 1 would auto-ship (SHADOW ONLY, nothing shipped), 2 stay human.
//   [AUTO ] watch publish_verify_missing_field — AUTO once enabled → branch, full CI, verify, auto-rollback...
//   [HUMAN] Scanner → connect gate — HUMAN review → no files listed — cannot verify blast radius...

The rollout it's built for

proposal → classifyChange → [human] land as a PR for review
                          → [auto]  implement on a branch
                                    → FULL CI (tsc + lint + tests + build); red = stop
                                    → SHADOW: log the diff + intended action, ship nothing
                                    → (only when enabled) auto-merge + deploy
                                    → verify on REAL metrics + error rate for a watch window
                                    → auto-rollback on regression
                                    → immutable audit log of every step

Ship the fence first (inert). Run it in shadow for as long as you like. Enable it narrowly — one surface, add_monitor / add_test only — with a kill switch, a veto window, and auto-rollback. Widen it an inch at a time, and never widen the allowlist or shrink the denylist without an explicit human decision.

Use it from any agent (MCP)

The same fence is an MCP server, so an agent can ask it before it acts. Two tools: classify_change (route one change) and shadow_run (route a whole backlog, ship nothing).

npm run mcp          # stdio server: npx tsx mcp/server.ts

Point an MCP client at it:

{
  "mcpServers": {
    "safe-autonomy": { "command": "npx", "args": ["tsx", "/path/to/safe-autonomy/mcp/server.ts"] }
  }
}

Then the agent calls, in its own words, "classify this change" and gets back a lane:

// classify_change { "files": ["src/api/stripe/charge.ts"], "kind": "add_monitor", "reversible": true }
// → HUMAN — touches human-only path(s): src/api/stripe/charge.ts

Bring your own denylist/allowlist over the wire (regex source strings, so JSON-safe):

// classify_change { ..., "config": { "humanOnlyPaths": ["/pricing/"], "autoKinds": ["add_test"] } }

Why it's tight (the honest reason)

Verify on real metrics, not just green tests — subtly-wrong changes pass tests. This whole library exists because the AI is fallible, and the point of a boundary is that "the AI was wrong" stays cheap.


Extracted from the autonomous-maintenance system running a production SaaS. Tests: npx vitest run.

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Control plane for autonomous software labor. Agents claim objectives over MCP with audit trail.

  • Remote MCP for AI Studio Android release gate MCP, structured receipts, audit logs, and reviewer-rea

  • MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/underpricedai/safe-autonomy'

If you have feedback or need assistance with the MCP directory API, please join our Discord server