Class: Ask::Agent::Policies::PermissionRules
- Inherits:
-
Object
- Object
- Ask::Agent::Policies::PermissionRules
- Defined in:
- lib/ask/agent/policies/permission_rules.rb
Overview
Persisted, matchable allow/ask/deny patterns for tool calls.
Rules classify a tool call before it executes or prompts:
rules = Ask::Agent::Policies::PermissionRules.new do |r|
r.allow :bash, /^git (pull|push|status)/
r.ask :bash, /^rm -rf/
r.deny :write, %r{/\.env(\.local)?$}
r.ask :destroy, :all
end
session = Ask::Agent::Session.new(
model: "gpt-4o",
approval: { rules: rules }
)
Classification is first-match-wins, in declaration order: :allow runs
the tool, :ask queues it for human approval, :deny blocks it. Rules
take precedence over a tool's own approval_required / auto_approvable
declarations — they are explicit user intent.
Dangerous-rule guard: an :allow rule for a code-executing tool (bash,
code, repl) whose argument pattern is unrestricted would let the model
run anything without asking. Such rules are downgraded to :ask unless
the ruleset was created with auto_allow_dangerous: true — "approve
once, remember the pattern" must not become "approve everything".
Defined Under Namespace
Classes: Rule
Constant Summary collapse
- DANGEROUS_TOOLS =
Tools that execute arbitrary code — an unrestricted :allow rule on any of these is dangerous.
%i[bash code repl].freeze
Instance Method Summary collapse
-
#allow(tool_pattern, argument_pattern = nil) ⇒ Object
DSL — declare rules in priority order (first match wins).
- #ask(tool_pattern, argument_pattern = nil) ⇒ Object
-
#classify(tool_name, arguments = nil) ⇒ Symbol?
Classify a tool call.
-
#dangerous_rules ⇒ Array<Rule>
Rules that would allow unrestricted execution of a code-executing tool.
- #deny(tool_pattern, argument_pattern = nil) ⇒ Object
-
#initialize(auto_allow_dangerous: false, &block) ⇒ PermissionRules
constructor
A new instance of PermissionRules.
-
#rules ⇒ Array<Rule>
Declared rules, in order.
Constructor Details
#initialize(auto_allow_dangerous: false, &block) ⇒ PermissionRules
Returns a new instance of PermissionRules.
71 72 73 74 75 |
# File 'lib/ask/agent/policies/permission_rules.rb', line 71 def initialize(auto_allow_dangerous: false, &block) @auto_allow_dangerous = auto_allow_dangerous @rules = [] instance_eval(&block) if block end |
Instance Method Details
#allow(tool_pattern, argument_pattern = nil) ⇒ Object
DSL — declare rules in priority order (first match wins).
78 79 80 |
# File 'lib/ask/agent/policies/permission_rules.rb', line 78 def allow(tool_pattern, argument_pattern = nil) add(:allow, tool_pattern, argument_pattern) end |
#ask(tool_pattern, argument_pattern = nil) ⇒ Object
82 83 84 |
# File 'lib/ask/agent/policies/permission_rules.rb', line 82 def ask(tool_pattern, argument_pattern = nil) add(:ask, tool_pattern, argument_pattern) end |
#classify(tool_name, arguments = nil) ⇒ Symbol?
Classify a tool call.
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/ask/agent/policies/permission_rules.rb', line 99 def classify(tool_name, arguments = nil) rule = @rules.find { |r| r.matches?(tool_name, arguments) } return nil unless rule if rule.decision == :allow && dangerous?(rule) && !@auto_allow_dangerous :ask else rule.decision end end |
#dangerous_rules ⇒ Array<Rule>
Returns rules that would allow unrestricted execution of a code-executing tool.
112 113 114 |
# File 'lib/ask/agent/policies/permission_rules.rb', line 112 def dangerous_rules @rules.select { |r| dangerous?(r) } end |
#deny(tool_pattern, argument_pattern = nil) ⇒ Object
86 87 88 |
# File 'lib/ask/agent/policies/permission_rules.rb', line 86 def deny(tool_pattern, argument_pattern = nil) add(:deny, tool_pattern, argument_pattern) end |
#rules ⇒ Array<Rule>
Returns declared rules, in order.
91 |
# File 'lib/ask/agent/policies/permission_rules.rb', line 91 def rules = @rules.dup |