Module: Legion::API::Routes::TbiPatterns

Defined in:
lib/legion/api/tbi_patterns.rb

Constant Summary collapse

MAX_DESCRIPTION_BYTES =
1024
MAX_PAYLOAD_SHAPE_BYTES =
65_536
VALID_TIERS =
%w[tier1 tier2 tier3 tier4 tier5].freeze

Class Method Summary collapse

Class Method Details

.anonymize(body) ⇒ Object

Anonymize pattern export: remove instance-identifying fields, compute a one-way hash for deduplication without fingerprinting.



161
162
163
164
165
166
167
168
169
170
171
# File 'lib/legion/api/tbi_patterns.rb', line 161

def self.anonymize(body)
  identifying_keys = %i[node_id instance_id hostname ip_address worker_id]
  sanitized = body.reject { |k, _v| identifying_keys.include?(k.to_sym) }
  # Remove both string and symbol variants
  sanitized = sanitized.reject { |k, _v| identifying_keys.map(&:to_s).include?(k.to_s) }

  salt_source = "#{body[:pattern_type]}:#{body[:tier]}:#{body[:description]}"
  source_hash = Digest::SHA256.hexdigest(salt_source)[0, 16]

  sanitized.merge(source_hash: source_hash)
end

.compute_quality(invocation_count:, success_rate:, tier:) ⇒ Object



181
182
183
184
185
186
187
188
189
190
# File 'lib/legion/api/tbi_patterns.rb', line 181

def self.compute_quality(invocation_count:, success_rate:, tier:)
  # tier weight: higher tiers (closer to tier5) earn a modest bonus
  tier_num    = tier.to_s.gsub(/[^0-9]/, '').to_i.clamp(1, 5)
  tier_weight = tier_num / 5.0

  count_score   = [invocation_count.to_f / 100.0, 1.0].min
  success_score = success_rate.to_f.clamp(0.0, 1.0)

  ((count_score * 0.4) + (success_score * 0.5) + (tier_weight * 0.1)).round(4)
end

.parse_float(value, default) ⇒ Object

Parse a float from user input; return default if blank or invalid.



204
205
206
207
208
209
210
211
212
# File 'lib/legion/api/tbi_patterns.rb', line 204

def self.parse_float(value, default)
  return default if value.nil?
  return default if value.to_s.strip.empty?
  raise ArgumentError, 'not numeric' unless value.to_s =~ /\A-?\d+(\.\d+)?\z/

  value.to_f.clamp(0.0, 1.0)
rescue ArgumentError
  default
end

.parse_integer(value, default) ⇒ Object

Parse an integer from user input; return default if blank or invalid.



193
194
195
196
197
198
199
200
201
# File 'lib/legion/api/tbi_patterns.rb', line 193

def self.parse_integer(value, default)
  return default if value.nil?
  return default if value.to_s.strip.empty?
  raise ArgumentError, 'not numeric' unless value.to_s =~ /\A-?\d+\z/

  [value.to_i, 0].max
rescue ArgumentError
  default
end

.registered(app) ⇒ Object



13
14
15
16
17
18
19
# File 'lib/legion/api/tbi_patterns.rb', line 13

def self.registered(app)
  register_export(app)
  register_discover(app)
  register_all(app)
  register_score(app)
  register_fetch(app)
end

.serialize_pattern_data(pattern_data) ⇒ Object



173
174
175
176
177
178
179
# File 'lib/legion/api/tbi_patterns.rb', line 173

def self.serialize_pattern_data(pattern_data)
  return pattern_data.to_s if pattern_data.is_a?(String)

  Legion::JSON.dump(pattern_data)
rescue StandardError
  Legion::JSON.dump(pattern_data.to_s)
end