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,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Memory
9
+ module Transfer
10
+ module Helpers
11
+ class DomainKnowledge
12
+ attr_reader :id, :domain, :proficiency, :learn_count, :transfer_count
13
+
14
+ PROFICIENCY_LABELS = [
15
+ [0.0, 0.2, 'novice'],
16
+ [0.2, 0.4, 'beginner'],
17
+ [0.4, 0.6, 'intermediate'],
18
+ [0.6, 0.8, 'advanced'],
19
+ [0.8, 1.01, 'expert']
20
+ ].freeze
21
+
22
+ def initialize(domain:)
23
+ @id = SecureRandom.uuid
24
+ @domain = domain
25
+ @proficiency = 0.0
26
+ @learn_count = 0
27
+ @transfer_count = 0
28
+ end
29
+
30
+ def learn!(amount:)
31
+ @proficiency = (@proficiency + amount).clamp(0.0, 1.0).round(10)
32
+ @learn_count += 1
33
+ self
34
+ end
35
+
36
+ def record_transfer!
37
+ @transfer_count += 1
38
+ self
39
+ end
40
+
41
+ def apply_boost!(amount)
42
+ @proficiency = (@proficiency + amount).clamp(0.0, 1.0).round(10)
43
+ self
44
+ end
45
+
46
+ def apply_penalty!(amount)
47
+ @proficiency = (@proficiency - amount).clamp(0.0, 1.0).round(10)
48
+ self
49
+ end
50
+
51
+ def proficiency_label
52
+ PROFICIENCY_LABELS.each do |low, high, label|
53
+ return label if @proficiency >= low && @proficiency < high
54
+ end
55
+ 'novice'
56
+ end
57
+
58
+ def to_h
59
+ {
60
+ id: @id,
61
+ domain: @domain,
62
+ proficiency: @proficiency.round(10),
63
+ proficiency_label: proficiency_label,
64
+ learn_count: @learn_count,
65
+ transfer_count: @transfer_count
66
+ }
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,188 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Memory
7
+ module Transfer
8
+ module Helpers
9
+ class TransferEngine
10
+ include Constants
11
+
12
+ attr_reader :domains, :similarities, :transfer_history
13
+
14
+ def initialize
15
+ @domains = {}
16
+ @similarities = {}
17
+ @transfer_history = []
18
+ end
19
+
20
+ def set_similarity(domain_a:, domain_b:, similarity:)
21
+ sim = similarity.clamp(0.0, 1.0).round(10)
22
+ @similarities[similarity_key(domain_a, domain_b)] = sim
23
+ sim
24
+ end
25
+
26
+ def learn_domain(domain:, amount:)
27
+ check_domain_limit!
28
+ entry = get_or_create_domain(domain)
29
+ entry.learn!(amount: amount.clamp(0.0, 1.0))
30
+ entry.to_h
31
+ end
32
+
33
+ def attempt_transfer(from_domain:, to_domain:)
34
+ source = @domains[from_domain]
35
+ return { status: :source_not_found, from_domain: from_domain } unless source
36
+
37
+ check_domain_limit!
38
+ target = get_or_create_domain(to_domain)
39
+ sim = similarity_between(from_domain, to_domain)
40
+ type = transfer_type(sim)
41
+ distance = transfer_distance(sim)
42
+ effect = apply_transfer_effect!(target, source, type)
43
+ source.record_transfer!
44
+ record_history!(from_domain, to_domain, sim, type, distance, effect)
45
+ build_transfer_result(from_domain, to_domain, sim, type, distance, effect, target)
46
+ end
47
+
48
+ def transfer_effectiveness(from_domain:, to_domain:)
49
+ sim = similarity_between(from_domain, to_domain)
50
+ build_effectiveness(from_domain, to_domain, sim, transfer_type(sim),
51
+ @domains[from_domain], @domains[to_domain])
52
+ end
53
+
54
+ def most_transferable(target_domain:, limit: 5)
55
+ candidates = candidate_rows(target_domain)
56
+ candidates.select { |r| r[:type] == :positive }
57
+ .sort_by { |r| -r[:similarity] }
58
+ .first(limit)
59
+ end
60
+
61
+ def interference_risks(target_domain:)
62
+ candidate_rows(target_domain)
63
+ .select { |r| r[:type] == :interference }
64
+ .sort_by { |r| -r[:similarity] }
65
+ end
66
+
67
+ def transfer_report
68
+ {
69
+ total_transfers: @transfer_history.size,
70
+ positive_transfers: @transfer_history.count { |h| h[:type] == :positive },
71
+ negative_transfers: @transfer_history.count { |h| h[:type] == :negative },
72
+ neutral_transfers: @transfer_history.count { |h| h[:type] == :neutral },
73
+ interference_events: @transfer_history.count { |h| h[:type] == :interference },
74
+ domain_count: @domains.size,
75
+ similarity_pairs: @similarities.size
76
+ }
77
+ end
78
+
79
+ def to_h
80
+ {
81
+ domains: @domains.transform_values(&:to_h),
82
+ similarities: @similarities.dup,
83
+ transfer_history: @transfer_history.dup,
84
+ report: transfer_report
85
+ }
86
+ end
87
+
88
+ private
89
+
90
+ def get_or_create_domain(name)
91
+ @domains[name] ||= DomainKnowledge.new(domain: name)
92
+ end
93
+
94
+ def similarity_key(domain_a, domain_b)
95
+ [domain_a, domain_b].sort.join(':')
96
+ end
97
+
98
+ def similarity_between(domain_a, domain_b)
99
+ @similarities[similarity_key(domain_a, domain_b)] || 0.0
100
+ end
101
+
102
+ def transfer_type(similarity)
103
+ if similarity >= POSITIVE_TRANSFER_THRESHOLD then :positive
104
+ elsif similarity >= NEGATIVE_TRANSFER_THRESHOLD then :interference
105
+ elsif similarity > 0.0 then :negative
106
+ else :neutral
107
+ end
108
+ end
109
+
110
+ def transfer_distance(similarity)
111
+ if similarity >= POSITIVE_TRANSFER_THRESHOLD then :near
112
+ elsif similarity >= NEGATIVE_TRANSFER_THRESHOLD then :moderate
113
+ else :far
114
+ end
115
+ end
116
+
117
+ def apply_transfer_effect!(target, source, type)
118
+ case type
119
+ when :positive
120
+ scaled = (source.proficiency * TRANSFER_BOOST).round(10)
121
+ target.apply_boost!(scaled)
122
+ scaled
123
+ when :interference
124
+ penalty = (source.proficiency * INTERFERENCE_PENALTY).round(10)
125
+ target.apply_penalty!(penalty)
126
+ -penalty
127
+ else
128
+ 0.0
129
+ end
130
+ end
131
+
132
+ def record_history!(from_domain, to_domain, sim, type, distance, effect)
133
+ @transfer_history << {
134
+ from_domain: from_domain,
135
+ to_domain: to_domain,
136
+ similarity: sim.round(10),
137
+ type: type,
138
+ distance: distance,
139
+ effect: effect,
140
+ at: Time.now.utc
141
+ }
142
+ end
143
+
144
+ def check_domain_limit!
145
+ raise "domain limit of #{MAX_DOMAINS} reached" if @domains.size >= MAX_DOMAINS
146
+ end
147
+
148
+ def candidate_rows(target_domain)
149
+ @domains.reject { |name, _| name == target_domain }.map do |name, entry|
150
+ sim = similarity_between(name, target_domain)
151
+ type = transfer_type(sim)
152
+ { domain: name, proficiency: entry.proficiency.round(10), similarity: sim.round(10), type: type }
153
+ end
154
+ end
155
+
156
+ def build_transfer_result(from_domain, to_domain, sim, type, distance, effect, target)
157
+ {
158
+ status: :ok,
159
+ from_domain: from_domain,
160
+ to_domain: to_domain,
161
+ similarity: sim.round(10),
162
+ type: type,
163
+ distance: distance,
164
+ effect: effect,
165
+ proficiency: target.proficiency.round(10)
166
+ }
167
+ end
168
+
169
+ def build_effectiveness(from_domain, to_domain, sim, type, source, target)
170
+ {
171
+ from_domain: from_domain,
172
+ to_domain: to_domain,
173
+ similarity: sim.round(10),
174
+ type: type,
175
+ type_label: TRANSFER_LABELS[type],
176
+ distance: transfer_distance(sim),
177
+ distance_label: DISTANCE_LABELS[transfer_distance(sim)],
178
+ source_proficiency: source&.proficiency&.round(10) || 0.0,
179
+ target_proficiency: target&.proficiency&.round(10) || 0.0
180
+ }
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Memory
7
+ module Transfer
8
+ module Runners
9
+ module TransferLearning
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex)
12
+
13
+ def learn_domain(domain:, amount:, **)
14
+ result = transfer_engine.learn_domain(domain: domain, amount: amount)
15
+ Legion::Logging.info "[transfer_learning] learn: domain=#{domain} amount=#{amount} proficiency=#{result[:proficiency]}"
16
+ result
17
+ end
18
+
19
+ def attempt_transfer(from_domain:, to_domain:, **)
20
+ result = transfer_engine.attempt_transfer(from_domain: from_domain, to_domain: to_domain)
21
+ Legion::Logging.info "[transfer_learning] transfer: from=#{from_domain} to=#{to_domain} type=#{result[:type]} effect=#{result[:effect]}"
22
+ result
23
+ end
24
+
25
+ def set_similarity(domain_a:, domain_b:, similarity:, **)
26
+ sim = transfer_engine.set_similarity(domain_a: domain_a, domain_b: domain_b, similarity: similarity)
27
+ Legion::Logging.debug "[transfer_learning] similarity set: #{domain_a}<->#{domain_b} similarity=#{sim}"
28
+ { domain_a: domain_a, domain_b: domain_b, similarity: sim }
29
+ end
30
+
31
+ def transfer_effectiveness(from_domain:, to_domain:, **)
32
+ result = transfer_engine.transfer_effectiveness(from_domain: from_domain, to_domain: to_domain)
33
+ Legion::Logging.debug "[transfer_learning] effectiveness: from=#{from_domain} to=#{to_domain} type=#{result[:type]}"
34
+ result
35
+ end
36
+
37
+ def most_transferable(target_domain:, limit: 5, **)
38
+ candidates = transfer_engine.most_transferable(target_domain: target_domain, limit: limit)
39
+ Legion::Logging.debug "[transfer_learning] most_transferable: target=#{target_domain} found=#{candidates.size}"
40
+ { target_domain: target_domain, candidates: candidates, count: candidates.size }
41
+ end
42
+
43
+ def interference_risks(target_domain:, **)
44
+ risks = transfer_engine.interference_risks(target_domain: target_domain)
45
+ Legion::Logging.debug "[transfer_learning] interference_risks: target=#{target_domain} risks=#{risks.size}"
46
+ { target_domain: target_domain, risks: risks, count: risks.size }
47
+ end
48
+
49
+ def transfer_report(**)
50
+ report = transfer_engine.transfer_report
51
+ Legion::Logging.debug "[transfer_learning] report: domains=#{report[:domain_count]} transfers=#{report[:total_transfers]}"
52
+ report
53
+ end
54
+
55
+ def get_domain(domain:, **)
56
+ entry = transfer_engine.domains[domain]
57
+ if entry
58
+ Legion::Logging.debug "[transfer_learning] get_domain: domain=#{domain} proficiency=#{entry.proficiency}"
59
+ { found: true, domain: entry.to_h }
60
+ else
61
+ Legion::Logging.debug "[transfer_learning] get_domain: domain=#{domain} not found"
62
+ { found: false, domain: domain }
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def transfer_engine
69
+ @transfer_engine ||= Helpers::TransferEngine.new
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Memory
7
+ module Transfer
8
+ VERSION = '0.1.0'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/memory/transfer/version'
4
+ require 'legion/extensions/agentic/memory/transfer/helpers/constants'
5
+ require 'legion/extensions/agentic/memory/transfer/helpers/domain_knowledge'
6
+ require 'legion/extensions/agentic/memory/transfer/helpers/transfer_engine'
7
+ require 'legion/extensions/agentic/memory/transfer/runners/transfer_learning'
8
+ require 'legion/extensions/agentic/memory/transfer/client'
9
+
10
+ module Legion
11
+ module Extensions
12
+ module Agentic
13
+ module Memory
14
+ module Transfer
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Memory
7
+ VERSION = '0.1.0'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'memory/version'
4
+ require_relative 'memory/archaeology'
5
+ require_relative 'memory/paleontology'
6
+ require_relative 'memory/palimpsest'
7
+ require_relative 'memory/compression'
8
+ require_relative 'memory/hologram'
9
+ require_relative 'memory/offloading'
10
+ require_relative 'memory/nostalgia'
11
+ require_relative 'memory/echo'
12
+ require_relative 'memory/echo_chamber'
13
+ require_relative 'memory/immune_memory'
14
+ require_relative 'memory/reserve'
15
+ require_relative 'memory/trace'
16
+ require_relative 'memory/episodic'
17
+ require_relative 'memory/semantic'
18
+ require_relative 'memory/semantic_priming'
19
+ require_relative 'memory/semantic_satiation'
20
+ require_relative 'memory/source_monitoring'
21
+ require_relative 'memory/transfer'
22
+
23
+ module Legion
24
+ module Extensions
25
+ module Agentic
26
+ module Memory
27
+ extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
28
+
29
+ def remote_invocable?
30
+ false
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Memory::Archaeology::Client do
4
+ let(:client) { described_class.new }
5
+
6
+ it 'creates with default engine' do
7
+ expect(client).to respond_to(:create_site)
8
+ end
9
+
10
+ describe '#create_site' do
11
+ it 'delegates to runner' do
12
+ result = client.create_site(domain: :cognitive)
13
+ expect(result[:success]).to be true
14
+ end
15
+ end
16
+
17
+ describe '#excavate' do
18
+ it 'delegates to runner' do
19
+ site_result = client.create_site(domain: :cognitive)
20
+ result = client.excavate(site_id: site_result[:site][:id])
21
+ expect(result[:success]).to be true
22
+ end
23
+ end
24
+
25
+ describe '#list_artifacts' do
26
+ it 'returns empty list' do
27
+ result = client.list_artifacts
28
+ expect(result[:count]).to eq 0
29
+ end
30
+ end
31
+
32
+ describe '#archaeology_status' do
33
+ it 'returns report' do
34
+ result = client.archaeology_status
35
+ expect(result[:report]).to be_a Hash
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Memory::Archaeology do
4
+ it 'has a version number' do
5
+ expect(described_class::VERSION).to eq '0.1.0'
6
+ end
7
+ end
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Memory::Archaeology::Helpers::ArchaeologyEngine do
4
+ let(:engine) { described_class.new }
5
+
6
+ describe '#create_site' do
7
+ it 'creates a site with the given domain' do
8
+ site = engine.create_site(domain: :cognitive)
9
+ expect(site.domain).to eq :cognitive
10
+ end
11
+
12
+ it 'tracks site in all_sites' do
13
+ engine.create_site(domain: :cognitive)
14
+ expect(engine.all_sites.size).to eq 1
15
+ end
16
+
17
+ it 'raises on invalid domain' do
18
+ expect { engine.create_site(domain: :bogus) }.to raise_error(ArgumentError)
19
+ end
20
+ end
21
+
22
+ describe '#dig' do
23
+ let(:site) { engine.create_site(domain: :cognitive) }
24
+
25
+ it 'returns hash with site survey and dug status' do
26
+ result = engine.dig(site_id: site.id)
27
+ expect(result[:dug]).to be true
28
+ expect(result[:site]).to be_a Hash
29
+ end
30
+
31
+ it 'raises for unknown site_id' do
32
+ expect { engine.dig(site_id: 'bad') }.to raise_error(ArgumentError, /site not found/)
33
+ end
34
+ end
35
+
36
+ describe '#excavate' do
37
+ let(:site) { engine.create_site(domain: :cognitive) }
38
+
39
+ it 'returns an Artifact' do
40
+ expect(engine.excavate(site_id: site.id)).to be_a(
41
+ Legion::Extensions::Agentic::Memory::Archaeology::Helpers::Artifact
42
+ )
43
+ end
44
+
45
+ it 'tracks artifact in all_artifacts' do
46
+ engine.excavate(site_id: site.id)
47
+ expect(engine.all_artifacts.size).to eq 1
48
+ end
49
+ end
50
+
51
+ describe '#restore_artifact' do
52
+ it 'boosts preservation' do
53
+ site = engine.create_site(domain: :cognitive)
54
+ a = engine.excavate(site_id: site.id)
55
+ a.decay!(rate: 0.3)
56
+ original = a.preservation
57
+ engine.restore_artifact(artifact_id: a.id, boost: 0.2)
58
+ expect(a.preservation).to be > original
59
+ end
60
+
61
+ it 'raises for unknown artifact_id' do
62
+ expect { engine.restore_artifact(artifact_id: 'bad') }.to raise_error(ArgumentError)
63
+ end
64
+ end
65
+
66
+ describe '#decay_all!' do
67
+ it 'reduces preservation on all artifacts' do
68
+ site = engine.create_site(domain: :cognitive)
69
+ a = engine.excavate(site_id: site.id)
70
+ original = a.preservation
71
+ engine.decay_all!
72
+ expect(a.preservation).to be < original
73
+ end
74
+
75
+ it 'prunes artifacts that reach 0.0' do
76
+ site = engine.create_site(domain: :cognitive)
77
+ a = engine.excavate(site_id: site.id)
78
+ a.instance_variable_set(:@preservation_quality, 0.01)
79
+ engine.decay_all!(rate: 0.5)
80
+ expect(engine.all_artifacts).not_to include(a)
81
+ end
82
+
83
+ it 'returns remaining artifact count' do
84
+ site = engine.create_site(domain: :cognitive)
85
+ engine.excavate(site_id: site.id)
86
+ expect(engine.decay_all!).to be_a Integer
87
+ end
88
+ end
89
+
90
+ describe '#artifacts_by_type' do
91
+ it 'filters by artifact_type' do
92
+ site = engine.create_site(domain: :cognitive)
93
+ 3.times { engine.excavate(site_id: site.id) }
94
+ first_type = engine.all_artifacts.first.artifact_type
95
+ results = engine.artifacts_by_type(first_type)
96
+ expect(results).to all(have_attributes(artifact_type: first_type))
97
+ end
98
+ end
99
+
100
+ describe '#artifacts_by_domain' do
101
+ it 'returns matching artifacts' do
102
+ site = engine.create_site(domain: :cognitive)
103
+ engine.excavate(site_id: site.id)
104
+ expect(engine.artifacts_by_domain(:cognitive).size).to eq 1
105
+ end
106
+
107
+ it 'returns empty for non-matching domain' do
108
+ site = engine.create_site(domain: :cognitive)
109
+ engine.excavate(site_id: site.id)
110
+ expect(engine.artifacts_by_domain(:emotional)).to be_empty
111
+ end
112
+ end
113
+
114
+ describe '#best_preserved' do
115
+ it 'returns artifacts sorted by preservation descending' do
116
+ site = engine.create_site(domain: :cognitive)
117
+ 5.times { engine.excavate(site_id: site.id) }
118
+ best = engine.best_preserved(limit: 3)
119
+ preservations = best.map(&:preservation)
120
+ expect(preservations).to eq preservations.sort.reverse
121
+ end
122
+ end
123
+
124
+ describe '#most_fragile' do
125
+ it 'returns only fragments' do
126
+ site = engine.create_site(domain: :cognitive)
127
+ 3.times { engine.excavate(site_id: site.id) }
128
+ engine.all_artifacts.first.instance_variable_set(:@preservation_quality, 0.1)
129
+ fragile = engine.most_fragile
130
+ expect(fragile).to all(be_fragment)
131
+ end
132
+ end
133
+
134
+ describe '#site_report' do
135
+ it 'returns site data with artifacts' do
136
+ site = engine.create_site(domain: :cognitive)
137
+ engine.excavate(site_id: site.id)
138
+ report = engine.site_report(site_id: site.id)
139
+ expect(report).to have_key(:artifacts)
140
+ end
141
+ end
142
+
143
+ describe '#archaeology_report' do
144
+ it 'returns comprehensive report' do
145
+ site = engine.create_site(domain: :cognitive)
146
+ engine.excavate(site_id: site.id)
147
+ report = engine.archaeology_report
148
+ %i[total_artifacts total_sites type_breakdown domain_breakdown
149
+ depth_breakdown avg_preservation avg_integrity fragment_count
150
+ ancient_count sites].each do |key|
151
+ expect(report).to have_key(key)
152
+ end
153
+ end
154
+
155
+ it 'returns correct counts' do
156
+ site = engine.create_site(domain: :cognitive)
157
+ 3.times { engine.excavate(site_id: site.id) }
158
+ expect(engine.archaeology_report[:total_artifacts]).to eq 3
159
+ end
160
+
161
+ it 'works empty' do
162
+ expect(engine.archaeology_report[:total_artifacts]).to eq 0
163
+ end
164
+ end
165
+ end