Class: Legion::Extensions::Agentic::Attention::Blindspot::Helpers::BlindspotEngine

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb

Constant Summary

Constants included from Constants

Constants::AWARENESS_LABELS, Constants::AWARENESS_THRESHOLD, Constants::COVERAGE_LABELS, Constants::DEFAULT_SEVERITY, Constants::DISCOVERY_METHODS, Constants::MAX_BLINDSPOTS, Constants::MAX_BOUNDARIES, Constants::SEVERITY_BOOST, Constants::SEVERITY_LABELS, Constants::STATUS_LABELS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Constants

label_for

Constructor Details

#initializeBlindspotEngine

Returns a new instance of BlindspotEngine.



14
15
16
17
18
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 14

def initialize
  @blindspots      = {}
  @boundaries      = {}
  @awareness_score = 1.0
end

Instance Attribute Details

#awareness_scoreObject (readonly)

Returns the value of attribute awareness_score.



12
13
14
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 12

def awareness_score
  @awareness_score
end

Instance Method Details

#acknowledge_blindspot(blindspot_id:) ⇒ Object



31
32
33
34
35
36
37
38
39
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 31

def acknowledge_blindspot(blindspot_id:)
  blindspot = @blindspots.fetch(blindspot_id, nil)
  return { found: false, blindspot_id: blindspot_id } unless blindspot

  blindspot.acknowledge!
  recalculate_awareness
  { found: true, blindspot_id: blindspot_id, status: blindspot.status,
    awareness_score: @awareness_score.round(10) }
end

#acknowledged_blindspotsObject



87
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 87

def acknowledged_blindspots = @blindspots.values.select { |b| b.status == :acknowledged }

#active_blindspotsObject



86
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 86

def active_blindspots       = @blindspots.values.select(&:active?)

#awareness_gapObject



103
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 103

def awareness_gap    = (1.0 - @awareness_score).clamp(0.0, 1.0).round(10)

#awareness_labelObject



102
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 102

def awareness_label  = Constants.label_for(AWARENESS_LABELS, @awareness_score) || :unaware

#blindspots_by_domain(domain) ⇒ Object



81
82
83
84
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 81

def blindspots_by_domain(domain)
  d = domain.to_sym
  @blindspots.values.select { |b| b.domain == d }
end

#coverage_reportObject



101
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 101

def coverage_report  = @boundaries.values.map(&:to_h)

#detect_boundary_gap(domain:, error_occurred: false) ⇒ Object



72
73
74
75
76
77
78
79
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 72

def detect_boundary_gap(domain:, error_occurred: false)
  boundary = boundary_for_domain(domain)
  return { gap_detected: false, domain: domain, reason: :no_boundary } unless boundary

  { gap_detected: boundary.gap_detected?(error_occurred: error_occurred),
    domain: domain, confidence: boundary.confidence,
    coverage: boundary.coverage_estimate }
end

#johari_reportObject



105
106
107
108
109
110
111
112
113
114
115
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 105

def johari_report
  { total_blindspots:   @blindspots.size,
    active:             active_blindspots.size,
    acknowledged:       acknowledged_blindspots.size,
    resolved:           resolved_blindspots.size,
    awareness_score:    @awareness_score.round(10),
    awareness_label:    awareness_label,
    awareness_gap:      awareness_gap,
    boundaries_tracked: @boundaries.size,
    most_severe:        most_severe(limit: 3).map(&:to_h) }
end

#mitigate_blindspot(blindspot_id:, boost: SEVERITY_BOOST) ⇒ Object



41
42
43
44
45
46
47
48
49
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 41

def mitigate_blindspot(blindspot_id:, boost: SEVERITY_BOOST)
  blindspot = @blindspots.fetch(blindspot_id, nil)
  return { found: false, blindspot_id: blindspot_id } unless blindspot

  blindspot.mitigate!(boost: boost)
  recalculate_awareness
  { found: true, blindspot_id: blindspot_id, status: blindspot.status,
    severity: blindspot.severity, awareness_score: @awareness_score.round(10) }
end

#mitigation_strategies(domain: nil) ⇒ Object



94
95
96
97
98
99
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 94

def mitigation_strategies(domain: nil)
  spots = domain ? blindspots_by_domain(domain) : @blindspots.values
  spots.select(&:active?).map do |b|
    { blindspot_id: b.id, domain: b.domain, severity: b.severity, strategy: strategy_for(b) }
  end
end

#most_severe(limit: 5) ⇒ Object



90
91
92
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 90

def most_severe(limit: 5)
  @blindspots.values.sort_by { |b| -b.severity }.first(limit)
end

#register_blindspot(domain:, discovered_by:, description:, severity: DEFAULT_SEVERITY) ⇒ Object



20
21
22
23
24
25
26
27
28
29
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 20

def register_blindspot(domain:, discovered_by:, description:, severity: DEFAULT_SEVERITY)
  return nil unless DISCOVERY_METHODS.include?(discovered_by.to_sym)

  prune_blindspots_if_needed
  blindspot = Blindspot.new(domain: domain, discovered_by: discovered_by,
                            description: description, severity: severity)
  @blindspots[blindspot.id] = blindspot
  recalculate_awareness
  blindspot
end

#resolve_blindspot(blindspot_id:) ⇒ Object



51
52
53
54
55
56
57
58
59
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 51

def resolve_blindspot(blindspot_id:)
  blindspot = @blindspots.fetch(blindspot_id, nil)
  return { found: false, blindspot_id: blindspot_id } unless blindspot

  blindspot.resolve!
  recalculate_awareness
  { found: true, blindspot_id: blindspot_id, status: blindspot.status,
    awareness_score: @awareness_score.round(10) }
end

#resolved_blindspotsObject



88
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 88

def resolved_blindspots     = @blindspots.values.select(&:resolved?)

#set_boundary(domain:, confidence: 0.5, coverage_estimate: 0.5) ⇒ Object



61
62
63
64
65
66
67
68
69
70
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 61

def set_boundary(domain:, confidence: 0.5, coverage_estimate: 0.5)
  prune_boundaries_if_needed
  existing = boundary_for_domain(domain)
  return update_boundary!(existing, confidence, coverage_estimate) if existing

  boundary = KnowledgeBoundary.new(domain: domain, confidence: confidence,
                                   coverage_estimate: coverage_estimate)
  @boundaries[boundary.id] = boundary
  boundary
end

#to_hObject



117
118
119
120
121
122
123
124
# File 'lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb', line 117

def to_h
  { total_blindspots: @blindspots.size,
    active:           active_blindspots.size,
    acknowledged:     acknowledged_blindspots.size,
    resolved:         resolved_blindspots.size,
    awareness_score:  @awareness_score.round(10),
    awareness_label:  awareness_label }
end