Module: OllamaAgent::PatchRisk
- Defined in:
- lib/ollama_agent/patch_risk.rb
Overview
Classifies a proposed unified diff for semi-automatic patch approval (obvious vs risky).
Constant Summary collapse
- FORBIDDEN_PATTERNS =
[ /\beval\s*\(/, /`rm\s+-rf/, /system\s*\(\s*["']sudo/, /\bFile\.delete\b/, /\bKernel\.exec\b/ ].freeze
- LARGE_DIFF_LINES =
80
Class Method Summary collapse
-
.assess(path, diff) ⇒ Object
Returns :auto_approve (no prompt) or :require_confirmation (prompt when confirm_patches is on).
- .critical_lib_file?(relative) ⇒ Boolean
- .critical_path?(relative) ⇒ Boolean
- .forbidden?(diff) ⇒ Boolean
- .large_diff?(diff, limit: nil) ⇒ Boolean
- .large_diff_line_limit ⇒ Object
- .obvious_path?(relative) ⇒ Boolean
- .risky?(relative, diff) ⇒ Boolean
- .safe_spec_change?(relative, diff) ⇒ Boolean
Class Method Details
.assess(path, diff) ⇒ Object
Returns :auto_approve (no prompt) or :require_confirmation (prompt when confirm_patches is on).
32 33 34 35 36 37 38 39 40 41 |
# File 'lib/ollama_agent/patch_risk.rb', line 32 def assess(path, diff) relative = path.to_s.tr("\\", "/") return :require_confirmation if risky?(relative, diff) return :auto_approve if obvious_path?(relative) return :auto_approve if safe_spec_change?(relative, diff) :require_confirmation end |
.critical_lib_file?(relative) ⇒ Boolean
63 64 65 66 67 68 69 70 |
# File 'lib/ollama_agent/patch_risk.rb', line 63 def critical_lib_file?(relative) return false unless relative.start_with?("lib/") relative.include?("sandboxed_tools") || relative.include?("patch_support") || relative.end_with?("ollama_agent/agent.rb") || relative.end_with?("ollama_agent/tools_schema.rb") end |
.critical_path?(relative) ⇒ Boolean
72 73 74 75 76 77 78 79 |
# File 'lib/ollama_agent/patch_risk.rb', line 72 def critical_path?(relative) return true if relative.match?(/\A(Gemfile|Gemfile\.lock)\z/) return true if relative.end_with?(".gemspec") return true if relative == "lib/ollama_agent/version.rb" return true if relative.start_with?("exe/") false end |
.forbidden?(diff) ⇒ Boolean
27 28 29 |
# File 'lib/ollama_agent/patch_risk.rb', line 27 def forbidden?(diff) FORBIDDEN_PATTERNS.any? { |pattern| diff.match?(pattern) } end |
.large_diff?(diff, limit: nil) ⇒ Boolean
50 51 52 53 |
# File 'lib/ollama_agent/patch_risk.rb', line 50 def large_diff?(diff, limit: nil) max = limit.nil? ? large_diff_line_limit : limit diff.scan(/^[-+][^-+]/).size > max end |
.large_diff_line_limit ⇒ Object
18 19 20 21 22 23 24 25 |
# File 'lib/ollama_agent/patch_risk.rb', line 18 def large_diff_line_limit v = ENV.fetch("OLLAMA_AGENT_PATCH_RISK_MAX_DIFF_LINES", nil) return LARGE_DIFF_LINES if v.nil? || v.to_s.strip.empty? Integer(v) rescue ArgumentError, TypeError LARGE_DIFF_LINES end |
.obvious_path?(relative) ⇒ Boolean
55 56 57 |
# File 'lib/ollama_agent/patch_risk.rb', line 55 def obvious_path?(relative) relative.end_with?(".md") || relative.start_with?("docs/") end |
.risky?(relative, diff) ⇒ Boolean
43 44 45 46 47 48 |
# File 'lib/ollama_agent/patch_risk.rb', line 43 def risky?(relative, diff) forbidden?(diff) || critical_path?(relative) || large_diff?(diff) || critical_lib_file?(relative) end |
.safe_spec_change?(relative, diff) ⇒ Boolean
59 60 61 |
# File 'lib/ollama_agent/patch_risk.rb', line 59 def safe_spec_change?(relative, diff) relative.start_with?("spec/") && !large_diff?(diff, limit: 40) end |