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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 67778a6febdad1ae0a13004c17e1b3ddc045b49d634771aace21c103b0f6dd61
4
+ data.tar.gz: cc2bf829f1148699ef2a125239c6ab61095237c7fe74214aefbe9461692f0a20
5
+ SHA512:
6
+ metadata.gz: 819f261ce1f0695201afe3baf912ea5250401940c124289e82d68b9a1c1e209988663c6bbbc75d92638ce9d594dcb688bcdc32bfd555491f5de7f96ebbe078a9
7
+ data.tar.gz: cf7a2eabc74347b03e5c3275a61f3ba44667225533cce82f943fd5e7a948a7ae04e88f5b04f660b573ab23bce15a71a01964d4dbc8c756917fe227e944700e66
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased]
4
+
5
+ ## [0.1.0] - 2026-03-18
6
+
7
+ ### Added
8
+ - Initial release as domain consolidation gem
9
+ - Consolidated source extensions into unified domain gem under `Legion::Extensions::Agentic::<Domain>`
10
+ - All sub-modules loaded from single entry point
11
+ - Full spec suite with zero failures
12
+ - RuboCop compliance across all files
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Matthew Iverson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,13 @@
1
+ # lex-agentic-memory
2
+
3
+ LEX agentic memory domain: episodic, semantic, and working memory
4
+
5
+ ## Sub-modules
6
+
7
+ *(populated as extensions are consolidated)*
8
+
9
+ ## Installation
10
+
11
+ ```ruby
12
+ gem 'lex-agentic-memory'
13
+ ```
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/legion/extensions/agentic/memory/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'lex-agentic-memory'
7
+ spec.version = Legion::Extensions::Agentic::Memory::VERSION
8
+ spec.authors = ['Esity']
9
+ spec.email = ['matthewdiverson@gmail.com']
10
+
11
+ spec.summary = 'LEX Agentic Memory'
12
+ spec.description = 'LEX agentic memory domain: episodic, semantic, and working memory'
13
+ spec.homepage = 'https://github.com/LegionIO/lex-agentic-memory'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 3.4'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = spec.homepage
19
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
20
+ spec.metadata['rubygems_mfa_required'] = 'true'
21
+
22
+ spec.files = Dir.chdir(__dir__) do
23
+ Dir.glob('{lib,spec}/**/*.rb') + %w[lex-agentic-memory.gemspec Gemfile LICENSE README.md CHANGELOG.md]
24
+ end
25
+ spec.require_paths = ['lib']
26
+
27
+ spec.add_development_dependency 'rspec', '~> 3.13'
28
+ spec.add_development_dependency 'rubocop', '~> 1.60'
29
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.26'
30
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Memory
7
+ module Archaeology
8
+ class Client
9
+ include Runners::CognitiveArchaeology
10
+
11
+ def initialize(engine: nil)
12
+ @default_engine = engine || Helpers::ArchaeologyEngine.new
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Memory
7
+ module Archaeology
8
+ module Helpers
9
+ class ArchaeologyEngine
10
+ def initialize
11
+ @sites = {}
12
+ @artifacts = {}
13
+ end
14
+
15
+ def create_site(domain:)
16
+ validate_site_capacity!
17
+ site = ExcavationSite.new(domain: domain)
18
+ @sites[site.id] = site
19
+ site
20
+ end
21
+
22
+ def dig(site_id:)
23
+ site = fetch_site!(site_id)
24
+ dug = site.dig_deeper!
25
+ { site: site.survey, dug: dug }
26
+ end
27
+
28
+ def excavate(site_id:)
29
+ site = fetch_site!(site_id)
30
+ validate_artifact_capacity!
31
+ artifact = site.excavate!
32
+ @artifacts[artifact.id] = artifact
33
+ artifact
34
+ end
35
+
36
+ def restore_artifact(artifact_id:, boost: 0.15)
37
+ artifact = fetch_artifact!(artifact_id)
38
+ artifact.restore!(boost: boost)
39
+ artifact
40
+ end
41
+
42
+ def decay_all!(rate: Constants::PRESERVATION_DECAY)
43
+ @artifacts.each_value { |a| a.decay!(rate: rate) }
44
+ prune_dust!
45
+ @artifacts.size
46
+ end
47
+
48
+ def artifacts_by_type(type)
49
+ @artifacts.values.select { |a| a.artifact_type == type.to_sym }
50
+ end
51
+
52
+ def artifacts_by_domain(domain)
53
+ @artifacts.values.select { |a| a.domain == domain.to_sym }
54
+ end
55
+
56
+ def artifacts_by_depth(depth_level)
57
+ @artifacts.values.select do |a|
58
+ a.depth_level == depth_level.to_sym
59
+ end
60
+ end
61
+
62
+ def best_preserved(limit: 10)
63
+ @artifacts.values.sort_by { |a| -a.preservation }.first(limit)
64
+ end
65
+
66
+ def most_fragile(limit: 10)
67
+ @artifacts.values
68
+ .select(&:fragment?)
69
+ .sort_by(&:preservation)
70
+ .first(limit)
71
+ end
72
+
73
+ def site_report(site_id:)
74
+ fetch_site!(site_id).to_h
75
+ end
76
+
77
+ def archaeology_report
78
+ {
79
+ total_artifacts: @artifacts.size,
80
+ total_sites: @sites.size,
81
+ type_breakdown: type_breakdown,
82
+ domain_breakdown: domain_breakdown,
83
+ depth_breakdown: depth_breakdown,
84
+ avg_preservation: avg_preservation,
85
+ avg_integrity: avg_integrity,
86
+ fragment_count: @artifacts.values.count(&:fragment?),
87
+ ancient_count: @artifacts.values.count(&:ancient?),
88
+ sites: @sites.values.map { |s| site_summary(s) }
89
+ }
90
+ end
91
+
92
+ def all_artifacts
93
+ @artifacts.values
94
+ end
95
+
96
+ def all_sites
97
+ @sites.values
98
+ end
99
+
100
+ private
101
+
102
+ def fetch_site!(site_id)
103
+ @sites.fetch(site_id) do
104
+ raise ArgumentError, "site not found: #{site_id.inspect}"
105
+ end
106
+ end
107
+
108
+ def fetch_artifact!(artifact_id)
109
+ @artifacts.fetch(artifact_id) do
110
+ raise ArgumentError,
111
+ "artifact not found: #{artifact_id.inspect}"
112
+ end
113
+ end
114
+
115
+ def validate_site_capacity!
116
+ return if @sites.size < Constants::MAX_SITES
117
+
118
+ raise ArgumentError,
119
+ "site capacity reached (max #{Constants::MAX_SITES})"
120
+ end
121
+
122
+ def validate_artifact_capacity!
123
+ return if @artifacts.size < Constants::MAX_ARTIFACTS
124
+
125
+ raise ArgumentError,
126
+ "artifact capacity reached (max #{Constants::MAX_ARTIFACTS})"
127
+ end
128
+
129
+ def prune_dust!
130
+ @artifacts.delete_if { |_, a| a.preservation <= 0.0 }
131
+ end
132
+
133
+ def type_breakdown
134
+ count_by(:artifact_type, Constants::ARTIFACT_TYPES)
135
+ end
136
+
137
+ def domain_breakdown
138
+ count_by(:domain, Constants::DOMAIN_TYPES)
139
+ end
140
+
141
+ def depth_breakdown
142
+ count_by(:depth_level, Constants::EXCAVATION_DEPTH_LEVELS)
143
+ end
144
+
145
+ def count_by(attr, values)
146
+ values.to_h do |v|
147
+ [v, @artifacts.values.count { |a| a.public_send(attr) == v }]
148
+ end
149
+ end
150
+
151
+ def avg_preservation
152
+ return 0.0 if @artifacts.empty?
153
+
154
+ (@artifacts.values.sum(&:preservation) / @artifacts.size).round(10)
155
+ end
156
+
157
+ def avg_integrity
158
+ return 0.0 if @artifacts.empty?
159
+
160
+ (@artifacts.values.sum(&:integrity) / @artifacts.size).round(10)
161
+ end
162
+
163
+ def site_summary(site)
164
+ site.survey.merge(
165
+ depth_progress: depth_progress(site),
166
+ artifact_types: site.artifacts_found
167
+ .each_with_object(Hash.new(0)) do |a, h|
168
+ h[a.artifact_type] += 1
169
+ end
170
+ )
171
+ end
172
+
173
+ def depth_progress(site)
174
+ idx = Constants::EXCAVATION_DEPTH_LEVELS.index(site.current_depth)
175
+ total = Constants::EXCAVATION_DEPTH_LEVELS.size - 1
176
+ total.zero? ? 1.0 : (idx.to_f / total).round(4)
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Memory
9
+ module Archaeology
10
+ module Helpers
11
+ class Artifact
12
+ attr_reader :id, :artifact_type, :domain, :content, :depth_level,
13
+ :discovered_at, :origin_epoch, :contextual_links
14
+
15
+ attr_accessor :preservation_quality, :integrity
16
+
17
+ alias type artifact_type
18
+
19
+ def initialize(type:, domain:, content:, depth_level:,
20
+ preservation: nil, integrity: nil,
21
+ origin_epoch: nil, contextual_links: nil)
22
+ validate_type!(type)
23
+ validate_domain!(domain)
24
+ validate_depth!(depth_level)
25
+
26
+ @id = SecureRandom.uuid
27
+ @artifact_type = type.to_sym
28
+ @domain = domain.to_sym
29
+ @content = content.to_s
30
+ @depth_level = depth_level.to_sym
31
+ pres = (preservation || Constants::DEFAULT_PRESERVATION).to_f
32
+ @preservation_quality = pres.clamp(0.0, 1.0).round(10)
33
+ @integrity = (integrity || derive_integrity).clamp(0.0, 1.0).round(10)
34
+ @discovered_at = Time.now.utc
35
+ @origin_epoch = origin_epoch || (Time.now.utc - rand(0..31_536_000))
36
+ @contextual_links = Array(contextual_links).dup
37
+ end
38
+
39
+ def preservation
40
+ @preservation_quality
41
+ end
42
+
43
+ def preservation=(val)
44
+ @preservation_quality = val.to_f.clamp(0.0, 1.0).round(10)
45
+ end
46
+
47
+ def decay!(rate: Constants::PRESERVATION_DECAY)
48
+ @preservation_quality = (@preservation_quality - rate.abs).clamp(0.0, 1.0).round(10)
49
+ @integrity = (@integrity - (rate.abs * 0.5)).clamp(0.0, 1.0).round(10)
50
+ self
51
+ end
52
+
53
+ def restore!(boost: 0.15)
54
+ @preservation_quality = (@preservation_quality + boost.abs).clamp(0.0, 1.0).round(10)
55
+ @integrity = (@integrity + (boost.abs * 0.5)).clamp(0.0, 1.0).round(10)
56
+ self
57
+ end
58
+
59
+ def fragment?
60
+ @preservation_quality < 0.3
61
+ end
62
+
63
+ def well_preserved?
64
+ @preservation_quality > 0.7
65
+ end
66
+
67
+ def ancient?
68
+ (Time.now.utc - @origin_epoch) > 15_552_000
69
+ end
70
+
71
+ def preservation_label
72
+ match_label(Constants::PRESERVATION_LABELS, @preservation_quality)
73
+ end
74
+
75
+ def integrity_label
76
+ match_label(Constants::INTEGRITY_LABELS, @integrity)
77
+ end
78
+
79
+ def link_to(other_id)
80
+ @contextual_links << other_id unless @contextual_links.include?(other_id)
81
+ end
82
+
83
+ def to_h
84
+ {
85
+ id: @id,
86
+ type: @artifact_type,
87
+ artifact_type: @artifact_type,
88
+ domain: @domain,
89
+ content: @content,
90
+ depth_level: @depth_level,
91
+ preservation: @preservation_quality,
92
+ preservation_quality: @preservation_quality,
93
+ preservation_label: preservation_label,
94
+ integrity: @integrity,
95
+ integrity_label: integrity_label,
96
+ discovered_at: @discovered_at,
97
+ origin_epoch: @origin_epoch,
98
+ contextual_links: @contextual_links,
99
+ fragment: fragment?,
100
+ well_preserved: well_preserved?,
101
+ ancient: ancient?
102
+ }
103
+ end
104
+
105
+ private
106
+
107
+ def derive_integrity
108
+ depth_mod = Constants::DEPTH_PRESERVATION_MODIFIER.fetch(@depth_level, 0.0)
109
+ (0.8 + depth_mod + rand(-0.1..0.1)).clamp(0.0, 1.0)
110
+ end
111
+
112
+ def validate_type!(type_val)
113
+ return if Constants::ARTIFACT_TYPES.include?(type_val.to_sym)
114
+
115
+ raise ArgumentError,
116
+ "unknown artifact type: #{type_val.inspect}; " \
117
+ "must be one of #{Constants::ARTIFACT_TYPES.inspect}"
118
+ end
119
+
120
+ def validate_domain!(domain_val)
121
+ return if Constants::DOMAIN_TYPES.include?(domain_val.to_sym)
122
+
123
+ raise ArgumentError,
124
+ "unknown domain: #{domain_val.inspect}; " \
125
+ "must be one of #{Constants::DOMAIN_TYPES.inspect}"
126
+ end
127
+
128
+ def validate_depth!(depth_val)
129
+ return if Constants::EXCAVATION_DEPTH_LEVELS.include?(depth_val.to_sym)
130
+
131
+ raise ArgumentError,
132
+ "unknown depth level: #{depth_val.inspect}; " \
133
+ "must be one of #{Constants::EXCAVATION_DEPTH_LEVELS.inspect}"
134
+ end
135
+
136
+ def match_label(label_table, value)
137
+ label_table.each { |range, label| return label if range.cover?(value) }
138
+ label_table.last.last
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Memory
7
+ module Archaeology
8
+ module Helpers
9
+ module Constants
10
+ MAX_ARTIFACTS = 500
11
+ MAX_SITES = 50
12
+ DEFAULT_PRESERVATION = 0.5
13
+ PRESERVATION_DECAY = 0.02
14
+ SEDIMENT_DENSITY_DEFAULT = 0.5
15
+
16
+ ARTIFACT_TYPES = %i[
17
+ pattern skill knowledge memory_fragment
18
+ association procedure belief schema
19
+ ].freeze
20
+
21
+ DOMAIN_TYPES = %i[
22
+ cognitive emotional procedural semantic
23
+ episodic social creative analytical
24
+ ].freeze
25
+
26
+ EXCAVATION_DEPTH_LEVELS = %i[surface shallow mid deep bedrock].freeze
27
+
28
+ EPOCH_NAMES = %i[
29
+ genesis formation expansion consolidation
30
+ crisis renewal maturation current
31
+ ].freeze
32
+
33
+ DEPTH_PRESERVATION_MODIFIER = {
34
+ surface: 0.0,
35
+ shallow: -0.1,
36
+ mid: -0.2,
37
+ deep: -0.35,
38
+ bedrock: -0.5
39
+ }.freeze
40
+
41
+ DEPTH_RARITY_WEIGHTS = {
42
+ surface: { pattern: 3, skill: 2, knowledge: 3, memory_fragment: 5,
43
+ association: 3, procedure: 2, belief: 1, schema: 1 },
44
+ shallow: { pattern: 3, skill: 3, knowledge: 3, memory_fragment: 4,
45
+ association: 3, procedure: 3, belief: 1, schema: 1 },
46
+ mid: { pattern: 2, skill: 3, knowledge: 3, memory_fragment: 3,
47
+ association: 3, procedure: 3, belief: 2, schema: 2 },
48
+ deep: { pattern: 1, skill: 2, knowledge: 2, memory_fragment: 2,
49
+ association: 2, procedure: 3, belief: 3, schema: 3 },
50
+ bedrock: { pattern: 1, skill: 1, knowledge: 1, memory_fragment: 1,
51
+ association: 1, procedure: 2, belief: 4, schema: 4 }
52
+ }.freeze
53
+
54
+ PRESERVATION_LABELS = [
55
+ [0.0..0.2, :dust],
56
+ [0.2..0.4, :fragmented],
57
+ [0.4..0.6, :partial],
58
+ [0.6..0.8, :intact],
59
+ [0.8..1.0, :pristine]
60
+ ].freeze
61
+
62
+ INTEGRITY_LABELS = [
63
+ [0.0..0.3, :corrupted],
64
+ [0.3..0.6, :degraded],
65
+ [0.6..0.8, :coherent],
66
+ [0.8..1.0, :complete]
67
+ ].freeze
68
+
69
+ DENSITY_LABELS = [
70
+ [0.0..0.2, :friable],
71
+ [0.2..0.4, :loose],
72
+ [0.4..0.6, :moderate],
73
+ [0.6..0.8, :dense],
74
+ [0.8..1.0, :compacted]
75
+ ].freeze
76
+
77
+ DEPTH_LABELS = {
78
+ surface: 'Surface Layer (recent, well-preserved)',
79
+ shallow: 'Shallow Layer (familiar but fading)',
80
+ mid: 'Mid Layer (semi-dormant knowledge)',
81
+ deep: 'Deep Layer (long-dormant patterns)',
82
+ bedrock: 'Bedrock Layer (foundational cognitive strata)'
83
+ }.freeze
84
+
85
+ def self.label_for(table, value)
86
+ table.each { |range, label| return label if range.cover?(value) }
87
+ table.last.last
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Memory
7
+ module Archaeology
8
+ module Helpers
9
+ class ExcavationSite
10
+ include Constants
11
+
12
+ attr_reader :id, :domain, :current_depth, :artifacts_found, :created_at
13
+
14
+ alias started_at created_at
15
+
16
+ def initialize(domain:)
17
+ validate_domain!(domain)
18
+ @id = SecureRandom.uuid
19
+ @domain = domain.to_sym
20
+ @current_depth = :surface
21
+ @artifacts_found = []
22
+ @created_at = Time.now.utc
23
+ end
24
+
25
+ def dig_deeper!
26
+ idx = EXCAVATION_DEPTH_LEVELS.index(@current_depth) || 0
27
+ return false if idx >= EXCAVATION_DEPTH_LEVELS.size - 1
28
+
29
+ @current_depth = EXCAVATION_DEPTH_LEVELS[idx + 1]
30
+ true
31
+ end
32
+
33
+ def complete?
34
+ @current_depth == EXCAVATION_DEPTH_LEVELS.last
35
+ end
36
+
37
+ def excavate!
38
+ weights = DEPTH_RARITY_WEIGHTS.fetch(@current_depth, {})
39
+ art_type = weighted_pick(weights)
40
+ artifact = Artifact.new(type: art_type, domain: @domain,
41
+ content: "#{art_type} from #{@current_depth}",
42
+ depth_level: @current_depth,
43
+ preservation: compute_base_preservation)
44
+ @artifacts_found << artifact
45
+ artifact
46
+ end
47
+
48
+ def survey
49
+ {
50
+ id: @id,
51
+ domain: @domain,
52
+ current_depth: @current_depth,
53
+ depth_label: DEPTH_LABELS.fetch(@current_depth, 'Unknown'),
54
+ artifacts_count: @artifacts_found.size,
55
+ complete: complete?,
56
+ started_at: @created_at.iso8601
57
+ }
58
+ end
59
+
60
+ def to_h
61
+ survey.merge(artifacts: @artifacts_found.map(&:to_h))
62
+ end
63
+
64
+ private
65
+
66
+ def validate_domain!(domain_val)
67
+ return if DOMAIN_TYPES.include?(domain_val.to_sym)
68
+
69
+ raise ArgumentError,
70
+ "unknown domain: #{domain_val.inspect}; " \
71
+ "must be one of #{DOMAIN_TYPES.inspect}"
72
+ end
73
+
74
+ def weighted_pick(weights)
75
+ total = weights.values.sum
76
+ return ARTIFACT_TYPES.sample if total.zero?
77
+
78
+ roll = rand(total)
79
+ cumulative = 0
80
+ weights.each do |type, weight|
81
+ cumulative += weight
82
+ return type if roll < cumulative
83
+ end
84
+ weights.keys.last
85
+ end
86
+
87
+ def compute_base_preservation
88
+ mod = DEPTH_PRESERVATION_MODIFIER.fetch(@current_depth, 0.0)
89
+ (DEFAULT_PRESERVATION + mod).clamp(0.0, 1.0)
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end