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,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module EpistemicVigilance
8
+ module Runners
9
+ module EpistemicVigilance
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex)
12
+
13
+ def register_epistemic_source(name:, domain:, **)
14
+ result = engine.register_source(name: name, domain: domain)
15
+ Legion::Logging.info "[epistemic_vigilance] registered source name=#{name} domain=#{domain} id=#{result[:id]}"
16
+ result
17
+ end
18
+
19
+ def submit_epistemic_claim(content:, source_id:, domain:, initial_confidence: 0.5, **)
20
+ result = engine.submit_claim(content: content, source_id: source_id, domain: domain,
21
+ initial_confidence: initial_confidence)
22
+ Legion::Logging.debug "[epistemic_vigilance] claim submitted domain=#{domain} verdict=#{result.dig(:assessment, :recommended_verdict)}"
23
+ result
24
+ end
25
+
26
+ def assess_epistemic_claim(claim_id:, **)
27
+ result = engine.assess_claim(claim_id: claim_id)
28
+ Legion::Logging.debug "[epistemic_vigilance] assess claim_id=#{claim_id} total=#{result[:total_score]&.round(3)}"
29
+ result
30
+ end
31
+
32
+ def support_epistemic_claim(claim_id:, **)
33
+ result = engine.support_claim(claim_id: claim_id)
34
+ Legion::Logging.debug "[epistemic_vigilance] support claim_id=#{claim_id} confidence=#{result[:confidence]&.round(3)}"
35
+ result
36
+ end
37
+
38
+ def challenge_epistemic_claim(claim_id:, **)
39
+ result = engine.challenge_claim(claim_id: claim_id)
40
+ Legion::Logging.debug "[epistemic_vigilance] challenge claim_id=#{claim_id} confidence=#{result[:confidence]&.round(3)}"
41
+ result
42
+ end
43
+
44
+ def adjudicate_epistemic_claim(claim_id:, verdict:, **)
45
+ result = engine.adjudicate_claim(claim_id: claim_id, verdict: verdict)
46
+ Legion::Logging.info "[epistemic_vigilance] adjudicate claim_id=#{claim_id} verdict=#{verdict}"
47
+ result
48
+ end
49
+
50
+ def source_reliability_report(source_id:, **)
51
+ result = engine.source_reliability(source_id: source_id)
52
+ Legion::Logging.debug "[epistemic_vigilance] source reliability source_id=#{source_id} label=#{result[:label]}"
53
+ result
54
+ end
55
+
56
+ def contested_claims_report(**)
57
+ claims = engine.contested_claims
58
+ Legion::Logging.debug "[epistemic_vigilance] contested claims count=#{claims.size}"
59
+ { contested: claims, count: claims.size }
60
+ end
61
+
62
+ def domain_vigilance_report(domain:, **)
63
+ level = engine.domain_vigilance_level(domain: domain)
64
+ claims = engine.claims_by_domain(domain: domain)
65
+ Legion::Logging.debug "[epistemic_vigilance] domain=#{domain} vigilance_level=#{level} claims=#{claims.size}"
66
+ { domain: domain, vigilance_level: level, claims: claims, count: claims.size }
67
+ end
68
+
69
+ def update_epistemic_vigilance(**)
70
+ decay_result = engine.decay_all
71
+ prune_result = engine.prune_rejected
72
+ Legion::Logging.debug "[epistemic_vigilance] decay+prune decayed=#{decay_result[:decayed]} pruned=#{prune_result[:pruned]}"
73
+ { decay: decay_result, prune: prune_result }
74
+ end
75
+
76
+ def epistemic_vigilance_stats(**)
77
+ engine.to_h
78
+ end
79
+
80
+ private
81
+
82
+ def engine
83
+ @engine ||= Helpers::VigilanceEngine.new
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ 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 EpistemicVigilance
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/epistemic_vigilance/version'
4
+ require 'legion/extensions/agentic/defense/epistemic_vigilance/helpers/constants'
5
+ require 'legion/extensions/agentic/defense/epistemic_vigilance/helpers/claim'
6
+ require 'legion/extensions/agentic/defense/epistemic_vigilance/helpers/source'
7
+ require 'legion/extensions/agentic/defense/epistemic_vigilance/helpers/vigilance_engine'
8
+ require 'legion/extensions/agentic/defense/epistemic_vigilance/runners/epistemic_vigilance'
9
+ require 'legion/extensions/agentic/defense/epistemic_vigilance/client'
10
+
11
+ module Legion
12
+ module Extensions
13
+ module Agentic
14
+ module Defense
15
+ module EpistemicVigilance
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Erosion
8
+ class Client
9
+ include Runners::CognitiveErosion
10
+
11
+ def initialize(engine: nil, **)
12
+ @default_engine = engine || Helpers::ErosionEngine.new
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :default_engine
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Defense
9
+ module Erosion
10
+ module Helpers
11
+ class Channel
12
+ attr_reader :channel_id, :formation_id, :agent, :depth, :width,
13
+ :flow_rate, :created_at, :updated_at, :last_active_at
14
+
15
+ def initialize(formation_id:, agent:, depth: 0.0, width: 0.1, flow_rate: 0.0, **)
16
+ raise ArgumentError, "invalid agent: #{agent}" unless Constants::EROSION_AGENTS.include?(agent)
17
+
18
+ @channel_id = SecureRandom.uuid
19
+ @formation_id = formation_id
20
+ @agent = agent
21
+ @depth = depth.clamp(0.0, 1.0).round(10)
22
+ @width = width.clamp(0.0, 1.0).round(10)
23
+ @flow_rate = flow_rate.clamp(0.0, 1.0).round(10)
24
+ @created_at = Time.now.utc
25
+ @updated_at = Time.now.utc
26
+ @last_active_at = nil
27
+ end
28
+
29
+ def deepen!(force)
30
+ force = force.clamp(0.0, 1.0)
31
+ @depth = (@depth + force).clamp(0.0, 1.0).round(10)
32
+ @flow_rate = [@flow_rate + (force * 0.1), 1.0].min.round(10)
33
+ @last_active_at = Time.now.utc
34
+ @updated_at = Time.now.utc
35
+ { depth: @depth, flow_rate: @flow_rate }
36
+ end
37
+
38
+ def widen!(amount = 0.05)
39
+ amount = amount.clamp(0.0, 1.0)
40
+ @width = (@width + amount).clamp(0.0, 1.0).round(10)
41
+ @updated_at = Time.now.utc
42
+ { width: @width }
43
+ end
44
+
45
+ def dormant?
46
+ return true if @last_active_at.nil?
47
+
48
+ (Time.now.utc - @last_active_at) > 3600
49
+ end
50
+
51
+ def active?
52
+ !dormant?
53
+ end
54
+
55
+ def depth_label
56
+ Constants::CHANNEL_DEPTH_LABELS.each do |range, label|
57
+ return label if range.cover?(@depth)
58
+ end
59
+ :surface_scratch
60
+ end
61
+
62
+ def to_h
63
+ {
64
+ channel_id: @channel_id,
65
+ formation_id: @formation_id,
66
+ agent: @agent,
67
+ depth: @depth,
68
+ width: @width,
69
+ flow_rate: @flow_rate,
70
+ depth_label: depth_label,
71
+ dormant: dormant?,
72
+ active: active?,
73
+ created_at: @created_at,
74
+ updated_at: @updated_at,
75
+ last_active_at: @last_active_at
76
+ }
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Erosion
8
+ module Helpers
9
+ module Constants
10
+ MATERIAL_TYPES = %i[granite sandstone limestone chalk clay].freeze
11
+
12
+ EROSION_AGENTS = %i[water wind ice pressure chemical].freeze
13
+
14
+ RESISTANCE = {
15
+ granite: 0.9,
16
+ sandstone: 0.5,
17
+ limestone: 0.4,
18
+ chalk: 0.2,
19
+ clay: 0.1
20
+ }.freeze
21
+
22
+ MAX_FORMATIONS = 200
23
+
24
+ CHANNEL_DEPTH_LABELS = {
25
+ (0.0...0.1) => :surface_scratch,
26
+ (0.1...0.3) => :shallow_groove,
27
+ (0.3...0.5) => :carved_channel,
28
+ (0.5...0.7) => :deep_channel,
29
+ (0.7...0.9) => :ravine,
30
+ (0.9..1.0) => :canyon
31
+ }.freeze
32
+
33
+ FORMATION_LABELS = {
34
+ (0.9..1.0) => :pristine,
35
+ (0.7...0.9) => :intact,
36
+ (0.5...0.7) => :weathered,
37
+ (0.3...0.5) => :eroded,
38
+ (0.1...0.3) => :crumbling,
39
+ (0.0...0.1) => :ruins
40
+ }.freeze
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Erosion
8
+ module Helpers
9
+ class ErosionEngine
10
+ def initialize
11
+ @formations = {}
12
+ @channels = {}
13
+ end
14
+
15
+ def create_formation(material_type:, domain:, content:, resistance: nil, **)
16
+ return { success: false, error: :max_formations_reached } if @formations.size >= Constants::MAX_FORMATIONS
17
+ return { success: false, error: :invalid_material_type } unless Constants::MATERIAL_TYPES.include?(material_type)
18
+
19
+ formation = Formation.new(
20
+ material_type: material_type,
21
+ domain: domain,
22
+ content: content,
23
+ resistance: resistance
24
+ )
25
+ @formations[formation.formation_id] = formation
26
+ { success: true, formation_id: formation.formation_id, formation: formation.to_h }
27
+ rescue ArgumentError => e
28
+ { success: false, error: e.message }
29
+ end
30
+
31
+ def erode(formation_id:, agent:, force:, **)
32
+ formation = @formations[formation_id]
33
+ return { success: false, error: :formation_not_found } unless formation
34
+ return { success: false, error: :invalid_agent } unless Constants::EROSION_AGENTS.include?(agent)
35
+
36
+ result = formation.erode!(agent, force)
37
+ channel = carve_channel(formation_id: formation_id, agent: agent, force: force)
38
+
39
+ { success: true, formation_id: formation_id, erosion: result, channel: channel }
40
+ rescue ArgumentError => e
41
+ { success: false, error: e.message }
42
+ end
43
+
44
+ def carve_channel(formation_id:, agent:, force: 0.1, **)
45
+ existing = find_channel(formation_id, agent)
46
+ if existing
47
+ existing.deepen!(force.clamp(0.0, 1.0))
48
+ existing.widen! if existing.depth >= 0.3
49
+ existing.to_h
50
+ else
51
+ channel = Channel.new(formation_id: formation_id, agent: agent)
52
+ channel.deepen!(force.clamp(0.0, 1.0))
53
+ @channels[channel.channel_id] = channel
54
+ channel.to_h
55
+ end
56
+ end
57
+
58
+ def weather_all!(force: 0.05, agent: :wind, **)
59
+ results = @formations.map do |id, formation|
60
+ erosion = formation.erode!(agent, force)
61
+ ch = carve_channel(formation_id: id, agent: agent, force: force)
62
+ { formation_id: id, erosion: erosion, channel: ch }
63
+ end
64
+ { success: true, weathered: results.size, results: results }
65
+ rescue ArgumentError => e
66
+ { success: false, error: e.message }
67
+ end
68
+
69
+ def deepest_channels(limit: 5, **)
70
+ limit = limit.clamp(1, @channels.size.positive? ? @channels.size : 1)
71
+ sorted = @channels.values.sort_by { |c| -c.depth }
72
+ sorted.first(limit).map(&:to_h)
73
+ end
74
+
75
+ def most_eroded(limit: 5, **)
76
+ limit = limit.clamp(1, @formations.size.positive? ? @formations.size : 1)
77
+ sorted = @formations.values.sort_by(&:erosion_depth).reverse
78
+ sorted.first(limit).map(&:to_h)
79
+ end
80
+
81
+ def erosion_report(**)
82
+ {
83
+ success: true,
84
+ total_formations: @formations.size,
85
+ total_channels: @channels.size,
86
+ canyons: @formations.values.count(&:canyon?),
87
+ weathered: @formations.values.count(&:weathered?),
88
+ pristine: @formations.values.count(&:pristine?),
89
+ average_depth: average_depth,
90
+ average_integrity: average_integrity,
91
+ deepest_channels: deepest_channels(limit: 3),
92
+ most_eroded: most_eroded(limit: 3)
93
+ }
94
+ end
95
+
96
+ def get_formation(formation_id)
97
+ formation = @formations[formation_id]
98
+ return { found: false } unless formation
99
+
100
+ { found: true, formation: formation.to_h }
101
+ end
102
+
103
+ def formation_count
104
+ @formations.size
105
+ end
106
+
107
+ def channel_count
108
+ @channels.size
109
+ end
110
+
111
+ private
112
+
113
+ def average_depth
114
+ return 0.0 if @formations.empty?
115
+
116
+ (@formations.values.sum(&:erosion_depth) / @formations.size.to_f).round(10)
117
+ end
118
+
119
+ def average_integrity
120
+ return 1.0 if @formations.empty?
121
+
122
+ (@formations.values.sum(&:integrity) / @formations.size.to_f).round(10)
123
+ end
124
+
125
+ def find_channel(formation_id, agent)
126
+ @channels.values.find { |c| c.formation_id == formation_id && c.agent == agent }
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Defense
9
+ module Erosion
10
+ module Helpers
11
+ class Formation
12
+ attr_reader :formation_id, :material_type, :domain, :content,
13
+ :resistance, :integrity, :erosion_depth, :created_at, :updated_at
14
+
15
+ def initialize(material_type:, domain:, content:, resistance: nil, **)
16
+ raise ArgumentError, "invalid material_type: #{material_type}" unless Constants::MATERIAL_TYPES.include?(material_type)
17
+
18
+ @formation_id = SecureRandom.uuid
19
+ @material_type = material_type
20
+ @domain = domain
21
+ @content = content
22
+ @resistance = resistance || Constants::RESISTANCE.fetch(material_type)
23
+ @integrity = 1.0
24
+ @erosion_depth = 0.0
25
+ @created_at = Time.now.utc
26
+ @updated_at = Time.now.utc
27
+ end
28
+
29
+ def erode!(agent, force)
30
+ raise ArgumentError, "invalid agent: #{agent}" unless Constants::EROSION_AGENTS.include?(agent)
31
+
32
+ force = force.clamp(0.0, 1.0)
33
+ effective_force = (force * (1.0 - @resistance)).round(10)
34
+
35
+ @integrity = (@integrity - effective_force).clamp(0.0, 1.0).round(10)
36
+ @erosion_depth = (@erosion_depth + effective_force).clamp(0.0, 1.0).round(10)
37
+ @updated_at = Time.now.utc
38
+
39
+ { agent: agent, force: force, effective_force: effective_force, integrity: @integrity, erosion_depth: @erosion_depth }
40
+ end
41
+
42
+ def resist!(amount = nil)
43
+ amount ||= @resistance * 0.1
44
+ amount = amount.clamp(0.0, 1.0)
45
+ @integrity = (@integrity + amount).clamp(0.0, 1.0).round(10)
46
+ @updated_at = Time.now.utc
47
+ { integrity: @integrity, recovered: amount }
48
+ end
49
+
50
+ def weathered?
51
+ @integrity < 0.7
52
+ end
53
+
54
+ def canyon?
55
+ @erosion_depth >= 0.7
56
+ end
57
+
58
+ def pristine?
59
+ @integrity >= 0.9
60
+ end
61
+
62
+ def integrity_label
63
+ Constants::FORMATION_LABELS.each do |range, label|
64
+ return label if range.cover?(@integrity)
65
+ end
66
+ :ruins
67
+ end
68
+
69
+ def depth_label
70
+ Constants::CHANNEL_DEPTH_LABELS.each do |range, label|
71
+ return label if range.cover?(@erosion_depth)
72
+ end
73
+ :surface_scratch
74
+ end
75
+
76
+ def to_h
77
+ {
78
+ formation_id: @formation_id,
79
+ material_type: @material_type,
80
+ domain: @domain,
81
+ content: @content,
82
+ resistance: @resistance,
83
+ integrity: @integrity,
84
+ erosion_depth: @erosion_depth,
85
+ integrity_label: integrity_label,
86
+ depth_label: depth_label,
87
+ weathered: weathered?,
88
+ canyon: canyon?,
89
+ pristine: pristine?,
90
+ created_at: @created_at,
91
+ updated_at: @updated_at
92
+ }
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Erosion
8
+ module Runners
9
+ module CognitiveErosion
10
+ extend self
11
+
12
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
13
+
14
+ def create_formation(material_type:, domain:, content:, resistance: nil, engine: nil, **)
15
+ eng = engine || default_engine
16
+ result = eng.create_formation(
17
+ material_type: material_type,
18
+ domain: domain,
19
+ content: content,
20
+ resistance: resistance
21
+ )
22
+ Legion::Logging.debug "[cognitive_erosion] formation created: #{result[:formation_id]}" if result[:success]
23
+ result
24
+ rescue ArgumentError => e
25
+ Legion::Logging.warn "[cognitive_erosion] create_formation failed: #{e.message}"
26
+ { success: false, error: e.message }
27
+ end
28
+
29
+ def erode(formation_id:, agent:, force:, engine: nil, **)
30
+ eng = engine || default_engine
31
+ result = eng.erode(formation_id: formation_id, agent: agent, force: force)
32
+ Legion::Logging.debug "[cognitive_erosion] eroded #{formation_id[0..7]} agent=#{agent} force=#{force.round(3)}" if result[:success]
33
+ result
34
+ rescue ArgumentError => e
35
+ Legion::Logging.warn "[cognitive_erosion] erode failed: #{e.message}"
36
+ { success: false, error: e.message }
37
+ end
38
+
39
+ def weather_all(force: 0.05, agent: :wind, engine: nil, **)
40
+ eng = engine || default_engine
41
+ result = eng.weather_all!(force: force, agent: agent)
42
+ Legion::Logging.debug "[cognitive_erosion] weather_all: #{result[:weathered]} formations weathered" if result[:success]
43
+ result
44
+ rescue ArgumentError => e
45
+ Legion::Logging.warn "[cognitive_erosion] weather_all failed: #{e.message}"
46
+ { success: false, error: e.message }
47
+ end
48
+
49
+ def deepest_channels(limit: 5, engine: nil, **)
50
+ eng = engine || default_engine
51
+ channels = eng.deepest_channels(limit: limit)
52
+ { success: true, channels: channels, count: channels.size }
53
+ rescue ArgumentError => e
54
+ { success: false, error: e.message }
55
+ end
56
+
57
+ def most_eroded(limit: 5, engine: nil, **)
58
+ eng = engine || default_engine
59
+ formations = eng.most_eroded(limit: limit)
60
+ { success: true, formations: formations, count: formations.size }
61
+ rescue ArgumentError => e
62
+ { success: false, error: e.message }
63
+ end
64
+
65
+ def erosion_report(engine: nil, **)
66
+ eng = engine || default_engine
67
+ result = eng.erosion_report
68
+ Legion::Logging.debug "[cognitive_erosion] report: formations=#{result[:total_formations]} " \
69
+ "channels=#{result[:total_channels]} canyons=#{result[:canyons]}"
70
+ result
71
+ rescue ArgumentError => e
72
+ { success: false, error: e.message }
73
+ end
74
+
75
+ def get_formation(formation_id:, engine: nil, **)
76
+ eng = engine || default_engine
77
+ eng.get_formation(formation_id)
78
+ rescue ArgumentError => e
79
+ { success: false, error: e.message }
80
+ end
81
+
82
+ private
83
+
84
+ def default_engine
85
+ @default_engine ||= Helpers::ErosionEngine.new
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ 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 Erosion
8
+ VERSION = '0.1.0'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+ require_relative 'erosion/version'
5
+ require_relative 'erosion/helpers/constants'
6
+ require_relative 'erosion/helpers/formation'
7
+ require_relative 'erosion/helpers/channel'
8
+ require_relative 'erosion/helpers/erosion_engine'
9
+ require_relative 'erosion/runners/cognitive_erosion'
10
+ require_relative 'erosion/client'
11
+
12
+ module Legion
13
+ module Extensions
14
+ module Agentic
15
+ module Defense
16
+ module Erosion
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end