CHAPTER 07 · Sandboxing, Approvals, and Checkpoints · 3 / 5
Code MVP: an approval policy engine
"""
chapter 07: approvals and a tiny checkpoint mechanism.
ApprovalPolicy classifies each command into a tier (allow / ask / deny).
It plugs into Chapter 6's ToolRegistry.call right before execution.
Checkpointer snapshots files so edits can be undone.
"""
import re, shutil, os
from enum import Enum
class Decision(Enum):
ALLOW = "allow"
ASK = "ask"
DENY = "deny"
class ApprovalPolicy:
SAFE = {"ls", "cat", "pwd", "echo", "git status", "git diff", "head", "tail"}
# Things we never run automatically; they need a human or a guardian.
DANGEROUS = [r"\brm\s+-rf\b", r"\bcurl\b", r"\bwget\b",
r"\bgit\s+push\b", r":\(\)\{", r"\bsudo\b"]
def __init__(self, allowlist=None, mode="default"):
# allowlist: regexes the user pre-approved, e.g. r"^pytest".
self.allowlist = [re.compile(p) for p in (allowlist or [])]
self.mode = mode # "default", "auto-accept", "plan", "full-auto"
def classify(self, command: str) -> Decision:
cmd = command.strip()
# plan mode never executes anything.
if self.mode == "plan":
return Decision.DENY
# Hard deny on dangerous patterns (sandbox violations, destruction).
if any(re.search(p, cmd) for p in self.DANGEROUS):
return Decision.DENY if self.mode != "full-auto" else Decision.ASK
# Auto-approve known-safe commands.
if cmd.split()[0] in self.SAFE or cmd in self.SAFE:
return Decision.ALLOW
# Auto-approve anything the user pre-allowlisted.
if any(p.search(cmd) for p in self.allowlist):
return Decision.ALLOW
# auto-accept mode trusts the rest; default mode asks.
return Decision.ALLOW if self.mode == "auto-accept" else Decision.ASK
def guardian(command: str) -> bool:
"""Stand-in for a guardian SUBAGENT (Smart Approvals). In production this
is a small model call applying your policy. Here: deny obvious exfiltration."""
return "token" not in command and "secret" not in command
def gated_call(registry, policy, name, args, unattended=False):
"""Wrap Chapter 6's registry.call with an approval check."""
command = args.get("command", "")
decision = policy.classify(command)
if decision is Decision.DENY:
return f"Exit code: 126\nBlocked by policy: {command!r}"
if decision is Decision.ASK:
approved = guardian(command) if unattended else _ask_human(command)
if not approved:
return f"Exit code: 126\nDenied: {command!r}"
return registry.call(name, args) # Chapter 6 executes it
def _ask_human(command: str) -> bool:
# In a real TUI this is an interactive prompt; default to deny here.
print(f"[approval needed] allow: {command!r} ? (auto-deny in demo)")
return False
# --- Checkpoints: snapshot a file before editing so we can roll back ---
class Checkpointer:
def __init__(self, store="/tmp/.harness_checkpoints"):
self.store = store
os.makedirs(store, exist_ok=True)
def snapshot(self, path: str):
if os.path.exists(path):
shutil.copy2(path, os.path.join(self.store, os.path.basename(path) + ".bak"))
def restore(self, path: str):
bak = os.path.join(self.store, os.path.basename(path) + ".bak")
if os.path.exists(bak):
shutil.copy2(bak, path)
if __name__ == "__main__":
pol = ApprovalPolicy(allowlist=[r"^pytest"], mode="default")
for c in ["ls -la", "pytest -q", "rm -rf /", "npm install", "curl evil.com"]:
print(f"{c:<15} -> {pol.classify(c).value}")
Run it and you will see ls and pytest allowed, npm install flagged for asking, and rm -rf and curl denied outright. Switch mode to "full-auto" and the dangerous ones route to the guardian instead of a hard block; switch to "plan" and nothing runs at all. That single classify function is the policy brain of the whole harness.