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,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Memory::Semantic::Helpers::Concept do
4
+ subject(:concept) { described_class.new(name: :dog, domain: :animals) }
5
+
6
+ describe '#initialize' do
7
+ it 'assigns fields' do
8
+ expect(concept.name).to eq(:dog)
9
+ expect(concept.domain).to eq(:animals)
10
+ expect(concept.access_count).to eq(0)
11
+ end
12
+
13
+ it 'defaults confidence to DEFAULT_CONFIDENCE' do
14
+ expect(concept.confidence).to eq(Legion::Extensions::Agentic::Memory::Semantic::Helpers::Constants::DEFAULT_CONFIDENCE)
15
+ end
16
+
17
+ it 'assigns uuid and timestamp' do
18
+ expect(concept.id).to match(/\A[0-9a-f-]{36}\z/)
19
+ expect(concept.created_at).to be_a(Time)
20
+ end
21
+
22
+ it 'accepts custom properties' do
23
+ c = described_class.new(name: :cat, properties: { legs: 4 })
24
+ expect(c.get_property(:legs)).to eq(4)
25
+ end
26
+ end
27
+
28
+ describe '#add_relation' do
29
+ it 'adds a typed relation' do
30
+ rel = concept.add_relation(type: :is_a, target_name: :mammal)
31
+ expect(rel[:type]).to eq(:is_a)
32
+ expect(rel[:target]).to eq(:mammal)
33
+ expect(concept.relations.size).to eq(1)
34
+ end
35
+
36
+ it 'rejects invalid relation types' do
37
+ expect(concept.add_relation(type: :invalid, target_name: :thing)).to be false
38
+ end
39
+
40
+ it 'reinforces existing relation instead of duplicating' do
41
+ concept.add_relation(type: :is_a, target_name: :mammal)
42
+ concept.add_relation(type: :is_a, target_name: :mammal)
43
+ expect(concept.relations.size).to eq(1)
44
+ end
45
+ end
46
+
47
+ describe '#relations_of_type' do
48
+ it 'filters by type' do
49
+ concept.add_relation(type: :is_a, target_name: :mammal)
50
+ concept.add_relation(type: :has_a, target_name: :tail)
51
+ expect(concept.relations_of_type(:is_a).size).to eq(1)
52
+ end
53
+ end
54
+
55
+ describe '#related_concepts' do
56
+ it 'lists unique related concept names' do
57
+ concept.add_relation(type: :is_a, target_name: :mammal)
58
+ concept.add_relation(type: :has_a, target_name: :tail)
59
+ expect(concept.related_concepts).to contain_exactly(:mammal, :tail)
60
+ end
61
+ end
62
+
63
+ describe '#access' do
64
+ it 'increments count and boosts confidence' do
65
+ before = concept.confidence
66
+ concept.access
67
+ expect(concept.access_count).to eq(1)
68
+ expect(concept.confidence).to be > before
69
+ end
70
+ end
71
+
72
+ describe '#decay' do
73
+ it 'reduces confidence' do
74
+ before = concept.confidence
75
+ concept.decay
76
+ expect(concept.confidence).to be < before
77
+ end
78
+
79
+ it 'does not drop below floor' do
80
+ 100.times { concept.decay }
81
+ expect(concept.confidence).to be >= Legion::Extensions::Agentic::Memory::Semantic::Helpers::Constants::CONFIDENCE_FLOOR
82
+ end
83
+
84
+ it 'prunes weak relations' do
85
+ concept.add_relation(type: :is_a, target_name: :mammal, confidence: 0.06)
86
+ 100.times { concept.decay }
87
+ expect(concept.relations).to be_empty
88
+ end
89
+ end
90
+
91
+ describe '#faded?' do
92
+ it 'returns false for healthy concept' do
93
+ expect(concept.faded?).to be false
94
+ end
95
+
96
+ it 'returns true at floor' do
97
+ concept.confidence = Legion::Extensions::Agentic::Memory::Semantic::Helpers::Constants::CONFIDENCE_FLOOR
98
+ expect(concept.faded?).to be true
99
+ end
100
+ end
101
+
102
+ describe '#label' do
103
+ it 'returns :provisional for default confidence' do
104
+ expect(concept.label).to eq(:provisional)
105
+ end
106
+
107
+ it 'returns :established for high confidence' do
108
+ concept.confidence = 0.9
109
+ expect(concept.label).to eq(:established)
110
+ end
111
+ end
112
+
113
+ describe '#to_h' do
114
+ it 'returns hash with all fields' do
115
+ h = concept.to_h
116
+ expect(h).to include(:id, :name, :domain, :confidence, :properties, :relations, :access_count, :label)
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Memory::Semantic::Helpers::KnowledgeStore do
4
+ subject(:store) { described_class.new }
5
+
6
+ describe '#store' do
7
+ it 'creates a new concept' do
8
+ concept = store.store(name: :dog, domain: :animals)
9
+ expect(concept.name).to eq(:dog)
10
+ expect(store.concept_count).to eq(1)
11
+ end
12
+
13
+ it 'updates existing concept on re-store' do
14
+ store.store(name: :dog, domain: :animals)
15
+ store.store(name: :dog, properties: { legs: 4 })
16
+ expect(store.concept_count).to eq(1)
17
+ expect(store.retrieve(name: :dog).get_property(:legs)).to eq(4)
18
+ end
19
+ end
20
+
21
+ describe '#relate' do
22
+ it 'creates relation between concepts' do
23
+ store.relate(source: :dog, target: :mammal, type: :is_a)
24
+ rels = store.query_relations(name: :dog, type: :is_a)
25
+ expect(rels.size).to eq(1)
26
+ expect(rels.first[:target]).to eq(:mammal)
27
+ end
28
+
29
+ it 'auto-creates concepts that do not exist' do
30
+ store.relate(source: :sparrow, target: :bird, type: :is_a)
31
+ expect(store.concept_count).to eq(2)
32
+ end
33
+ end
34
+
35
+ describe '#retrieve' do
36
+ it 'returns concept and increments access' do
37
+ store.store(name: :dog, domain: :animals)
38
+ concept = store.retrieve(name: :dog)
39
+ expect(concept.access_count).to eq(1)
40
+ end
41
+
42
+ it 'returns nil for unknown concept' do
43
+ expect(store.retrieve(name: :unknown)).to be_nil
44
+ end
45
+
46
+ it 'records retrieval in history' do
47
+ store.store(name: :dog)
48
+ store.retrieve(name: :dog)
49
+ expect(store.retrieval_history.size).to eq(1)
50
+ end
51
+ end
52
+
53
+ describe '#check_is_a' do
54
+ it 'returns true for valid is_a relation' do
55
+ store.relate(source: :dog, target: :mammal, type: :is_a)
56
+ expect(store.check_is_a(:dog, :mammal)).to be true
57
+ end
58
+
59
+ it 'returns false for non-existent relation' do
60
+ store.store(name: :dog)
61
+ expect(store.check_is_a(:dog, :reptile)).to be false
62
+ end
63
+ end
64
+
65
+ describe '#instances_of' do
66
+ it 'finds all instances of a category' do
67
+ store.relate(source: :dog, target: :mammal, type: :is_a)
68
+ store.relate(source: :cat, target: :mammal, type: :is_a)
69
+ store.relate(source: :sparrow, target: :bird, type: :is_a)
70
+ instances = store.instances_of(:mammal)
71
+ expect(instances.map(&:name)).to contain_exactly(:dog, :cat)
72
+ end
73
+ end
74
+
75
+ describe '#spreading_activation' do
76
+ it 'activates seed concept' do
77
+ store.store(name: :dog)
78
+ activated = store.spreading_activation(seed: :dog)
79
+ expect(activated).to have_key(:dog)
80
+ end
81
+
82
+ it 'spreads to related concepts' do
83
+ store.relate(source: :dog, target: :mammal, type: :is_a)
84
+ store.relate(source: :mammal, target: :animal, type: :is_a)
85
+ activated = store.spreading_activation(seed: :dog, hops: 3)
86
+ expect(activated.keys).to include(:dog, :mammal)
87
+ end
88
+
89
+ it 'diminishes activation with each hop' do
90
+ store.relate(source: :dog, target: :mammal, type: :is_a)
91
+ activated = store.spreading_activation(seed: :dog)
92
+ expect(activated[:dog]).to be > activated[:mammal] if activated.key?(:mammal)
93
+ end
94
+ end
95
+
96
+ describe '#concepts_in_domain' do
97
+ it 'returns concepts in specified domain' do
98
+ store.store(name: :dog, domain: :animals)
99
+ store.store(name: :ruby, domain: :programming)
100
+ expect(store.concepts_in_domain(:animals).map(&:name)).to eq([:dog])
101
+ end
102
+ end
103
+
104
+ describe '#search' do
105
+ it 'finds concepts matching query' do
106
+ store.store(name: :golden_retriever)
107
+ store.store(name: :golden_gate)
108
+ store.store(name: :poodle)
109
+ results = store.search(:golden)
110
+ expect(results.size).to eq(2)
111
+ end
112
+ end
113
+
114
+ describe '#decay_all' do
115
+ it 'decays all concepts' do
116
+ store.store(name: :dog, confidence: 0.5)
117
+ store.decay_all
118
+ concept = store.concepts[:dog]
119
+ expect(concept.confidence).to be < 0.5 if concept
120
+ end
121
+
122
+ it 'prunes faded concepts' do
123
+ floor = Legion::Extensions::Agentic::Memory::Semantic::Helpers::Constants::CONFIDENCE_FLOOR
124
+ store.store(name: :weak, confidence: floor + 0.004)
125
+ store.decay_all
126
+ expect(store.concept_count).to eq(0)
127
+ end
128
+ end
129
+
130
+ describe '#to_h' do
131
+ it 'returns stats' do
132
+ store.store(name: :dog, domain: :animals)
133
+ store.relate(source: :dog, target: :mammal, type: :is_a)
134
+ h = store.to_h
135
+ expect(h).to include(:concepts, :relations, :domains, :history_size)
136
+ expect(h[:concepts]).to eq(2)
137
+ expect(h[:relations]).to eq(1)
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Memory::Semantic::Runners::SemanticMemory do
4
+ let(:client) { Legion::Extensions::Agentic::Memory::Semantic::Client.new }
5
+
6
+ describe '#store_concept' do
7
+ it 'stores a concept' do
8
+ result = client.store_concept(name: :dog, domain: :animals)
9
+ expect(result[:success]).to be true
10
+ expect(result[:concept][:name]).to eq(:dog)
11
+ end
12
+ end
13
+
14
+ describe '#relate_concepts' do
15
+ it 'creates a relation' do
16
+ result = client.relate_concepts(source: :dog, target: :mammal, type: :is_a)
17
+ expect(result[:success]).to be true
18
+ expect(result[:type]).to eq(:is_a)
19
+ end
20
+ end
21
+
22
+ describe '#retrieve_concept' do
23
+ it 'retrieves stored concept' do
24
+ client.store_concept(name: :dog, domain: :animals)
25
+ result = client.retrieve_concept(name: :dog)
26
+ expect(result[:found]).to be true
27
+ expect(result[:concept][:name]).to eq(:dog)
28
+ end
29
+
30
+ it 'returns found: false for unknown' do
31
+ result = client.retrieve_concept(name: :unknown)
32
+ expect(result[:found]).to be false
33
+ end
34
+ end
35
+
36
+ describe '#query_concept_relations' do
37
+ it 'returns relations' do
38
+ client.relate_concepts(source: :dog, target: :mammal, type: :is_a)
39
+ result = client.query_concept_relations(name: :dog, type: :is_a)
40
+ expect(result[:count]).to eq(1)
41
+ end
42
+ end
43
+
44
+ describe '#check_category' do
45
+ it 'checks is_a membership' do
46
+ client.relate_concepts(source: :dog, target: :mammal, type: :is_a)
47
+ result = client.check_category(concept: :dog, category: :mammal)
48
+ expect(result[:is_member]).to be true
49
+ end
50
+
51
+ it 'returns false for non-member' do
52
+ client.store_concept(name: :dog)
53
+ result = client.check_category(concept: :dog, category: :reptile)
54
+ expect(result[:is_member]).to be false
55
+ end
56
+ end
57
+
58
+ describe '#find_instances' do
59
+ it 'finds instances of category' do
60
+ client.relate_concepts(source: :dog, target: :mammal, type: :is_a)
61
+ client.relate_concepts(source: :cat, target: :mammal, type: :is_a)
62
+ result = client.find_instances(category: :mammal)
63
+ expect(result[:count]).to eq(2)
64
+ end
65
+ end
66
+
67
+ describe '#activate_spread' do
68
+ it 'spreads activation from seed' do
69
+ client.relate_concepts(source: :dog, target: :mammal, type: :is_a)
70
+ result = client.activate_spread(seed: :dog)
71
+ expect(result[:success]).to be true
72
+ expect(result[:activated]).to have_key(:dog)
73
+ end
74
+ end
75
+
76
+ describe '#concepts_in' do
77
+ it 'returns concepts in domain' do
78
+ client.store_concept(name: :dog, domain: :animals)
79
+ client.store_concept(name: :ruby, domain: :programming)
80
+ result = client.concepts_in(domain: :animals)
81
+ expect(result[:count]).to eq(1)
82
+ expect(result[:concepts]).to eq([:dog])
83
+ end
84
+ end
85
+
86
+ describe '#update_semantic_memory' do
87
+ it 'decays and returns counts' do
88
+ client.store_concept(name: :dog)
89
+ result = client.update_semantic_memory
90
+ expect(result[:success]).to be true
91
+ expect(result).to have_key(:concepts)
92
+ expect(result).to have_key(:relations)
93
+ end
94
+ end
95
+
96
+ describe '#semantic_memory_stats' do
97
+ it 'returns stats' do
98
+ result = client.semantic_memory_stats
99
+ expect(result[:success]).to be true
100
+ expect(result[:stats]).to include(:concepts, :relations, :domains)
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Memory::SemanticPriming::Helpers::Connection do
4
+ subject(:conn) { described_class.new(source_id: 'src-1', target_id: 'tgt-1') }
5
+
6
+ describe '#initialize' do
7
+ it 'assigns a UUID id' do
8
+ expect(conn.id).to match(/\A[0-9a-f-]{36}\z/)
9
+ end
10
+
11
+ it 'sets source and target' do
12
+ expect(conn.source_id).to eq('src-1')
13
+ expect(conn.target_id).to eq('tgt-1')
14
+ end
15
+
16
+ it 'defaults weight to 0.5' do
17
+ expect(conn.weight).to eq(0.5)
18
+ end
19
+
20
+ it 'clamps low weight' do
21
+ low = described_class.new(source_id: 'a', target_id: 'b', weight: 0.0)
22
+ expect(low.weight).to eq(0.05)
23
+ end
24
+ end
25
+
26
+ describe '#strengthen!' do
27
+ it 'increases weight' do
28
+ original = conn.weight
29
+ conn.strengthen!
30
+ expect(conn.weight).to be > original
31
+ end
32
+
33
+ it 'clamps at 1.0' do
34
+ 30.times { conn.strengthen!(amount: 0.1) }
35
+ expect(conn.weight).to eq(1.0)
36
+ end
37
+ end
38
+
39
+ describe '#weaken!' do
40
+ it 'decreases weight' do
41
+ original = conn.weight
42
+ conn.weaken!
43
+ expect(conn.weight).to be < original
44
+ end
45
+ end
46
+
47
+ describe '#traverse!' do
48
+ it 'increments traversal count' do
49
+ conn.traverse!
50
+ expect(conn.traversal_count).to eq(1)
51
+ end
52
+
53
+ it 'strengthens connection' do
54
+ original = conn.weight
55
+ conn.traverse!
56
+ expect(conn.weight).to be > original
57
+ end
58
+ end
59
+
60
+ describe '#spreading_amount' do
61
+ it 'computes spread based on activation and weight' do
62
+ amount = conn.spreading_amount(0.8)
63
+ expect(amount).to be > 0
64
+ expect(amount).to be < 0.8
65
+ end
66
+
67
+ it 'returns zero for zero activation' do
68
+ expect(conn.spreading_amount(0.0)).to eq(0.0)
69
+ end
70
+ end
71
+
72
+ describe '#strong?' do
73
+ it 'is false at default weight' do
74
+ expect(conn.strong?).to be false
75
+ end
76
+
77
+ it 'is true at high weight' do
78
+ high = described_class.new(source_id: 'a', target_id: 'b', weight: 0.8)
79
+ expect(high.strong?).to be true
80
+ end
81
+ end
82
+
83
+ describe '#weight_label' do
84
+ it 'returns a symbol' do
85
+ expect(conn.weight_label).to be_a(Symbol)
86
+ end
87
+ end
88
+
89
+ describe '#to_h' do
90
+ it 'includes all fields' do
91
+ hash = conn.to_h
92
+ expect(hash).to include(
93
+ :id, :source_id, :target_id, :weight, :weight_label,
94
+ :strong, :weak, :traversal_count, :created_at
95
+ )
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,208 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Memory::SemanticPriming::Helpers::PrimingNetwork do
4
+ subject(:network) { described_class.new }
5
+
6
+ let(:doctor) { network.add_node(label: 'doctor') }
7
+ let(:nurse) { network.add_node(label: 'nurse') }
8
+ let(:hospital) { network.add_node(label: 'hospital') }
9
+
10
+ describe '#add_node' do
11
+ it 'creates a semantic node' do
12
+ node = network.add_node(label: 'test')
13
+ expect(node).to be_a(Legion::Extensions::Agentic::Memory::SemanticPriming::Helpers::SemanticNode)
14
+ end
15
+
16
+ it 'stores the node' do
17
+ node = network.add_node(label: 'stored')
18
+ found = network.find_node_by_label(label: 'stored')
19
+ expect(found.id).to eq(node.id)
20
+ end
21
+ end
22
+
23
+ describe '#remove_node' do
24
+ it 'removes the node' do
25
+ node = network.add_node(label: 'remove_me')
26
+ network.remove_node(node_id: node.id)
27
+ expect(network.find_node_by_label(label: 'remove_me')).to be_nil
28
+ end
29
+
30
+ it 'returns nil for unknown node' do
31
+ expect(network.remove_node(node_id: 'nonexistent')).to be_nil
32
+ end
33
+
34
+ it 'removes associated connections' do
35
+ network.connect(source_id: doctor.id, target_id: nurse.id)
36
+ network.remove_node(node_id: doctor.id)
37
+ expect(network.connection_between(source_id: doctor.id, target_id: nurse.id)).to be_nil
38
+ end
39
+ end
40
+
41
+ describe '#connect' do
42
+ it 'creates a connection between nodes' do
43
+ conn = network.connect(source_id: doctor.id, target_id: nurse.id)
44
+ expect(conn).to be_a(Legion::Extensions::Agentic::Memory::SemanticPriming::Helpers::Connection)
45
+ end
46
+
47
+ it 'returns nil for self-connection' do
48
+ expect(network.connect(source_id: doctor.id, target_id: doctor.id)).to be_nil
49
+ end
50
+
51
+ it 'returns nil for unknown nodes' do
52
+ expect(network.connect(source_id: 'bad', target_id: nurse.id)).to be_nil
53
+ end
54
+ end
55
+
56
+ describe '#prime_node' do
57
+ it 'increases node activation' do
58
+ doctor
59
+ network.prime_node(node_id: doctor.id)
60
+ expect(doctor.activation).to be > 0.0
61
+ end
62
+
63
+ it 'returns nil for unknown node' do
64
+ expect(network.prime_node(node_id: 'bad')).to be_nil
65
+ end
66
+ end
67
+
68
+ describe '#prime_and_spread' do
69
+ it 'primes the target and spreads to neighbors' do
70
+ network.connect(source_id: doctor.id, target_id: nurse.id, weight: 0.8)
71
+ result = network.prime_and_spread(node_id: doctor.id, amount: 0.8)
72
+ expect(result[:primed_node][:activation]).to be > 0
73
+ expect(result[:spread].size).to be >= 1
74
+ end
75
+
76
+ it 'spreads activation through multi-hop paths' do
77
+ network.connect(source_id: doctor.id, target_id: nurse.id, weight: 0.9)
78
+ network.connect(source_id: nurse.id, target_id: hospital.id, weight: 0.9)
79
+ network.prime_and_spread(node_id: doctor.id, amount: 0.9)
80
+ expect(hospital.activation).to be > 0
81
+ end
82
+
83
+ it 'returns nil for unknown node' do
84
+ expect(network.prime_and_spread(node_id: 'bad')).to be_nil
85
+ end
86
+ end
87
+
88
+ describe '#spread_activation' do
89
+ it 'activates connected nodes' do
90
+ network.connect(source_id: doctor.id, target_id: nurse.id)
91
+ network.prime_node(node_id: doctor.id, amount: 0.8)
92
+ activated = network.spread_activation(source_id: doctor.id)
93
+ expect(activated.size).to be >= 1
94
+ end
95
+ end
96
+
97
+ describe '#decay_all!' do
98
+ it 'reduces activation on all nodes' do
99
+ network.prime_node(node_id: doctor.id, amount: 0.5)
100
+ network.decay_all!
101
+ expect(doctor.activation).to be < 0.5
102
+ end
103
+ end
104
+
105
+ describe '#reset_all!' do
106
+ it 'resets all activations to zero' do
107
+ network.prime_node(node_id: doctor.id, amount: 0.5)
108
+ network.reset_all!
109
+ expect(doctor.activation).to eq(0.0)
110
+ end
111
+ end
112
+
113
+ describe '#find_node_by_label' do
114
+ it 'finds node by label string' do
115
+ doctor
116
+ found = network.find_node_by_label(label: 'doctor')
117
+ expect(found.id).to eq(doctor.id)
118
+ end
119
+
120
+ it 'returns nil for unknown label' do
121
+ expect(network.find_node_by_label(label: 'nonexistent')).to be_nil
122
+ end
123
+ end
124
+
125
+ describe '#neighbors' do
126
+ it 'returns connected nodes' do
127
+ network.connect(source_id: doctor.id, target_id: nurse.id)
128
+ nbrs = network.neighbors(node_id: doctor.id)
129
+ expect(nbrs.map(&:id)).to include(nurse.id)
130
+ end
131
+ end
132
+
133
+ describe '#connection_between' do
134
+ it 'finds bidirectional connection' do
135
+ network.connect(source_id: doctor.id, target_id: nurse.id)
136
+ conn = network.connection_between(source_id: nurse.id, target_id: doctor.id)
137
+ expect(conn).not_to be_nil
138
+ end
139
+ end
140
+
141
+ describe '#primed_nodes' do
142
+ it 'returns only primed nodes' do
143
+ network.prime_node(node_id: doctor.id, amount: 0.5)
144
+ nurse
145
+ expect(network.primed_nodes.map(&:id)).to include(doctor.id)
146
+ expect(network.primed_nodes.map(&:id)).not_to include(nurse.id)
147
+ end
148
+ end
149
+
150
+ describe '#most_primed' do
151
+ it 'returns nodes sorted by activation descending' do
152
+ network.prime_node(node_id: doctor.id, amount: 0.8)
153
+ network.prime_node(node_id: nurse.id, amount: 0.3)
154
+ top = network.most_primed(limit: 2)
155
+ expect(top.first.id).to eq(doctor.id)
156
+ end
157
+ end
158
+
159
+ describe '#average_activation' do
160
+ it 'returns 0.0 with no nodes' do
161
+ expect(network.average_activation).to eq(0.0)
162
+ end
163
+
164
+ it 'computes mean activation' do
165
+ network.prime_node(node_id: doctor.id, amount: 0.6)
166
+ nurse
167
+ avg = network.average_activation
168
+ expect(avg).to be > 0.0
169
+ expect(avg).to be < 0.6
170
+ end
171
+ end
172
+
173
+ describe '#network_density' do
174
+ it 'returns 0.0 with fewer than 2 nodes' do
175
+ network.add_node(label: 'solo')
176
+ expect(network.network_density).to eq(0.0)
177
+ end
178
+
179
+ it 'increases with more connections' do
180
+ network.connect(source_id: doctor.id, target_id: nurse.id)
181
+ hospital
182
+ density1 = network.network_density
183
+ network.connect(source_id: doctor.id, target_id: hospital.id)
184
+ density2 = network.network_density
185
+ expect(density2).to be > density1
186
+ end
187
+ end
188
+
189
+ describe '#priming_report' do
190
+ it 'returns comprehensive report' do
191
+ doctor
192
+ report = network.priming_report
193
+ expect(report).to include(
194
+ :total_nodes, :total_connections, :primed_count, :active_count,
195
+ :average_activation, :average_weight, :network_density,
196
+ :most_primed, :strongest_connections
197
+ )
198
+ end
199
+ end
200
+
201
+ describe '#to_h' do
202
+ it 'returns summary hash' do
203
+ doctor
204
+ hash = network.to_h
205
+ expect(hash).to include(:total_nodes, :total_connections, :primed_count, :active_count)
206
+ end
207
+ end
208
+ end