#!/usr/bin/env python3 """Classify proposed agent commands against the homelab sandbox policy.""" from __future__ import annotations import argparse import csv import json import sys from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] POLICY_FILE = REPO_ROOT / "infra" / "agent-sandbox" / "policy.tsv" def load_policy() -> list[dict[str, str]]: with POLICY_FILE.open(encoding="utf-8", newline="") as handle: return list(csv.DictReader(handle, delimiter="\t")) def classify(command: str) -> dict[str, str]: normalized = " ".join(command.strip().split()) best: dict[str, str] | None = None for rule in load_policy(): pattern = rule["pattern"] if pattern in normalized: if best is None or len(pattern) > len(best["pattern"]): best = rule if best is None: return { "command": normalized, "decision": "approval", "pattern": "default", "reason": "Unknown command; require explicit approval before execution.", } return { "command": normalized, "decision": best["decision"], "pattern": best["pattern"], "reason": best["reason"], } def print_result(result: dict[str, str]) -> int: print("Agent Sandbox") print("=============") print(f"command: {result['command']}") print(f"decision: {result['decision']}") print(f"matched: {result['pattern']}") print(f"reason: {result['reason']}") if result["decision"] == "allow": return 0 if result["decision"] == "approval": return 2 return 3 def main() -> int: parser = argparse.ArgumentParser(description=__doc__) subparsers = parser.add_subparsers(dest="command", required=True) check_parser = subparsers.add_parser("check") check_parser.add_argument("candidate", nargs="+") check_parser.add_argument("--json", action="store_true") subparsers.add_parser("policy") args = parser.parse_args() if args.command == "policy": for rule in load_policy(): print(f"{rule['decision']:8} {rule['pattern']} - {rule['reason']}") return 0 if args.command == "check": result = classify(" ".join(args.candidate)) if args.json: print(json.dumps(result, indent=2, sort_keys=True)) return 0 if result["decision"] == "allow" else 2 return print_result(result) return 2 if __name__ == "__main__": raise SystemExit(main())