lex-agentic-memory 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 (267) 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-memory.gemspec +30 -0
  7. data/lib/legion/extensions/agentic/memory/archaeology/client.rb +19 -0
  8. data/lib/legion/extensions/agentic/memory/archaeology/helpers/archaeology_engine.rb +184 -0
  9. data/lib/legion/extensions/agentic/memory/archaeology/helpers/artifact.rb +146 -0
  10. data/lib/legion/extensions/agentic/memory/archaeology/helpers/constants.rb +95 -0
  11. data/lib/legion/extensions/agentic/memory/archaeology/helpers/excavation_site.rb +97 -0
  12. data/lib/legion/extensions/agentic/memory/archaeology/runners/cognitive_archaeology.rb +86 -0
  13. data/lib/legion/extensions/agentic/memory/archaeology/version.rb +13 -0
  14. data/lib/legion/extensions/agentic/memory/archaeology.rb +22 -0
  15. data/lib/legion/extensions/agentic/memory/compression/client.rb +15 -0
  16. data/lib/legion/extensions/agentic/memory/compression/helpers/compression_engine.rb +145 -0
  17. data/lib/legion/extensions/agentic/memory/compression/helpers/constants.rb +44 -0
  18. data/lib/legion/extensions/agentic/memory/compression/helpers/information_chunk.rb +81 -0
  19. data/lib/legion/extensions/agentic/memory/compression/runners/cognitive_compression.rb +76 -0
  20. data/lib/legion/extensions/agentic/memory/compression/version.rb +13 -0
  21. data/lib/legion/extensions/agentic/memory/compression.rb +19 -0
  22. data/lib/legion/extensions/agentic/memory/echo/client.rb +19 -0
  23. data/lib/legion/extensions/agentic/memory/echo/helpers/constants.rb +57 -0
  24. data/lib/legion/extensions/agentic/memory/echo/helpers/echo.rb +95 -0
  25. data/lib/legion/extensions/agentic/memory/echo/helpers/echo_engine.rb +136 -0
  26. data/lib/legion/extensions/agentic/memory/echo/runners/cognitive_echo.rb +81 -0
  27. data/lib/legion/extensions/agentic/memory/echo/version.rb +13 -0
  28. data/lib/legion/extensions/agentic/memory/echo.rb +19 -0
  29. data/lib/legion/extensions/agentic/memory/echo_chamber/client.rb +19 -0
  30. data/lib/legion/extensions/agentic/memory/echo_chamber/helpers/chamber.rb +134 -0
  31. data/lib/legion/extensions/agentic/memory/echo_chamber/helpers/chamber_engine.rb +156 -0
  32. data/lib/legion/extensions/agentic/memory/echo_chamber/helpers/constants.rb +60 -0
  33. data/lib/legion/extensions/agentic/memory/echo_chamber/helpers/echo.rb +96 -0
  34. data/lib/legion/extensions/agentic/memory/echo_chamber/runners/cognitive_echo_chamber.rb +84 -0
  35. data/lib/legion/extensions/agentic/memory/echo_chamber/version.rb +13 -0
  36. data/lib/legion/extensions/agentic/memory/echo_chamber.rb +21 -0
  37. data/lib/legion/extensions/agentic/memory/episodic/actors/decay.rb +45 -0
  38. data/lib/legion/extensions/agentic/memory/episodic/client.rb +25 -0
  39. data/lib/legion/extensions/agentic/memory/episodic/helpers/constants.rb +36 -0
  40. data/lib/legion/extensions/agentic/memory/episodic/helpers/episode.rb +104 -0
  41. data/lib/legion/extensions/agentic/memory/episodic/helpers/episodic_binding.rb +57 -0
  42. data/lib/legion/extensions/agentic/memory/episodic/helpers/episodic_store.rb +141 -0
  43. data/lib/legion/extensions/agentic/memory/episodic/runners/episodic_buffer.rb +108 -0
  44. data/lib/legion/extensions/agentic/memory/episodic/version.rb +13 -0
  45. data/lib/legion/extensions/agentic/memory/episodic.rb +20 -0
  46. data/lib/legion/extensions/agentic/memory/hologram/client.rb +23 -0
  47. data/lib/legion/extensions/agentic/memory/hologram/helpers/constants.rb +67 -0
  48. data/lib/legion/extensions/agentic/memory/hologram/helpers/hologram.rb +118 -0
  49. data/lib/legion/extensions/agentic/memory/hologram/helpers/hologram_engine.rb +117 -0
  50. data/lib/legion/extensions/agentic/memory/hologram/helpers/holographic_fragment.rb +70 -0
  51. data/lib/legion/extensions/agentic/memory/hologram/runners/cognitive_hologram.rb +110 -0
  52. data/lib/legion/extensions/agentic/memory/hologram/version.rb +13 -0
  53. data/lib/legion/extensions/agentic/memory/hologram.rb +22 -0
  54. data/lib/legion/extensions/agentic/memory/immune_memory/client.rb +19 -0
  55. data/lib/legion/extensions/agentic/memory/immune_memory/helpers/constants.rb +84 -0
  56. data/lib/legion/extensions/agentic/memory/immune_memory/helpers/encounter.rb +54 -0
  57. data/lib/legion/extensions/agentic/memory/immune_memory/helpers/immune_memory_engine.rb +171 -0
  58. data/lib/legion/extensions/agentic/memory/immune_memory/helpers/memory_cell.rb +97 -0
  59. data/lib/legion/extensions/agentic/memory/immune_memory/runners/cognitive_immune_memory.rb +76 -0
  60. data/lib/legion/extensions/agentic/memory/immune_memory/version.rb +13 -0
  61. data/lib/legion/extensions/agentic/memory/immune_memory.rb +20 -0
  62. data/lib/legion/extensions/agentic/memory/nostalgia/client.rb +31 -0
  63. data/lib/legion/extensions/agentic/memory/nostalgia/helpers/constants.rb +68 -0
  64. data/lib/legion/extensions/agentic/memory/nostalgia/helpers/nostalgia_engine.rb +148 -0
  65. data/lib/legion/extensions/agentic/memory/nostalgia/helpers/nostalgia_event.rb +44 -0
  66. data/lib/legion/extensions/agentic/memory/nostalgia/helpers/nostalgic_memory.rb +97 -0
  67. data/lib/legion/extensions/agentic/memory/nostalgia/runners/analysis.rb +61 -0
  68. data/lib/legion/extensions/agentic/memory/nostalgia/runners/recall.rb +60 -0
  69. data/lib/legion/extensions/agentic/memory/nostalgia/version.rb +13 -0
  70. data/lib/legion/extensions/agentic/memory/nostalgia.rb +21 -0
  71. data/lib/legion/extensions/agentic/memory/offloading/client.rb +29 -0
  72. data/lib/legion/extensions/agentic/memory/offloading/helpers/constants.rb +55 -0
  73. data/lib/legion/extensions/agentic/memory/offloading/helpers/external_store.rb +82 -0
  74. data/lib/legion/extensions/agentic/memory/offloading/helpers/offloaded_item.rb +65 -0
  75. data/lib/legion/extensions/agentic/memory/offloading/helpers/offloading_engine.rb +138 -0
  76. data/lib/legion/extensions/agentic/memory/offloading/runners/cognitive_offloading.rb +102 -0
  77. data/lib/legion/extensions/agentic/memory/offloading/version.rb +13 -0
  78. data/lib/legion/extensions/agentic/memory/offloading.rb +20 -0
  79. data/lib/legion/extensions/agentic/memory/paleontology/client.rb +19 -0
  80. data/lib/legion/extensions/agentic/memory/paleontology/helpers/constants.rb +69 -0
  81. data/lib/legion/extensions/agentic/memory/paleontology/helpers/excavation.rb +62 -0
  82. data/lib/legion/extensions/agentic/memory/paleontology/helpers/fossil.rb +125 -0
  83. data/lib/legion/extensions/agentic/memory/paleontology/helpers/paleontology_engine.rb +170 -0
  84. data/lib/legion/extensions/agentic/memory/paleontology/runners/cognitive_paleontology.rb +93 -0
  85. data/lib/legion/extensions/agentic/memory/paleontology/version.rb +13 -0
  86. data/lib/legion/extensions/agentic/memory/paleontology.rb +22 -0
  87. data/lib/legion/extensions/agentic/memory/palimpsest/client.rb +19 -0
  88. data/lib/legion/extensions/agentic/memory/palimpsest/helpers/belief_layer.rb +81 -0
  89. data/lib/legion/extensions/agentic/memory/palimpsest/helpers/constants.rb +56 -0
  90. data/lib/legion/extensions/agentic/memory/palimpsest/helpers/palimpsest.rb +124 -0
  91. data/lib/legion/extensions/agentic/memory/palimpsest/helpers/palimpsest_engine.rb +117 -0
  92. data/lib/legion/extensions/agentic/memory/palimpsest/runners/cognitive_palimpsest.rb +105 -0
  93. data/lib/legion/extensions/agentic/memory/palimpsest/version.rb +13 -0
  94. data/lib/legion/extensions/agentic/memory/palimpsest.rb +21 -0
  95. data/lib/legion/extensions/agentic/memory/reserve/client.rb +19 -0
  96. data/lib/legion/extensions/agentic/memory/reserve/helpers/constants.rb +58 -0
  97. data/lib/legion/extensions/agentic/memory/reserve/helpers/pathway.rb +112 -0
  98. data/lib/legion/extensions/agentic/memory/reserve/helpers/reserve_engine.rb +163 -0
  99. data/lib/legion/extensions/agentic/memory/reserve/runners/cognitive_reserve.rb +92 -0
  100. data/lib/legion/extensions/agentic/memory/reserve/version.rb +13 -0
  101. data/lib/legion/extensions/agentic/memory/reserve.rb +19 -0
  102. data/lib/legion/extensions/agentic/memory/semantic/actors/decay.rb +45 -0
  103. data/lib/legion/extensions/agentic/memory/semantic/client.rb +28 -0
  104. data/lib/legion/extensions/agentic/memory/semantic/helpers/concept.rb +101 -0
  105. data/lib/legion/extensions/agentic/memory/semantic/helpers/constants.rb +51 -0
  106. data/lib/legion/extensions/agentic/memory/semantic/helpers/knowledge_store.rb +145 -0
  107. data/lib/legion/extensions/agentic/memory/semantic/runners/semantic_memory.rb +94 -0
  108. data/lib/legion/extensions/agentic/memory/semantic/version.rb +13 -0
  109. data/lib/legion/extensions/agentic/memory/semantic.rb +20 -0
  110. data/lib/legion/extensions/agentic/memory/semantic_priming/client.rb +19 -0
  111. data/lib/legion/extensions/agentic/memory/semantic_priming/helpers/connection.rb +77 -0
  112. data/lib/legion/extensions/agentic/memory/semantic_priming/helpers/constants.rb +68 -0
  113. data/lib/legion/extensions/agentic/memory/semantic_priming/helpers/priming_network.rb +206 -0
  114. data/lib/legion/extensions/agentic/memory/semantic_priming/helpers/semantic_node.rb +81 -0
  115. data/lib/legion/extensions/agentic/memory/semantic_priming/runners/semantic_priming.rb +120 -0
  116. data/lib/legion/extensions/agentic/memory/semantic_priming/version.rb +13 -0
  117. data/lib/legion/extensions/agentic/memory/semantic_priming.rb +20 -0
  118. data/lib/legion/extensions/agentic/memory/semantic_satiation/client.rb +28 -0
  119. data/lib/legion/extensions/agentic/memory/semantic_satiation/helpers/concept.rb +82 -0
  120. data/lib/legion/extensions/agentic/memory/semantic_satiation/helpers/constants.rb +37 -0
  121. data/lib/legion/extensions/agentic/memory/semantic_satiation/helpers/satiation_engine.rb +103 -0
  122. data/lib/legion/extensions/agentic/memory/semantic_satiation/runners/semantic_satiation.rb +92 -0
  123. data/lib/legion/extensions/agentic/memory/semantic_satiation/version.rb +13 -0
  124. data/lib/legion/extensions/agentic/memory/semantic_satiation.rb +19 -0
  125. data/lib/legion/extensions/agentic/memory/source_monitoring/actors/decay.rb +31 -0
  126. data/lib/legion/extensions/agentic/memory/source_monitoring/client.rb +28 -0
  127. data/lib/legion/extensions/agentic/memory/source_monitoring/helpers/constants.rb +66 -0
  128. data/lib/legion/extensions/agentic/memory/source_monitoring/helpers/source_record.rb +94 -0
  129. data/lib/legion/extensions/agentic/memory/source_monitoring/helpers/source_tracker.rb +119 -0
  130. data/lib/legion/extensions/agentic/memory/source_monitoring/runners/source_monitoring.rb +95 -0
  131. data/lib/legion/extensions/agentic/memory/source_monitoring/version.rb +13 -0
  132. data/lib/legion/extensions/agentic/memory/source_monitoring.rb +19 -0
  133. data/lib/legion/extensions/agentic/memory/trace/actors/decay.rb +45 -0
  134. data/lib/legion/extensions/agentic/memory/trace/actors/tier_migration.rb +45 -0
  135. data/lib/legion/extensions/agentic/memory/trace/batch_decay.rb +44 -0
  136. data/lib/legion/extensions/agentic/memory/trace/client.rb +32 -0
  137. data/lib/legion/extensions/agentic/memory/trace/helpers/cache_store.rb +167 -0
  138. data/lib/legion/extensions/agentic/memory/trace/helpers/decay.rb +68 -0
  139. data/lib/legion/extensions/agentic/memory/trace/helpers/error_tracer.rb +94 -0
  140. data/lib/legion/extensions/agentic/memory/trace/helpers/store.rb +260 -0
  141. data/lib/legion/extensions/agentic/memory/trace/helpers/trace.rb +106 -0
  142. data/lib/legion/extensions/agentic/memory/trace/local_migrations/20260316000001_create_memory_traces.rb +31 -0
  143. data/lib/legion/extensions/agentic/memory/trace/local_migrations/20260316000002_create_memory_associations.rb +13 -0
  144. data/lib/legion/extensions/agentic/memory/trace/persistent_store.rb +94 -0
  145. data/lib/legion/extensions/agentic/memory/trace/quota.rb +55 -0
  146. data/lib/legion/extensions/agentic/memory/trace/runners/consolidation.rb +121 -0
  147. data/lib/legion/extensions/agentic/memory/trace/runners/traces.rb +105 -0
  148. data/lib/legion/extensions/agentic/memory/trace/version.rb +13 -0
  149. data/lib/legion/extensions/agentic/memory/trace.rb +54 -0
  150. data/lib/legion/extensions/agentic/memory/transfer/client.rb +28 -0
  151. data/lib/legion/extensions/agentic/memory/transfer/helpers/constants.rb +34 -0
  152. data/lib/legion/extensions/agentic/memory/transfer/helpers/domain_knowledge.rb +74 -0
  153. data/lib/legion/extensions/agentic/memory/transfer/helpers/transfer_engine.rb +188 -0
  154. data/lib/legion/extensions/agentic/memory/transfer/runners/transfer_learning.rb +77 -0
  155. data/lib/legion/extensions/agentic/memory/transfer/version.rb +13 -0
  156. data/lib/legion/extensions/agentic/memory/transfer.rb +19 -0
  157. data/lib/legion/extensions/agentic/memory/version.rb +11 -0
  158. data/lib/legion/extensions/agentic/memory.rb +35 -0
  159. data/spec/legion/extensions/agentic/memory/archaeology/client_spec.rb +38 -0
  160. data/spec/legion/extensions/agentic/memory/archaeology/cognitive_archaeology_spec.rb +7 -0
  161. data/spec/legion/extensions/agentic/memory/archaeology/helpers/archaeology_engine_spec.rb +165 -0
  162. data/spec/legion/extensions/agentic/memory/archaeology/helpers/artifact_spec.rb +196 -0
  163. data/spec/legion/extensions/agentic/memory/archaeology/helpers/constants_spec.rb +42 -0
  164. data/spec/legion/extensions/agentic/memory/archaeology/helpers/excavation_site_spec.rb +115 -0
  165. data/spec/legion/extensions/agentic/memory/archaeology/runners/cognitive_archaeology_spec.rb +96 -0
  166. data/spec/legion/extensions/agentic/memory/compression/helpers/compression_engine_spec.rb +138 -0
  167. data/spec/legion/extensions/agentic/memory/compression/helpers/constants_spec.rb +50 -0
  168. data/spec/legion/extensions/agentic/memory/compression/helpers/information_chunk_spec.rb +123 -0
  169. data/spec/legion/extensions/agentic/memory/compression/runners/cognitive_compression_spec.rb +80 -0
  170. data/spec/legion/extensions/agentic/memory/echo/client_spec.rb +20 -0
  171. data/spec/legion/extensions/agentic/memory/echo/cognitive_echo_spec.rb +7 -0
  172. data/spec/legion/extensions/agentic/memory/echo/helpers/echo_engine_spec.rb +152 -0
  173. data/spec/legion/extensions/agentic/memory/echo/helpers/echo_spec.rb +128 -0
  174. data/spec/legion/extensions/agentic/memory/echo/runners_spec.rb +80 -0
  175. data/spec/legion/extensions/agentic/memory/echo_chamber/client_spec.rb +84 -0
  176. data/spec/legion/extensions/agentic/memory/echo_chamber/helpers/chamber_engine_spec.rb +266 -0
  177. data/spec/legion/extensions/agentic/memory/echo_chamber/helpers/chamber_spec.rb +249 -0
  178. data/spec/legion/extensions/agentic/memory/echo_chamber/helpers/constants_spec.rb +130 -0
  179. data/spec/legion/extensions/agentic/memory/echo_chamber/helpers/echo_spec.rb +252 -0
  180. data/spec/legion/extensions/agentic/memory/echo_chamber/runners/cognitive_echo_chamber_spec.rb +185 -0
  181. data/spec/legion/extensions/agentic/memory/episodic/client_spec.rb +80 -0
  182. data/spec/legion/extensions/agentic/memory/episodic/episodic_buffer_spec.rb +15 -0
  183. data/spec/legion/extensions/agentic/memory/episodic/helpers/constants_spec.rb +86 -0
  184. data/spec/legion/extensions/agentic/memory/episodic/helpers/episode_spec.rb +188 -0
  185. data/spec/legion/extensions/agentic/memory/episodic/helpers/episodic_binding_spec.rb +114 -0
  186. data/spec/legion/extensions/agentic/memory/episodic/helpers/episodic_store_spec.rb +201 -0
  187. data/spec/legion/extensions/agentic/memory/episodic/runners/episodic_buffer_spec.rb +208 -0
  188. data/spec/legion/extensions/agentic/memory/hologram/client_spec.rb +89 -0
  189. data/spec/legion/extensions/agentic/memory/hologram/cognitive_hologram_spec.rb +39 -0
  190. data/spec/legion/extensions/agentic/memory/hologram/helpers/constants_spec.rb +143 -0
  191. data/spec/legion/extensions/agentic/memory/hologram/helpers/hologram_engine_spec.rb +268 -0
  192. data/spec/legion/extensions/agentic/memory/hologram/helpers/hologram_spec.rb +256 -0
  193. data/spec/legion/extensions/agentic/memory/hologram/helpers/holographic_fragment_spec.rb +213 -0
  194. data/spec/legion/extensions/agentic/memory/hologram/runners/cognitive_hologram_spec.rb +239 -0
  195. data/spec/legion/extensions/agentic/memory/immune_memory/client_spec.rb +18 -0
  196. data/spec/legion/extensions/agentic/memory/immune_memory/cognitive_immune_memory_spec.rb +7 -0
  197. data/spec/legion/extensions/agentic/memory/immune_memory/helpers/encounter_spec.rb +85 -0
  198. data/spec/legion/extensions/agentic/memory/immune_memory/helpers/immune_memory_engine_spec.rb +203 -0
  199. data/spec/legion/extensions/agentic/memory/immune_memory/helpers/memory_cell_spec.rb +190 -0
  200. data/spec/legion/extensions/agentic/memory/immune_memory/runners_spec.rb +83 -0
  201. data/spec/legion/extensions/agentic/memory/nostalgia/client_spec.rb +71 -0
  202. data/spec/legion/extensions/agentic/memory/nostalgia/helpers/constants_spec.rb +65 -0
  203. data/spec/legion/extensions/agentic/memory/nostalgia/helpers/nostalgia_engine_spec.rb +191 -0
  204. data/spec/legion/extensions/agentic/memory/nostalgia/helpers/nostalgia_event_spec.rb +59 -0
  205. data/spec/legion/extensions/agentic/memory/nostalgia/helpers/nostalgic_memory_spec.rb +134 -0
  206. data/spec/legion/extensions/agentic/memory/nostalgia/runners/analysis_spec.rb +97 -0
  207. data/spec/legion/extensions/agentic/memory/nostalgia/runners/recall_spec.rb +81 -0
  208. data/spec/legion/extensions/agentic/memory/offloading/client_spec.rb +30 -0
  209. data/spec/legion/extensions/agentic/memory/offloading/helpers/constants_spec.rb +71 -0
  210. data/spec/legion/extensions/agentic/memory/offloading/helpers/external_store_spec.rb +158 -0
  211. data/spec/legion/extensions/agentic/memory/offloading/helpers/offloaded_item_spec.rb +123 -0
  212. data/spec/legion/extensions/agentic/memory/offloading/helpers/offloading_engine_spec.rb +250 -0
  213. data/spec/legion/extensions/agentic/memory/offloading/runners/cognitive_offloading_spec.rb +194 -0
  214. data/spec/legion/extensions/agentic/memory/paleontology/client_spec.rb +27 -0
  215. data/spec/legion/extensions/agentic/memory/paleontology/cognitive_paleontology_spec.rb +7 -0
  216. data/spec/legion/extensions/agentic/memory/paleontology/helpers/constants_spec.rb +33 -0
  217. data/spec/legion/extensions/agentic/memory/paleontology/helpers/excavation_spec.rb +71 -0
  218. data/spec/legion/extensions/agentic/memory/paleontology/helpers/fossil_spec.rb +134 -0
  219. data/spec/legion/extensions/agentic/memory/paleontology/helpers/paleontology_engine_spec.rb +148 -0
  220. data/spec/legion/extensions/agentic/memory/paleontology/runners/cognitive_paleontology_spec.rb +89 -0
  221. data/spec/legion/extensions/agentic/memory/palimpsest/client_spec.rb +58 -0
  222. data/spec/legion/extensions/agentic/memory/palimpsest/helpers/belief_layer_spec.rb +150 -0
  223. data/spec/legion/extensions/agentic/memory/palimpsest/helpers/constants_spec.rb +63 -0
  224. data/spec/legion/extensions/agentic/memory/palimpsest/helpers/palimpsest_engine_spec.rb +164 -0
  225. data/spec/legion/extensions/agentic/memory/palimpsest/helpers/palimpsest_spec.rb +172 -0
  226. data/spec/legion/extensions/agentic/memory/palimpsest/runners/cognitive_palimpsest_spec.rb +165 -0
  227. data/spec/legion/extensions/agentic/memory/reserve/client_spec.rb +37 -0
  228. data/spec/legion/extensions/agentic/memory/reserve/helpers/pathway_spec.rb +165 -0
  229. data/spec/legion/extensions/agentic/memory/reserve/helpers/reserve_engine_spec.rb +196 -0
  230. data/spec/legion/extensions/agentic/memory/reserve/runners/cognitive_reserve_spec.rb +96 -0
  231. data/spec/legion/extensions/agentic/memory/semantic/client_spec.rb +35 -0
  232. data/spec/legion/extensions/agentic/memory/semantic/helpers/concept_spec.rb +119 -0
  233. data/spec/legion/extensions/agentic/memory/semantic/helpers/knowledge_store_spec.rb +140 -0
  234. data/spec/legion/extensions/agentic/memory/semantic/runners/semantic_memory_spec.rb +103 -0
  235. data/spec/legion/extensions/agentic/memory/semantic_priming/helpers/connection_spec.rb +98 -0
  236. data/spec/legion/extensions/agentic/memory/semantic_priming/helpers/priming_network_spec.rb +208 -0
  237. data/spec/legion/extensions/agentic/memory/semantic_priming/helpers/semantic_node_spec.rb +125 -0
  238. data/spec/legion/extensions/agentic/memory/semantic_priming/semantic_priming_spec.rb +7 -0
  239. data/spec/legion/extensions/agentic/memory/semantic_satiation/client_spec.rb +19 -0
  240. data/spec/legion/extensions/agentic/memory/semantic_satiation/helpers/concept_spec.rb +167 -0
  241. data/spec/legion/extensions/agentic/memory/semantic_satiation/helpers/constants_spec.rb +81 -0
  242. data/spec/legion/extensions/agentic/memory/semantic_satiation/helpers/satiation_engine_spec.rb +189 -0
  243. data/spec/legion/extensions/agentic/memory/semantic_satiation/runners/semantic_satiation_spec.rb +176 -0
  244. data/spec/legion/extensions/agentic/memory/source_monitoring/client_spec.rb +25 -0
  245. data/spec/legion/extensions/agentic/memory/source_monitoring/helpers/source_record_spec.rb +152 -0
  246. data/spec/legion/extensions/agentic/memory/source_monitoring/helpers/source_tracker_spec.rb +139 -0
  247. data/spec/legion/extensions/agentic/memory/source_monitoring/runners/source_monitoring_spec.rb +102 -0
  248. data/spec/legion/extensions/agentic/memory/trace/actors/decay_spec.rb +62 -0
  249. data/spec/legion/extensions/agentic/memory/trace/actors/tier_migration_spec.rb +62 -0
  250. data/spec/legion/extensions/agentic/memory/trace/batch_decay_spec.rb +26 -0
  251. data/spec/legion/extensions/agentic/memory/trace/client_spec.rb +62 -0
  252. data/spec/legion/extensions/agentic/memory/trace/helpers/decay_spec.rb +134 -0
  253. data/spec/legion/extensions/agentic/memory/trace/helpers/store_spec.rb +217 -0
  254. data/spec/legion/extensions/agentic/memory/trace/helpers/trace_spec.rb +120 -0
  255. data/spec/legion/extensions/agentic/memory/trace/local_persistence_spec.rb +255 -0
  256. data/spec/legion/extensions/agentic/memory/trace/memory_spec.rb +11 -0
  257. data/spec/legion/extensions/agentic/memory/trace/persistent_store_spec.rb +50 -0
  258. data/spec/legion/extensions/agentic/memory/trace/quota_spec.rb +56 -0
  259. data/spec/legion/extensions/agentic/memory/trace/runners/consolidation_spec.rb +118 -0
  260. data/spec/legion/extensions/agentic/memory/trace/runners/traces_spec.rb +69 -0
  261. data/spec/legion/extensions/agentic/memory/transfer/client_spec.rb +18 -0
  262. data/spec/legion/extensions/agentic/memory/transfer/helpers/constants_spec.rb +41 -0
  263. data/spec/legion/extensions/agentic/memory/transfer/helpers/domain_knowledge_spec.rb +134 -0
  264. data/spec/legion/extensions/agentic/memory/transfer/helpers/transfer_engine_spec.rb +299 -0
  265. data/spec/legion/extensions/agentic/memory/transfer/runners/transfer_learning_spec.rb +144 -0
  266. data/spec/spec_helper.rb +46 -0
  267. metadata +351 -0
@@ -0,0 +1,252 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Memory::EchoChamber::Helpers::Echo do
4
+ subject(:echo) { described_class.new(content: 'everything I believe is true') }
5
+
6
+ describe '#initialize' do
7
+ it 'assigns a UUID id' do
8
+ expect(echo.id).to match(/\A[0-9a-f-]{36}\z/)
9
+ end
10
+
11
+ it 'stores content' do
12
+ expect(echo.content).to eq('everything I believe is true')
13
+ end
14
+
15
+ it 'defaults echo_type to :belief' do
16
+ expect(echo.echo_type).to eq(:belief)
17
+ end
18
+
19
+ it 'defaults domain to :general' do
20
+ expect(echo.domain).to eq(:general)
21
+ end
22
+
23
+ it 'defaults amplitude to 0.5' do
24
+ expect(echo.amplitude).to eq(0.5)
25
+ end
26
+
27
+ it 'preserves original_amplitude' do
28
+ expect(echo.original_amplitude).to eq(0.5)
29
+ end
30
+
31
+ it 'initializes frequency to 1' do
32
+ expect(echo.frequency).to eq(1)
33
+ end
34
+
35
+ it 'records created_at' do
36
+ expect(echo.created_at).to be_a(Time)
37
+ end
38
+
39
+ it 'clamps amplitude above 1.0' do
40
+ high = described_class.new(content: 'x', amplitude: 5.0)
41
+ expect(high.amplitude).to eq(1.0)
42
+ end
43
+
44
+ it 'clamps amplitude below 0.0' do
45
+ low = described_class.new(content: 'x', amplitude: -1.0)
46
+ expect(low.amplitude).to eq(0.0)
47
+ end
48
+
49
+ it 'validates echo_type, falls back to :belief' do
50
+ bad = described_class.new(content: 'x', echo_type: :nonsense)
51
+ expect(bad.echo_type).to eq(:belief)
52
+ end
53
+
54
+ it 'accepts all valid echo types' do
55
+ %i[belief assumption bias hypothesis conviction].each do |type|
56
+ e = described_class.new(content: 'x', echo_type: type)
57
+ expect(e.echo_type).to eq(type)
58
+ end
59
+ end
60
+
61
+ it 'stores source_agent' do
62
+ e = described_class.new(content: 'x', source_agent: 'agent-123')
63
+ expect(e.source_agent).to eq('agent-123')
64
+ end
65
+
66
+ it 'accepts custom domain' do
67
+ e = described_class.new(content: 'x', domain: :politics)
68
+ expect(e.domain).to eq(:politics)
69
+ end
70
+ end
71
+
72
+ describe '#amplify!' do
73
+ it 'increases amplitude' do
74
+ original = echo.amplitude
75
+ echo.amplify!
76
+ expect(echo.amplitude).to be > original
77
+ end
78
+
79
+ it 'increments frequency' do
80
+ echo.amplify!
81
+ expect(echo.frequency).to eq(2)
82
+ end
83
+
84
+ it 'clamps amplitude at 1.0' do
85
+ high = described_class.new(content: 'x', amplitude: 0.95)
86
+ 5.times { high.amplify! }
87
+ expect(high.amplitude).to eq(1.0)
88
+ end
89
+
90
+ it 'accepts custom rate' do
91
+ original = echo.amplitude
92
+ echo.amplify!(0.2)
93
+ expect(echo.amplitude).to be_within(0.001).of(original + 0.2)
94
+ end
95
+
96
+ it 'returns self for chaining' do
97
+ expect(echo.amplify!).to eq(echo)
98
+ end
99
+ end
100
+
101
+ describe '#dampen!' do
102
+ it 'decreases amplitude' do
103
+ strong = described_class.new(content: 'x', amplitude: 0.8)
104
+ original = strong.amplitude
105
+ strong.dampen!
106
+ expect(strong.amplitude).to be < original
107
+ end
108
+
109
+ it 'clamps amplitude at 0.0' do
110
+ 30.times { echo.dampen! }
111
+ expect(echo.amplitude).to eq(0.0)
112
+ end
113
+
114
+ it 'accepts custom rate' do
115
+ original = echo.amplitude
116
+ echo.dampen!(0.1)
117
+ expect(echo.amplitude).to be_within(0.001).of(original - 0.1)
118
+ end
119
+
120
+ it 'returns self for chaining' do
121
+ expect(echo.dampen!).to eq(echo)
122
+ end
123
+ end
124
+
125
+ describe '#resonate?' do
126
+ it 'is false at default amplitude (0.5)' do
127
+ expect(echo.resonate?).to be false
128
+ end
129
+
130
+ it 'is true when amplitude exceeds disruption threshold' do
131
+ strong = described_class.new(content: 'x', amplitude: 0.8)
132
+ expect(strong.resonate?).to be true
133
+ end
134
+ end
135
+
136
+ describe '#fading?' do
137
+ it 'is false at default amplitude (0.5)' do
138
+ expect(echo.fading?).to be false
139
+ end
140
+
141
+ it 'is true when amplitude is at or below porous threshold' do
142
+ weak = described_class.new(content: 'x', amplitude: 0.2)
143
+ expect(weak.fading?).to be true
144
+ end
145
+ end
146
+
147
+ describe '#silent?' do
148
+ it 'is false at default amplitude' do
149
+ expect(echo.silent?).to be false
150
+ end
151
+
152
+ it 'is true when amplitude is at silent threshold' do
153
+ faint = described_class.new(content: 'x', amplitude: 0.04)
154
+ expect(faint.silent?).to be true
155
+ end
156
+ end
157
+
158
+ describe '#frequency_label' do
159
+ it 'returns a symbol' do
160
+ expect(echo.frequency_label).to be_a(Symbol)
161
+ end
162
+
163
+ it 'returns :silent for frequency 1 (score 0.05)' do
164
+ expect(echo.frequency_label).to eq(:silent)
165
+ end
166
+
167
+ it 'returns higher label after many amplifications' do
168
+ 20.times { echo.amplify! }
169
+ expect(echo.frequency_label).not_to eq(:silent)
170
+ end
171
+ end
172
+
173
+ describe '#amplitude_label' do
174
+ it 'returns a symbol' do
175
+ expect(echo.amplitude_label).to be_a(Symbol)
176
+ end
177
+
178
+ it 'returns :moderate for default amplitude 0.5' do
179
+ expect(echo.amplitude_label).to eq(:moderate)
180
+ end
181
+
182
+ it 'returns :deafening for high amplitude' do
183
+ loud = described_class.new(content: 'x', amplitude: 0.9)
184
+ expect(loud.amplitude_label).to eq(:deafening)
185
+ end
186
+
187
+ it 'returns :muted for low amplitude' do
188
+ quiet = described_class.new(content: 'x', amplitude: 0.1)
189
+ expect(quiet.amplitude_label).to eq(:muted)
190
+ end
191
+ end
192
+
193
+ describe '#to_h' do
194
+ let(:hash) { echo.to_h }
195
+
196
+ it 'includes :id' do
197
+ expect(hash).to have_key(:id)
198
+ end
199
+
200
+ it 'includes :content' do
201
+ expect(hash[:content]).to eq('everything I believe is true')
202
+ end
203
+
204
+ it 'includes :echo_type' do
205
+ expect(hash[:echo_type]).to eq(:belief)
206
+ end
207
+
208
+ it 'includes :domain' do
209
+ expect(hash[:domain]).to eq(:general)
210
+ end
211
+
212
+ it 'includes :amplitude' do
213
+ expect(hash[:amplitude]).to eq(0.5)
214
+ end
215
+
216
+ it 'includes :original_amplitude' do
217
+ expect(hash[:original_amplitude]).to eq(0.5)
218
+ end
219
+
220
+ it 'includes :frequency' do
221
+ expect(hash[:frequency]).to eq(1)
222
+ end
223
+
224
+ it 'includes :frequency_label' do
225
+ expect(hash).to have_key(:frequency_label)
226
+ end
227
+
228
+ it 'includes :amplitude_label' do
229
+ expect(hash).to have_key(:amplitude_label)
230
+ end
231
+
232
+ it 'includes :resonate boolean' do
233
+ expect(hash[:resonate]).to be(false).or be(true)
234
+ end
235
+
236
+ it 'includes :fading boolean' do
237
+ expect(hash[:fading]).to be(false).or be(true)
238
+ end
239
+
240
+ it 'includes :silent boolean' do
241
+ expect(hash[:silent]).to be(false).or be(true)
242
+ end
243
+
244
+ it 'includes :source_agent' do
245
+ expect(hash).to have_key(:source_agent)
246
+ end
247
+
248
+ it 'includes :created_at' do
249
+ expect(hash[:created_at]).to be_a(Time)
250
+ end
251
+ end
252
+ end
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Memory::EchoChamber::Runners::CognitiveEchoChamber do
4
+ let(:engine) { Legion::Extensions::Agentic::Memory::EchoChamber::Helpers::ChamberEngine.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_echo' do
13
+ it 'returns success with echo hash' do
14
+ result = runner.create_echo(content: 'beliefs compound', engine: engine)
15
+ expect(result[:success]).to be true
16
+ expect(result[:echo][:content]).to eq('beliefs compound')
17
+ end
18
+
19
+ it 'uses default echo_type :belief' do
20
+ result = runner.create_echo(content: 'test', engine: engine)
21
+ expect(result[:echo][:echo_type]).to eq(:belief)
22
+ end
23
+
24
+ it 'accepts custom echo_type' do
25
+ result = runner.create_echo(content: 'test', echo_type: :assumption, engine: engine)
26
+ expect(result[:echo][:echo_type]).to eq(:assumption)
27
+ end
28
+
29
+ it 'accepts custom domain' do
30
+ result = runner.create_echo(content: 'test', domain: :politics, engine: engine)
31
+ expect(result[:echo][:domain]).to eq(:politics)
32
+ end
33
+
34
+ it 'accepts source_agent' do
35
+ result = runner.create_echo(content: 'test', source_agent: 'agent-x', engine: engine)
36
+ expect(result[:echo][:source_agent]).to eq('agent-x')
37
+ end
38
+
39
+ it 'returns failure for empty content' do
40
+ result = runner.create_echo(content: '', engine: engine)
41
+ expect(result[:success]).to be false
42
+ expect(result[:error]).not_to be_empty
43
+ end
44
+
45
+ it 'returns failure for blank content' do
46
+ result = runner.create_echo(content: ' ', engine: engine)
47
+ expect(result[:success]).to be false
48
+ end
49
+ end
50
+
51
+ describe '#create_chamber' do
52
+ it 'returns success with chamber hash' do
53
+ result = runner.create_chamber(label: 'ideology', engine: engine)
54
+ expect(result[:success]).to be true
55
+ expect(result[:chamber][:label]).to eq('ideology')
56
+ end
57
+
58
+ it 'accepts custom domain' do
59
+ result = runner.create_chamber(label: 'test', domain: :science, engine: engine)
60
+ expect(result[:chamber][:domain]).to eq(:science)
61
+ end
62
+
63
+ it 'accepts custom wall_thickness' do
64
+ result = runner.create_chamber(label: 'test', wall_thickness: 0.9, engine: engine)
65
+ expect(result[:chamber][:wall_thickness]).to eq(0.9)
66
+ end
67
+
68
+ it 'returns failure for empty label' do
69
+ result = runner.create_chamber(label: '', engine: engine)
70
+ expect(result[:success]).to be false
71
+ end
72
+
73
+ it 'returns failure for blank label' do
74
+ result = runner.create_chamber(label: ' ', engine: engine)
75
+ expect(result[:success]).to be false
76
+ end
77
+ end
78
+
79
+ describe '#amplify' do
80
+ it 'returns success for existing echo' do
81
+ echo = engine.create_echo(content: 'test', amplitude: 0.5)
82
+ result = runner.amplify(echo_id: echo.id, engine: engine)
83
+ expect(result[:success]).to be true
84
+ end
85
+
86
+ it 'increases amplitude' do
87
+ echo = engine.create_echo(content: 'test', amplitude: 0.5)
88
+ result = runner.amplify(echo_id: echo.id, engine: engine)
89
+ expect(result[:echo][:amplitude]).to be > 0.5
90
+ end
91
+
92
+ it 'returns failure for missing echo' do
93
+ result = runner.amplify(echo_id: 'nonexistent', engine: engine)
94
+ expect(result[:success]).to be false
95
+ expect(result[:error]).to eq('echo not found')
96
+ end
97
+
98
+ it 'accepts custom rate' do
99
+ echo = engine.create_echo(content: 'test', amplitude: 0.5)
100
+ result = runner.amplify(echo_id: echo.id, rate: 0.2, engine: engine)
101
+ expect(result[:echo][:amplitude]).to be_within(0.001).of(0.7)
102
+ end
103
+ end
104
+
105
+ describe '#disrupt' do
106
+ it 'returns result from engine' do
107
+ chamber = engine.create_chamber(label: 'test', wall_thickness: 0.3)
108
+ result = runner.disrupt(chamber_id: chamber.id, force: 0.8, engine: engine)
109
+ expect(result).to have_key(:success)
110
+ end
111
+
112
+ it 'succeeds with sufficient force' do
113
+ chamber = engine.create_chamber(label: 'test', wall_thickness: 0.3)
114
+ result = runner.disrupt(chamber_id: chamber.id, force: 0.8, engine: engine)
115
+ expect(result[:success]).to be true
116
+ end
117
+
118
+ it 'fails with insufficient force' do
119
+ chamber = engine.create_chamber(label: 'test', wall_thickness: 0.8)
120
+ result = runner.disrupt(chamber_id: chamber.id, force: 0.2, engine: engine)
121
+ expect(result[:success]).to be false
122
+ end
123
+ end
124
+
125
+ describe '#list_echoes' do
126
+ before do
127
+ engine.create_echo(content: 'bias 1', echo_type: :bias, domain: :science)
128
+ engine.create_echo(content: 'belief 1', echo_type: :belief, domain: :politics)
129
+ engine.create_echo(content: 'belief 2', echo_type: :belief, domain: :science)
130
+ end
131
+
132
+ it 'returns all active echoes with no filter' do
133
+ result = runner.list_echoes(engine: engine)
134
+ expect(result[:success]).to be true
135
+ expect(result[:count]).to eq(3)
136
+ end
137
+
138
+ it 'filters by echo_type' do
139
+ result = runner.list_echoes(echo_type: :belief, engine: engine)
140
+ expect(result[:count]).to eq(2)
141
+ end
142
+
143
+ it 'filters by domain' do
144
+ result = runner.list_echoes(domain: :science, engine: engine)
145
+ expect(result[:count]).to eq(2)
146
+ end
147
+
148
+ it 'filters by both echo_type and domain' do
149
+ result = runner.list_echoes(echo_type: :belief, domain: :science, engine: engine)
150
+ expect(result[:count]).to eq(1)
151
+ end
152
+
153
+ it 'returns echo hashes in result' do
154
+ result = runner.list_echoes(engine: engine)
155
+ expect(result[:echoes].first).to have_key(:id)
156
+ end
157
+ end
158
+
159
+ describe '#chamber_status' do
160
+ it 'returns success' do
161
+ result = runner.chamber_status(engine: engine)
162
+ expect(result[:success]).to be true
163
+ end
164
+
165
+ it 'includes echo report fields' do
166
+ result = runner.chamber_status(engine: engine)
167
+ expect(result).to include(
168
+ :total_echoes, :active_echoes, :resonating_echoes,
169
+ :total_chambers, :sealed_chambers, :porous_chambers
170
+ )
171
+ end
172
+
173
+ it 'reflects created echoes' do
174
+ engine.create_echo(content: 'test')
175
+ result = runner.chamber_status(engine: engine)
176
+ expect(result[:total_echoes]).to eq(1)
177
+ end
178
+
179
+ it 'reflects created chambers' do
180
+ engine.create_chamber(label: 'test')
181
+ result = runner.chamber_status(engine: engine)
182
+ expect(result[:total_chambers]).to eq(1)
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/memory/episodic/client'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Memory::Episodic::Client do
6
+ let(:client) { described_class.new }
7
+
8
+ it 'responds to create_episode' do
9
+ expect(client).to respond_to(:create_episode)
10
+ end
11
+
12
+ it 'responds to add_binding' do
13
+ expect(client).to respond_to(:add_binding)
14
+ end
15
+
16
+ it 'responds to attend_episode' do
17
+ expect(client).to respond_to(:attend_episode)
18
+ end
19
+
20
+ it 'responds to rehearse_episode' do
21
+ expect(client).to respond_to(:rehearse_episode)
22
+ end
23
+
24
+ it 'responds to check_integration' do
25
+ expect(client).to respond_to(:check_integration)
26
+ end
27
+
28
+ it 'responds to retrieve_by_modality' do
29
+ expect(client).to respond_to(:retrieve_by_modality)
30
+ end
31
+
32
+ it 'responds to retrieve_multimodal' do
33
+ expect(client).to respond_to(:retrieve_multimodal)
34
+ end
35
+
36
+ it 'responds to most_coherent' do
37
+ expect(client).to respond_to(:most_coherent)
38
+ end
39
+
40
+ it 'responds to update_episodic_buffer' do
41
+ expect(client).to respond_to(:update_episodic_buffer)
42
+ end
43
+
44
+ it 'responds to episodic_buffer_stats' do
45
+ expect(client).to respond_to(:episodic_buffer_stats)
46
+ end
47
+
48
+ it 'uses provided store' do
49
+ store = Legion::Extensions::Agentic::Memory::Episodic::Helpers::EpisodicStore.new
50
+ c = described_class.new(store: store)
51
+ c.create_episode
52
+ expect(store.count).to eq(1)
53
+ end
54
+
55
+ it 'round-trips a full episode lifecycle' do
56
+ ep = client.create_episode
57
+ expect(ep[:success]).to be true
58
+
59
+ add_result = client.add_binding(
60
+ episode_id: ep[:episode_id], modality: :verbal, content: 'hello', source: :phonological_loop
61
+ )
62
+ expect(add_result[:success]).to be true
63
+
64
+ client.add_binding(
65
+ episode_id: ep[:episode_id], modality: :visual, content: 'image', source: :visuospatial, strength: 0.9
66
+ )
67
+
68
+ attend_result = client.attend_episode(episode_id: ep[:episode_id])
69
+ expect(attend_result[:success]).to be true
70
+
71
+ integration = client.check_integration(episode_id: ep[:episode_id])
72
+ expect(integration[:success]).to be true
73
+
74
+ multimodal = client.retrieve_multimodal
75
+ expect(multimodal[:count]).to eq(1)
76
+
77
+ stats = client.episodic_buffer_stats
78
+ expect(stats[:episode_count]).to eq(1)
79
+ end
80
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Memory::Episodic do
4
+ it 'has a version number' do
5
+ expect(Legion::Extensions::Agentic::Memory::Episodic::VERSION).not_to be_nil
6
+ end
7
+
8
+ it 'has a version that is a string' do
9
+ expect(Legion::Extensions::Agentic::Memory::Episodic::VERSION).to be_a(String)
10
+ end
11
+
12
+ it 'version is 0.1.0' do
13
+ expect(Legion::Extensions::Agentic::Memory::Episodic::VERSION).to eq('0.1.0')
14
+ end
15
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Memory::Episodic::Helpers::Constants do
4
+ describe 'capacity constants' do
5
+ it 'defines MAX_EPISODES as 30' do
6
+ expect(described_class::MAX_EPISODES).to eq(30)
7
+ end
8
+
9
+ it 'defines MAX_BINDINGS_PER_EPISODE as 10' do
10
+ expect(described_class::MAX_BINDINGS_PER_EPISODE).to eq(10)
11
+ end
12
+
13
+ it 'defines MAX_HISTORY as 200' do
14
+ expect(described_class::MAX_HISTORY).to eq(200)
15
+ end
16
+ end
17
+
18
+ describe 'timing constants' do
19
+ it 'defines EPISODE_TTL as 120' do
20
+ expect(described_class::EPISODE_TTL).to eq(120)
21
+ end
22
+
23
+ it 'defines RECENTLY_ACCESSED_WINDOW as 30' do
24
+ expect(described_class::RECENTLY_ACCESSED_WINDOW).to eq(30)
25
+ end
26
+ end
27
+
28
+ describe 'strength constants' do
29
+ it 'defines BINDING_STRENGTH_FLOOR as 0.05' do
30
+ expect(described_class::BINDING_STRENGTH_FLOOR).to eq(0.05)
31
+ end
32
+
33
+ it 'defines BINDING_DECAY as 0.015' do
34
+ expect(described_class::BINDING_DECAY).to eq(0.015)
35
+ end
36
+
37
+ it 'defines DEFAULT_BINDING_STRENGTH as 0.5' do
38
+ expect(described_class::DEFAULT_BINDING_STRENGTH).to eq(0.5)
39
+ end
40
+
41
+ it 'defines ATTENTION_BOOST as 0.2' do
42
+ expect(described_class::ATTENTION_BOOST).to eq(0.2)
43
+ end
44
+
45
+ it 'defines REHEARSAL_BOOST as 0.15' do
46
+ expect(described_class::REHEARSAL_BOOST).to eq(0.15)
47
+ end
48
+
49
+ it 'defines INTEGRATION_THRESHOLD as 0.4' do
50
+ expect(described_class::INTEGRATION_THRESHOLD).to eq(0.4)
51
+ end
52
+ end
53
+
54
+ describe 'MODALITIES' do
55
+ it 'includes all 7 expected modalities' do
56
+ expected = %i[verbal visual spatial semantic emotional procedural temporal]
57
+ expect(described_class::MODALITIES).to eq(expected)
58
+ end
59
+
60
+ it 'is frozen' do
61
+ expect(described_class::MODALITIES).to be_frozen
62
+ end
63
+ end
64
+
65
+ describe 'COHERENCE_LABELS' do
66
+ it 'maps low scores to :fragmented' do
67
+ label = described_class::COHERENCE_LABELS.find { |range, _| range.cover?(0.1) }&.last
68
+ expect(label).to eq(:fragmented)
69
+ end
70
+
71
+ it 'maps mid scores to :partial' do
72
+ label = described_class::COHERENCE_LABELS.find { |range, _| range.cover?(0.45) }&.last
73
+ expect(label).to eq(:partial)
74
+ end
75
+
76
+ it 'maps high scores to :coherent' do
77
+ label = described_class::COHERENCE_LABELS.find { |range, _| range.cover?(0.7) }&.last
78
+ expect(label).to eq(:coherent)
79
+ end
80
+
81
+ it 'maps very high scores to :vivid' do
82
+ label = described_class::COHERENCE_LABELS.find { |range, _| range.cover?(0.9) }&.last
83
+ expect(label).to eq(:vivid)
84
+ end
85
+ end
86
+ end