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,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Quicksand
8
+ module Runners
9
+ module CognitiveQuicksand
10
+ extend self
11
+
12
+ def create_trap(trap_type:, domain:, content:,
13
+ depth: nil, viscosity: nil, engine: nil, **)
14
+ eng = resolve_engine(engine)
15
+ t = eng.create_trap(trap_type: trap_type, domain: domain, content: content,
16
+ depth: depth, viscosity: viscosity)
17
+ { success: true, trap: t.to_h }
18
+ rescue ArgumentError => e
19
+ { success: false, error: e.message }
20
+ end
21
+
22
+ def create_pit(saturation: nil, danger_level: nil, engine: nil, **)
23
+ eng = resolve_engine(engine)
24
+ p = eng.create_pit(saturation: saturation, danger_level: danger_level)
25
+ { success: true, pit: p.to_h }
26
+ rescue ArgumentError => e
27
+ { success: false, error: e.message }
28
+ end
29
+
30
+ def struggle(trap_id:, engine: nil, **)
31
+ eng = resolve_engine(engine)
32
+ result = eng.struggle(trap_id: trap_id)
33
+ { success: true, trap: result[:trap].to_h,
34
+ depth: result[:depth], struggle_count: result[:struggle_count] }
35
+ rescue ArgumentError => e
36
+ { success: false, error: e.message }
37
+ end
38
+
39
+ def calm_down(trap_id:, rate: nil, engine: nil, **)
40
+ eng = resolve_engine(engine)
41
+ trap = eng.calm(trap_id: trap_id, rate: rate || Helpers::Constants::CALM_RATE)
42
+ { success: true, trap: trap.to_h }
43
+ rescue ArgumentError => e
44
+ { success: false, error: e.message }
45
+ end
46
+
47
+ def attempt_escape(trap_id:, engine: nil, **)
48
+ eng = resolve_engine(engine)
49
+ result = eng.attempt_escape(trap_id: trap_id)
50
+ { success: true, trap: result[:trap].to_h, result: result[:result] }
51
+ rescue ArgumentError => e
52
+ { success: false, error: e.message }
53
+ end
54
+
55
+ def list_traps(engine: nil, trap_type: nil, **)
56
+ eng = resolve_engine(engine)
57
+ results = eng.all_traps
58
+ results = results.select { |t| t.trap_type == trap_type.to_sym } if trap_type
59
+ { success: true, traps: results.map(&:to_h), count: results.size }
60
+ end
61
+
62
+ def quicksand_status(engine: nil, **)
63
+ eng = resolve_engine(engine)
64
+ { success: true, report: eng.quicksand_report }
65
+ end
66
+
67
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
68
+
69
+ private
70
+
71
+ def resolve_engine(engine)
72
+ engine || default_engine
73
+ end
74
+
75
+ def default_engine
76
+ @default_engine ||= Helpers::QuicksandEngine.new
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ 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 Quicksand
8
+ VERSION = '0.1.0'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ require_relative 'quicksand/version'
6
+ require_relative 'quicksand/helpers/constants'
7
+ require_relative 'quicksand/helpers/trap'
8
+ require_relative 'quicksand/helpers/pit'
9
+ require_relative 'quicksand/helpers/quicksand_engine'
10
+ require_relative 'quicksand/runners/cognitive_quicksand'
11
+ require_relative 'quicksand/client'
12
+
13
+ module Legion
14
+ module Extensions
15
+ module Agentic
16
+ module Defense
17
+ module Quicksand
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/defense/quicksilver/helpers/constants'
4
+ require 'legion/extensions/agentic/defense/quicksilver/helpers/droplet'
5
+ require 'legion/extensions/agentic/defense/quicksilver/helpers/pool'
6
+ require 'legion/extensions/agentic/defense/quicksilver/helpers/quicksilver_engine'
7
+ require 'legion/extensions/agentic/defense/quicksilver/runners/cognitive_quicksilver'
8
+
9
+ module Legion
10
+ module Extensions
11
+ module Agentic
12
+ module Defense
13
+ module Quicksilver
14
+ class Client
15
+ include Runners::CognitiveQuicksilver
16
+
17
+ def initialize
18
+ @quicksilver_engine = Helpers::QuicksilverEngine.new
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :quicksilver_engine
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Quicksilver
8
+ module Helpers
9
+ module Constants
10
+ FORM_TYPES = %i[liquid droplet bead stream pool].freeze
11
+ SURFACE_TYPES = %i[glass metal wood stone fabric].freeze
12
+
13
+ MAX_DROPLETS = 500
14
+ MAX_POOLS = 50
15
+
16
+ FLUIDITY_BASE = 0.8
17
+ SURFACE_TENSION = 0.3
18
+ EVAPORATION_RATE = 0.02
19
+ COALESCENCE_BONUS = 0.1
20
+
21
+ COHESION_LABELS = [
22
+ { range: (0.8..1.0), label: :unified },
23
+ { range: (0.6...0.8), label: :cohesive },
24
+ { range: (0.4...0.6), label: :scattered },
25
+ { range: (0.2...0.4), label: :dispersed },
26
+ { range: (0.0...0.2), label: :atomized }
27
+ ].freeze
28
+
29
+ FLUIDITY_LABELS = [
30
+ { range: (0.8..1.0), label: :liquid },
31
+ { range: (0.6...0.8), label: :flowing },
32
+ { range: (0.4...0.6), label: :viscous },
33
+ { range: (0.2...0.4), label: :sluggish },
34
+ { range: (0.0...0.2), label: :solid }
35
+ ].freeze
36
+
37
+ module_function
38
+
39
+ def label_for(table, value)
40
+ clamped = value.clamp(0.0, 1.0)
41
+ entry = table.find { |row| row[:range].include?(clamped) }
42
+ entry ? entry[:label] : table.last[:label]
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Defense
9
+ module Quicksilver
10
+ module Helpers
11
+ class Droplet
12
+ attr_reader :id, :form, :content, :mass, :fluidity, :surface, :captured, :created_at
13
+
14
+ FORM_FLUIDITY = {
15
+ liquid: 0.9,
16
+ droplet: 0.8,
17
+ bead: 0.7,
18
+ stream: 0.6,
19
+ pool: 0.3
20
+ }.freeze
21
+
22
+ def initialize(form:, content:, mass: 0.3, fluidity: Constants::FLUIDITY_BASE, surface: :glass)
23
+ raise ArgumentError, "invalid form: #{form}" unless Constants::FORM_TYPES.include?(form)
24
+ raise ArgumentError, "invalid surface: #{surface}" unless Constants::SURFACE_TYPES.include?(surface)
25
+
26
+ @id = SecureRandom.uuid
27
+ @form = form
28
+ @content = content
29
+ @mass = mass.clamp(0.0, 1.0)
30
+ @fluidity = fluidity.clamp(0.0, 1.0)
31
+ @surface = surface
32
+ @captured = false
33
+ @created_at = Time.now.utc
34
+ end
35
+
36
+ def shift_form!(new_form)
37
+ raise ArgumentError, "invalid form: #{new_form}" unless Constants::FORM_TYPES.include?(new_form)
38
+
39
+ @form = new_form
40
+ @fluidity = FORM_FLUIDITY.fetch(new_form, Constants::FLUIDITY_BASE).clamp(0.0, 1.0)
41
+ self
42
+ end
43
+
44
+ def merge!(other_droplet)
45
+ @mass = (@mass + other_droplet.mass + Constants::COALESCENCE_BONUS).clamp(0.0, 1.0)
46
+ @form = @mass >= other_droplet.mass ? @form : other_droplet.form
47
+ @fluidity = ((@fluidity + other_droplet.fluidity) / 2.0).round(10)
48
+ self
49
+ end
50
+
51
+ def split!
52
+ return nil if @mass <= 0.2
53
+
54
+ half_mass = (@mass / 2.0).round(10)
55
+ @mass = half_mass
56
+
57
+ self.class.new(
58
+ form: @form,
59
+ content: @content,
60
+ mass: half_mass,
61
+ fluidity: @fluidity,
62
+ surface: @surface
63
+ )
64
+ end
65
+
66
+ def capture!
67
+ @captured = true
68
+ @fluidity = (@fluidity / 2.0).round(10)
69
+ self
70
+ end
71
+
72
+ def release!
73
+ @captured = false
74
+ @fluidity = (@fluidity * 2.0).clamp(0.0, 1.0)
75
+ self
76
+ end
77
+
78
+ def evaporate!
79
+ @mass = (@mass - Constants::EVAPORATION_RATE).clamp(0.0, 1.0).round(10)
80
+ self
81
+ end
82
+
83
+ def elusive?
84
+ @fluidity >= 0.7 && !@captured
85
+ end
86
+
87
+ def stable?
88
+ @fluidity < 0.4 || @captured
89
+ end
90
+
91
+ def vanishing?
92
+ @mass < 0.1
93
+ end
94
+
95
+ def cohesion_label
96
+ Constants.label_for(Constants::COHESION_LABELS, @mass)
97
+ end
98
+
99
+ def fluidity_label
100
+ Constants.label_for(Constants::FLUIDITY_LABELS, @fluidity)
101
+ end
102
+
103
+ def to_h
104
+ {
105
+ id: @id,
106
+ form: @form,
107
+ content: @content,
108
+ mass: @mass.round(10),
109
+ fluidity: @fluidity.round(10),
110
+ surface: @surface,
111
+ captured: @captured,
112
+ elusive: elusive?,
113
+ stable: stable?,
114
+ vanishing: vanishing?,
115
+ cohesion: cohesion_label,
116
+ fluidity_lbl: fluidity_label,
117
+ created_at: @created_at
118
+ }
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Defense
9
+ module Quicksilver
10
+ module Helpers
11
+ class Pool
12
+ attr_reader :id, :surface_type, :depth, :droplet_ids, :surface_tension, :created_at
13
+
14
+ DEPTH_CHANGE = 0.05
15
+ TENSION_DECREASE = 0.1
16
+ TENSION_INCREASE = 0.05
17
+
18
+ def initialize(surface_type:, depth: 0.5, surface_tension: Constants::SURFACE_TENSION)
19
+ raise ArgumentError, "invalid surface_type: #{surface_type}" unless Constants::SURFACE_TYPES.include?(surface_type)
20
+
21
+ @id = SecureRandom.uuid
22
+ @surface_type = surface_type
23
+ @depth = depth.clamp(0.0, 1.0)
24
+ @droplet_ids = []
25
+ @surface_tension = surface_tension.clamp(0.0, 1.0)
26
+ @created_at = Time.now.utc
27
+ end
28
+
29
+ def add_droplet(droplet_id)
30
+ @droplet_ids << droplet_id unless @droplet_ids.include?(droplet_id)
31
+ @depth = (@depth + DEPTH_CHANGE).clamp(0.0, 1.0).round(10)
32
+ self
33
+ end
34
+
35
+ def remove_droplet(droplet_id)
36
+ @droplet_ids.delete(droplet_id)
37
+ @depth = (@depth - DEPTH_CHANGE).clamp(0.0, 1.0).round(10)
38
+ self
39
+ end
40
+
41
+ def agitate!
42
+ @surface_tension = (@surface_tension - TENSION_DECREASE).clamp(0.0, 1.0).round(10)
43
+ released = []
44
+ @droplet_ids.each do |did|
45
+ released << did if rand > @surface_tension
46
+ end
47
+ released.each { |did| remove_droplet(did) }
48
+ released
49
+ end
50
+
51
+ def settle!
52
+ @surface_tension = (@surface_tension + TENSION_INCREASE).clamp(0.0, 1.0).round(10)
53
+ self
54
+ end
55
+
56
+ def reflective?
57
+ @depth >= 0.7 && @surface_tension >= 0.5
58
+ end
59
+
60
+ def shallow?
61
+ @depth < 0.2
62
+ end
63
+
64
+ def to_h
65
+ {
66
+ id: @id,
67
+ surface_type: @surface_type,
68
+ depth: @depth.round(10),
69
+ droplet_ids: @droplet_ids.dup,
70
+ droplet_count: @droplet_ids.size,
71
+ surface_tension: @surface_tension.round(10),
72
+ reflective: reflective?,
73
+ shallow: shallow?,
74
+ created_at: @created_at
75
+ }
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Quicksilver
8
+ module Helpers
9
+ class QuicksilverEngine
10
+ def initialize
11
+ @droplets = {}
12
+ @pools = {}
13
+ end
14
+
15
+ def create_droplet(form:, content:, **)
16
+ raise ArgumentError, 'droplet limit reached' if @droplets.size >= Constants::MAX_DROPLETS
17
+
18
+ droplet = Droplet.new(form: form, content: content, **)
19
+ @droplets[droplet.id] = droplet
20
+ droplet
21
+ end
22
+
23
+ def create_pool(surface_type:, **)
24
+ raise ArgumentError, 'pool limit reached' if @pools.size >= Constants::MAX_POOLS
25
+
26
+ pool = Pool.new(surface_type: surface_type, **)
27
+ @pools[pool.id] = pool
28
+ pool
29
+ end
30
+
31
+ def shift_form(droplet_id:, new_form:)
32
+ droplet = fetch_droplet!(droplet_id)
33
+ droplet.shift_form!(new_form)
34
+ droplet
35
+ end
36
+
37
+ def merge_droplets(droplet_a_id:, droplet_b_id:)
38
+ a = fetch_droplet!(droplet_a_id)
39
+ b = fetch_droplet!(droplet_b_id)
40
+ a.merge!(b)
41
+ @droplets.delete(droplet_b_id)
42
+ a
43
+ end
44
+
45
+ def split_droplet(droplet_id:)
46
+ droplet = fetch_droplet!(droplet_id)
47
+ twin = droplet.split!
48
+ return nil unless twin
49
+
50
+ @droplets[twin.id] = twin
51
+ [droplet, twin]
52
+ end
53
+
54
+ def capture_droplet(droplet_id:)
55
+ fetch_droplet!(droplet_id).capture!
56
+ end
57
+
58
+ def release_droplet(droplet_id:)
59
+ fetch_droplet!(droplet_id).release!
60
+ end
61
+
62
+ def add_to_pool(droplet_id:, pool_id:)
63
+ fetch_droplet!(droplet_id)
64
+ pool = fetch_pool!(pool_id)
65
+ pool.add_droplet(droplet_id)
66
+ pool
67
+ end
68
+
69
+ def agitate_pool(pool_id:)
70
+ fetch_pool!(pool_id).agitate!
71
+ end
72
+
73
+ def evaporate_all!
74
+ vanished = []
75
+ @droplets.each_value(&:evaporate!)
76
+ @droplets.each { |id, d| vanished << id if d.vanishing? }
77
+ vanished.each { |id| @droplets.delete(id) }
78
+ vanished
79
+ end
80
+
81
+ def quicksilver_report
82
+ droplets = @droplets.values
83
+ total = droplets.size
84
+ {
85
+ total_droplets: total,
86
+ total_pools: @pools.size,
87
+ captured_count: droplets.count(&:captured),
88
+ elusive_count: droplets.count(&:elusive?),
89
+ vanishing_count: droplets.count(&:vanishing?),
90
+ avg_mass: avg_metric(droplets, total, :mass),
91
+ avg_fluidity: avg_metric(droplets, total, :fluidity)
92
+ }
93
+ end
94
+
95
+ def droplets
96
+ @droplets.values.map(&:to_h)
97
+ end
98
+
99
+ def pools
100
+ @pools.values.map(&:to_h)
101
+ end
102
+
103
+ private
104
+
105
+ def avg_metric(droplets, total, method)
106
+ return 0.0 if total.zero?
107
+
108
+ (droplets.sum(&method) / total.to_f).round(10)
109
+ end
110
+
111
+ def fetch_droplet!(id)
112
+ @droplets.fetch(id) { raise ArgumentError, "droplet not found: #{id}" }
113
+ end
114
+
115
+ def fetch_pool!(id)
116
+ @pools.fetch(id) { raise ArgumentError, "pool not found: #{id}" }
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Defense
7
+ module Quicksilver
8
+ module Runners
9
+ module CognitiveQuicksilver
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex)
12
+
13
+ def create_droplet(form: :droplet, content: '', engine: nil, **)
14
+ raise ArgumentError, "invalid form: #{form}" unless Helpers::Constants::FORM_TYPES.include?(form)
15
+
16
+ eng = engine || quicksilver_engine
17
+ droplet = eng.create_droplet(form: form, content: content.to_s)
18
+ Legion::Logging.debug "[cognitive_quicksilver] create_droplet id=#{droplet.id} form=#{droplet.form}"
19
+ { success: true, droplet: droplet.to_h }
20
+ rescue ArgumentError => e
21
+ Legion::Logging.debug "[cognitive_quicksilver] create_droplet failed: #{e.message}"
22
+ { success: false, error: e.message }
23
+ end
24
+
25
+ def create_pool(surface_type: :glass, engine: nil, **)
26
+ raise ArgumentError, "invalid surface_type: #{surface_type}" unless Helpers::Constants::SURFACE_TYPES.include?(surface_type)
27
+
28
+ eng = engine || quicksilver_engine
29
+ pool = eng.create_pool(surface_type: surface_type)
30
+ Legion::Logging.debug "[cognitive_quicksilver] create_pool id=#{pool.id} surface=#{pool.surface_type}"
31
+ { success: true, pool: pool.to_h }
32
+ rescue ArgumentError => e
33
+ Legion::Logging.debug "[cognitive_quicksilver] create_pool failed: #{e.message}"
34
+ { success: false, error: e.message }
35
+ end
36
+
37
+ def shift_form(droplet_id:, new_form:, engine: nil, **)
38
+ raise ArgumentError, "invalid form: #{new_form}" unless Helpers::Constants::FORM_TYPES.include?(new_form)
39
+
40
+ eng = engine || quicksilver_engine
41
+ droplet = eng.shift_form(droplet_id: droplet_id, new_form: new_form)
42
+ Legion::Logging.debug "[cognitive_quicksilver] shift_form id=#{droplet_id} new_form=#{new_form}"
43
+ { success: true, droplet: droplet.to_h }
44
+ rescue ArgumentError => e
45
+ Legion::Logging.debug "[cognitive_quicksilver] shift_form failed: #{e.message}"
46
+ { success: false, error: e.message }
47
+ end
48
+
49
+ def merge(droplet_a_id:, droplet_b_id:, engine: nil, **)
50
+ eng = engine || quicksilver_engine
51
+ droplet = eng.merge_droplets(droplet_a_id: droplet_a_id, droplet_b_id: droplet_b_id)
52
+ Legion::Logging.debug "[cognitive_quicksilver] merge a=#{droplet_a_id} b=#{droplet_b_id} result_mass=#{droplet.mass.round(2)}"
53
+ { success: true, droplet: droplet.to_h }
54
+ rescue ArgumentError => e
55
+ Legion::Logging.debug "[cognitive_quicksilver] merge failed: #{e.message}"
56
+ { success: false, error: e.message }
57
+ end
58
+
59
+ def split(droplet_id:, engine: nil, **)
60
+ eng = engine || quicksilver_engine
61
+ result = eng.split_droplet(droplet_id: droplet_id)
62
+ if result.nil?
63
+ Legion::Logging.debug "[cognitive_quicksilver] split id=#{droplet_id} too_small"
64
+ return { success: false, error: 'droplet mass too small to split' }
65
+ end
66
+
67
+ original, twin = result
68
+ Legion::Logging.debug "[cognitive_quicksilver] split id=#{droplet_id} twin_id=#{twin.id}"
69
+ { success: true, original: original.to_h, twin: twin.to_h }
70
+ rescue ArgumentError => e
71
+ Legion::Logging.debug "[cognitive_quicksilver] split failed: #{e.message}"
72
+ { success: false, error: e.message }
73
+ end
74
+
75
+ def capture(droplet_id:, engine: nil, **)
76
+ eng = engine || quicksilver_engine
77
+ droplet = eng.capture_droplet(droplet_id: droplet_id)
78
+ Legion::Logging.debug "[cognitive_quicksilver] capture id=#{droplet_id} fluidity=#{droplet.fluidity.round(2)}"
79
+ { success: true, droplet: droplet.to_h }
80
+ rescue ArgumentError => e
81
+ Legion::Logging.debug "[cognitive_quicksilver] capture failed: #{e.message}"
82
+ { success: false, error: e.message }
83
+ end
84
+
85
+ def release(droplet_id:, engine: nil, **)
86
+ eng = engine || quicksilver_engine
87
+ droplet = eng.release_droplet(droplet_id: droplet_id)
88
+ Legion::Logging.debug "[cognitive_quicksilver] release id=#{droplet_id} fluidity=#{droplet.fluidity.round(2)}"
89
+ { success: true, droplet: droplet.to_h }
90
+ rescue ArgumentError => e
91
+ Legion::Logging.debug "[cognitive_quicksilver] release failed: #{e.message}"
92
+ { success: false, error: e.message }
93
+ end
94
+
95
+ def add_to_pool(droplet_id:, pool_id:, engine: nil, **)
96
+ eng = engine || quicksilver_engine
97
+ pool = eng.add_to_pool(droplet_id: droplet_id, pool_id: pool_id)
98
+ Legion::Logging.debug "[cognitive_quicksilver] add_to_pool droplet=#{droplet_id} pool=#{pool_id}"
99
+ { success: true, pool: pool.to_h }
100
+ rescue ArgumentError => e
101
+ Legion::Logging.debug "[cognitive_quicksilver] add_to_pool failed: #{e.message}"
102
+ { success: false, error: e.message }
103
+ end
104
+
105
+ def list_droplets(engine: nil, **)
106
+ eng = engine || quicksilver_engine
107
+ items = eng.droplets
108
+ Legion::Logging.debug "[cognitive_quicksilver] list_droplets count=#{items.size}"
109
+ { success: true, droplets: items, count: items.size }
110
+ end
111
+
112
+ def quicksilver_status(engine: nil, **)
113
+ eng = engine || quicksilver_engine
114
+ report = eng.quicksilver_report
115
+ Legion::Logging.debug "[cognitive_quicksilver] status droplets=#{report[:total_droplets]} pools=#{report[:total_pools]}"
116
+ { success: true, **report }
117
+ end
118
+
119
+ private
120
+
121
+ def quicksilver_engine
122
+ @quicksilver_engine ||= Helpers::QuicksilverEngine.new
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ 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 Quicksilver
8
+ VERSION = '0.1.0'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end