lex-agentic-attention 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 (315) 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-attention.gemspec +30 -0
  7. data/lib/legion/extensions/agentic/attention/arousal/client.rb +27 -0
  8. data/lib/legion/extensions/agentic/attention/arousal/helpers/arousal_model.rb +84 -0
  9. data/lib/legion/extensions/agentic/attention/arousal/helpers/constants.rb +44 -0
  10. data/lib/legion/extensions/agentic/attention/arousal/runners/arousal.rb +119 -0
  11. data/lib/legion/extensions/agentic/attention/arousal/version.rb +13 -0
  12. data/lib/legion/extensions/agentic/attention/arousal.rb +18 -0
  13. data/lib/legion/extensions/agentic/attention/blindspot/client.rb +19 -0
  14. data/lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot.rb +98 -0
  15. data/lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb +174 -0
  16. data/lib/legion/extensions/agentic/attention/blindspot/helpers/constants.rb +63 -0
  17. data/lib/legion/extensions/agentic/attention/blindspot/helpers/knowledge_boundary.rb +62 -0
  18. data/lib/legion/extensions/agentic/attention/blindspot/runners/cognitive_blindspot.rb +103 -0
  19. data/lib/legion/extensions/agentic/attention/blindspot/version.rb +13 -0
  20. data/lib/legion/extensions/agentic/attention/blindspot.rb +20 -0
  21. data/lib/legion/extensions/agentic/attention/blink/client.rb +19 -0
  22. data/lib/legion/extensions/agentic/attention/blink/helpers/blink_engine.rb +171 -0
  23. data/lib/legion/extensions/agentic/attention/blink/helpers/constants.rb +46 -0
  24. data/lib/legion/extensions/agentic/attention/blink/helpers/stimulus.rb +68 -0
  25. data/lib/legion/extensions/agentic/attention/blink/runners/attentional_blink.rb +75 -0
  26. data/lib/legion/extensions/agentic/attention/blink/version.rb +13 -0
  27. data/lib/legion/extensions/agentic/attention/blink.rb +19 -0
  28. data/lib/legion/extensions/agentic/attention/economy/client.rb +28 -0
  29. data/lib/legion/extensions/agentic/attention/economy/helpers/attention_budget.rb +143 -0
  30. data/lib/legion/extensions/agentic/attention/economy/helpers/constants.rb +38 -0
  31. data/lib/legion/extensions/agentic/attention/economy/helpers/demand.rb +72 -0
  32. data/lib/legion/extensions/agentic/attention/economy/runners/attention_economy.rb +90 -0
  33. data/lib/legion/extensions/agentic/attention/economy/version.rb +13 -0
  34. data/lib/legion/extensions/agentic/attention/economy.rb +19 -0
  35. data/lib/legion/extensions/agentic/attention/feature_binding/actors/decay.rb +45 -0
  36. data/lib/legion/extensions/agentic/attention/feature_binding/client.rb +29 -0
  37. data/lib/legion/extensions/agentic/attention/feature_binding/helpers/binding_field.rb +124 -0
  38. data/lib/legion/extensions/agentic/attention/feature_binding/helpers/bound_object.rb +89 -0
  39. data/lib/legion/extensions/agentic/attention/feature_binding/helpers/constants.rb +52 -0
  40. data/lib/legion/extensions/agentic/attention/feature_binding/helpers/feature.rb +52 -0
  41. data/lib/legion/extensions/agentic/attention/feature_binding/runners/feature_binding.rb +102 -0
  42. data/lib/legion/extensions/agentic/attention/feature_binding/version.rb +13 -0
  43. data/lib/legion/extensions/agentic/attention/feature_binding.rb +20 -0
  44. data/lib/legion/extensions/agentic/attention/focus/client.rb +30 -0
  45. data/lib/legion/extensions/agentic/attention/focus/helpers/constants.rb +38 -0
  46. data/lib/legion/extensions/agentic/attention/focus/helpers/focus.rb +78 -0
  47. data/lib/legion/extensions/agentic/attention/focus/helpers/focus_manager.rb +67 -0
  48. data/lib/legion/extensions/agentic/attention/focus/helpers/habituation.rb +61 -0
  49. data/lib/legion/extensions/agentic/attention/focus/runners/attention.rb +121 -0
  50. data/lib/legion/extensions/agentic/attention/focus/version.rb +13 -0
  51. data/lib/legion/extensions/agentic/attention/focus.rb +20 -0
  52. data/lib/legion/extensions/agentic/attention/kaleidoscope/client.rb +15 -0
  53. data/lib/legion/extensions/agentic/attention/kaleidoscope/helpers/constants.rb +48 -0
  54. data/lib/legion/extensions/agentic/attention/kaleidoscope/helpers/facet.rb +90 -0
  55. data/lib/legion/extensions/agentic/attention/kaleidoscope/helpers/kaleidoscope_engine.rb +142 -0
  56. data/lib/legion/extensions/agentic/attention/kaleidoscope/helpers/pattern.rb +110 -0
  57. data/lib/legion/extensions/agentic/attention/kaleidoscope/runners/cognitive_kaleidoscope.rb +91 -0
  58. data/lib/legion/extensions/agentic/attention/kaleidoscope/version.rb +13 -0
  59. data/lib/legion/extensions/agentic/attention/kaleidoscope.rb +22 -0
  60. data/lib/legion/extensions/agentic/attention/latent_inhibition/client.rb +28 -0
  61. data/lib/legion/extensions/agentic/attention/latent_inhibition/helpers/constants.rb +33 -0
  62. data/lib/legion/extensions/agentic/attention/latent_inhibition/helpers/inhibition_engine.rb +118 -0
  63. data/lib/legion/extensions/agentic/attention/latent_inhibition/helpers/stimulus_record.rb +70 -0
  64. data/lib/legion/extensions/agentic/attention/latent_inhibition/runners/latent_inhibition.rb +78 -0
  65. data/lib/legion/extensions/agentic/attention/latent_inhibition/version.rb +13 -0
  66. data/lib/legion/extensions/agentic/attention/latent_inhibition.rb +19 -0
  67. data/lib/legion/extensions/agentic/attention/lens/client.rb +29 -0
  68. data/lib/legion/extensions/agentic/attention/lens/helpers/constants.rb +58 -0
  69. data/lib/legion/extensions/agentic/attention/lens/helpers/lens.rb +99 -0
  70. data/lib/legion/extensions/agentic/attention/lens/helpers/lens_engine.rb +101 -0
  71. data/lib/legion/extensions/agentic/attention/lens/helpers/lens_stack.rb +134 -0
  72. data/lib/legion/extensions/agentic/attention/lens/runners/cognitive_lens.rb +90 -0
  73. data/lib/legion/extensions/agentic/attention/lens/version.rb +13 -0
  74. data/lib/legion/extensions/agentic/attention/lens.rb +22 -0
  75. data/lib/legion/extensions/agentic/attention/lighthouse/client.rb +25 -0
  76. data/lib/legion/extensions/agentic/attention/lighthouse/helpers/beacon.rb +76 -0
  77. data/lib/legion/extensions/agentic/attention/lighthouse/helpers/constants.rb +49 -0
  78. data/lib/legion/extensions/agentic/attention/lighthouse/helpers/fog.rb +74 -0
  79. data/lib/legion/extensions/agentic/attention/lighthouse/helpers/lighthouse_engine.rb +127 -0
  80. data/lib/legion/extensions/agentic/attention/lighthouse/runners/cognitive_lighthouse.rb +80 -0
  81. data/lib/legion/extensions/agentic/attention/lighthouse/version.rb +13 -0
  82. data/lib/legion/extensions/agentic/attention/lighthouse.rb +22 -0
  83. data/lib/legion/extensions/agentic/attention/priming/client.rb +21 -0
  84. data/lib/legion/extensions/agentic/attention/priming/helpers/activation_network.rb +130 -0
  85. data/lib/legion/extensions/agentic/attention/priming/helpers/concept_node.rb +92 -0
  86. data/lib/legion/extensions/agentic/attention/priming/helpers/constants.rb +54 -0
  87. data/lib/legion/extensions/agentic/attention/priming/runners/priming.rb +94 -0
  88. data/lib/legion/extensions/agentic/attention/priming/version.rb +13 -0
  89. data/lib/legion/extensions/agentic/attention/priming.rb +19 -0
  90. data/lib/legion/extensions/agentic/attention/prism/client.rb +26 -0
  91. data/lib/legion/extensions/agentic/attention/prism/helpers/beam.rb +169 -0
  92. data/lib/legion/extensions/agentic/attention/prism/helpers/constants.rb +46 -0
  93. data/lib/legion/extensions/agentic/attention/prism/helpers/prism_engine.rb +136 -0
  94. data/lib/legion/extensions/agentic/attention/prism/helpers/spectral_component.rb +72 -0
  95. data/lib/legion/extensions/agentic/attention/prism/runners/cognitive_prism.rb +79 -0
  96. data/lib/legion/extensions/agentic/attention/prism/version.rb +13 -0
  97. data/lib/legion/extensions/agentic/attention/prism.rb +22 -0
  98. data/lib/legion/extensions/agentic/attention/regulation/client.rb +19 -0
  99. data/lib/legion/extensions/agentic/attention/regulation/helpers/attention_controller.rb +157 -0
  100. data/lib/legion/extensions/agentic/attention/regulation/helpers/attention_target.rb +64 -0
  101. data/lib/legion/extensions/agentic/attention/regulation/helpers/constants.rb +41 -0
  102. data/lib/legion/extensions/agentic/attention/regulation/runners/attention_regulation.rb +88 -0
  103. data/lib/legion/extensions/agentic/attention/regulation/version.rb +13 -0
  104. data/lib/legion/extensions/agentic/attention/regulation.rb +20 -0
  105. data/lib/legion/extensions/agentic/attention/relevance_theory/helpers/client.rb +17 -0
  106. data/lib/legion/extensions/agentic/attention/relevance_theory/helpers/cognitive_input.rb +88 -0
  107. data/lib/legion/extensions/agentic/attention/relevance_theory/helpers/constants.rb +50 -0
  108. data/lib/legion/extensions/agentic/attention/relevance_theory/helpers/relevance_engine.rb +152 -0
  109. data/lib/legion/extensions/agentic/attention/relevance_theory/runners/relevance_theory.rb +98 -0
  110. data/lib/legion/extensions/agentic/attention/relevance_theory/version.rb +13 -0
  111. data/lib/legion/extensions/agentic/attention/relevance_theory.rb +19 -0
  112. data/lib/legion/extensions/agentic/attention/salience/client.rb +21 -0
  113. data/lib/legion/extensions/agentic/attention/salience/helpers/constants.rb +44 -0
  114. data/lib/legion/extensions/agentic/attention/salience/helpers/salience_map.rb +122 -0
  115. data/lib/legion/extensions/agentic/attention/salience/helpers/signal_integrator.rb +97 -0
  116. data/lib/legion/extensions/agentic/attention/salience/runners/salience.rb +70 -0
  117. data/lib/legion/extensions/agentic/attention/salience/version.rb +13 -0
  118. data/lib/legion/extensions/agentic/attention/salience.rb +19 -0
  119. data/lib/legion/extensions/agentic/attention/schema/actors/decay.rb +45 -0
  120. data/lib/legion/extensions/agentic/attention/schema/client.rb +28 -0
  121. data/lib/legion/extensions/agentic/attention/schema/helpers/attention_schema_model.rb +226 -0
  122. data/lib/legion/extensions/agentic/attention/schema/helpers/constants.rb +66 -0
  123. data/lib/legion/extensions/agentic/attention/schema/helpers/schema_item.rb +68 -0
  124. data/lib/legion/extensions/agentic/attention/schema/runners/attention_schema.rb +117 -0
  125. data/lib/legion/extensions/agentic/attention/schema/version.rb +13 -0
  126. data/lib/legion/extensions/agentic/attention/schema.rb +19 -0
  127. data/lib/legion/extensions/agentic/attention/sensory_gating/client.rb +15 -0
  128. data/lib/legion/extensions/agentic/attention/sensory_gating/helpers/constants.rb +44 -0
  129. data/lib/legion/extensions/agentic/attention/sensory_gating/helpers/gating_engine.rb +109 -0
  130. data/lib/legion/extensions/agentic/attention/sensory_gating/helpers/sensory_filter.rb +100 -0
  131. data/lib/legion/extensions/agentic/attention/sensory_gating/runners/sensory_gating.rb +73 -0
  132. data/lib/legion/extensions/agentic/attention/sensory_gating/version.rb +13 -0
  133. data/lib/legion/extensions/agentic/attention/sensory_gating.rb +19 -0
  134. data/lib/legion/extensions/agentic/attention/signal_detection/client.rb +28 -0
  135. data/lib/legion/extensions/agentic/attention/signal_detection/helpers/constants.rb +66 -0
  136. data/lib/legion/extensions/agentic/attention/signal_detection/helpers/detection_engine.rb +129 -0
  137. data/lib/legion/extensions/agentic/attention/signal_detection/helpers/detector.rb +136 -0
  138. data/lib/legion/extensions/agentic/attention/signal_detection/runners/signal_detection.rb +113 -0
  139. data/lib/legion/extensions/agentic/attention/signal_detection/version.rb +13 -0
  140. data/lib/legion/extensions/agentic/attention/signal_detection.rb +19 -0
  141. data/lib/legion/extensions/agentic/attention/spotlight/client.rb +29 -0
  142. data/lib/legion/extensions/agentic/attention/spotlight/helpers/attention_target.rb +61 -0
  143. data/lib/legion/extensions/agentic/attention/spotlight/helpers/constants.rb +44 -0
  144. data/lib/legion/extensions/agentic/attention/spotlight/helpers/spotlight.rb +78 -0
  145. data/lib/legion/extensions/agentic/attention/spotlight/helpers/spotlight_engine.rb +163 -0
  146. data/lib/legion/extensions/agentic/attention/spotlight/runners/attention_spotlight.rb +122 -0
  147. data/lib/legion/extensions/agentic/attention/spotlight/version.rb +13 -0
  148. data/lib/legion/extensions/agentic/attention/spotlight.rb +20 -0
  149. data/lib/legion/extensions/agentic/attention/subliminal/client.rb +19 -0
  150. data/lib/legion/extensions/agentic/attention/subliminal/helpers/constants.rb +74 -0
  151. data/lib/legion/extensions/agentic/attention/subliminal/helpers/influence_event.rb +44 -0
  152. data/lib/legion/extensions/agentic/attention/subliminal/helpers/subliminal_engine.rb +149 -0
  153. data/lib/legion/extensions/agentic/attention/subliminal/helpers/subliminal_trace.rb +101 -0
  154. data/lib/legion/extensions/agentic/attention/subliminal/runners/subliminal.rb +71 -0
  155. data/lib/legion/extensions/agentic/attention/subliminal/version.rb +13 -0
  156. data/lib/legion/extensions/agentic/attention/subliminal.rb +20 -0
  157. data/lib/legion/extensions/agentic/attention/surprise/client.rb +22 -0
  158. data/lib/legion/extensions/agentic/attention/surprise/helpers/constants.rb +35 -0
  159. data/lib/legion/extensions/agentic/attention/surprise/helpers/habituation_model.rb +62 -0
  160. data/lib/legion/extensions/agentic/attention/surprise/helpers/surprise_event.rb +43 -0
  161. data/lib/legion/extensions/agentic/attention/surprise/helpers/surprise_store.rb +74 -0
  162. data/lib/legion/extensions/agentic/attention/surprise/runners/surprise.rb +174 -0
  163. data/lib/legion/extensions/agentic/attention/surprise/version.rb +13 -0
  164. data/lib/legion/extensions/agentic/attention/surprise.rb +20 -0
  165. data/lib/legion/extensions/agentic/attention/switching/client.rb +19 -0
  166. data/lib/legion/extensions/agentic/attention/switching/helpers/constants.rb +64 -0
  167. data/lib/legion/extensions/agentic/attention/switching/helpers/switch_event.rb +60 -0
  168. data/lib/legion/extensions/agentic/attention/switching/helpers/switching_engine.rb +172 -0
  169. data/lib/legion/extensions/agentic/attention/switching/helpers/task_set.rb +91 -0
  170. data/lib/legion/extensions/agentic/attention/switching/runners/attention_switching.rb +92 -0
  171. data/lib/legion/extensions/agentic/attention/switching/version.rb +13 -0
  172. data/lib/legion/extensions/agentic/attention/switching.rb +20 -0
  173. data/lib/legion/extensions/agentic/attention/synesthesia/client.rb +29 -0
  174. data/lib/legion/extensions/agentic/attention/synesthesia/helpers/constants.rb +52 -0
  175. data/lib/legion/extensions/agentic/attention/synesthesia/helpers/sensory_mapping.rb +70 -0
  176. data/lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb +177 -0
  177. data/lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthetic_event.rb +49 -0
  178. data/lib/legion/extensions/agentic/attention/synesthesia/runners/cognitive_synesthesia.rb +83 -0
  179. data/lib/legion/extensions/agentic/attention/synesthesia/version.rb +13 -0
  180. data/lib/legion/extensions/agentic/attention/synesthesia.rb +20 -0
  181. data/lib/legion/extensions/agentic/attention/telescope/client.rb +15 -0
  182. data/lib/legion/extensions/agentic/attention/telescope/helpers/constants.rb +60 -0
  183. data/lib/legion/extensions/agentic/attention/telescope/helpers/observation.rb +68 -0
  184. data/lib/legion/extensions/agentic/attention/telescope/helpers/observatory_engine.rb +126 -0
  185. data/lib/legion/extensions/agentic/attention/telescope/helpers/telescope.rb +129 -0
  186. data/lib/legion/extensions/agentic/attention/telescope/runners/cognitive_telescope.rb +103 -0
  187. data/lib/legion/extensions/agentic/attention/telescope/version.rb +13 -0
  188. data/lib/legion/extensions/agentic/attention/telescope.rb +22 -0
  189. data/lib/legion/extensions/agentic/attention/version.rb +11 -0
  190. data/lib/legion/extensions/agentic/attention.rb +41 -0
  191. data/spec/legion/extensions/agentic/attention/arousal/client_spec.rb +42 -0
  192. data/spec/legion/extensions/agentic/attention/arousal/helpers/arousal_model_spec.rb +160 -0
  193. data/spec/legion/extensions/agentic/attention/arousal/helpers/constants_spec.rb +61 -0
  194. data/spec/legion/extensions/agentic/attention/arousal/runners/arousal_spec.rb +137 -0
  195. data/spec/legion/extensions/agentic/attention/blindspot/client_spec.rb +41 -0
  196. data/spec/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine_spec.rb +246 -0
  197. data/spec/legion/extensions/agentic/attention/blindspot/helpers/blindspot_spec.rb +204 -0
  198. data/spec/legion/extensions/agentic/attention/blindspot/helpers/constants_spec.rb +82 -0
  199. data/spec/legion/extensions/agentic/attention/blindspot/helpers/knowledge_boundary_spec.rb +104 -0
  200. data/spec/legion/extensions/agentic/attention/blindspot/runners/cognitive_blindspot_spec.rb +179 -0
  201. data/spec/legion/extensions/agentic/attention/blink/client_spec.rb +18 -0
  202. data/spec/legion/extensions/agentic/attention/blink/helpers/blink_engine_spec.rb +147 -0
  203. data/spec/legion/extensions/agentic/attention/blink/helpers/constants_spec.rb +27 -0
  204. data/spec/legion/extensions/agentic/attention/blink/helpers/stimulus_spec.rb +77 -0
  205. data/spec/legion/extensions/agentic/attention/blink/runners/attentional_blink_spec.rb +77 -0
  206. data/spec/legion/extensions/agentic/attention/economy/client_spec.rb +30 -0
  207. data/spec/legion/extensions/agentic/attention/economy/helpers/attention_budget_spec.rb +222 -0
  208. data/spec/legion/extensions/agentic/attention/economy/helpers/constants_spec.rb +112 -0
  209. data/spec/legion/extensions/agentic/attention/economy/helpers/demand_spec.rb +128 -0
  210. data/spec/legion/extensions/agentic/attention/economy/runners/attention_economy_spec.rb +163 -0
  211. data/spec/legion/extensions/agentic/attention/feature_binding/client_spec.rb +20 -0
  212. data/spec/legion/extensions/agentic/attention/feature_binding/helpers/binding_field_spec.rb +207 -0
  213. data/spec/legion/extensions/agentic/attention/feature_binding/helpers/bound_object_spec.rb +149 -0
  214. data/spec/legion/extensions/agentic/attention/feature_binding/helpers/feature_spec.rb +86 -0
  215. data/spec/legion/extensions/agentic/attention/feature_binding/runners/feature_binding_spec.rb +106 -0
  216. data/spec/legion/extensions/agentic/attention/focus/client_spec.rb +19 -0
  217. data/spec/legion/extensions/agentic/attention/focus/helpers/focus_manager_spec.rb +105 -0
  218. data/spec/legion/extensions/agentic/attention/focus/helpers/focus_spec.rb +148 -0
  219. data/spec/legion/extensions/agentic/attention/focus/helpers/habituation_spec.rb +97 -0
  220. data/spec/legion/extensions/agentic/attention/focus/runners/attention_spec.rb +134 -0
  221. data/spec/legion/extensions/agentic/attention/kaleidoscope/client_spec.rb +38 -0
  222. data/spec/legion/extensions/agentic/attention/kaleidoscope/helpers/constants_spec.rb +79 -0
  223. data/spec/legion/extensions/agentic/attention/kaleidoscope/helpers/facet_spec.rb +155 -0
  224. data/spec/legion/extensions/agentic/attention/kaleidoscope/helpers/kaleidoscope_engine_spec.rb +164 -0
  225. data/spec/legion/extensions/agentic/attention/kaleidoscope/helpers/pattern_spec.rb +157 -0
  226. data/spec/legion/extensions/agentic/attention/kaleidoscope/runners/cognitive_kaleidoscope_spec.rb +112 -0
  227. data/spec/legion/extensions/agentic/attention/latent_inhibition/client_spec.rb +49 -0
  228. data/spec/legion/extensions/agentic/attention/latent_inhibition/helpers/constants_spec.rb +57 -0
  229. data/spec/legion/extensions/agentic/attention/latent_inhibition/helpers/inhibition_engine_spec.rb +207 -0
  230. data/spec/legion/extensions/agentic/attention/latent_inhibition/helpers/stimulus_record_spec.rb +175 -0
  231. data/spec/legion/extensions/agentic/attention/latent_inhibition/runners/latent_inhibition_spec.rb +148 -0
  232. data/spec/legion/extensions/agentic/attention/lens/client_spec.rb +64 -0
  233. data/spec/legion/extensions/agentic/attention/lens/helpers/constants_spec.rb +91 -0
  234. data/spec/legion/extensions/agentic/attention/lens/helpers/lens_engine_spec.rb +158 -0
  235. data/spec/legion/extensions/agentic/attention/lens/helpers/lens_spec.rb +222 -0
  236. data/spec/legion/extensions/agentic/attention/lens/helpers/lens_stack_spec.rb +179 -0
  237. data/spec/legion/extensions/agentic/attention/lens/runners/cognitive_lens_spec.rb +182 -0
  238. data/spec/legion/extensions/agentic/attention/lighthouse/client_spec.rb +103 -0
  239. data/spec/legion/extensions/agentic/attention/lighthouse/helpers/beacon_spec.rb +170 -0
  240. data/spec/legion/extensions/agentic/attention/lighthouse/helpers/constants_spec.rb +94 -0
  241. data/spec/legion/extensions/agentic/attention/lighthouse/helpers/fog_spec.rb +166 -0
  242. data/spec/legion/extensions/agentic/attention/lighthouse/helpers/lighthouse_engine_spec.rb +238 -0
  243. data/spec/legion/extensions/agentic/attention/lighthouse/runners/cognitive_lighthouse_spec.rb +182 -0
  244. data/spec/legion/extensions/agentic/attention/priming/client_spec.rb +80 -0
  245. data/spec/legion/extensions/agentic/attention/priming/helpers/activation_network_spec.rb +176 -0
  246. data/spec/legion/extensions/agentic/attention/priming/helpers/concept_node_spec.rb +165 -0
  247. data/spec/legion/extensions/agentic/attention/priming/helpers/constants_spec.rb +51 -0
  248. data/spec/legion/extensions/agentic/attention/priming/runners/priming_spec.rb +141 -0
  249. data/spec/legion/extensions/agentic/attention/prism/client_spec.rb +86 -0
  250. data/spec/legion/extensions/agentic/attention/prism/helpers/beam_spec.rb +182 -0
  251. data/spec/legion/extensions/agentic/attention/prism/helpers/constants_spec.rb +93 -0
  252. data/spec/legion/extensions/agentic/attention/prism/helpers/prism_engine_spec.rb +253 -0
  253. data/spec/legion/extensions/agentic/attention/prism/helpers/spectral_component_spec.rb +171 -0
  254. data/spec/legion/extensions/agentic/attention/prism/runners/cognitive_prism_spec.rb +132 -0
  255. data/spec/legion/extensions/agentic/attention/regulation/client_spec.rb +58 -0
  256. data/spec/legion/extensions/agentic/attention/regulation/helpers/attention_controller_spec.rb +295 -0
  257. data/spec/legion/extensions/agentic/attention/regulation/helpers/attention_target_spec.rb +122 -0
  258. data/spec/legion/extensions/agentic/attention/regulation/runners/attention_regulation_spec.rb +147 -0
  259. data/spec/legion/extensions/agentic/attention/relevance_theory/helpers/cognitive_input_spec.rb +121 -0
  260. data/spec/legion/extensions/agentic/attention/relevance_theory/helpers/relevance_engine_spec.rb +149 -0
  261. data/spec/legion/extensions/agentic/attention/relevance_theory/relevance_theory_spec.rb +11 -0
  262. data/spec/legion/extensions/agentic/attention/relevance_theory/runners/relevance_theory_spec.rb +86 -0
  263. data/spec/legion/extensions/agentic/attention/salience/client_spec.rb +60 -0
  264. data/spec/legion/extensions/agentic/attention/salience/helpers/constants_spec.rb +100 -0
  265. data/spec/legion/extensions/agentic/attention/salience/helpers/salience_map_spec.rb +189 -0
  266. data/spec/legion/extensions/agentic/attention/salience/helpers/signal_integrator_spec.rb +149 -0
  267. data/spec/legion/extensions/agentic/attention/salience/runners/salience_spec.rb +143 -0
  268. data/spec/legion/extensions/agentic/attention/schema/client_spec.rb +47 -0
  269. data/spec/legion/extensions/agentic/attention/schema/helpers/attention_schema_model_spec.rb +219 -0
  270. data/spec/legion/extensions/agentic/attention/schema/helpers/schema_item_spec.rb +114 -0
  271. data/spec/legion/extensions/agentic/attention/schema/runners/attention_schema_spec.rb +185 -0
  272. data/spec/legion/extensions/agentic/attention/sensory_gating/helpers/gating_engine_spec.rb +112 -0
  273. data/spec/legion/extensions/agentic/attention/sensory_gating/helpers/sensory_filter_spec.rb +121 -0
  274. data/spec/legion/extensions/agentic/attention/sensory_gating/runners/sensory_gating_spec.rb +61 -0
  275. data/spec/legion/extensions/agentic/attention/signal_detection/client_spec.rb +20 -0
  276. data/spec/legion/extensions/agentic/attention/signal_detection/helpers/constants_spec.rb +85 -0
  277. data/spec/legion/extensions/agentic/attention/signal_detection/helpers/detection_engine_spec.rb +143 -0
  278. data/spec/legion/extensions/agentic/attention/signal_detection/helpers/detector_spec.rb +179 -0
  279. data/spec/legion/extensions/agentic/attention/signal_detection/runners/signal_detection_spec.rb +151 -0
  280. data/spec/legion/extensions/agentic/attention/spotlight/client_spec.rb +31 -0
  281. data/spec/legion/extensions/agentic/attention/spotlight/helpers/attention_target_spec.rb +121 -0
  282. data/spec/legion/extensions/agentic/attention/spotlight/helpers/constants_spec.rb +82 -0
  283. data/spec/legion/extensions/agentic/attention/spotlight/helpers/spotlight_engine_spec.rb +275 -0
  284. data/spec/legion/extensions/agentic/attention/spotlight/helpers/spotlight_spec.rb +196 -0
  285. data/spec/legion/extensions/agentic/attention/spotlight/runners/attention_spotlight_spec.rb +251 -0
  286. data/spec/legion/extensions/agentic/attention/subliminal/client_spec.rb +21 -0
  287. data/spec/legion/extensions/agentic/attention/subliminal/helpers/influence_event_spec.rb +58 -0
  288. data/spec/legion/extensions/agentic/attention/subliminal/helpers/subliminal_engine_spec.rb +161 -0
  289. data/spec/legion/extensions/agentic/attention/subliminal/helpers/subliminal_trace_spec.rb +168 -0
  290. data/spec/legion/extensions/agentic/attention/subliminal/runners_spec.rb +78 -0
  291. data/spec/legion/extensions/agentic/attention/subliminal/subliminal_spec.rb +7 -0
  292. data/spec/legion/extensions/agentic/attention/surprise/client_spec.rb +122 -0
  293. data/spec/legion/extensions/agentic/attention/surprise/helpers/constants_spec.rb +112 -0
  294. data/spec/legion/extensions/agentic/attention/surprise/helpers/habituation_model_spec.rb +127 -0
  295. data/spec/legion/extensions/agentic/attention/surprise/helpers/surprise_event_spec.rb +102 -0
  296. data/spec/legion/extensions/agentic/attention/surprise/helpers/surprise_store_spec.rb +171 -0
  297. data/spec/legion/extensions/agentic/attention/surprise/runners/surprise_spec.rb +266 -0
  298. data/spec/legion/extensions/agentic/attention/switching/attention_switching_spec.rb +7 -0
  299. data/spec/legion/extensions/agentic/attention/switching/helpers/switch_event_spec.rb +74 -0
  300. data/spec/legion/extensions/agentic/attention/switching/helpers/switching_engine_spec.rb +164 -0
  301. data/spec/legion/extensions/agentic/attention/switching/helpers/task_set_spec.rb +134 -0
  302. data/spec/legion/extensions/agentic/attention/synesthesia/client_spec.rb +57 -0
  303. data/spec/legion/extensions/agentic/attention/synesthesia/helpers/constants_spec.rb +89 -0
  304. data/spec/legion/extensions/agentic/attention/synesthesia/helpers/sensory_mapping_spec.rb +135 -0
  305. data/spec/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine_spec.rb +260 -0
  306. data/spec/legion/extensions/agentic/attention/synesthesia/helpers/synesthetic_event_spec.rb +83 -0
  307. data/spec/legion/extensions/agentic/attention/synesthesia/runners/cognitive_synesthesia_spec.rb +192 -0
  308. data/spec/legion/extensions/agentic/attention/telescope/client_spec.rb +30 -0
  309. data/spec/legion/extensions/agentic/attention/telescope/helpers/constants_spec.rb +108 -0
  310. data/spec/legion/extensions/agentic/attention/telescope/helpers/observation_spec.rb +138 -0
  311. data/spec/legion/extensions/agentic/attention/telescope/helpers/observatory_engine_spec.rb +197 -0
  312. data/spec/legion/extensions/agentic/attention/telescope/helpers/telescope_spec.rb +251 -0
  313. data/spec/legion/extensions/agentic/attention/telescope/runners/cognitive_telescope_spec.rb +191 -0
  314. data/spec/spec_helper.rb +46 -0
  315. metadata +399 -0
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Attention::Subliminal::Helpers::SubliminalTrace do
4
+ subject(:trace) { described_class.new(content: 'faint memory of danger') }
5
+
6
+ describe '#initialize' do
7
+ it 'assigns a UUID id' do
8
+ expect(trace.id).to match(/\A[0-9a-f-]{36}\z/)
9
+ end
10
+
11
+ it 'stores content' do
12
+ expect(trace.content).to eq('faint memory of danger')
13
+ end
14
+
15
+ it 'defaults trace_type to :associative' do
16
+ expect(trace.trace_type).to eq(:associative)
17
+ end
18
+
19
+ it 'defaults domain to :general' do
20
+ expect(trace.domain).to eq(:general)
21
+ end
22
+
23
+ it 'defaults activation to DEFAULT_ACTIVATION' do
24
+ expect(trace.activation).to eq(0.2)
25
+ end
26
+
27
+ it 'clamps activation to subliminal ceiling' do
28
+ high = described_class.new(content: 'x', activation: 0.9)
29
+ expect(high.activation).to eq(0.39)
30
+ end
31
+
32
+ it 'clamps activation to subliminal floor' do
33
+ low = described_class.new(content: 'x', activation: 0.001)
34
+ expect(low.activation).to eq(0.02)
35
+ end
36
+
37
+ it 'defaults influence_target to :attention' do
38
+ expect(trace.influence_target).to eq(:attention)
39
+ end
40
+
41
+ it 'validates trace_type' do
42
+ bad = described_class.new(content: 'x', trace_type: :nonexistent)
43
+ expect(bad.trace_type).to eq(:associative)
44
+ end
45
+
46
+ it 'validates influence_target' do
47
+ bad = described_class.new(content: 'x', influence_target: :nonexistent)
48
+ expect(bad.influence_target).to eq(:attention)
49
+ end
50
+ end
51
+
52
+ describe '#boost!' do
53
+ it 'increases activation' do
54
+ original = trace.activation
55
+ trace.boost!
56
+ expect(trace.activation).to be > original
57
+ end
58
+
59
+ it 'clamps at subliminal ceiling' do
60
+ 10.times { trace.boost! }
61
+ expect(trace.activation).to eq(0.39)
62
+ end
63
+ end
64
+
65
+ describe '#decay!' do
66
+ it 'decreases activation' do
67
+ original = trace.activation
68
+ trace.decay!
69
+ expect(trace.activation).to be < original
70
+ end
71
+
72
+ it 'clamps at 0.0' do
73
+ 50.times { trace.decay! }
74
+ expect(trace.activation).to eq(0.0)
75
+ end
76
+ end
77
+
78
+ describe '#exert_influence!' do
79
+ it 'returns influence magnitude' do
80
+ mag = trace.exert_influence!
81
+ expect(mag).to be > 0.0
82
+ end
83
+
84
+ it 'increments influence_count' do
85
+ trace.exert_influence!
86
+ expect(trace.influence_count).to eq(1)
87
+ end
88
+
89
+ it 'slightly decreases activation' do
90
+ original = trace.activation
91
+ trace.exert_influence!
92
+ expect(trace.activation).to be < original
93
+ end
94
+ end
95
+
96
+ describe '#near_threshold?' do
97
+ it 'is false at default activation' do
98
+ expect(trace.near_threshold?).to be false
99
+ end
100
+
101
+ it 'is true when near conscious threshold' do
102
+ near = described_class.new(content: 'x', activation: 0.35)
103
+ expect(near.near_threshold?).to be true
104
+ end
105
+ end
106
+
107
+ describe '#active?' do
108
+ it 'is true at default activation' do
109
+ expect(trace.active?).to be true
110
+ end
111
+
112
+ it 'is false when fully decayed' do
113
+ 50.times { trace.decay! }
114
+ expect(trace.active?).to be false
115
+ end
116
+ end
117
+
118
+ describe '#extinct?' do
119
+ it 'is false at default activation' do
120
+ expect(trace.extinct?).to be false
121
+ end
122
+
123
+ it 'is true when nearly zero' do
124
+ 50.times { trace.decay! }
125
+ expect(trace.extinct?).to be true
126
+ end
127
+ end
128
+
129
+ describe '#potent?' do
130
+ it 'is true at default activation' do
131
+ expect(trace.potent?).to be true
132
+ end
133
+
134
+ it 'is false when low' do
135
+ faint = described_class.new(content: 'x', activation: 0.1)
136
+ expect(faint.potent?).to be false
137
+ end
138
+ end
139
+
140
+ describe '#breached_threshold?' do
141
+ it 'is false by default' do
142
+ expect(trace.breached_threshold?).to be false
143
+ end
144
+ end
145
+
146
+ describe '#persistence' do
147
+ it 'is 1.0 initially' do
148
+ expect(trace.persistence).to eq(1.0)
149
+ end
150
+
151
+ it 'decreases after decay' do
152
+ trace.decay!
153
+ expect(trace.persistence).to be < 1.0
154
+ end
155
+ end
156
+
157
+ describe '#to_h' do
158
+ it 'includes all fields' do
159
+ hash = trace.to_h
160
+ expect(hash).to include(
161
+ :id, :content, :trace_type, :domain, :activation,
162
+ :original_activation, :influence_target, :influence_count,
163
+ :influence_magnitude, :near_threshold, :active, :extinct,
164
+ :activation_label, :persistence, :created_at
165
+ )
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Attention::Subliminal::Runners::Subliminal do
4
+ let(:engine) { Legion::Extensions::Agentic::Attention::Subliminal::Helpers::SubliminalEngine.new }
5
+ let(:runner) do
6
+ obj = Object.new
7
+ obj.extend(described_class)
8
+ obj.instance_variable_set(:@default_engine, engine)
9
+ obj
10
+ end
11
+
12
+ describe '#create_subliminal_trace' do
13
+ it 'returns success with trace hash' do
14
+ result = runner.create_subliminal_trace(content: 'test', engine: engine)
15
+ expect(result[:success]).to be true
16
+ expect(result[:trace][:content]).to eq('test')
17
+ end
18
+ end
19
+
20
+ describe '#boost_trace' do
21
+ it 'returns success for known trace' do
22
+ trace = engine.create_trace(content: 'test')
23
+ result = runner.boost_trace(trace_id: trace.id, engine: engine)
24
+ expect(result[:success]).to be true
25
+ end
26
+
27
+ it 'returns failure for unknown trace' do
28
+ result = runner.boost_trace(trace_id: 'bad', engine: engine)
29
+ expect(result[:success]).to be false
30
+ end
31
+ end
32
+
33
+ describe '#process_influences' do
34
+ it 'returns success' do
35
+ result = runner.process_influences(engine: engine)
36
+ expect(result[:success]).to be true
37
+ end
38
+ end
39
+
40
+ describe '#decay_all' do
41
+ it 'returns success' do
42
+ result = runner.decay_all(engine: engine)
43
+ expect(result[:success]).to be true
44
+ end
45
+ end
46
+
47
+ describe '#active_traces' do
48
+ it 'returns active list' do
49
+ engine.create_trace(content: 'test')
50
+ result = runner.active_traces(engine: engine)
51
+ expect(result[:count]).to eq(1)
52
+ end
53
+ end
54
+
55
+ describe '#near_threshold' do
56
+ it 'returns near-threshold list' do
57
+ engine.create_trace(content: 'near', activation: 0.35)
58
+ result = runner.near_threshold(engine: engine)
59
+ expect(result[:count]).to eq(1)
60
+ end
61
+ end
62
+
63
+ describe '#influence_on' do
64
+ it 'returns influence level' do
65
+ result = runner.influence_on(target: :attention, engine: engine)
66
+ expect(result[:success]).to be true
67
+ expect(result[:influence]).to eq(0.0)
68
+ end
69
+ end
70
+
71
+ describe '#subliminal_status' do
72
+ it 'returns comprehensive status' do
73
+ result = runner.subliminal_status(engine: engine)
74
+ expect(result[:success]).to be true
75
+ expect(result).to include(:total_traces, :subliminal_load)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Attention::Subliminal do
4
+ it 'has a version number' do
5
+ expect(Legion::Extensions::Agentic::Attention::Subliminal::VERSION).to eq('0.1.0')
6
+ end
7
+ end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Attention::Surprise::Client do
6
+ subject(:client) { described_class.new }
7
+
8
+ describe '#initialize' do
9
+ it 'creates a default store' do
10
+ expect(client.store).to be_a(Legion::Extensions::Agentic::Attention::Surprise::Helpers::SurpriseStore)
11
+ end
12
+
13
+ it 'creates a default habituation_model' do
14
+ expect(client.habituation_model).to be_a(Legion::Extensions::Agentic::Attention::Surprise::Helpers::HabituationModel)
15
+ end
16
+
17
+ it 'accepts an injected store' do
18
+ custom = Legion::Extensions::Agentic::Attention::Surprise::Helpers::SurpriseStore.new
19
+ c = described_class.new(store: custom)
20
+ expect(c.store).to equal(custom)
21
+ end
22
+
23
+ it 'accepts an injected habituation_model' do
24
+ custom = Legion::Extensions::Agentic::Attention::Surprise::Helpers::HabituationModel.new
25
+ c = described_class.new(habituation_model: custom)
26
+ expect(c.habituation_model).to equal(custom)
27
+ end
28
+ end
29
+
30
+ describe 'full orienting response workflow' do
31
+ it 'detects surprise, habituates, and recovers sensitivity' do
32
+ # Phase 1: Fresh domain — max sensitivity
33
+ sens_before = client.domain_sensitivity(domain: :cpu_load)[:sensitivity]
34
+ expect(sens_before).to eq(1.0)
35
+
36
+ # Phase 2: Large unexpected event fires orienting response
37
+ first = client.evaluate_surprise(domain: :cpu_load, predicted: 0.2, actual: 0.95, valence: :negative)
38
+ expect(first[:success]).to be true
39
+ expect(first[:orienting_triggered]).to be true
40
+
41
+ # Phase 3: Sensitivity reduced (habituation)
42
+ sens_after = client.domain_sensitivity(domain: :cpu_load)[:sensitivity]
43
+ expect(sens_after).to be < sens_before
44
+
45
+ # Phase 4: Repeated surprises continue to habituate
46
+ 5.times { client.evaluate_surprise(domain: :cpu_load, predicted: 0.2, actual: 0.95, valence: :negative) }
47
+ sens_habituated = client.domain_sensitivity(domain: :cpu_load)[:sensitivity]
48
+ expect(sens_habituated).to be < sens_after
49
+
50
+ # Phase 5: Tick decay slightly recovers sensitivity
51
+ client.update_surprise(tick_result: {})
52
+ sens_recovered = client.domain_sensitivity(domain: :cpu_load)[:sensitivity]
53
+ expect(sens_recovered).to be >= sens_habituated
54
+
55
+ # Phase 6: Stats reflect accumulated history (1 initial + 5 repeated = 6 events)
56
+ stats = client.surprise_stats
57
+ expect(stats[:total_events]).to be >= 6
58
+ expect(stats[:domain_count]).to be >= 1
59
+
60
+ # Phase 7: Manual reset restores full sensitivity
61
+ client.reset_habituation(domain: :cpu_load)
62
+ sens_reset = client.domain_sensitivity(domain: :cpu_load)[:sensitivity]
63
+ expect(sens_reset).to be > sens_habituated
64
+ end
65
+
66
+ it 'tracks multiple domains independently' do
67
+ client.evaluate_surprise(domain: :memory, predicted: 0.0, actual: 1.0, valence: :negative)
68
+ client.evaluate_surprise(domain: :disk_io, predicted: 0.0, actual: 1.0, valence: :negative)
69
+ client.evaluate_surprise(domain: :network, predicted: 0.3, actual: 0.4, valence: :neutral)
70
+
71
+ stats = client.surprise_stats
72
+ expect(stats[:domain_count]).to eq(3)
73
+
74
+ # Memory and disk_io were strongly surprising; network was not
75
+ mem_sens = client.domain_sensitivity(domain: :memory)[:sensitivity]
76
+ net_sens = client.domain_sensitivity(domain: :network)[:sensitivity]
77
+ expect(mem_sens).to be < 1.0
78
+ expect(net_sens).to be < 1.0
79
+ end
80
+
81
+ it 'processes tick predictions end-to-end' do
82
+ tick = {
83
+ predictions: [
84
+ { domain: :error_rate, predicted: 0.01, actual: 0.45, valence: :negative },
85
+ { domain: :latency, predicted: 0.1, actual: 0.15, valence: :neutral }
86
+ ]
87
+ }
88
+ result = client.update_surprise(tick_result: tick)
89
+ expect(result[:success]).to be true
90
+ expect(result[:evaluated]).to eq(2)
91
+
92
+ # Events should appear in recent surprises
93
+ recent = client.recent_surprises(count: 5)
94
+ domains = recent[:events].map { |e| e[:domain] }
95
+ expect(domains).to include(:error_rate, :latency)
96
+ end
97
+
98
+ it 'positive surprise is less alarming than negative surprise for the same delta' do
99
+ client.evaluate_surprise(domain: :pos_outcome, predicted: 0.5, actual: 1.0, valence: :positive)
100
+ client.evaluate_surprise(domain: :neg_outcome, predicted: 0.5, actual: 0.0, valence: :negative)
101
+
102
+ pos_event = client.recent_surprises(count: 2)[:events].find { |e| e[:domain] == :pos_outcome }
103
+ neg_event = client.recent_surprises(count: 2)[:events].find { |e| e[:domain] == :neg_outcome }
104
+
105
+ expect(neg_event[:magnitude]).to be > pos_event[:magnitude]
106
+ end
107
+
108
+ it 'cooldown prevents orienting spam from the same domain' do
109
+ domain = :noisy_sensor
110
+ results = 5.times.map { client.evaluate_surprise(domain: domain, predicted: 0.0, actual: 1.0, valence: :negative) }
111
+ orienting_count = results.count { |r| r[:orienting_triggered] }
112
+ # Only the first should fire (cooldown blocks subsequent)
113
+ expect(orienting_count).to eq(1)
114
+ end
115
+
116
+ it 'reports most surprising domain in stats' do
117
+ client.evaluate_surprise(domain: :low, predicted: 0.4, actual: 0.5, valence: :neutral)
118
+ client.evaluate_surprise(domain: :high, predicted: 0.0, actual: 1.0, valence: :negative)
119
+ expect(client.surprise_stats[:most_surprising_domain]).to eq(:high)
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Attention::Surprise::Helpers::Constants do
6
+ describe 'SURPRISE_THRESHOLD' do
7
+ it 'is a float between 0 and 1' do
8
+ expect(described_class::SURPRISE_THRESHOLD).to be_a(Float)
9
+ expect(described_class::SURPRISE_THRESHOLD).to be_between(0.0, 1.0).exclusive
10
+ end
11
+
12
+ it 'is 0.4' do
13
+ expect(described_class::SURPRISE_THRESHOLD).to eq(0.4)
14
+ end
15
+ end
16
+
17
+ describe 'HABITUATION_RATE' do
18
+ it 'is a positive float less than 1' do
19
+ expect(described_class::HABITUATION_RATE).to be_a(Float)
20
+ expect(described_class::HABITUATION_RATE).to be_between(0.0, 1.0).exclusive
21
+ end
22
+ end
23
+
24
+ describe 'SENSITIZATION_RATE' do
25
+ it 'is a positive float less than HABITUATION_RATE' do
26
+ expect(described_class::SENSITIZATION_RATE).to be < described_class::HABITUATION_RATE
27
+ end
28
+ end
29
+
30
+ describe 'SURPRISE_DECAY' do
31
+ it 'is a positive float between 0 and 1' do
32
+ expect(described_class::SURPRISE_DECAY).to be_a(Float)
33
+ expect(described_class::SURPRISE_DECAY).to be_between(0.0, 1.0).exclusive
34
+ end
35
+ end
36
+
37
+ describe 'MAX_SURPRISE_HISTORY' do
38
+ it 'is a positive integer' do
39
+ expect(described_class::MAX_SURPRISE_HISTORY).to be_a(Integer)
40
+ expect(described_class::MAX_SURPRISE_HISTORY).to be > 0
41
+ end
42
+
43
+ it 'is 200' do
44
+ expect(described_class::MAX_SURPRISE_HISTORY).to eq(200)
45
+ end
46
+ end
47
+
48
+ describe 'SURPRISE_ALPHA' do
49
+ it 'is an EMA alpha between 0 and 1' do
50
+ expect(described_class::SURPRISE_ALPHA).to be_a(Float)
51
+ expect(described_class::SURPRISE_ALPHA).to be_between(0.0, 1.0).exclusive
52
+ end
53
+ end
54
+
55
+ describe 'VALENCE_WEIGHTS' do
56
+ it 'contains positive, negative, and neutral keys' do
57
+ expect(described_class::VALENCE_WEIGHTS.keys).to contain_exactly(:positive, :negative, :neutral)
58
+ end
59
+
60
+ it 'weights negative surprise higher than positive' do
61
+ expect(described_class::VALENCE_WEIGHTS[:negative]).to be > described_class::VALENCE_WEIGHTS[:positive]
62
+ end
63
+
64
+ it 'weights negative surprise highest' do
65
+ expect(described_class::VALENCE_WEIGHTS[:negative]).to eq(described_class::VALENCE_WEIGHTS.values.max)
66
+ end
67
+
68
+ it 'is frozen' do
69
+ expect(described_class::VALENCE_WEIGHTS).to be_frozen
70
+ end
71
+
72
+ it 'has all positive float values' do
73
+ described_class::VALENCE_WEIGHTS.each_value do |v|
74
+ expect(v).to be_a(Float)
75
+ expect(v).to be > 0.0
76
+ end
77
+ end
78
+ end
79
+
80
+ describe 'DOMAIN_HABITUATION_FLOOR' do
81
+ it 'is a positive float less than 1' do
82
+ expect(described_class::DOMAIN_HABITUATION_FLOOR).to be_a(Float)
83
+ expect(described_class::DOMAIN_HABITUATION_FLOOR).to be_between(0.0, 1.0).exclusive
84
+ end
85
+
86
+ it 'is less than SURPRISE_THRESHOLD' do
87
+ expect(described_class::DOMAIN_HABITUATION_FLOOR).to be < described_class::SURPRISE_THRESHOLD
88
+ end
89
+ end
90
+
91
+ describe 'MAX_DOMAINS' do
92
+ it 'is a positive integer' do
93
+ expect(described_class::MAX_DOMAINS).to be_a(Integer)
94
+ expect(described_class::MAX_DOMAINS).to be > 0
95
+ end
96
+
97
+ it 'is 50' do
98
+ expect(described_class::MAX_DOMAINS).to eq(50)
99
+ end
100
+ end
101
+
102
+ describe 'ORIENTING_COOLDOWN' do
103
+ it 'is a positive integer' do
104
+ expect(described_class::ORIENTING_COOLDOWN).to be_a(Integer)
105
+ expect(described_class::ORIENTING_COOLDOWN).to be > 0
106
+ end
107
+
108
+ it 'is 3' do
109
+ expect(described_class::ORIENTING_COOLDOWN).to eq(3)
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Attention::Surprise::Helpers::HabituationModel do
6
+ subject(:model) { described_class.new }
7
+
8
+ let(:floor) { Legion::Extensions::Agentic::Attention::Surprise::Helpers::Constants::DOMAIN_HABITUATION_FLOOR }
9
+ let(:habituation_rate) { Legion::Extensions::Agentic::Attention::Surprise::Helpers::Constants::HABITUATION_RATE }
10
+ let(:sensitization_rate) { Legion::Extensions::Agentic::Attention::Surprise::Helpers::Constants::SENSITIZATION_RATE }
11
+
12
+ describe '#sensitivity_for' do
13
+ it 'returns 1.0 for unknown domains (fully sensitive)' do
14
+ expect(model.sensitivity_for(:new_domain)).to eq(1.0)
15
+ end
16
+
17
+ it 'returns the stored sensitivity for a known domain' do
18
+ model.habituate(:known)
19
+ expect(model.sensitivity_for(:known)).to be < 1.0
20
+ end
21
+ end
22
+
23
+ describe '#habituate' do
24
+ it 'reduces sensitivity by HABITUATION_RATE' do
25
+ initial = model.sensitivity_for(:domain_a)
26
+ model.habituate(:domain_a)
27
+ expect(model.sensitivity_for(:domain_a)).to be_within(0.0001).of(initial - habituation_rate)
28
+ end
29
+
30
+ it 'never goes below DOMAIN_HABITUATION_FLOOR' do
31
+ 100.times { model.habituate(:floor_domain) }
32
+ expect(model.sensitivity_for(:floor_domain)).to be >= floor
33
+ end
34
+
35
+ it 'returns the updated sensitivity' do
36
+ result = model.habituate(:returning_domain)
37
+ expect(result).to eq(model.sensitivity_for(:returning_domain))
38
+ end
39
+
40
+ it 'habituates different domains independently' do
41
+ model.habituate(:domain_x)
42
+ expect(model.sensitivity_for(:domain_y)).to eq(1.0)
43
+ end
44
+ end
45
+
46
+ describe '#sensitize' do
47
+ it 'increases sensitivity toward 1.0' do
48
+ model.habituate(:sens_domain)
49
+ before = model.sensitivity_for(:sens_domain)
50
+ model.sensitize(:sens_domain)
51
+ expect(model.sensitivity_for(:sens_domain)).to be > before
52
+ end
53
+
54
+ it 'never exceeds 1.0' do
55
+ 100.times { model.sensitize(:fresh_domain) }
56
+ expect(model.sensitivity_for(:fresh_domain)).to be <= 1.0
57
+ end
58
+
59
+ it 'returns the updated sensitivity' do
60
+ model.habituate(:ret_domain)
61
+ result = model.sensitize(:ret_domain)
62
+ expect(result).to eq(model.sensitivity_for(:ret_domain))
63
+ end
64
+
65
+ it 'increases by SENSITIZATION_RATE when below 1.0' do
66
+ model.habituate(:rate_domain)
67
+ before = model.sensitivity_for(:rate_domain)
68
+ model.sensitize(:rate_domain)
69
+ expect(model.sensitivity_for(:rate_domain)).to be_within(0.0001).of(before + sensitization_rate)
70
+ end
71
+ end
72
+
73
+ describe '#decay_all' do
74
+ it 'slightly recovers sensitivity across all domains' do
75
+ model.habituate(:d1)
76
+ model.habituate(:d2)
77
+ before_d1 = model.sensitivity_for(:d1)
78
+ before_d2 = model.sensitivity_for(:d2)
79
+ model.decay_all
80
+ expect(model.sensitivity_for(:d1)).to be > before_d1
81
+ expect(model.sensitivity_for(:d2)).to be > before_d2
82
+ end
83
+
84
+ it 'does not push sensitivity above 1.0' do
85
+ model.decay_all
86
+ expect(model.sensitivity_for(:d1)).to be <= 1.0
87
+ end
88
+
89
+ it 'has no effect when no domains are tracked' do
90
+ expect { model.decay_all }.not_to raise_error
91
+ end
92
+ end
93
+
94
+ describe '#to_h' do
95
+ it 'returns a hash with domains and sensitivities keys' do
96
+ model.habituate(:d1)
97
+ h = model.to_h
98
+ expect(h).to include(:domains, :sensitivities)
99
+ end
100
+
101
+ it 'reports correct domain count' do
102
+ model.habituate(:alpha)
103
+ model.habituate(:beta)
104
+ expect(model.to_h[:domains]).to eq(2)
105
+ end
106
+
107
+ it 'rounds sensitivity values to 4 decimal places' do
108
+ model.habituate(:precision_domain)
109
+ h = model.to_h
110
+ h[:sensitivities].each_value do |v|
111
+ expect(v.to_s.length).to be <= 7
112
+ end
113
+ end
114
+
115
+ it 'returns 0 domains when nothing tracked' do
116
+ expect(model.to_h[:domains]).to eq(0)
117
+ end
118
+ end
119
+
120
+ describe 'domain limit enforcement' do
121
+ it 'does not exceed MAX_DOMAINS tracked domains' do
122
+ max = Legion::Extensions::Agentic::Attention::Surprise::Helpers::Constants::MAX_DOMAINS
123
+ (max + 10).times { |i| model.habituate(:"domain_#{i}") }
124
+ expect(model.to_h[:domains]).to be <= max
125
+ end
126
+ end
127
+ end