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,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Defense::ErrorMonitoring::Helpers::ErrorMonitor do
4
+ subject(:monitor) { described_class.new }
5
+
6
+ let(:constants) { Legion::Extensions::Agentic::Defense::ErrorMonitoring::Helpers::Constants }
7
+
8
+ describe '#register_error' do
9
+ it 'creates an error signal' do
10
+ signal = monitor.register_error(action: :parse, domain: :data, intended: :valid, actual: :malformed,
11
+ severity: 0.5)
12
+ expect(signal).to be_a(Legion::Extensions::Agentic::Defense::ErrorMonitoring::Helpers::ErrorSignal)
13
+ expect(monitor.error_count).to eq(1)
14
+ end
15
+
16
+ it 'increases error rate' do
17
+ before = monitor.error_rate
18
+ monitor.register_error(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.8)
19
+ expect(monitor.error_rate).to be > before
20
+ end
21
+
22
+ it 'applies post-error slowdown' do
23
+ monitor.register_error(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.8)
24
+ expect(monitor.slowdown).to be > 0
25
+ end
26
+
27
+ it 'decreases confidence' do
28
+ before = monitor.confidence
29
+ monitor.register_error(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.5)
30
+ expect(monitor.confidence).to be < before
31
+ end
32
+
33
+ it 'limits error log size' do
34
+ (constants::MAX_ERROR_LOG + 10).times do |i|
35
+ monitor.register_error(action: :"a_#{i}", domain: :d, intended: :i, actual: :a, severity: 0.3)
36
+ end
37
+ expect(monitor.error_count).to eq(constants::MAX_ERROR_LOG)
38
+ end
39
+ end
40
+
41
+ describe '#register_success' do
42
+ it 'decreases error rate' do
43
+ monitor.register_error(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.8)
44
+ before = monitor.error_rate
45
+ monitor.register_success(action: :b, domain: :d)
46
+ expect(monitor.error_rate).to be < before
47
+ end
48
+
49
+ it 'increases confidence' do
50
+ monitor.register_error(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.5)
51
+ before = monitor.confidence
52
+ monitor.register_success(action: :b, domain: :d)
53
+ expect(monitor.confidence).to be > before
54
+ end
55
+ end
56
+
57
+ describe '#register_conflict' do
58
+ it 'records a conflict' do
59
+ entry = monitor.register_conflict(action_a: :run, action_b: :hide, domain: :safety, intensity: 0.8)
60
+ expect(entry[:action_a]).to eq(:run)
61
+ expect(entry[:intensity]).to eq(0.8)
62
+ end
63
+
64
+ it 'increases conflict level' do
65
+ monitor.register_conflict(action_a: :a, action_b: :b, domain: :d, intensity: 0.9)
66
+ expect(monitor.conflict_level).to be > 0
67
+ end
68
+ end
69
+
70
+ describe '#register_correction' do
71
+ it 'records a correction' do
72
+ monitor.register_error(action: :parse, domain: :data, intended: :valid, actual: :malformed, severity: 0.5)
73
+ entry = monitor.register_correction(action: :parse, domain: :data, original_error: :malformed, correction: :retry)
74
+ expect(entry[:correction]).to eq(:retry)
75
+ end
76
+
77
+ it 'marks the error as corrected' do
78
+ monitor.register_error(action: :parse, domain: :data, intended: :valid, actual: :malformed, severity: 0.5)
79
+ monitor.register_correction(action: :parse, domain: :data, original_error: :malformed, correction: :retry)
80
+ expect(monitor.uncorrected_errors).to be_empty
81
+ end
82
+
83
+ it 'boosts confidence' do
84
+ monitor.register_error(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.5)
85
+ before = monitor.confidence
86
+ monitor.register_correction(action: :a, domain: :d, original_error: :a, correction: :fix)
87
+ expect(monitor.confidence).to be > before
88
+ end
89
+ end
90
+
91
+ describe '#recent_errors' do
92
+ it 'returns recent errors' do
93
+ 3.times { |i| monitor.register_error(action: :"a_#{i}", domain: :d, intended: :i, actual: :a, severity: 0.3) }
94
+ expect(monitor.recent_errors(limit: 2).size).to eq(2)
95
+ end
96
+ end
97
+
98
+ describe '#errors_in' do
99
+ it 'filters by domain' do
100
+ monitor.register_error(action: :a, domain: :network, intended: :i, actual: :a, severity: 0.3)
101
+ monitor.register_error(action: :b, domain: :data, intended: :i, actual: :a, severity: 0.3)
102
+ expect(monitor.errors_in(domain: :network).size).to eq(1)
103
+ end
104
+ end
105
+
106
+ describe '#uncorrected_errors' do
107
+ it 'returns only uncorrected errors' do
108
+ monitor.register_error(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.3)
109
+ monitor.register_error(action: :b, domain: :d, intended: :i, actual: :a, severity: 0.3)
110
+ monitor.register_correction(action: :a, domain: :d, original_error: :a, correction: :fix)
111
+ expect(monitor.uncorrected_errors.size).to eq(1)
112
+ end
113
+ end
114
+
115
+ describe '#conflict_active?' do
116
+ it 'returns false initially' do
117
+ expect(monitor.conflict_active?).to be false
118
+ end
119
+
120
+ it 'returns true after sustained high-intensity conflict' do
121
+ 20.times { monitor.register_conflict(action_a: :a, action_b: :b, domain: :d, intensity: 0.9) }
122
+ expect(monitor.conflict_active?).to be true
123
+ end
124
+ end
125
+
126
+ describe '#monitoring_state' do
127
+ it 'returns :normal initially' do
128
+ expect(monitor.monitoring_state).to eq(:normal)
129
+ end
130
+
131
+ it 'returns :vigilant after errors (slowdown active)' do
132
+ monitor.register_error(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.8)
133
+ expect(monitor.monitoring_state).to eq(:vigilant)
134
+ end
135
+
136
+ it 'returns :relaxed after many successes' do
137
+ 50.times { monitor.register_success(action: :a, domain: :d) }
138
+ expect(monitor.monitoring_state).to eq(:relaxed)
139
+ end
140
+ end
141
+
142
+ describe '#tick' do
143
+ it 'decays slowdown' do
144
+ monitor.register_error(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.8)
145
+ before = monitor.slowdown
146
+ monitor.tick
147
+ expect(monitor.slowdown).to be < before
148
+ end
149
+
150
+ it 'decays conflict level' do
151
+ monitor.register_conflict(action_a: :a, action_b: :b, domain: :d, intensity: 0.9)
152
+ before = monitor.conflict_level
153
+ monitor.tick
154
+ expect(monitor.conflict_level).to be < before
155
+ end
156
+ end
157
+
158
+ describe '#correction_rate' do
159
+ it 'returns 0 with no errors' do
160
+ expect(monitor.correction_rate).to eq(0.0)
161
+ end
162
+
163
+ it 'returns ratio of corrected to total' do
164
+ monitor.register_error(action: :first, domain: :d, intended: :i, actual: :a, severity: 0.3)
165
+ monitor.register_error(action: :second, domain: :d, intended: :i, actual: :a, severity: 0.3)
166
+ monitor.register_correction(action: :first, domain: :d, original_error: :a, correction: :fix)
167
+ expect(monitor.correction_rate).to eq(0.5)
168
+ end
169
+ end
170
+
171
+ describe '#to_h' do
172
+ it 'returns stats hash' do
173
+ h = monitor.to_h
174
+ expect(h).to include(:error_rate, :conflict_level, :confidence, :slowdown, :state,
175
+ :state_label, :total_errors, :uncorrected, :correction_rate, :conflict_active)
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Defense::ErrorMonitoring::Helpers::ErrorSignal do
4
+ subject(:signal) do
5
+ described_class.new(action: :api_call, domain: :network, intended: :success, actual: :timeout, severity: 0.7)
6
+ end
7
+
8
+ let(:constants) { Legion::Extensions::Agentic::Defense::ErrorMonitoring::Helpers::Constants }
9
+
10
+ describe '#initialize' do
11
+ it 'sets attributes' do
12
+ expect(signal.action).to eq(:api_call)
13
+ expect(signal.domain).to eq(:network)
14
+ expect(signal.intended).to eq(:success)
15
+ expect(signal.actual).to eq(:timeout)
16
+ expect(signal.severity).to eq(0.7)
17
+ expect(signal.corrected).to be false
18
+ end
19
+
20
+ it 'clamps severity' do
21
+ high = described_class.new(action: :a, domain: :d, intended: :i, actual: :a, severity: 1.5)
22
+ expect(high.severity).to eq(1.0)
23
+ end
24
+
25
+ it 'records detected_at' do
26
+ expect(signal.detected_at).to be_a(Time)
27
+ end
28
+ end
29
+
30
+ describe '#mark_corrected' do
31
+ it 'marks the error as corrected' do
32
+ signal.mark_corrected
33
+ expect(signal.corrected).to be true
34
+ end
35
+ end
36
+
37
+ describe '#severe?' do
38
+ it 'returns true for high severity' do
39
+ expect(signal.severe?).to be true
40
+ end
41
+
42
+ it 'returns false for low severity' do
43
+ low = described_class.new(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.3)
44
+ expect(low.severe?).to be false
45
+ end
46
+ end
47
+
48
+ describe '#age' do
49
+ it 'returns elapsed time' do
50
+ expect(signal.age).to be >= 0.0
51
+ end
52
+ end
53
+
54
+ describe '#label' do
55
+ it 'returns :major for 0.7 severity' do
56
+ expect(signal.label).to eq(:major)
57
+ end
58
+
59
+ it 'returns :trivial for low severity' do
60
+ low = described_class.new(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.1)
61
+ expect(low.label).to eq(:trivial)
62
+ end
63
+
64
+ it 'returns :critical for high severity' do
65
+ crit = described_class.new(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.9)
66
+ expect(crit.label).to eq(:critical)
67
+ end
68
+ end
69
+
70
+ describe '#to_h' do
71
+ it 'returns hash with all fields' do
72
+ h = signal.to_h
73
+ expect(h).to include(:action, :domain, :intended, :actual, :severity, :label, :detected_at, :corrected, :age)
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Defense::ErrorMonitoring::Runners::ErrorMonitoring do
4
+ let(:client) { Legion::Extensions::Agentic::Defense::ErrorMonitoring::Client.new }
5
+
6
+ describe '#report_error' do
7
+ it 'registers an error' do
8
+ result = client.report_error(action: :api_call, domain: :network, intended: :ok, actual: :timeout, severity: 0.6)
9
+ expect(result[:success]).to be true
10
+ expect(result[:error][:action]).to eq(:api_call)
11
+ expect(result[:slowdown]).to be > 0
12
+ end
13
+ end
14
+
15
+ describe '#report_success' do
16
+ it 'registers a success' do
17
+ result = client.report_success(action: :api_call, domain: :network)
18
+ expect(result[:success]).to be true
19
+ expect(result[:error_rate]).to be_a(Float)
20
+ end
21
+ end
22
+
23
+ describe '#report_conflict' do
24
+ it 'registers a conflict' do
25
+ result = client.report_conflict(action_a: :run, action_b: :hide, domain: :safety, intensity: 0.7)
26
+ expect(result[:success]).to be true
27
+ expect(result[:conflict][:action_a]).to eq(:run)
28
+ end
29
+ end
30
+
31
+ describe '#apply_correction' do
32
+ it 'applies a correction' do
33
+ client.report_error(action: :parse, domain: :data, intended: :valid, actual: :bad, severity: 0.5)
34
+ result = client.apply_correction(action: :parse, domain: :data, original_error: :bad, correction: :retry)
35
+ expect(result[:success]).to be true
36
+ expect(result[:confidence]).to be > 0
37
+ end
38
+ end
39
+
40
+ describe '#recent_errors' do
41
+ it 'returns recent errors' do
42
+ client.report_error(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.3)
43
+ result = client.recent_errors(limit: 5)
44
+ expect(result[:count]).to eq(1)
45
+ end
46
+ end
47
+
48
+ describe '#errors_in_domain' do
49
+ it 'filters errors by domain' do
50
+ client.report_error(action: :a, domain: :net, intended: :i, actual: :a, severity: 0.3)
51
+ client.report_error(action: :b, domain: :data, intended: :i, actual: :a, severity: 0.3)
52
+ result = client.errors_in_domain(domain: :net)
53
+ expect(result[:count]).to eq(1)
54
+ end
55
+ end
56
+
57
+ describe '#uncorrected_errors' do
58
+ it 'returns uncorrected errors' do
59
+ client.report_error(action: :a, domain: :d, intended: :i, actual: :a, severity: 0.3)
60
+ result = client.uncorrected_errors
61
+ expect(result[:count]).to eq(1)
62
+ end
63
+ end
64
+
65
+ describe '#monitoring_state' do
66
+ it 'returns current state' do
67
+ result = client.monitoring_state
68
+ expect(result[:success]).to be true
69
+ expect(result[:state]).to be_a(Symbol)
70
+ end
71
+ end
72
+
73
+ describe '#update_error_monitoring' do
74
+ it 'runs tick' do
75
+ result = client.update_error_monitoring
76
+ expect(result[:success]).to be true
77
+ end
78
+ end
79
+
80
+ describe '#error_monitoring_stats' do
81
+ it 'returns stats' do
82
+ result = client.error_monitoring_stats
83
+ expect(result[:success]).to be true
84
+ expect(result[:stats]).to include(:error_rate, :confidence, :state)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Actors
6
+ class Every; end # rubocop:disable Lint/EmptyClass
7
+ end
8
+ end
9
+ end
10
+
11
+ $LOADED_FEATURES << 'legion/extensions/actors/every'
12
+
13
+ require_relative '../../../../../../../lib/legion/extensions/agentic/defense/extinction/actors/protocol_monitor'
14
+
15
+ RSpec.describe Legion::Extensions::Agentic::Defense::Extinction::Actor::ProtocolMonitor do
16
+ subject(:actor) { described_class.new }
17
+
18
+ describe '#runner_class' do
19
+ it { expect(actor.runner_class).to eq Legion::Extensions::Agentic::Defense::Extinction::Runners::Extinction }
20
+ end
21
+
22
+ describe '#runner_function' do
23
+ it { expect(actor.runner_function).to eq 'monitor_protocol' }
24
+ end
25
+
26
+ describe '#time' do
27
+ it { expect(actor.time).to eq 300 }
28
+ end
29
+
30
+ describe '#run_now?' do
31
+ it { expect(actor.run_now?).to be false }
32
+ end
33
+
34
+ describe '#use_runner?' do
35
+ it { expect(actor.use_runner?).to be false }
36
+ end
37
+
38
+ describe '#check_subtask?' do
39
+ it { expect(actor.check_subtask?).to be false }
40
+ end
41
+
42
+ describe '#generate_task?' do
43
+ it { expect(actor.generate_task?).to be false }
44
+ end
45
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/defense/extinction/client'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Defense::Extinction::Client do
6
+ it 'responds to extinction runner methods' do
7
+ client = described_class.new
8
+ expect(client).to respond_to(:escalate)
9
+ expect(client).to respond_to(:deescalate)
10
+ expect(client).to respond_to(:extinction_status)
11
+ expect(client).to respond_to(:check_reversibility)
12
+ end
13
+ end
@@ -0,0 +1,180 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/defense/extinction/helpers/levels'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Defense::Extinction::Helpers::Levels do
6
+ describe 'ESCALATION_LEVELS' do
7
+ it 'defines exactly four levels' do
8
+ expect(described_class::ESCALATION_LEVELS.size).to eq(4)
9
+ end
10
+
11
+ it 'is keyed by integers 1 through 4' do
12
+ expect(described_class::ESCALATION_LEVELS.keys).to eq([1, 2, 3, 4])
13
+ end
14
+
15
+ it 'is frozen' do
16
+ expect(described_class::ESCALATION_LEVELS).to be_frozen
17
+ end
18
+
19
+ it 'defines level 1 as mesh_isolation' do
20
+ expect(described_class::ESCALATION_LEVELS[1][:name]).to eq(:mesh_isolation)
21
+ end
22
+
23
+ it 'defines level 2 as forced_sentinel' do
24
+ expect(described_class::ESCALATION_LEVELS[2][:name]).to eq(:forced_sentinel)
25
+ end
26
+
27
+ it 'defines level 3 as full_suspension' do
28
+ expect(described_class::ESCALATION_LEVELS[3][:name]).to eq(:full_suspension)
29
+ end
30
+
31
+ it 'defines level 4 as cryptographic_erasure' do
32
+ expect(described_class::ESCALATION_LEVELS[4][:name]).to eq(:cryptographic_erasure)
33
+ end
34
+
35
+ it 'marks levels 1-3 as reversible' do
36
+ [1, 2, 3].each do |level|
37
+ expect(described_class::ESCALATION_LEVELS[level][:reversible]).to be true
38
+ end
39
+ end
40
+
41
+ it 'marks level 4 as not reversible' do
42
+ expect(described_class::ESCALATION_LEVELS[4][:reversible]).to be false
43
+ end
44
+
45
+ it 'assigns governance_council authority to levels 1 and 2' do
46
+ expect(described_class::ESCALATION_LEVELS[1][:authority]).to eq(:governance_council)
47
+ expect(described_class::ESCALATION_LEVELS[2][:authority]).to eq(:governance_council)
48
+ end
49
+
50
+ it 'assigns council_plus_executive authority to level 3' do
51
+ expect(described_class::ESCALATION_LEVELS[3][:authority]).to eq(:council_plus_executive)
52
+ end
53
+
54
+ it 'assigns physical_keyholders authority to level 4' do
55
+ expect(described_class::ESCALATION_LEVELS[4][:authority]).to eq(:physical_keyholders)
56
+ end
57
+ end
58
+
59
+ describe 'VALID_LEVELS' do
60
+ it 'contains exactly [1, 2, 3, 4]' do
61
+ expect(described_class::VALID_LEVELS).to eq([1, 2, 3, 4])
62
+ end
63
+
64
+ it 'is frozen' do
65
+ expect(described_class::VALID_LEVELS).to be_frozen
66
+ end
67
+ end
68
+
69
+ describe '.valid_level?' do
70
+ it 'returns true for level 1' do
71
+ expect(described_class.valid_level?(1)).to be true
72
+ end
73
+
74
+ it 'returns true for level 2' do
75
+ expect(described_class.valid_level?(2)).to be true
76
+ end
77
+
78
+ it 'returns true for level 3' do
79
+ expect(described_class.valid_level?(3)).to be true
80
+ end
81
+
82
+ it 'returns true for level 4' do
83
+ expect(described_class.valid_level?(4)).to be true
84
+ end
85
+
86
+ it 'returns false for level 0' do
87
+ expect(described_class.valid_level?(0)).to be false
88
+ end
89
+
90
+ it 'returns false for level 5' do
91
+ expect(described_class.valid_level?(5)).to be false
92
+ end
93
+
94
+ it 'returns false for negative levels' do
95
+ expect(described_class.valid_level?(-1)).to be false
96
+ end
97
+
98
+ it 'returns false for nil' do
99
+ expect(described_class.valid_level?(nil)).to be false
100
+ end
101
+
102
+ it 'returns false for string level' do
103
+ expect(described_class.valid_level?('1')).to be false
104
+ end
105
+ end
106
+
107
+ describe '.level_info' do
108
+ it 'returns the full info hash for a valid level' do
109
+ info = described_class.level_info(1)
110
+ expect(info).to be_a(Hash)
111
+ expect(info.keys).to contain_exactly(:name, :reversible, :authority)
112
+ end
113
+
114
+ it 'returns nil for an invalid level' do
115
+ expect(described_class.level_info(99)).to be_nil
116
+ end
117
+
118
+ it 'returns nil for level 0' do
119
+ expect(described_class.level_info(0)).to be_nil
120
+ end
121
+
122
+ [1, 2, 3, 4].each do |level|
123
+ it "returns a hash for level #{level}" do
124
+ expect(described_class.level_info(level)).to be_a(Hash)
125
+ end
126
+ end
127
+ end
128
+
129
+ describe '.reversible?' do
130
+ it 'returns true for level 1' do
131
+ expect(described_class.reversible?(1)).to be true
132
+ end
133
+
134
+ it 'returns true for level 2' do
135
+ expect(described_class.reversible?(2)).to be true
136
+ end
137
+
138
+ it 'returns true for level 3' do
139
+ expect(described_class.reversible?(3)).to be true
140
+ end
141
+
142
+ it 'returns false for level 4' do
143
+ expect(described_class.reversible?(4)).to be false
144
+ end
145
+
146
+ it 'returns false for an invalid level (fallback to false)' do
147
+ expect(described_class.reversible?(99)).to be false
148
+ end
149
+
150
+ it 'returns false for nil level' do
151
+ expect(described_class.reversible?(nil)).to be false
152
+ end
153
+ end
154
+
155
+ describe '.required_authority' do
156
+ it 'returns :governance_council for level 1' do
157
+ expect(described_class.required_authority(1)).to eq(:governance_council)
158
+ end
159
+
160
+ it 'returns :governance_council for level 2' do
161
+ expect(described_class.required_authority(2)).to eq(:governance_council)
162
+ end
163
+
164
+ it 'returns :council_plus_executive for level 3' do
165
+ expect(described_class.required_authority(3)).to eq(:council_plus_executive)
166
+ end
167
+
168
+ it 'returns :physical_keyholders for level 4' do
169
+ expect(described_class.required_authority(4)).to eq(:physical_keyholders)
170
+ end
171
+
172
+ it 'returns nil for an invalid level' do
173
+ expect(described_class.required_authority(0)).to be_nil
174
+ end
175
+
176
+ it 'returns nil for an out-of-range level' do
177
+ expect(described_class.required_authority(5)).to be_nil
178
+ end
179
+ end
180
+ end