fix(approval): reduce prompt friction and make approval cards answerable forever
Approval friction (harmless commands kept prompting): - Persist "Allow for this session" grants to approval_allowlist.yaml under a new sessions scope (capped LRU), hydrated lazily, so they survive `opc ui` restarts and re-entering the session instead of living only in memory. - Safe-prefix matching now accepts compound read-only commands: every segment must match a safe prefix, and fd-duplication / /dev/null redirections (2>&1, 2>/dev/null) no longer disqualify a command; real write redirections (>, >>, <) still do. Default safe prefixes gain common read-only commands (cd, cat, head, grep, git log, ...). - First-use approval now gates only MEDIUM+ risk; heuristically LOW actions proceed without a card. - Shell-substitution detection flags eval/source only at command position of a segment (no more false positives on `grep source file`); $(...) and backticks still flag anywhere. Approval card timeout redesign (deferred decisions): - The card's structured approval context (action, allowlist patterns, scopes) now travels through the escalation event into the persisted card metadata. - Timeout without a default action no longer marks the card timed out, and the session-detail reconciler no longer stales deferred-capable cards: the card stays pending and clickable indefinitely, including across restarts. - Clicking after the inline wait expired applies the allowlist grant (approve-once grants the exact command at session scope), resolves the card, and rewrites the reply to target the parked AWAITING_HUMAN checkpoint so the task resumes through the normal message pipeline and the retried command auto-approves. With no parked checkpoint the grant still lands and a helper reply explains the state. Verified: approval engine suite (40) incl. new deferred-decision and compound-command tests, ws_handler + runtime suites green, real escalated commands from project 999 replayed against the user's config now auto-approve while pip install / $(...) / rm -rf / write redirects still prompt. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -994,6 +994,12 @@ class AutonomyConfig(BaseModel):
|
||||
safe_command_prefixes: list[str] = Field(default_factory=lambda: [
|
||||
"ls", "pwd", "echo", "rg", "find", "git status", "git diff", "python -V",
|
||||
"python3 -V", "node -v", "npm -v", "curl", "wget", "yt-dlp", "aria2c", "ffmpeg",
|
||||
# Read-only commands agents chain constantly; each segment of a compound
|
||||
# command must match one of these for the whole command to stay LOW risk.
|
||||
"cd", "cat", "head", "tail", "grep", "wc", "sort", "uniq", "cut", "tr",
|
||||
"stat", "file", "which", "date", "du", "df", "tree", "basename", "dirname",
|
||||
"realpath", "readlink", "uname", "nproc", "whoami", "hostname", "git log",
|
||||
"git show", "git rev-parse",
|
||||
])
|
||||
permissions_v2: PermissionsV2Config = Field(default_factory=PermissionsV2Config)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user