Class: Legion::Extensions::Agentic::Self::Fingerprint::Helpers::FingerprintEngine
- Inherits:
-
Object
- Object
- Legion::Extensions::Agentic::Self::Fingerprint::Helpers::FingerprintEngine
- Defined in:
- lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb
Instance Attribute Summary collapse
-
#samples ⇒ Object
readonly
Returns the value of attribute samples.
Instance Method Summary collapse
- #anomaly_check(category:, value:) ⇒ Object
- #fingerprint_hash ⇒ Object
- #fingerprint_report ⇒ Object
- #identity_confidence ⇒ Object
- #identity_label ⇒ Object
-
#initialize ⇒ FingerprintEngine
constructor
A new instance of FingerprintEngine.
- #record_observation(category:, value:) ⇒ Object
- #sample_count ⇒ Object
- #strongest_traits(top_n = 3) ⇒ Object
- #to_h ⇒ Object
- #trait_count ⇒ Object
- #trait_profile ⇒ Object
- #verify_identity(observations:) ⇒ Object
- #weakest_traits(top_n = 3) ⇒ Object
Constructor Details
#initialize ⇒ FingerprintEngine
Returns a new instance of FingerprintEngine.
12 13 14 15 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 12 def initialize @traits = {} @samples = [] end |
Instance Attribute Details
#samples ⇒ Object (readonly)
Returns the value of attribute samples.
10 11 12 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 10 def samples @samples end |
Instance Method Details
#anomaly_check(category:, value:) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 80 def anomaly_check(category:, value:) trait = @traits[category] return { anomaly: false, reason: :no_baseline } unless trait dev = trait.deviation_from(value.clamp(0.0, 1.0)) anomaly = dev >= Constants::DEVIATION_THRESHOLD { anomaly: anomaly, category: category, value: value.clamp(0.0, 1.0), baseline: trait.baseline, deviation: dev.round(10), threshold: Constants::DEVIATION_THRESHOLD } end |
#fingerprint_hash ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 96 def fingerprint_hash return nil if @traits.empty? profile_string = Constants::TRAIT_CATEGORIES.map do |cat| t = @traits[cat] t ? "#{cat}:#{t.baseline.round(6)}" : "#{cat}:nil" end.join('|') require 'digest' ::Digest::SHA256.hexdigest(profile_string)[0, 16] end |
#fingerprint_report ⇒ Object
116 117 118 119 120 121 122 123 124 125 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 116 def fingerprint_report { fingerprint_hash: fingerprint_hash, identity_confidence: identity_confidence, identity_label: identity_label, trait_count: trait_count, sample_count: @samples.size, traits: @traits.transform_values(&:to_h) } end |
#identity_confidence ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 63 def identity_confidence return 0.0 if @traits.empty? stable_count = @traits.values.count(&:stable?) sampled = @traits.values.select { |t| t.sample_count.positive? } return 0.0 if sampled.empty? coverage = sampled.size.to_f / Constants::TRAIT_CATEGORIES.size stability = stable_count.to_f / @traits.size ((coverage * 0.6) + (stability * 0.4)).round(10).clamp(0.0, 1.0) end |
#identity_label ⇒ Object
76 77 78 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 76 def identity_label Constants.identity_label_for(identity_confidence) end |
#record_observation(category:, value:) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 17 def record_observation(category:, value:) return { status: :invalid_category, category: category } unless Constants::TRAIT_CATEGORIES.include?(category) trait = get_or_create_trait(category) trait.record_sample!(value.clamp(0.0, 1.0)) @samples << { category: category, value: value.clamp(0.0, 1.0), recorded_at: Time.now.utc } @samples.shift while @samples.size > Constants::MAX_SAMPLES { status: :recorded, category: category, baseline: trait.baseline, variance: trait.variance, samples: trait.sample_count } end |
#sample_count ⇒ Object
112 113 114 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 112 def sample_count @samples.size end |
#strongest_traits(top_n = 3) ⇒ Object
49 50 51 52 53 54 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 49 def strongest_traits(top_n = 3) @traits.values .sort_by { |t| -t.baseline } .first(top_n) .map(&:to_h) end |
#to_h ⇒ Object
127 128 129 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 127 def to_h fingerprint_report end |
#trait_count ⇒ Object
108 109 110 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 108 def trait_count @traits.size end |
#trait_profile ⇒ Object
45 46 47 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 45 def trait_profile @traits.transform_values(&:baseline) end |
#verify_identity(observations:) ⇒ Object
35 36 37 38 39 40 41 42 43 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 35 def verify_identity(observations:) return { match_score: 0.0, verdict: :insufficient_data } if observations.empty? || @traits.empty? scored = score_observations(observations) return { match_score: 0.0, verdict: :insufficient_data } if scored.empty? score = (scored.sum / scored.size).round(10) { match_score: score, verdict: score_verdict(score), observations_checked: scored.size } end |
#weakest_traits(top_n = 3) ⇒ Object
56 57 58 59 60 61 |
# File 'lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb', line 56 def weakest_traits(top_n = 3) @traits.values .sort_by(&:baseline) .first(top_n) .map(&:to_h) end |