lex-agentic-defense 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +12 -0
  3. data/Gemfile +5 -0
  4. data/LICENSE +21 -0
  5. data/README.md +13 -0
  6. data/lex-agentic-defense.gemspec +30 -0
  7. data/lib/legion/extensions/agentic/defense/avalanche/client.rb +22 -0
  8. data/lib/legion/extensions/agentic/defense/avalanche/helpers/avalanche_engine.rb +132 -0
  9. data/lib/legion/extensions/agentic/defense/avalanche/helpers/cascade.rb +76 -0
  10. data/lib/legion/extensions/agentic/defense/avalanche/helpers/constants.rb +44 -0
  11. data/lib/legion/extensions/agentic/defense/avalanche/helpers/snowpack.rb +86 -0
  12. data/lib/legion/extensions/agentic/defense/avalanche/runners/cognitive_avalanche.rb +75 -0
  13. data/lib/legion/extensions/agentic/defense/avalanche/version.rb +13 -0
  14. data/lib/legion/extensions/agentic/defense/avalanche.rb +22 -0
  15. data/lib/legion/extensions/agentic/defense/bias/actors/update.rb +45 -0
  16. data/lib/legion/extensions/agentic/defense/bias/client.rb +30 -0
  17. data/lib/legion/extensions/agentic/defense/bias/helpers/bias_detector.rb +107 -0
  18. data/lib/legion/extensions/agentic/defense/bias/helpers/bias_event.rb +44 -0
  19. data/lib/legion/extensions/agentic/defense/bias/helpers/bias_store.rb +84 -0
  20. data/lib/legion/extensions/agentic/defense/bias/helpers/constants.rb +28 -0
  21. data/lib/legion/extensions/agentic/defense/bias/runners/bias.rb +151 -0
  22. data/lib/legion/extensions/agentic/defense/bias/version.rb +13 -0
  23. data/lib/legion/extensions/agentic/defense/bias.rb +20 -0
  24. data/lib/legion/extensions/agentic/defense/confabulation/actors/decay.rb +45 -0
  25. data/lib/legion/extensions/agentic/defense/confabulation/client.rb +28 -0
  26. data/lib/legion/extensions/agentic/defense/confabulation/helpers/claim.rb +67 -0
  27. data/lib/legion/extensions/agentic/defense/confabulation/helpers/confabulation_engine.rb +120 -0
  28. data/lib/legion/extensions/agentic/defense/confabulation/helpers/constants.rb +29 -0
  29. data/lib/legion/extensions/agentic/defense/confabulation/runners/confabulation.rb +74 -0
  30. data/lib/legion/extensions/agentic/defense/confabulation/version.rb +13 -0
  31. data/lib/legion/extensions/agentic/defense/confabulation.rb +19 -0
  32. data/lib/legion/extensions/agentic/defense/dissonance/client.rb +32 -0
  33. data/lib/legion/extensions/agentic/defense/dissonance/helpers/belief.rb +46 -0
  34. data/lib/legion/extensions/agentic/defense/dissonance/helpers/constants.rb +27 -0
  35. data/lib/legion/extensions/agentic/defense/dissonance/helpers/dissonance_event.rb +52 -0
  36. data/lib/legion/extensions/agentic/defense/dissonance/helpers/dissonance_model.rb +159 -0
  37. data/lib/legion/extensions/agentic/defense/dissonance/runners/dissonance.rb +163 -0
  38. data/lib/legion/extensions/agentic/defense/dissonance/version.rb +13 -0
  39. data/lib/legion/extensions/agentic/defense/dissonance.rb +20 -0
  40. data/lib/legion/extensions/agentic/defense/epistemic_vigilance/actors/update.rb +45 -0
  41. data/lib/legion/extensions/agentic/defense/epistemic_vigilance/client.rb +27 -0
  42. data/lib/legion/extensions/agentic/defense/epistemic_vigilance/helpers/claim.rb +78 -0
  43. data/lib/legion/extensions/agentic/defense/epistemic_vigilance/helpers/client.rb +23 -0
  44. data/lib/legion/extensions/agentic/defense/epistemic_vigilance/helpers/constants.rb +37 -0
  45. data/lib/legion/extensions/agentic/defense/epistemic_vigilance/helpers/source.rb +64 -0
  46. data/lib/legion/extensions/agentic/defense/epistemic_vigilance/helpers/vigilance_engine.rb +195 -0
  47. data/lib/legion/extensions/agentic/defense/epistemic_vigilance/runners/epistemic_vigilance.rb +91 -0
  48. data/lib/legion/extensions/agentic/defense/epistemic_vigilance/version.rb +13 -0
  49. data/lib/legion/extensions/agentic/defense/epistemic_vigilance.rb +20 -0
  50. data/lib/legion/extensions/agentic/defense/erosion/client.rb +23 -0
  51. data/lib/legion/extensions/agentic/defense/erosion/helpers/channel.rb +84 -0
  52. data/lib/legion/extensions/agentic/defense/erosion/helpers/constants.rb +47 -0
  53. data/lib/legion/extensions/agentic/defense/erosion/helpers/erosion_engine.rb +134 -0
  54. data/lib/legion/extensions/agentic/defense/erosion/helpers/formation.rb +100 -0
  55. data/lib/legion/extensions/agentic/defense/erosion/runners/cognitive_erosion.rb +93 -0
  56. data/lib/legion/extensions/agentic/defense/erosion/version.rb +13 -0
  57. data/lib/legion/extensions/agentic/defense/erosion.rb +21 -0
  58. data/lib/legion/extensions/agentic/defense/error_monitoring/actors/tick.rb +45 -0
  59. data/lib/legion/extensions/agentic/defense/error_monitoring/client.rb +28 -0
  60. data/lib/legion/extensions/agentic/defense/error_monitoring/helpers/constants.rb +50 -0
  61. data/lib/legion/extensions/agentic/defense/error_monitoring/helpers/error_monitor.rb +174 -0
  62. data/lib/legion/extensions/agentic/defense/error_monitoring/helpers/error_signal.rb +60 -0
  63. data/lib/legion/extensions/agentic/defense/error_monitoring/runners/error_monitoring.rb +102 -0
  64. data/lib/legion/extensions/agentic/defense/error_monitoring/version.rb +13 -0
  65. data/lib/legion/extensions/agentic/defense/error_monitoring.rb +19 -0
  66. data/lib/legion/extensions/agentic/defense/extinction/actors/protocol_monitor.rb +45 -0
  67. data/lib/legion/extensions/agentic/defense/extinction/client.rb +27 -0
  68. data/lib/legion/extensions/agentic/defense/extinction/helpers/levels.rb +43 -0
  69. data/lib/legion/extensions/agentic/defense/extinction/helpers/protocol_state.rb +125 -0
  70. data/lib/legion/extensions/agentic/defense/extinction/local_migrations/20260316000040_create_extinction_state.rb +13 -0
  71. data/lib/legion/extensions/agentic/defense/extinction/runners/extinction.rb +130 -0
  72. data/lib/legion/extensions/agentic/defense/extinction/version.rb +13 -0
  73. data/lib/legion/extensions/agentic/defense/extinction.rb +25 -0
  74. data/lib/legion/extensions/agentic/defense/friction/client.rb +15 -0
  75. data/lib/legion/extensions/agentic/defense/friction/helpers/constants.rb +38 -0
  76. data/lib/legion/extensions/agentic/defense/friction/helpers/friction_engine.rb +131 -0
  77. data/lib/legion/extensions/agentic/defense/friction/helpers/state_transition.rb +73 -0
  78. data/lib/legion/extensions/agentic/defense/friction/runners/cognitive_friction.rb +82 -0
  79. data/lib/legion/extensions/agentic/defense/friction/version.rb +13 -0
  80. data/lib/legion/extensions/agentic/defense/friction.rb +19 -0
  81. data/lib/legion/extensions/agentic/defense/immune_response/client.rb +19 -0
  82. data/lib/legion/extensions/agentic/defense/immune_response/helpers/antibody.rb +72 -0
  83. data/lib/legion/extensions/agentic/defense/immune_response/helpers/antigen.rb +87 -0
  84. data/lib/legion/extensions/agentic/defense/immune_response/helpers/constants.rb +75 -0
  85. data/lib/legion/extensions/agentic/defense/immune_response/helpers/immune_engine.rb +184 -0
  86. data/lib/legion/extensions/agentic/defense/immune_response/helpers/immune_response.rb +76 -0
  87. data/lib/legion/extensions/agentic/defense/immune_response/runners/cognitive_immune_response.rb +114 -0
  88. data/lib/legion/extensions/agentic/defense/immune_response/version.rb +13 -0
  89. data/lib/legion/extensions/agentic/defense/immune_response.rb +21 -0
  90. data/lib/legion/extensions/agentic/defense/immunology/client.rb +29 -0
  91. data/lib/legion/extensions/agentic/defense/immunology/helpers/antibody.rb +55 -0
  92. data/lib/legion/extensions/agentic/defense/immunology/helpers/constants.rb +43 -0
  93. data/lib/legion/extensions/agentic/defense/immunology/helpers/immune_engine.rb +187 -0
  94. data/lib/legion/extensions/agentic/defense/immunology/helpers/threat.rb +67 -0
  95. data/lib/legion/extensions/agentic/defense/immunology/runners/cognitive_immunology.rb +92 -0
  96. data/lib/legion/extensions/agentic/defense/immunology/version.rb +13 -0
  97. data/lib/legion/extensions/agentic/defense/immunology.rb +20 -0
  98. data/lib/legion/extensions/agentic/defense/phantom/client.rb +29 -0
  99. data/lib/legion/extensions/agentic/defense/phantom/helpers/constants.rb +54 -0
  100. data/lib/legion/extensions/agentic/defense/phantom/helpers/phantom_engine.rb +106 -0
  101. data/lib/legion/extensions/agentic/defense/phantom/helpers/phantom_limb.rb +103 -0
  102. data/lib/legion/extensions/agentic/defense/phantom/helpers/phantom_signal.rb +40 -0
  103. data/lib/legion/extensions/agentic/defense/phantom/runners/cognitive_phantom.rb +79 -0
  104. data/lib/legion/extensions/agentic/defense/phantom/version.rb +13 -0
  105. data/lib/legion/extensions/agentic/defense/phantom.rb +21 -0
  106. data/lib/legion/extensions/agentic/defense/quicksand/client.rb +15 -0
  107. data/lib/legion/extensions/agentic/defense/quicksand/helpers/constants.rb +48 -0
  108. data/lib/legion/extensions/agentic/defense/quicksand/helpers/pit.rb +82 -0
  109. data/lib/legion/extensions/agentic/defense/quicksand/helpers/quicksand_engine.rb +137 -0
  110. data/lib/legion/extensions/agentic/defense/quicksand/helpers/trap.rb +101 -0
  111. data/lib/legion/extensions/agentic/defense/quicksand/runners/cognitive_quicksand.rb +84 -0
  112. data/lib/legion/extensions/agentic/defense/quicksand/version.rb +13 -0
  113. data/lib/legion/extensions/agentic/defense/quicksand.rb +22 -0
  114. data/lib/legion/extensions/agentic/defense/quicksilver/client.rb +29 -0
  115. data/lib/legion/extensions/agentic/defense/quicksilver/helpers/constants.rb +50 -0
  116. data/lib/legion/extensions/agentic/defense/quicksilver/helpers/droplet.rb +126 -0
  117. data/lib/legion/extensions/agentic/defense/quicksilver/helpers/pool.rb +83 -0
  118. data/lib/legion/extensions/agentic/defense/quicksilver/helpers/quicksilver_engine.rb +124 -0
  119. data/lib/legion/extensions/agentic/defense/quicksilver/runners/cognitive_quicksilver.rb +130 -0
  120. data/lib/legion/extensions/agentic/defense/quicksilver/version.rb +13 -0
  121. data/lib/legion/extensions/agentic/defense/quicksilver.rb +21 -0
  122. data/lib/legion/extensions/agentic/defense/version.rb +11 -0
  123. data/lib/legion/extensions/agentic/defense/whirlpool/client.rb +65 -0
  124. data/lib/legion/extensions/agentic/defense/whirlpool/helpers/captured_thought.rb +67 -0
  125. data/lib/legion/extensions/agentic/defense/whirlpool/helpers/constants.rb +45 -0
  126. data/lib/legion/extensions/agentic/defense/whirlpool/helpers/vortex.rb +91 -0
  127. data/lib/legion/extensions/agentic/defense/whirlpool/helpers/whirlpool_engine.rb +92 -0
  128. data/lib/legion/extensions/agentic/defense/whirlpool/runners/cognitive_whirlpool.rb +117 -0
  129. data/lib/legion/extensions/agentic/defense/whirlpool/version.rb +13 -0
  130. data/lib/legion/extensions/agentic/defense/whirlpool.rb +22 -0
  131. data/lib/legion/extensions/agentic/defense.rb +32 -0
  132. data/spec/legion/extensions/agentic/defense/avalanche/client_spec.rb +96 -0
  133. data/spec/legion/extensions/agentic/defense/avalanche/helpers/avalanche_engine_spec.rb +276 -0
  134. data/spec/legion/extensions/agentic/defense/avalanche/helpers/cascade_spec.rb +190 -0
  135. data/spec/legion/extensions/agentic/defense/avalanche/helpers/constants_spec.rb +129 -0
  136. data/spec/legion/extensions/agentic/defense/avalanche/helpers/snowpack_spec.rb +197 -0
  137. data/spec/legion/extensions/agentic/defense/avalanche/runners/cognitive_avalanche_spec.rb +211 -0
  138. data/spec/legion/extensions/agentic/defense/bias/client_spec.rb +16 -0
  139. data/spec/legion/extensions/agentic/defense/bias/helpers/bias_detector_spec.rb +160 -0
  140. data/spec/legion/extensions/agentic/defense/bias/helpers/bias_event_spec.rb +64 -0
  141. data/spec/legion/extensions/agentic/defense/bias/helpers/bias_store_spec.rb +143 -0
  142. data/spec/legion/extensions/agentic/defense/bias/runners/bias_spec.rb +155 -0
  143. data/spec/legion/extensions/agentic/defense/confabulation/client_spec.rb +34 -0
  144. data/spec/legion/extensions/agentic/defense/confabulation/helpers/claim_spec.rb +119 -0
  145. data/spec/legion/extensions/agentic/defense/confabulation/helpers/confabulation_engine_spec.rb +163 -0
  146. data/spec/legion/extensions/agentic/defense/confabulation/helpers/constants_spec.rb +55 -0
  147. data/spec/legion/extensions/agentic/defense/confabulation/runners/confabulation_spec.rb +119 -0
  148. data/spec/legion/extensions/agentic/defense/dissonance/client_spec.rb +51 -0
  149. data/spec/legion/extensions/agentic/defense/dissonance/helpers/belief_spec.rb +103 -0
  150. data/spec/legion/extensions/agentic/defense/dissonance/helpers/constants_spec.rb +60 -0
  151. data/spec/legion/extensions/agentic/defense/dissonance/helpers/dissonance_event_spec.rb +113 -0
  152. data/spec/legion/extensions/agentic/defense/dissonance/helpers/dissonance_model_spec.rb +252 -0
  153. data/spec/legion/extensions/agentic/defense/dissonance/runners/dissonance_spec.rb +323 -0
  154. data/spec/legion/extensions/agentic/defense/epistemic_vigilance/client_spec.rb +28 -0
  155. data/spec/legion/extensions/agentic/defense/epistemic_vigilance/helpers/claim_spec.rb +135 -0
  156. data/spec/legion/extensions/agentic/defense/epistemic_vigilance/helpers/constants_spec.rb +59 -0
  157. data/spec/legion/extensions/agentic/defense/epistemic_vigilance/helpers/source_spec.rb +117 -0
  158. data/spec/legion/extensions/agentic/defense/epistemic_vigilance/helpers/vigilance_engine_spec.rb +273 -0
  159. data/spec/legion/extensions/agentic/defense/epistemic_vigilance/runners/epistemic_vigilance_spec.rb +157 -0
  160. data/spec/legion/extensions/agentic/defense/erosion/client_spec.rb +90 -0
  161. data/spec/legion/extensions/agentic/defense/erosion/helpers/channel_spec.rb +173 -0
  162. data/spec/legion/extensions/agentic/defense/erosion/helpers/constants_spec.rb +137 -0
  163. data/spec/legion/extensions/agentic/defense/erosion/helpers/erosion_engine_spec.rb +263 -0
  164. data/spec/legion/extensions/agentic/defense/erosion/helpers/formation_spec.rb +206 -0
  165. data/spec/legion/extensions/agentic/defense/erosion/runners/cognitive_erosion_spec.rb +153 -0
  166. data/spec/legion/extensions/agentic/defense/error_monitoring/client_spec.rb +40 -0
  167. data/spec/legion/extensions/agentic/defense/error_monitoring/helpers/error_monitor_spec.rb +178 -0
  168. data/spec/legion/extensions/agentic/defense/error_monitoring/helpers/error_signal_spec.rb +76 -0
  169. data/spec/legion/extensions/agentic/defense/error_monitoring/runners/error_monitoring_spec.rb +87 -0
  170. data/spec/legion/extensions/agentic/defense/extinction/actors/protocol_monitor_spec.rb +45 -0
  171. data/spec/legion/extensions/agentic/defense/extinction/client_spec.rb +13 -0
  172. data/spec/legion/extensions/agentic/defense/extinction/helpers/levels_spec.rb +180 -0
  173. data/spec/legion/extensions/agentic/defense/extinction/helpers/protocol_state_spec.rb +291 -0
  174. data/spec/legion/extensions/agentic/defense/extinction/local_persistence_spec.rb +188 -0
  175. data/spec/legion/extensions/agentic/defense/extinction/runners/extinction_spec.rb +114 -0
  176. data/spec/legion/extensions/agentic/defense/friction/helpers/constants_spec.rb +46 -0
  177. data/spec/legion/extensions/agentic/defense/friction/helpers/friction_engine_spec.rb +175 -0
  178. data/spec/legion/extensions/agentic/defense/friction/helpers/state_transition_spec.rb +124 -0
  179. data/spec/legion/extensions/agentic/defense/friction/runners/cognitive_friction_spec.rb +89 -0
  180. data/spec/legion/extensions/agentic/defense/immune_response/client_spec.rb +32 -0
  181. data/spec/legion/extensions/agentic/defense/immune_response/cognitive_immune_response_spec.rb +7 -0
  182. data/spec/legion/extensions/agentic/defense/immune_response/helpers/antibody_spec.rb +117 -0
  183. data/spec/legion/extensions/agentic/defense/immune_response/helpers/antigen_spec.rb +125 -0
  184. data/spec/legion/extensions/agentic/defense/immune_response/helpers/constants_spec.rb +45 -0
  185. data/spec/legion/extensions/agentic/defense/immune_response/helpers/immune_engine_spec.rb +222 -0
  186. data/spec/legion/extensions/agentic/defense/immune_response/helpers/immune_response_spec.rb +84 -0
  187. data/spec/legion/extensions/agentic/defense/immune_response/runners_spec.rb +141 -0
  188. data/spec/legion/extensions/agentic/defense/immunology/client_spec.rb +61 -0
  189. data/spec/legion/extensions/agentic/defense/immunology/helpers/antibody_spec.rb +98 -0
  190. data/spec/legion/extensions/agentic/defense/immunology/helpers/constants_spec.rb +86 -0
  191. data/spec/legion/extensions/agentic/defense/immunology/helpers/immune_engine_spec.rb +275 -0
  192. data/spec/legion/extensions/agentic/defense/immunology/helpers/threat_spec.rb +133 -0
  193. data/spec/legion/extensions/agentic/defense/immunology/runners/cognitive_immunology_spec.rb +177 -0
  194. data/spec/legion/extensions/agentic/defense/phantom/client_spec.rb +53 -0
  195. data/spec/legion/extensions/agentic/defense/phantom/helpers/constants_spec.rb +87 -0
  196. data/spec/legion/extensions/agentic/defense/phantom/helpers/phantom_engine_spec.rb +222 -0
  197. data/spec/legion/extensions/agentic/defense/phantom/helpers/phantom_limb_spec.rb +180 -0
  198. data/spec/legion/extensions/agentic/defense/phantom/helpers/phantom_signal_spec.rb +59 -0
  199. data/spec/legion/extensions/agentic/defense/phantom/runners/cognitive_phantom_spec.rb +193 -0
  200. data/spec/legion/extensions/agentic/defense/quicksand/client_spec.rb +35 -0
  201. data/spec/legion/extensions/agentic/defense/quicksand/helpers/constants_spec.rb +58 -0
  202. data/spec/legion/extensions/agentic/defense/quicksand/helpers/pit_spec.rb +103 -0
  203. data/spec/legion/extensions/agentic/defense/quicksand/helpers/quicksand_engine_spec.rb +153 -0
  204. data/spec/legion/extensions/agentic/defense/quicksand/helpers/trap_spec.rb +166 -0
  205. data/spec/legion/extensions/agentic/defense/quicksand/runners/cognitive_quicksand_spec.rb +90 -0
  206. data/spec/legion/extensions/agentic/defense/quicksilver/client_spec.rb +72 -0
  207. data/spec/legion/extensions/agentic/defense/quicksilver/helpers/constants_spec.rb +105 -0
  208. data/spec/legion/extensions/agentic/defense/quicksilver/helpers/droplet_spec.rb +310 -0
  209. data/spec/legion/extensions/agentic/defense/quicksilver/helpers/pool_spec.rb +174 -0
  210. data/spec/legion/extensions/agentic/defense/quicksilver/helpers/quicksilver_engine_spec.rb +226 -0
  211. data/spec/legion/extensions/agentic/defense/quicksilver/runners/cognitive_quicksilver_spec.rb +227 -0
  212. data/spec/legion/extensions/agentic/defense/whirlpool/client_spec.rb +63 -0
  213. data/spec/legion/extensions/agentic/defense/whirlpool/helpers/captured_thought_spec.rb +171 -0
  214. data/spec/legion/extensions/agentic/defense/whirlpool/helpers/constants_spec.rb +65 -0
  215. data/spec/legion/extensions/agentic/defense/whirlpool/helpers/vortex_spec.rb +189 -0
  216. data/spec/legion/extensions/agentic/defense/whirlpool/helpers/whirlpool_engine_spec.rb +227 -0
  217. data/spec/legion/extensions/agentic/defense/whirlpool/runners/cognitive_whirlpool_spec.rb +226 -0
  218. data/spec/spec_helper.rb +46 -0
  219. metadata +303 -0
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Defense
9
+ module Immunology
10
+ module Helpers
11
+ class Antibody
12
+ attr_reader :id, :tactic, :pattern, :created_at
13
+ attr_accessor :strength, :matches
14
+
15
+ def initialize(tactic:, pattern:, strength: 0.5)
16
+ @id = SecureRandom.uuid
17
+ @tactic = tactic
18
+ @pattern = pattern
19
+ @strength = strength.clamp(0.0, 1.0)
20
+ @matches = 0
21
+ @created_at = Time.now.utc
22
+ end
23
+
24
+ def match!
25
+ @matches += 1
26
+ boost = Constants::RESISTANCE_BOOST / (@matches + 1)
27
+ @strength = (@strength + boost.round(10)).clamp(0.0, 1.0).round(10)
28
+ end
29
+
30
+ def decay!
31
+ @strength = (@strength - Constants::RESISTANCE_DECAY).clamp(0.0, 1.0).round(10)
32
+ end
33
+
34
+ def effective?
35
+ @strength >= 0.3
36
+ end
37
+
38
+ def to_h
39
+ {
40
+ id: @id,
41
+ tactic: @tactic,
42
+ pattern: @pattern,
43
+ strength: @strength,
44
+ matches: @matches,
45
+ effective: effective?,
46
+ created_at: @created_at
47
+ }
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Immunology
8
+ module Helpers
9
+ module Constants
10
+ DEFAULT_RESISTANCE = 0.5
11
+ RESISTANCE_BOOST = 0.1
12
+ RESISTANCE_DECAY = 0.02
13
+ MAX_THREATS = 500
14
+ MAX_ANTIBODIES = 200
15
+
16
+ THREAT_LABELS = {
17
+ (0.8..) => :critical,
18
+ (0.6...0.8) => :severe,
19
+ (0.4...0.6) => :moderate,
20
+ (0.2...0.4) => :low,
21
+ (..0.2) => :negligible
22
+ }.freeze
23
+
24
+ IMMUNITY_LABELS = {
25
+ (0.8..) => :immune,
26
+ (0.6...0.8) => :resistant,
27
+ (0.4...0.6) => :normal,
28
+ (0.2...0.4) => :vulnerable,
29
+ (..0.2) => :compromised
30
+ }.freeze
31
+
32
+ MANIPULATION_TACTICS = %i[
33
+ authority_appeal emotional_blackmail false_urgency
34
+ social_proof_abuse gaslighting strawman ad_hominem
35
+ sunk_cost_exploit bandwagon fear_mongering
36
+ ].freeze
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,187 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Immunology
8
+ module Helpers
9
+ class ImmuneEngine
10
+ attr_reader :resistance, :inflammatory
11
+
12
+ def initialize
13
+ @threats = {}
14
+ @antibodies = {}
15
+ @resistance = Constants::DEFAULT_RESISTANCE
16
+ @inflammatory = false
17
+ end
18
+
19
+ def detect_threat(source:, tactic:, content_hash:, threat_level: 0.5)
20
+ prune_threats_if_full
21
+
22
+ threat = Threat.new(
23
+ source: source,
24
+ tactic: tactic,
25
+ content_hash: content_hash,
26
+ threat_level: threat_level
27
+ )
28
+
29
+ matched = match_antibodies_for_tactic(tactic)
30
+ matched.each do |ab|
31
+ ab.match!
32
+ reduction = (ab.strength * 0.2).round(10)
33
+ threat.threat_level = (threat.threat_level - reduction).clamp(0.0, 1.0).round(10)
34
+ end
35
+
36
+ @threats[threat.id] = threat
37
+ Legion::Logging.debug "[cognitive_immunology] threat detected: id=#{threat.id} tactic=#{tactic} level=#{threat.threat_level.round(2)}"
38
+ threat
39
+ end
40
+
41
+ def quarantine_threat(threat_id:)
42
+ threat = @threats.fetch(threat_id, nil)
43
+ return { success: false, reason: 'not found' } unless threat
44
+
45
+ threat.quarantine!
46
+ Legion::Logging.info "[cognitive_immunology] quarantined: id=#{threat_id} tactic=#{threat.tactic}"
47
+ { success: true, threat_id: threat_id }
48
+ end
49
+
50
+ def release_threat(threat_id:)
51
+ threat = @threats.fetch(threat_id, nil)
52
+ return { success: false, reason: 'not found' } unless threat
53
+
54
+ threat.release!
55
+ Legion::Logging.debug "[cognitive_immunology] released: id=#{threat_id}"
56
+ { success: true, threat_id: threat_id }
57
+ end
58
+
59
+ def inoculate(threat_id:)
60
+ threat = @threats.fetch(threat_id, nil)
61
+ return { success: false, reason: 'not found' } unless threat
62
+
63
+ threat.expose!
64
+ boost = (Constants::RESISTANCE_BOOST / (threat.exposure_count + 1)).round(10)
65
+ @resistance = (@resistance + boost).clamp(0.0, 1.0).round(10)
66
+ Legion::Logging.debug "[cognitive_immunology] inoculate: id=#{threat_id} exposure=#{threat.exposure_count} resistance=#{@resistance.round(2)}"
67
+ { success: true, threat_id: threat_id, exposure_count: threat.exposure_count, resistance: @resistance }
68
+ end
69
+
70
+ def create_antibody(tactic:, pattern:, strength: 0.5)
71
+ prune_antibodies_if_full
72
+
73
+ ab = Antibody.new(tactic: tactic, pattern: pattern, strength: strength)
74
+ @antibodies[ab.id] = ab
75
+ Legion::Logging.info "[cognitive_immunology] antibody created: id=#{ab.id} tactic=#{tactic} strength=#{strength}"
76
+ ab
77
+ end
78
+
79
+ def scan_for_tactic(tactic:)
80
+ @threats.values.select { |t| t.tactic == tactic }
81
+ end
82
+
83
+ def trigger_inflammatory_response
84
+ @inflammatory = true
85
+ Legion::Logging.warn '[cognitive_immunology] inflammatory response triggered — heightened scrutiny mode'
86
+ { inflammatory: true }
87
+ end
88
+
89
+ def resolve_inflammation
90
+ @inflammatory = false
91
+ Legion::Logging.info '[cognitive_immunology] inflammation resolved — returning to normal scrutiny'
92
+ { inflammatory: false }
93
+ end
94
+
95
+ def overall_immunity
96
+ ab_coverage = antibody_coverage_score
97
+ score = ((@resistance * 0.6) + (ab_coverage * 0.4)).round(10)
98
+ score.clamp(0.0, 1.0)
99
+ end
100
+
101
+ def immunity_label
102
+ score = overall_immunity
103
+ Constants::IMMUNITY_LABELS.find { |range, _| range.cover?(score) }&.last || :compromised
104
+ end
105
+
106
+ def vulnerability_report
107
+ covered_tactics = @antibodies.values.map(&:tactic).uniq
108
+ uncovered = Constants::MANIPULATION_TACTICS.reject { |t| covered_tactics.include?(t) }
109
+ {
110
+ covered: covered_tactics,
111
+ uncovered: uncovered,
112
+ coverage: (covered_tactics.size.to_f / Constants::MANIPULATION_TACTICS.size).round(10)
113
+ }
114
+ end
115
+
116
+ def threat_history(limit: 10)
117
+ @threats.values
118
+ .sort_by(&:created_at)
119
+ .last(limit)
120
+ .map(&:to_h)
121
+ end
122
+
123
+ def decay_all
124
+ @antibodies.each_value(&:decay!)
125
+ @resistance = (@resistance - Constants::RESISTANCE_DECAY).clamp(0.0, 1.0).round(10)
126
+ Legion::Logging.debug "[cognitive_immunology] decay cycle: resistance=#{@resistance.round(2)} antibodies=#{@antibodies.size}"
127
+ { resistance: @resistance, antibodies_decayed: @antibodies.size }
128
+ end
129
+
130
+ def prune_ineffective
131
+ before = @antibodies.size
132
+ @antibodies.select! { |_, ab| ab.effective? }
133
+ pruned = before - @antibodies.size
134
+ Legion::Logging.debug "[cognitive_immunology] pruned #{pruned} ineffective antibodies"
135
+ { pruned: pruned, remaining: @antibodies.size }
136
+ end
137
+
138
+ def to_h
139
+ {
140
+ threat_count: @threats.size,
141
+ quarantined_count: @threats.values.count(&:quarantined),
142
+ antibody_count: @antibodies.size,
143
+ effective_antibody_count: @antibodies.values.count(&:effective?),
144
+ resistance: @resistance,
145
+ inflammatory: @inflammatory,
146
+ overall_immunity: overall_immunity,
147
+ immunity_label: immunity_label
148
+ }
149
+ end
150
+
151
+ private
152
+
153
+ def match_antibodies_for_tactic(tactic)
154
+ @antibodies.values.select { |ab| ab.tactic == tactic && ab.effective? }
155
+ end
156
+
157
+ def antibody_coverage_score
158
+ return 0.0 if @antibodies.empty?
159
+
160
+ effective = @antibodies.values.select(&:effective?)
161
+ return 0.0 if effective.empty?
162
+
163
+ avg_strength = effective.sum(&:strength) / effective.size.to_f
164
+ tactic_coverage = vulnerability_report[:coverage]
165
+ ((avg_strength * 0.5) + (tactic_coverage * 0.5)).round(10)
166
+ end
167
+
168
+ def prune_threats_if_full
169
+ return unless @threats.size >= Constants::MAX_THREATS
170
+
171
+ oldest = @threats.values.min_by(&:created_at)
172
+ @threats.delete(oldest.id) if oldest
173
+ end
174
+
175
+ def prune_antibodies_if_full
176
+ return unless @antibodies.size >= Constants::MAX_ANTIBODIES
177
+
178
+ weakest = @antibodies.values.min_by(&:strength)
179
+ @antibodies.delete(weakest.id) if weakest
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Defense
9
+ module Immunology
10
+ module Helpers
11
+ class Threat
12
+ attr_reader :id, :source, :tactic, :content_hash, :created_at
13
+ attr_accessor :threat_level, :quarantined, :exposure_count
14
+
15
+ def initialize(source:, tactic:, content_hash:, threat_level: 0.5)
16
+ @id = SecureRandom.uuid
17
+ @source = source
18
+ @tactic = tactic
19
+ @content_hash = content_hash
20
+ @threat_level = threat_level.clamp(0.0, 1.0)
21
+ @quarantined = false
22
+ @exposure_count = 0
23
+ @created_at = Time.now.utc
24
+ end
25
+
26
+ def threat_label
27
+ Constants::THREAT_LABELS.find { |range, _| range.cover?(@threat_level) }&.last || :negligible
28
+ end
29
+
30
+ def quarantine!
31
+ @quarantined = true
32
+ end
33
+
34
+ def release!
35
+ @quarantined = false
36
+ end
37
+
38
+ def expose!
39
+ @exposure_count += 1
40
+ reduction = (0.05 / (@exposure_count + 1)).round(10)
41
+ @threat_level = (@threat_level - reduction).clamp(0.0, 1.0).round(10)
42
+ end
43
+
44
+ def escalate!(amount: 0.1)
45
+ @threat_level = (@threat_level + amount).clamp(0.0, 1.0).round(10)
46
+ end
47
+
48
+ def to_h
49
+ {
50
+ id: @id,
51
+ source: @source,
52
+ tactic: @tactic,
53
+ content_hash: @content_hash,
54
+ threat_level: @threat_level,
55
+ threat_label: threat_label,
56
+ quarantined: @quarantined,
57
+ exposure_count: @exposure_count,
58
+ created_at: @created_at
59
+ }
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Immunology
8
+ module Runners
9
+ module CognitiveImmunology
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex)
12
+
13
+ def detect_threat(source:, tactic:, content_hash:, threat_level: 0.5, **)
14
+ threat = engine.detect_threat(source: source, tactic: tactic, content_hash: content_hash, threat_level: threat_level)
15
+ { success: true, threat: threat.to_h }
16
+ end
17
+
18
+ def quarantine_threat(threat_id:, **)
19
+ result = engine.quarantine_threat(threat_id: threat_id)
20
+ result.merge(success: result.fetch(:success, false))
21
+ end
22
+
23
+ def release_threat(threat_id:, **)
24
+ result = engine.release_threat(threat_id: threat_id)
25
+ result.merge(success: result.fetch(:success, false))
26
+ end
27
+
28
+ def inoculate(threat_id:, **)
29
+ engine.inoculate(threat_id: threat_id)
30
+ end
31
+
32
+ def create_antibody(tactic:, pattern:, strength: 0.5, **)
33
+ ab = engine.create_antibody(tactic: tactic, pattern: pattern, strength: strength)
34
+ { success: true, antibody: ab.to_h }
35
+ end
36
+
37
+ def scan_for_tactic(tactic:, **)
38
+ threats = engine.scan_for_tactic(tactic: tactic)
39
+ { success: true, tactic: tactic, threats: threats.map(&:to_h), count: threats.size }
40
+ end
41
+
42
+ def trigger_inflammatory_response(**)
43
+ result = engine.trigger_inflammatory_response
44
+ { success: true }.merge(result)
45
+ end
46
+
47
+ def resolve_inflammation(**)
48
+ result = engine.resolve_inflammation
49
+ { success: true }.merge(result)
50
+ end
51
+
52
+ def overall_immunity(**)
53
+ score = engine.overall_immunity
54
+ { success: true, score: score, label: engine.immunity_label }
55
+ end
56
+
57
+ def vulnerability_report(**)
58
+ report = engine.vulnerability_report
59
+ { success: true }.merge(report)
60
+ end
61
+
62
+ def threat_history(limit: 10, **)
63
+ threats = engine.threat_history(limit: limit)
64
+ { success: true, threats: threats, count: threats.size }
65
+ end
66
+
67
+ def decay_all(**)
68
+ result = engine.decay_all
69
+ { success: true }.merge(result)
70
+ end
71
+
72
+ def prune_ineffective(**)
73
+ result = engine.prune_ineffective
74
+ { success: true }.merge(result)
75
+ end
76
+
77
+ def immune_status(**)
78
+ { success: true }.merge(engine.to_h)
79
+ end
80
+
81
+ private
82
+
83
+ def engine
84
+ @engine ||= Helpers::ImmuneEngine.new
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Immunology
8
+ VERSION = '0.1.0'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/defense/immunology/version'
4
+ require 'legion/extensions/agentic/defense/immunology/helpers/constants'
5
+ require 'legion/extensions/agentic/defense/immunology/helpers/threat'
6
+ require 'legion/extensions/agentic/defense/immunology/helpers/antibody'
7
+ require 'legion/extensions/agentic/defense/immunology/helpers/immune_engine'
8
+ require 'legion/extensions/agentic/defense/immunology/runners/cognitive_immunology'
9
+ require 'legion/extensions/agentic/defense/immunology/client'
10
+
11
+ module Legion
12
+ module Extensions
13
+ module Agentic
14
+ module Defense
15
+ module Immunology
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/defense/phantom/helpers/constants'
4
+ require 'legion/extensions/agentic/defense/phantom/helpers/phantom_signal'
5
+ require 'legion/extensions/agentic/defense/phantom/helpers/phantom_limb'
6
+ require 'legion/extensions/agentic/defense/phantom/helpers/phantom_engine'
7
+ require 'legion/extensions/agentic/defense/phantom/runners/cognitive_phantom'
8
+
9
+ module Legion
10
+ module Extensions
11
+ module Agentic
12
+ module Defense
13
+ module Phantom
14
+ class Client
15
+ include Runners::CognitivePhantom
16
+
17
+ def initialize(**)
18
+ @phantom_engine = Helpers::PhantomEngine.new
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :phantom_engine
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Phantom
8
+ module Helpers
9
+ module Constants
10
+ MAX_PHANTOMS = 100
11
+ INITIAL_INTENSITY = 0.8
12
+ INTENSITY_DECAY = 0.05
13
+ MIN_INTENSITY = 0.01
14
+
15
+ PHANTOM_STATES = %i[acute adapting residual resolved].freeze
16
+ TRIGGER_TYPES = %i[stimulus_match contextual_association temporal_pattern habitual].freeze
17
+
18
+ STATE_THRESHOLDS = {
19
+ acute: 0.6,
20
+ adapting: 0.3,
21
+ residual: MIN_INTENSITY
22
+ }.freeze
23
+
24
+ PHANTOM_LABELS = {
25
+ acute: 'Active phantom — strong ghost signals firing',
26
+ adapting: 'Adapting — agent learning to cope with absence',
27
+ residual: 'Residual — faint ghost signals, near resolution',
28
+ resolved: 'Resolved — phantom fully integrated and silent'
29
+ }.freeze
30
+
31
+ module_function
32
+
33
+ def label_for(state)
34
+ PHANTOM_LABELS.fetch(state, 'Unknown state')
35
+ end
36
+
37
+ def state_for(intensity)
38
+ if intensity >= STATE_THRESHOLDS[:acute]
39
+ :acute
40
+ elsif intensity >= STATE_THRESHOLDS[:adapting]
41
+ :adapting
42
+ elsif intensity > MIN_INTENSITY
43
+ :residual
44
+ else
45
+ :resolved
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Phantom
8
+ module Helpers
9
+ class PhantomEngine
10
+ def initialize
11
+ @phantoms = {}
12
+ end
13
+
14
+ def register_removal(capability_name:, capability_domain: :general)
15
+ if @phantoms.size >= Constants::MAX_PHANTOMS
16
+ Legion::Logging.warn "[cognitive_phantom] MAX_PHANTOMS (#{Constants::MAX_PHANTOMS}) reached, skipping #{capability_name}"
17
+ return nil
18
+ end
19
+
20
+ limb = PhantomLimb.new(capability_name: capability_name, capability_domain: capability_domain)
21
+ @phantoms[limb.id] = limb
22
+ Legion::Logging.info "[cognitive_phantom] registered phantom: capability=#{capability_name} domain=#{capability_domain} id=#{limb.id[0..7]}"
23
+ limb
24
+ end
25
+
26
+ def process_stimulus(stimulus:, domain: :general)
27
+ fired = []
28
+ @phantoms.each_value do |limb|
29
+ next if limb.resolved?
30
+ next unless domain_match?(limb, domain)
31
+
32
+ signal = limb.trigger!(stimulus)
33
+ next unless signal
34
+
35
+ fired << signal
36
+ intensity_str = limb.intensity.round(3).to_s
37
+ Legion::Logging.debug "[cognitive_phantom] phantom fired: cap=#{limb.capability_name} trigger=#{signal.trigger_type} i=#{intensity_str}"
38
+ end
39
+ fired
40
+ end
41
+
42
+ def decay_all!
43
+ @phantoms.each_value(&:decay!)
44
+ resolve_check!
45
+ end
46
+
47
+ def acknowledge(phantom_id:)
48
+ limb = @phantoms[phantom_id]
49
+ return { acknowledged: false, reason: :not_found } unless limb
50
+
51
+ limb.adapt!
52
+ Legion::Logging.info "[cognitive_phantom] acknowledged phantom id=#{phantom_id[0..7]} intensity=#{limb.intensity.round(3)} state=#{limb.state}"
53
+ { acknowledged: true, phantom_id: phantom_id, state: limb.state, intensity: limb.intensity }
54
+ end
55
+
56
+ def all_phantoms
57
+ @phantoms.values
58
+ end
59
+
60
+ def active_phantoms
61
+ @phantoms.values.reject(&:resolved?)
62
+ end
63
+
64
+ def phantom_activity_report
65
+ all = @phantoms.values
66
+ by_state = Constants::PHANTOM_STATES.to_h { |s| [s, all.count { |p| p.state == s }] }
67
+ {
68
+ total: all.size,
69
+ active: active_phantoms.size,
70
+ by_state: by_state,
71
+ total_activations: all.sum(&:activation_count)
72
+ }
73
+ end
74
+
75
+ def most_persistent(limit: 5)
76
+ active_phantoms.sort_by(&:activation_count).last(limit).reverse
77
+ end
78
+
79
+ def recently_triggered(limit: 5)
80
+ active_phantoms
81
+ .select(&:last_triggered)
82
+ .sort_by(&:last_triggered)
83
+ .last(limit)
84
+ .reverse
85
+ end
86
+
87
+ def resolve_check!
88
+ newly_resolved = @phantoms.values.select(&:resolved?)
89
+ newly_resolved.each do |limb|
90
+ Legion::Logging.info "[cognitive_phantom] resolved: capability=#{limb.capability_name} activations=#{limb.activation_count}"
91
+ end
92
+ newly_resolved.size
93
+ end
94
+
95
+ private
96
+
97
+ def domain_match?(limb, domain)
98
+ domain == :any || limb.capability_domain == domain || limb.capability_domain == :general
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end