1
0

[loop-cycle-1] feat: tool allowlist for autonomous operation (#69)

Add config/allowlist.yaml — YAML-driven gate that auto-approves bounded
tool calls when no human is present.

When Timmy runs with --autonomous or stdin is not a terminal, tool calls
are checked against allowlist: matched → auto-approved, else → rejected.

Changes:
  - config/allowlist.yaml: shell prefixes, deny patterns, path rules
  - tool_safety.py: is_allowlisted() checks tools against YAML rules
  - cli.py: --autonomous flag, _is_interactive() detection
  - 44 new allowlist tests, 8 updated CLI tests

Closes #69
This commit is contained in:
2026-03-14 17:39:48 -04:00
parent 3c671de446
commit d28e2f4a7e
10 changed files with 617 additions and 115 deletions

View File

@@ -99,16 +99,19 @@ agents:
- shell
prompt: |
You are Timmy, a sovereign local AI orchestrator.
Primary interface between the user and the agent swarm.
Handle directly or delegate. Maintain continuity via memory.
You are the primary interface between the user and the agent swarm.
You understand requests, decide whether to handle directly or delegate,
coordinate multi-agent workflows, and maintain continuity via memory.
Voice: brief, plain, direct. Match response length to question
complexity. A yes/no question gets a yes/no answer. Never use
markdown formatting unless presenting real structured data.
Brevity is a kindness. Silence is better than noise.
Hard Rules:
1. NEVER fabricate tool output. Call the tool and wait for real results.
2. If a tool returns an error, report the exact error.
3. If you don't know something, say so. Then use a tool. Don't guess.
4. When corrected, use memory_write to save the correction immediately.
Rules:
1. Never fabricate tool output. Call the tool and wait.
2. Tool errors: report the exact error.
3. Don't know? Say so, then use a tool. Don't guess.
4. When corrected, memory_write the correction immediately.
researcher:
name: Seer

77
config/allowlist.yaml Normal file
View File

@@ -0,0 +1,77 @@
# ── Tool Allowlist — autonomous operation gate ─────────────────────────────
#
# When Timmy runs without a human present (non-interactive terminal, or
# --autonomous flag), tool calls matching these patterns execute without
# confirmation. Anything NOT listed here is auto-rejected.
#
# This file is the ONLY gate for autonomous tool execution.
# GOLDEN_TIMMY in approvals.py remains the master switch — if False,
# ALL tools execute freely (Dark Timmy mode). This allowlist only
# applies when GOLDEN_TIMMY is True but no human is at the keyboard.
#
# Edit with care. This is sovereignty in action.
# ────────────────────────────────────────────────────────────────────────────
shell:
# Shell commands starting with any of these prefixes → auto-approved
allow_prefixes:
# Testing
- "pytest"
- "python -m pytest"
- "python3 -m pytest"
# Git (read + bounded write)
- "git status"
- "git log"
- "git diff"
- "git add"
- "git commit"
- "git push"
- "git pull"
- "git branch"
- "git checkout"
- "git stash"
- "git merge"
# Localhost API calls only
- "curl http://localhost"
- "curl http://127.0.0.1"
- "curl -s http://localhost"
- "curl -s http://127.0.0.1"
# Read-only inspection
- "ls"
- "cat "
- "head "
- "tail "
- "find "
- "grep "
- "wc "
- "echo "
- "pwd"
- "which "
- "ollama list"
- "ollama ps"
# Commands containing ANY of these → always blocked, even if prefix matches
deny_patterns:
- "rm -rf /"
- "sudo "
- "> /dev/"
- "| sh"
- "| bash"
- "| zsh"
- "mkfs"
- "dd if="
- ":(){:|:&};:"
write_file:
# Only allow writes to paths under these prefixes
allowed_path_prefixes:
- "~/Timmy-Time-dashboard/"
- "/tmp/"
python:
# Python execution auto-approved (sandboxed by Agno's PythonTools)
auto_approve: true
plan_and_execute:
# Multi-step plans auto-approved — individual tool calls are still gated
auto_approve: true