Class: Insika::Policy::Engine

Inherits:
Object
  • Object
show all
Defined in:
lib/insika/policy/engine.rb

Overview

Pipeline stage 3. Aggregates the profile's policies in the declared order: intersection of non-nil allows, union of denies (commutative, ties impossible by construction). Fail-closed: a crash or an unregistered name becomes a deny. Runs INLINE on the fiber (pure, no IO — no Async, no timeout of its own).

Defined Under Namespace

Classes: Resolution

Instance Method Summary collapse

Constructor Details

#initialize(policy_registry:, event_stream:) ⇒ Engine

Returns a new instance of Engine.



15
16
17
18
# File 'lib/insika/policy/engine.rb', line 15

def initialize(policy_registry:, event_stream:)
  @registry = policy_registry # duck-type: fetch(name)
  @event_stream = event_stream
end

Instance Method Details

#decide(request) ⇒ Object

-> Resolution | raise PolicyDenied



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/insika/policy/engine.rb', line 21

def decide(request)
  audit = []
  allow_tool_sets = []
  deny_tools = []
  allow_skill_sets = []
  deny_skills = []
  requires_approval = []

  Array(request.profile.policies).each do |name|
    decision = evaluate(name, request)
    audit << { policy: name.to_s, verdict: decision.verdict, reason: decision.reason }

    deny_turn!(name, decision.reason, audit) if decision.verdict == :deny

    allow_tool_sets << decision.allow_tools.map(&:to_s) unless decision.allow_tools.nil?
    deny_tools.concat(Array(decision.deny_tools).map(&:to_s))
    allow_skill_sets << decision.allow_skills.map(&:to_s) unless decision.allow_skills.nil?
    deny_skills.concat(Array(decision.deny_skills).map(&:to_s))
    requires_approval.concat(Array(decision.requires_approval).map(&:to_s))
  end

  Resolution.new(
    allowed_tools: filter(request.candidate_tools, allow_tool_sets, deny_tools) { |e| e.name.to_s },
    allowed_skills: filter(request.candidate_skills, allow_skill_sets, deny_skills) { |s| s.name.to_s },
    requires_approval: requires_approval.uniq,
    audit: audit
  )
end