lex-agentic-imagination 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 (246) 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-imagination.gemspec +34 -0
  7. data/lib/legion/extensions/agentic/imagination/alchemy/client.rb +15 -0
  8. data/lib/legion/extensions/agentic/imagination/alchemy/helpers/alchemy_engine.rb +140 -0
  9. data/lib/legion/extensions/agentic/imagination/alchemy/helpers/constants.rb +76 -0
  10. data/lib/legion/extensions/agentic/imagination/alchemy/helpers/crucible.rb +80 -0
  11. data/lib/legion/extensions/agentic/imagination/alchemy/helpers/substance.rb +118 -0
  12. data/lib/legion/extensions/agentic/imagination/alchemy/runners/cognitive_alchemy.rb +88 -0
  13. data/lib/legion/extensions/agentic/imagination/alchemy/version.rb +13 -0
  14. data/lib/legion/extensions/agentic/imagination/alchemy.rb +22 -0
  15. data/lib/legion/extensions/agentic/imagination/aurora/client.rb +25 -0
  16. data/lib/legion/extensions/agentic/imagination/aurora/helpers/aurora_engine.rb +123 -0
  17. data/lib/legion/extensions/agentic/imagination/aurora/helpers/aurora_event.rb +85 -0
  18. data/lib/legion/extensions/agentic/imagination/aurora/helpers/constants.rb +91 -0
  19. data/lib/legion/extensions/agentic/imagination/aurora/helpers/spectral_band.rb +79 -0
  20. data/lib/legion/extensions/agentic/imagination/aurora/runners/cognitive_aurora.rb +84 -0
  21. data/lib/legion/extensions/agentic/imagination/aurora/version.rb +13 -0
  22. data/lib/legion/extensions/agentic/imagination/aurora.rb +22 -0
  23. data/lib/legion/extensions/agentic/imagination/constellation/client.rb +15 -0
  24. data/lib/legion/extensions/agentic/imagination/constellation/helpers/constants.rb +59 -0
  25. data/lib/legion/extensions/agentic/imagination/constellation/helpers/constellation.rb +90 -0
  26. data/lib/legion/extensions/agentic/imagination/constellation/helpers/sky_engine.rb +131 -0
  27. data/lib/legion/extensions/agentic/imagination/constellation/helpers/star.rb +92 -0
  28. data/lib/legion/extensions/agentic/imagination/constellation/runners/cognitive_constellation.rb +76 -0
  29. data/lib/legion/extensions/agentic/imagination/constellation/version.rb +13 -0
  30. data/lib/legion/extensions/agentic/imagination/constellation.rb +22 -0
  31. data/lib/legion/extensions/agentic/imagination/creativity/client.rb +27 -0
  32. data/lib/legion/extensions/agentic/imagination/creativity/helpers/constants.rb +50 -0
  33. data/lib/legion/extensions/agentic/imagination/creativity/helpers/creative_engine.rb +151 -0
  34. data/lib/legion/extensions/agentic/imagination/creativity/helpers/idea.rb +106 -0
  35. data/lib/legion/extensions/agentic/imagination/creativity/helpers/idea_store.rb +103 -0
  36. data/lib/legion/extensions/agentic/imagination/creativity/runners/creativity.rb +176 -0
  37. data/lib/legion/extensions/agentic/imagination/creativity/version.rb +13 -0
  38. data/lib/legion/extensions/agentic/imagination/creativity.rb +20 -0
  39. data/lib/legion/extensions/agentic/imagination/dream/actors/dream_cycle.rb +45 -0
  40. data/lib/legion/extensions/agentic/imagination/dream/client.rb +29 -0
  41. data/lib/legion/extensions/agentic/imagination/dream/helpers/agenda.rb +74 -0
  42. data/lib/legion/extensions/agentic/imagination/dream/helpers/association_walker.rb +59 -0
  43. data/lib/legion/extensions/agentic/imagination/dream/helpers/constants.rb +34 -0
  44. data/lib/legion/extensions/agentic/imagination/dream/helpers/contradiction_detector.rb +86 -0
  45. data/lib/legion/extensions/agentic/imagination/dream/helpers/dream_journal.rb +231 -0
  46. data/lib/legion/extensions/agentic/imagination/dream/helpers/dream_store.rb +91 -0
  47. data/lib/legion/extensions/agentic/imagination/dream/helpers/llm_enhancer.rb +273 -0
  48. data/lib/legion/extensions/agentic/imagination/dream/runners/dream_cycle.rb +328 -0
  49. data/lib/legion/extensions/agentic/imagination/dream/version.rb +13 -0
  50. data/lib/legion/extensions/agentic/imagination/dream.rb +23 -0
  51. data/lib/legion/extensions/agentic/imagination/embodied_simulation/client.rb +19 -0
  52. data/lib/legion/extensions/agentic/imagination/embodied_simulation/helpers/constants.rb +49 -0
  53. data/lib/legion/extensions/agentic/imagination/embodied_simulation/helpers/simulation.rb +136 -0
  54. data/lib/legion/extensions/agentic/imagination/embodied_simulation/helpers/simulation_engine.rb +180 -0
  55. data/lib/legion/extensions/agentic/imagination/embodied_simulation/helpers/simulation_step.rb +49 -0
  56. data/lib/legion/extensions/agentic/imagination/embodied_simulation/runners/embodied_simulation.rb +99 -0
  57. data/lib/legion/extensions/agentic/imagination/embodied_simulation/version.rb +13 -0
  58. data/lib/legion/extensions/agentic/imagination/embodied_simulation.rb +21 -0
  59. data/lib/legion/extensions/agentic/imagination/garden/client.rb +15 -0
  60. data/lib/legion/extensions/agentic/imagination/garden/helpers/constants.rb +49 -0
  61. data/lib/legion/extensions/agentic/imagination/garden/helpers/garden_engine.rb +138 -0
  62. data/lib/legion/extensions/agentic/imagination/garden/helpers/plant.rb +116 -0
  63. data/lib/legion/extensions/agentic/imagination/garden/helpers/plot.rb +95 -0
  64. data/lib/legion/extensions/agentic/imagination/garden/runners/cognitive_garden.rb +75 -0
  65. data/lib/legion/extensions/agentic/imagination/garden/version.rb +13 -0
  66. data/lib/legion/extensions/agentic/imagination/garden.rb +22 -0
  67. data/lib/legion/extensions/agentic/imagination/genesis/client.rb +27 -0
  68. data/lib/legion/extensions/agentic/imagination/genesis/helpers/concept.rb +86 -0
  69. data/lib/legion/extensions/agentic/imagination/genesis/helpers/constants.rb +132 -0
  70. data/lib/legion/extensions/agentic/imagination/genesis/helpers/genesis_engine.rb +251 -0
  71. data/lib/legion/extensions/agentic/imagination/genesis/helpers/seed.rb +70 -0
  72. data/lib/legion/extensions/agentic/imagination/genesis/runners/genesis.rb +105 -0
  73. data/lib/legion/extensions/agentic/imagination/genesis/version.rb +13 -0
  74. data/lib/legion/extensions/agentic/imagination/genesis.rb +20 -0
  75. data/lib/legion/extensions/agentic/imagination/greenhouse/client.rb +24 -0
  76. data/lib/legion/extensions/agentic/imagination/greenhouse/helpers/constants.rb +89 -0
  77. data/lib/legion/extensions/agentic/imagination/greenhouse/helpers/greenhouse.rb +116 -0
  78. data/lib/legion/extensions/agentic/imagination/greenhouse/helpers/greenhouse_engine.rb +121 -0
  79. data/lib/legion/extensions/agentic/imagination/greenhouse/helpers/seedling.rb +155 -0
  80. data/lib/legion/extensions/agentic/imagination/greenhouse/runners/cognitive_greenhouse.rb +87 -0
  81. data/lib/legion/extensions/agentic/imagination/greenhouse/version.rb +13 -0
  82. data/lib/legion/extensions/agentic/imagination/greenhouse.rb +21 -0
  83. data/lib/legion/extensions/agentic/imagination/imagery/client.rb +21 -0
  84. data/lib/legion/extensions/agentic/imagination/imagery/helpers/constants.rb +55 -0
  85. data/lib/legion/extensions/agentic/imagination/imagery/helpers/scenario.rb +123 -0
  86. data/lib/legion/extensions/agentic/imagination/imagery/helpers/simulation_store.rb +80 -0
  87. data/lib/legion/extensions/agentic/imagination/imagery/runners/imagination.rb +210 -0
  88. data/lib/legion/extensions/agentic/imagination/imagery/version.rb +13 -0
  89. data/lib/legion/extensions/agentic/imagination/imagery.rb +20 -0
  90. data/lib/legion/extensions/agentic/imagination/liminal/client.rb +19 -0
  91. data/lib/legion/extensions/agentic/imagination/liminal/helpers/constants.rb +79 -0
  92. data/lib/legion/extensions/agentic/imagination/liminal/helpers/liminal_engine.rb +115 -0
  93. data/lib/legion/extensions/agentic/imagination/liminal/helpers/threshold_crossing.rb +136 -0
  94. data/lib/legion/extensions/agentic/imagination/liminal/runners/cognitive_liminal.rb +72 -0
  95. data/lib/legion/extensions/agentic/imagination/liminal/version.rb +13 -0
  96. data/lib/legion/extensions/agentic/imagination/liminal.rb +19 -0
  97. data/lib/legion/extensions/agentic/imagination/lucidity/client.rb +25 -0
  98. data/lib/legion/extensions/agentic/imagination/lucidity/helpers/constants.rb +48 -0
  99. data/lib/legion/extensions/agentic/imagination/lucidity/helpers/dream_state.rb +135 -0
  100. data/lib/legion/extensions/agentic/imagination/lucidity/helpers/journal_entry.rb +68 -0
  101. data/lib/legion/extensions/agentic/imagination/lucidity/helpers/lucidity_engine.rb +181 -0
  102. data/lib/legion/extensions/agentic/imagination/lucidity/runners/cognitive_lucidity.rb +95 -0
  103. data/lib/legion/extensions/agentic/imagination/lucidity/version.rb +13 -0
  104. data/lib/legion/extensions/agentic/imagination/lucidity.rb +22 -0
  105. data/lib/legion/extensions/agentic/imagination/mental_simulation/helpers/client.rb +23 -0
  106. data/lib/legion/extensions/agentic/imagination/mental_simulation/helpers/constants.rb +43 -0
  107. data/lib/legion/extensions/agentic/imagination/mental_simulation/helpers/simulation.rb +116 -0
  108. data/lib/legion/extensions/agentic/imagination/mental_simulation/helpers/simulation_engine.rb +141 -0
  109. data/lib/legion/extensions/agentic/imagination/mental_simulation/helpers/simulation_step.rb +53 -0
  110. data/lib/legion/extensions/agentic/imagination/mental_simulation/runners/mental_simulation.rb +92 -0
  111. data/lib/legion/extensions/agentic/imagination/mental_simulation/version.rb +13 -0
  112. data/lib/legion/extensions/agentic/imagination/mental_simulation.rb +20 -0
  113. data/lib/legion/extensions/agentic/imagination/origami/client.rb +41 -0
  114. data/lib/legion/extensions/agentic/imagination/origami/helpers/constants.rb +29 -0
  115. data/lib/legion/extensions/agentic/imagination/origami/helpers/crease.rb +53 -0
  116. data/lib/legion/extensions/agentic/imagination/origami/helpers/figure.rb +106 -0
  117. data/lib/legion/extensions/agentic/imagination/origami/helpers/origami_engine.rb +116 -0
  118. data/lib/legion/extensions/agentic/imagination/origami/runners/cognitive_origami.rb +71 -0
  119. data/lib/legion/extensions/agentic/imagination/origami/version.rb +13 -0
  120. data/lib/legion/extensions/agentic/imagination/origami.rb +22 -0
  121. data/lib/legion/extensions/agentic/imagination/prospection/actors/decay.rb +45 -0
  122. data/lib/legion/extensions/agentic/imagination/prospection/client.rb +26 -0
  123. data/lib/legion/extensions/agentic/imagination/prospection/helpers/constants.rb +41 -0
  124. data/lib/legion/extensions/agentic/imagination/prospection/helpers/prospection_engine.rb +129 -0
  125. data/lib/legion/extensions/agentic/imagination/prospection/helpers/scenario.rb +120 -0
  126. data/lib/legion/extensions/agentic/imagination/prospection/runners/prospection.rb +127 -0
  127. data/lib/legion/extensions/agentic/imagination/prospection/version.rb +13 -0
  128. data/lib/legion/extensions/agentic/imagination/prospection.rb +20 -0
  129. data/lib/legion/extensions/agentic/imagination/time_travel/client.rb +27 -0
  130. data/lib/legion/extensions/agentic/imagination/time_travel/helpers/constants.rb +37 -0
  131. data/lib/legion/extensions/agentic/imagination/time_travel/helpers/mental_journey.rb +149 -0
  132. data/lib/legion/extensions/agentic/imagination/time_travel/helpers/temporal_waypoint.rb +68 -0
  133. data/lib/legion/extensions/agentic/imagination/time_travel/helpers/time_traveler.rb +205 -0
  134. data/lib/legion/extensions/agentic/imagination/time_travel/runners/mental_time_travel.rb +145 -0
  135. data/lib/legion/extensions/agentic/imagination/time_travel/version.rb +13 -0
  136. data/lib/legion/extensions/agentic/imagination/time_travel.rb +20 -0
  137. data/lib/legion/extensions/agentic/imagination/version.rb +11 -0
  138. data/lib/legion/extensions/agentic/imagination/volcano/client.rb +47 -0
  139. data/lib/legion/extensions/agentic/imagination/volcano/helpers/chamber.rb +123 -0
  140. data/lib/legion/extensions/agentic/imagination/volcano/helpers/constants.rb +45 -0
  141. data/lib/legion/extensions/agentic/imagination/volcano/helpers/magma.rb +72 -0
  142. data/lib/legion/extensions/agentic/imagination/volcano/helpers/volcano_engine.rb +120 -0
  143. data/lib/legion/extensions/agentic/imagination/volcano/runners/cognitive_volcano.rb +108 -0
  144. data/lib/legion/extensions/agentic/imagination/volcano/version.rb +13 -0
  145. data/lib/legion/extensions/agentic/imagination/volcano.rb +21 -0
  146. data/lib/legion/extensions/agentic/imagination.rb +34 -0
  147. data/spec/legion/extensions/agentic/imagination/alchemy/client_spec.rb +16 -0
  148. data/spec/legion/extensions/agentic/imagination/alchemy/helpers/alchemy_engine_spec.rb +145 -0
  149. data/spec/legion/extensions/agentic/imagination/alchemy/helpers/constants_spec.rb +45 -0
  150. data/spec/legion/extensions/agentic/imagination/alchemy/helpers/crucible_spec.rb +111 -0
  151. data/spec/legion/extensions/agentic/imagination/alchemy/helpers/substance_spec.rb +174 -0
  152. data/spec/legion/extensions/agentic/imagination/alchemy/runners/cognitive_alchemy_spec.rb +99 -0
  153. data/spec/legion/extensions/agentic/imagination/aurora/client_spec.rb +164 -0
  154. data/spec/legion/extensions/agentic/imagination/aurora/helpers/aurora_engine_spec.rb +291 -0
  155. data/spec/legion/extensions/agentic/imagination/aurora/helpers/aurora_event_spec.rb +217 -0
  156. data/spec/legion/extensions/agentic/imagination/aurora/helpers/spectral_band_spec.rb +186 -0
  157. data/spec/legion/extensions/agentic/imagination/constellation/client_spec.rb +16 -0
  158. data/spec/legion/extensions/agentic/imagination/constellation/helpers/constants_spec.rb +35 -0
  159. data/spec/legion/extensions/agentic/imagination/constellation/helpers/constellation_spec.rb +116 -0
  160. data/spec/legion/extensions/agentic/imagination/constellation/helpers/sky_engine_spec.rb +136 -0
  161. data/spec/legion/extensions/agentic/imagination/constellation/helpers/star_spec.rb +126 -0
  162. data/spec/legion/extensions/agentic/imagination/constellation/runners/cognitive_constellation_spec.rb +86 -0
  163. data/spec/legion/extensions/agentic/imagination/creativity/client_spec.rb +68 -0
  164. data/spec/legion/extensions/agentic/imagination/creativity/helpers/constants_spec.rb +129 -0
  165. data/spec/legion/extensions/agentic/imagination/creativity/helpers/creative_engine_spec.rb +220 -0
  166. data/spec/legion/extensions/agentic/imagination/creativity/helpers/idea_store_spec.rb +232 -0
  167. data/spec/legion/extensions/agentic/imagination/creativity/runners/creativity_spec.rb +237 -0
  168. data/spec/legion/extensions/agentic/imagination/dream/actors/dream_cycle_spec.rb +51 -0
  169. data/spec/legion/extensions/agentic/imagination/dream/client_spec.rb +27 -0
  170. data/spec/legion/extensions/agentic/imagination/dream/helpers/agenda_spec.rb +148 -0
  171. data/spec/legion/extensions/agentic/imagination/dream/helpers/association_walker_spec.rb +123 -0
  172. data/spec/legion/extensions/agentic/imagination/dream/helpers/contradiction_detector_spec.rb +183 -0
  173. data/spec/legion/extensions/agentic/imagination/dream/helpers/dream_store_spec.rb +141 -0
  174. data/spec/legion/extensions/agentic/imagination/dream/integration_spec.rb +98 -0
  175. data/spec/legion/extensions/agentic/imagination/dream/runners/dream_cycle_spec.rb +116 -0
  176. data/spec/legion/extensions/agentic/imagination/embodied_simulation/client_spec.rb +44 -0
  177. data/spec/legion/extensions/agentic/imagination/embodied_simulation/helpers/simulation_engine_spec.rb +201 -0
  178. data/spec/legion/extensions/agentic/imagination/embodied_simulation/helpers/simulation_spec.rb +178 -0
  179. data/spec/legion/extensions/agentic/imagination/embodied_simulation/helpers/simulation_step_spec.rb +83 -0
  180. data/spec/legion/extensions/agentic/imagination/embodied_simulation/runners/embodied_simulation_spec.rb +124 -0
  181. data/spec/legion/extensions/agentic/imagination/garden/client_spec.rb +34 -0
  182. data/spec/legion/extensions/agentic/imagination/garden/helpers/constants_spec.rb +41 -0
  183. data/spec/legion/extensions/agentic/imagination/garden/helpers/garden_engine_spec.rb +119 -0
  184. data/spec/legion/extensions/agentic/imagination/garden/helpers/plant_spec.rb +147 -0
  185. data/spec/legion/extensions/agentic/imagination/garden/helpers/plot_spec.rb +92 -0
  186. data/spec/legion/extensions/agentic/imagination/garden/runners/cognitive_garden_spec.rb +75 -0
  187. data/spec/legion/extensions/agentic/imagination/genesis/client_spec.rb +110 -0
  188. data/spec/legion/extensions/agentic/imagination/genesis/cognitive_genesis_spec.rb +31 -0
  189. data/spec/legion/extensions/agentic/imagination/genesis/helpers/concept_spec.rb +221 -0
  190. data/spec/legion/extensions/agentic/imagination/genesis/helpers/constants_spec.rb +145 -0
  191. data/spec/legion/extensions/agentic/imagination/genesis/helpers/genesis_engine_spec.rb +339 -0
  192. data/spec/legion/extensions/agentic/imagination/genesis/helpers/seed_spec.rb +197 -0
  193. data/spec/legion/extensions/agentic/imagination/genesis/runners/genesis_spec.rb +177 -0
  194. data/spec/legion/extensions/agentic/imagination/greenhouse/client_spec.rb +89 -0
  195. data/spec/legion/extensions/agentic/imagination/greenhouse/helpers/constants_spec.rb +74 -0
  196. data/spec/legion/extensions/agentic/imagination/greenhouse/helpers/greenhouse_engine_spec.rb +163 -0
  197. data/spec/legion/extensions/agentic/imagination/greenhouse/helpers/greenhouse_spec.rb +193 -0
  198. data/spec/legion/extensions/agentic/imagination/greenhouse/helpers/seedling_spec.rb +224 -0
  199. data/spec/legion/extensions/agentic/imagination/greenhouse/runners/cognitive_greenhouse_spec.rb +139 -0
  200. data/spec/legion/extensions/agentic/imagination/imagery/client_spec.rb +20 -0
  201. data/spec/legion/extensions/agentic/imagination/imagery/helpers/constants_spec.rb +25 -0
  202. data/spec/legion/extensions/agentic/imagination/imagery/helpers/scenario_spec.rb +111 -0
  203. data/spec/legion/extensions/agentic/imagination/imagery/helpers/simulation_store_spec.rb +89 -0
  204. data/spec/legion/extensions/agentic/imagination/imagery/runners/imagination_spec.rb +99 -0
  205. data/spec/legion/extensions/agentic/imagination/liminal/client_spec.rb +21 -0
  206. data/spec/legion/extensions/agentic/imagination/liminal/cognitive_liminal_spec.rb +7 -0
  207. data/spec/legion/extensions/agentic/imagination/liminal/helpers/liminal_engine_spec.rb +130 -0
  208. data/spec/legion/extensions/agentic/imagination/liminal/helpers/threshold_crossing_spec.rb +155 -0
  209. data/spec/legion/extensions/agentic/imagination/liminal/runners_spec.rb +81 -0
  210. data/spec/legion/extensions/agentic/imagination/lucidity/client_spec.rb +76 -0
  211. data/spec/legion/extensions/agentic/imagination/lucidity/cognitive_lucidity_spec.rb +19 -0
  212. data/spec/legion/extensions/agentic/imagination/lucidity/helpers/constants_spec.rb +89 -0
  213. data/spec/legion/extensions/agentic/imagination/lucidity/helpers/dream_state_spec.rb +210 -0
  214. data/spec/legion/extensions/agentic/imagination/lucidity/helpers/journal_entry_spec.rb +103 -0
  215. data/spec/legion/extensions/agentic/imagination/lucidity/helpers/lucidity_engine_spec.rb +259 -0
  216. data/spec/legion/extensions/agentic/imagination/lucidity/runners/cognitive_lucidity_spec.rb +156 -0
  217. data/spec/legion/extensions/agentic/imagination/mental_simulation/helpers/constants_spec.rb +107 -0
  218. data/spec/legion/extensions/agentic/imagination/mental_simulation/helpers/simulation_engine_spec.rb +217 -0
  219. data/spec/legion/extensions/agentic/imagination/mental_simulation/helpers/simulation_spec.rb +223 -0
  220. data/spec/legion/extensions/agentic/imagination/mental_simulation/helpers/simulation_step_spec.rb +111 -0
  221. data/spec/legion/extensions/agentic/imagination/mental_simulation/runners/mental_simulation_spec.rb +184 -0
  222. data/spec/legion/extensions/agentic/imagination/origami/client_spec.rb +98 -0
  223. data/spec/legion/extensions/agentic/imagination/origami/helpers/constants_spec.rb +70 -0
  224. data/spec/legion/extensions/agentic/imagination/origami/helpers/crease_spec.rb +121 -0
  225. data/spec/legion/extensions/agentic/imagination/origami/helpers/figure_spec.rb +212 -0
  226. data/spec/legion/extensions/agentic/imagination/origami/helpers/origami_engine_spec.rb +239 -0
  227. data/spec/legion/extensions/agentic/imagination/origami/runners/cognitive_origami_spec.rb +112 -0
  228. data/spec/legion/extensions/agentic/imagination/prospection/client_spec.rb +107 -0
  229. data/spec/legion/extensions/agentic/imagination/prospection/helpers/prospection_engine_spec.rb +197 -0
  230. data/spec/legion/extensions/agentic/imagination/prospection/helpers/scenario_spec.rb +260 -0
  231. data/spec/legion/extensions/agentic/imagination/prospection/runners/prospection_spec.rb +156 -0
  232. data/spec/legion/extensions/agentic/imagination/time_travel/client_spec.rb +34 -0
  233. data/spec/legion/extensions/agentic/imagination/time_travel/helpers/constants_spec.rb +83 -0
  234. data/spec/legion/extensions/agentic/imagination/time_travel/helpers/mental_journey_spec.rb +274 -0
  235. data/spec/legion/extensions/agentic/imagination/time_travel/helpers/temporal_waypoint_spec.rb +177 -0
  236. data/spec/legion/extensions/agentic/imagination/time_travel/helpers/time_traveler_spec.rb +334 -0
  237. data/spec/legion/extensions/agentic/imagination/time_travel/runners/mental_time_travel_spec.rb +323 -0
  238. data/spec/legion/extensions/agentic/imagination/volcano/client_spec.rb +89 -0
  239. data/spec/legion/extensions/agentic/imagination/volcano/helpers/chamber_spec.rb +266 -0
  240. data/spec/legion/extensions/agentic/imagination/volcano/helpers/constants_spec.rb +83 -0
  241. data/spec/legion/extensions/agentic/imagination/volcano/helpers/magma_spec.rb +157 -0
  242. data/spec/legion/extensions/agentic/imagination/volcano/helpers/volcano_engine_spec.rb +191 -0
  243. data/spec/legion/extensions/agentic/imagination/volcano/integration_spec.rb +148 -0
  244. data/spec/legion/extensions/agentic/imagination/volcano/runners/cognitive_volcano_spec.rb +167 -0
  245. data/spec/spec_helper.rb +54 -0
  246. metadata +386 -0
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe 'Dream cycle integration' do
4
+ let(:memory_store) { Legion::Extensions::Memory::Helpers::Store.new }
5
+ let(:memory_client) { Legion::Extensions::Memory::Client.new(store: memory_store) }
6
+ let(:identity_client) { Legion::Extensions::Identity::Client.new }
7
+ let(:emotion_client) { Legion::Extensions::Emotion::Client.new }
8
+ let(:tick_client) { Legion::Extensions::Tick::Client.new(mode: :dormant) }
9
+ let(:dream_client) do
10
+ Legion::Extensions::Agentic::Imagination::Dream::Client.new(
11
+ memory: memory_client, identity: identity_client, emotion: emotion_client
12
+ )
13
+ end
14
+ let(:trace_helper) { Legion::Extensions::Memory::Helpers::Trace }
15
+
16
+ it 'runs a complete dream cycle with populated memory' do
17
+ # 1. Seed memory with 10 episodic traces (some unresolved)
18
+ 10.times do |i|
19
+ t = trace_helper.new_trace(
20
+ type: :episodic,
21
+ content_payload: { event: "meeting_#{i}" },
22
+ emotional_intensity: rand,
23
+ emotional_valence: rand(-1.0..1.0),
24
+ domain_tags: ['work']
25
+ )
26
+ t[:unresolved] = true if i < 3
27
+ memory_store.store(t)
28
+ end
29
+
30
+ # 2. Add contradicting trust traces
31
+ t_pos = trace_helper.new_trace(type: :trust, content_payload: { assessment: 'reliable' },
32
+ domain_tags: ['partner'], emotional_valence: 0.9, emotional_intensity: 0.8)
33
+ t_neg = trace_helper.new_trace(type: :trust, content_payload: { assessment: 'unreliable' },
34
+ domain_tags: ['partner'], emotional_valence: -0.8, emotional_intensity: 0.3)
35
+ t_neg[:last_reinforced] = Time.now.utc - 172_800
36
+ memory_store.store(t_pos)
37
+ memory_store.store(t_neg)
38
+
39
+ # 3. Link traces for association walking
40
+ all_ids = memory_store.all_traces.map { |t| t[:trace_id] }
41
+ all_ids.each_cons(2) do |a, b|
42
+ ta = memory_store.get(a)
43
+ tb = memory_store.get(b)
44
+ ta[:associated_traces] << b
45
+ tb[:associated_traces] << a
46
+ end
47
+
48
+ # 4. Simulate tick transition to dormant_active
49
+ tick_state = tick_client.send(:tick_state)
50
+ allow(tick_state).to receive(:seconds_since_signal).and_return(1801.0)
51
+ transition = tick_client.evaluate_mode_transition(signals: [])
52
+ expect(transition[:new_mode]).to eq(:dormant_active)
53
+
54
+ # 5. Run dream cycle
55
+ result = dream_client.execute_dream_cycle
56
+ expect(result[:status]).to eq(:completed)
57
+
58
+ # 6. Verify each phase produced output
59
+ expect(result[:phases][:memory_audit][:decayed]).to be >= 0
60
+ expect(result[:phases][:memory_audit][:unresolved_count]).to be >= 3
61
+ expect(result[:phases][:association_walk]).to have_key(:walk_results)
62
+ expect(result[:phases][:contradiction_resolution][:detected]).to be >= 1
63
+ expect(result[:phases][:identity_entropy_check]).to have_key(:entropy)
64
+ expect(result[:phases][:agenda_formation]).to have_key(:agenda_items)
65
+ expect(result[:phases][:consolidation_commit][:dream_store_cleared]).to be true
66
+
67
+ # 7. Verify unresolved flags cleared after cycle
68
+ unresolved = memory_store.all_traces.select { |t| t[:unresolved] == true }
69
+ expect(unresolved).to be_empty
70
+
71
+ # 8. Verify dream-tagged semantic traces exist in memory (organic recall mechanism)
72
+ dream_traces = memory_store.all_traces.select { |t| t[:domain_tags].any? { |d| d.start_with?('dream:') } }
73
+ # May be 0 if no agenda items formed (depends on phase outputs), but structure should work
74
+ expect(dream_traces).to all(satisfy { |t| t[:trace_type] == :semantic })
75
+
76
+ # 9. Simulate return to dormant after dream completes
77
+ transition = tick_client.evaluate_mode_transition(signals: [], dream_complete: true)
78
+ expect(transition[:new_mode]).to eq(:dormant)
79
+ end
80
+
81
+ it 'handles empty memory gracefully' do
82
+ result = dream_client.execute_dream_cycle
83
+ expect(result[:status]).to eq(:completed)
84
+ expect(result[:phases][:memory_audit][:decayed]).to eq(0)
85
+ expect(result[:phases][:association_walk][:walk_results]).to be_empty
86
+ expect(result[:phases][:contradiction_resolution][:detected]).to eq(0)
87
+ end
88
+
89
+ it 'handles memory with no unresolved traces' do
90
+ 5.times do |i|
91
+ memory_store.store(trace_helper.new_trace(type: :episodic, content_payload: { i: i }))
92
+ end
93
+ result = dream_client.execute_dream_cycle
94
+ expect(result[:status]).to eq(:completed)
95
+ expect(result[:phases][:association_walk][:walk_results]).to be_empty
96
+ expect(result[:phases][:association_walk][:start_trace]).to be_nil
97
+ end
98
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Imagination::Dream::Runners::DreamCycle do
4
+ let(:memory_store) { Legion::Extensions::Memory::Helpers::Store.new }
5
+ let(:memory_client) { Legion::Extensions::Memory::Client.new(store: memory_store) }
6
+ let(:identity_client) { Legion::Extensions::Identity::Client.new }
7
+ let(:emotion_client) { Legion::Extensions::Emotion::Client.new }
8
+ let(:client) do
9
+ Legion::Extensions::Agentic::Imagination::Dream::Client.new(
10
+ memory: memory_client,
11
+ identity: identity_client,
12
+ emotion: emotion_client
13
+ )
14
+ end
15
+ let(:trace_helper) { Legion::Extensions::Memory::Helpers::Trace }
16
+
17
+ describe '#execute_dream_cycle' do
18
+ it 'returns a result hash with all eight phases' do
19
+ result = client.execute_dream_cycle
20
+ expect(result[:phases].keys).to contain_exactly(
21
+ :memory_audit, :association_walk, :contradiction_resolution,
22
+ :identity_entropy_check, :agenda_formation, :consolidation_commit,
23
+ :dream_reflection, :dream_narration
24
+ )
25
+ end
26
+
27
+ it 'returns completed status' do
28
+ result = client.execute_dream_cycle
29
+ expect(result[:status]).to eq(:completed)
30
+ end
31
+ end
32
+
33
+ describe '#phase_memory_audit' do
34
+ before do
35
+ 3.times { |i| memory_store.store(trace_helper.new_trace(type: :episodic, content_payload: { i: i })) }
36
+ end
37
+
38
+ it 'runs decay and migration' do
39
+ result = client.phase_memory_audit
40
+ expect(result).to have_key(:decayed)
41
+ expect(result).to have_key(:migrated)
42
+ end
43
+
44
+ it 'identifies consolidation candidates' do
45
+ t = trace_helper.new_trace(type: :episodic, content_payload: {})
46
+ t[:reinforcement_count] = 10
47
+ t[:strength] = 0.3
48
+ memory_store.store(t)
49
+ client.phase_memory_audit
50
+ expect(memory_store.get(t[:trace_id])[:consolidation_candidate]).to be true
51
+ end
52
+ end
53
+
54
+ describe '#phase_association_walk' do
55
+ it 'returns walk results when unresolved traces exist' do
56
+ t1 = trace_helper.new_trace(type: :episodic, content_payload: {}, emotional_intensity: 0.8, unresolved: true)
57
+ t2 = trace_helper.new_trace(type: :semantic, content_payload: {})
58
+ memory_store.store(t1)
59
+ memory_store.store(t2)
60
+ t1[:associated_traces] << t2[:trace_id]
61
+ t2[:associated_traces] << t1[:trace_id]
62
+ result = client.phase_association_walk
63
+ expect(result[:walk_results]).to be_an(Array)
64
+ end
65
+
66
+ it 'returns empty when no unresolved traces' do
67
+ memory_store.store(trace_helper.new_trace(type: :episodic, content_payload: {}))
68
+ result = client.phase_association_walk
69
+ expect(result[:walk_results]).to be_empty
70
+ end
71
+ end
72
+
73
+ describe '#phase_contradiction_resolution' do
74
+ it 'detects and resolves contradictions' do
75
+ t1 = trace_helper.new_trace(type: :trust, content_payload: {},
76
+ domain_tags: ['reliability'], emotional_valence: 0.8, emotional_intensity: 0.9)
77
+ t2 = trace_helper.new_trace(type: :trust, content_payload: {},
78
+ domain_tags: ['reliability'], emotional_valence: -0.7, emotional_intensity: 0.2)
79
+ t2[:last_reinforced] = Time.now.utc - 86_400
80
+ memory_store.store(t1)
81
+ memory_store.store(t2)
82
+ result = client.phase_contradiction_resolution
83
+ expect(result[:detected]).to be >= 1
84
+ end
85
+ end
86
+
87
+ describe '#phase_identity_entropy_check' do
88
+ it 'returns entropy assessment' do
89
+ result = client.phase_identity_entropy_check
90
+ expect(result).to have_key(:entropy)
91
+ expect(result).to have_key(:classification)
92
+ end
93
+ end
94
+
95
+ describe '#phase_agenda_formation' do
96
+ it 'builds agenda from collected phase data' do
97
+ t = trace_helper.new_trace(type: :episodic, content_payload: {}, unresolved: true, emotional_intensity: 0.7)
98
+ memory_store.store(t)
99
+ client.phase_memory_audit
100
+ client.phase_association_walk
101
+ client.phase_contradiction_resolution
102
+ client.phase_identity_entropy_check
103
+ result = client.phase_agenda_formation
104
+ expect(result).to have_key(:agenda_items)
105
+ end
106
+ end
107
+
108
+ describe '#phase_consolidation_commit' do
109
+ it 'writes agenda traces to memory and clears dream store' do
110
+ client.dream_store.add_agenda_item(type: :curious, content: { path: %w[a b] }, weight: 0.8)
111
+ result = client.phase_consolidation_commit
112
+ expect(result[:traces_written]).to be >= 0
113
+ expect(result[:dream_store_cleared]).to be true
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Imagination::EmbodiedSimulation::Client do
4
+ subject(:client) { described_class.new }
5
+
6
+ it 'creates and evaluates a simulation lifecycle' do
7
+ result = client.create_simulation(simulation_type: :action_rehearsal, domain: :nav, initial_state: {})
8
+ expect(result[:success]).to be true
9
+ sim_id = result[:simulation_id]
10
+
11
+ client.add_simulation_step(sim_id: sim_id, action: :move, expected_state: { pos: 1 },
12
+ confidence: 0.8, somatic_signal: 0.4)
13
+ eval_result = client.evaluate_simulation(sim_id: sim_id)
14
+ expect(eval_result[:recommendation]).to eq(:proceed)
15
+
16
+ client.complete_simulation(sim_id: sim_id, valence: :positive)
17
+ cal = client.calibrate_simulation(sim_id: sim_id, actual_valence: :positive)
18
+ expect(cal[:calibration]).to be > 0.5
19
+ end
20
+
21
+ it 'runs rehearsal and counterfactual' do
22
+ rehearsal = client.rehearse_action(
23
+ domain: :task,
24
+ action_sequence: [
25
+ { action: :step_one, expected_state: { done: true }, confidence: 0.9, somatic_signal: 0.3 }
26
+ ]
27
+ )
28
+ expect(rehearsal[:success]).to be true
29
+
30
+ counter = client.run_counterfactual(
31
+ domain: :decision,
32
+ actual_outcome: :failure,
33
+ alternative_actions: [{ action: :alt_path, expected_state: { done: true } }]
34
+ )
35
+ expect(counter[:success]).to be true
36
+ end
37
+
38
+ it 'accepts injected engine' do
39
+ engine = Legion::Extensions::Agentic::Imagination::EmbodiedSimulation::Helpers::SimulationEngine.new
40
+ c = described_class.new(engine: engine)
41
+ c.create_simulation(simulation_type: :exploratory, domain: :x, initial_state: {})
42
+ expect(engine.simulations.size).to eq(1)
43
+ end
44
+ end
@@ -0,0 +1,201 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Imagination::EmbodiedSimulation::Helpers::SimulationEngine do
4
+ subject(:engine) { described_class.new }
5
+
6
+ describe '#create_simulation' do
7
+ it 'creates a simulation' do
8
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :nav, initial_state: {})
9
+ expect(sim).to be_a(Legion::Extensions::Agentic::Imagination::EmbodiedSimulation::Helpers::Simulation)
10
+ expect(sim.id).to be_a(Symbol)
11
+ end
12
+
13
+ it 'rejects invalid types' do
14
+ expect(engine.create_simulation(simulation_type: :bogus, domain: :x, initial_state: {})).to be_nil
15
+ end
16
+
17
+ it 'enforces MAX_SIMULATIONS' do
18
+ 30.times { |i| engine.create_simulation(simulation_type: :predictive, domain: :"d_#{i}", initial_state: {}) }
19
+ expect(engine.create_simulation(simulation_type: :predictive, domain: :overflow, initial_state: {})).to be_nil
20
+ end
21
+ end
22
+
23
+ describe '#add_step' do
24
+ it 'adds step to existing simulation' do
25
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
26
+ step = engine.add_step(sim_id: sim.id, action: :go, expected_state: { pos: 1 })
27
+ expect(step.action).to eq(:go)
28
+ end
29
+
30
+ it 'returns nil for unknown sim' do
31
+ expect(engine.add_step(sim_id: :bogus, action: :go, expected_state: {})).to be_nil
32
+ end
33
+ end
34
+
35
+ describe '#complete_simulation' do
36
+ it 'completes and records in history' do
37
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
38
+ engine.complete_simulation(sim_id: sim.id, valence: :positive)
39
+ expect(engine.history.size).to eq(1)
40
+ expect(engine.history.first[:valence]).to eq(:positive)
41
+ end
42
+
43
+ it 'returns nil for unknown sim' do
44
+ expect(engine.complete_simulation(sim_id: :bogus, valence: :positive)).to be_nil
45
+ end
46
+ end
47
+
48
+ describe '#abort_simulation' do
49
+ it 'aborts a simulation' do
50
+ sim = engine.create_simulation(simulation_type: :exploratory, domain: :x, initial_state: {})
51
+ engine.abort_simulation(sim_id: sim.id)
52
+ expect(sim.state).to eq(:aborted)
53
+ end
54
+ end
55
+
56
+ describe '#rehearse' do
57
+ it 'creates and runs an action rehearsal' do
58
+ actions = [
59
+ { action: :step_one, expected_state: { pos: 1 }, confidence: 0.8, somatic_signal: 0.3 },
60
+ { action: :step_two, expected_state: { pos: 2 }, confidence: 0.6, somatic_signal: -0.1 }
61
+ ]
62
+ sim = engine.rehearse(domain: :navigation, action_sequence: actions)
63
+ expect(sim.simulation_type).to eq(:action_rehearsal)
64
+ expect(sim.step_count).to eq(2)
65
+ end
66
+
67
+ it 'returns nil when limit reached' do
68
+ 30.times { |i| engine.create_simulation(simulation_type: :predictive, domain: :"d_#{i}", initial_state: {}) }
69
+ expect(engine.rehearse(domain: :x, action_sequence: [{ action: :a }])).to be_nil
70
+ end
71
+ end
72
+
73
+ describe '#counterfactual' do
74
+ it 'creates a counterfactual simulation' do
75
+ alts = [{ action: :alt_a, expected_state: { result: :better } }]
76
+ sim = engine.counterfactual(domain: :decision, actual_outcome: :bad, alternative_actions: alts)
77
+ expect(sim.simulation_type).to eq(:counterfactual)
78
+ expect(sim.initial_state[:actual_outcome]).to eq(:bad)
79
+ end
80
+ end
81
+
82
+ describe '#evaluate_simulation' do
83
+ it 'evaluates a simulation with steps' do
84
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
85
+ engine.add_step(sim_id: sim.id, action: :go, expected_state: {}, confidence: 0.8, somatic_signal: 0.5)
86
+ result = engine.evaluate_simulation(sim_id: sim.id)
87
+ expect(result[:recommendation]).to eq(:proceed)
88
+ end
89
+
90
+ it 'returns :insufficient_data for empty sim' do
91
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
92
+ result = engine.evaluate_simulation(sim_id: sim.id)
93
+ expect(result[:recommendation]).to eq(:insufficient_data)
94
+ end
95
+
96
+ it 'returns :abort for very negative somatic' do
97
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
98
+ engine.add_step(sim_id: sim.id, action: :bad, expected_state: {}, somatic_signal: -0.8)
99
+ result = engine.evaluate_simulation(sim_id: sim.id)
100
+ expect(result[:recommendation]).to eq(:abort)
101
+ end
102
+
103
+ it 'returns :proceed_with_caution for mixed signals' do
104
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
105
+ engine.add_step(sim_id: sim.id, action: :ok, expected_state: {}, somatic_signal: 0.5, confidence: 0.8)
106
+ engine.add_step(sim_id: sim.id, action: :risky, expected_state: {}, somatic_signal: -0.4, confidence: 0.6)
107
+ result = engine.evaluate_simulation(sim_id: sim.id)
108
+ expect(result[:recommendation]).to eq(:proceed_with_caution)
109
+ end
110
+
111
+ it 'returns nil for unknown sim' do
112
+ expect(engine.evaluate_simulation(sim_id: :bogus)).to be_nil
113
+ end
114
+ end
115
+
116
+ describe '#compare_simulations' do
117
+ it 'ranks simulations by combined score' do
118
+ sim_a = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
119
+ engine.add_step(sim_id: sim_a.id, action: :a, expected_state: {}, confidence: 0.9, somatic_signal: 0.8)
120
+ sim_b = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
121
+ engine.add_step(sim_id: sim_b.id, action: :b, expected_state: {}, confidence: 0.3, somatic_signal: -0.2)
122
+
123
+ ranked = engine.compare_simulations(sim_a.id, sim_b.id)
124
+ expect(ranked.first[:id]).to eq(sim_a.id)
125
+ end
126
+
127
+ it 'returns empty for no matches' do
128
+ expect(engine.compare_simulations(:x, :y)).to eq([])
129
+ end
130
+ end
131
+
132
+ describe '#simulations_for' do
133
+ it 'filters by domain' do
134
+ engine.create_simulation(simulation_type: :predictive, domain: :nav, initial_state: {})
135
+ engine.create_simulation(simulation_type: :predictive, domain: :social, initial_state: {})
136
+ expect(engine.simulations_for(domain: :nav).size).to eq(1)
137
+ end
138
+ end
139
+
140
+ describe '#active_simulations' do
141
+ it 'returns running simulations' do
142
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
143
+ engine.add_step(sim_id: sim.id, action: :go, expected_state: {})
144
+ expect(engine.active_simulations.size).to eq(1)
145
+ end
146
+ end
147
+
148
+ describe '#completed_simulations' do
149
+ it 'returns completed simulations' do
150
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
151
+ engine.complete_simulation(sim_id: sim.id, valence: :positive)
152
+ expect(engine.completed_simulations.size).to eq(1)
153
+ end
154
+ end
155
+
156
+ describe '#calibrate' do
157
+ it 'increases calibration on correct prediction' do
158
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
159
+ engine.complete_simulation(sim_id: sim.id, valence: :positive)
160
+ initial = engine.calibration
161
+ engine.calibrate(sim_id: sim.id, actual_valence: :positive)
162
+ expect(engine.calibration).to be > initial
163
+ end
164
+
165
+ it 'decreases calibration on incorrect prediction' do
166
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
167
+ engine.complete_simulation(sim_id: sim.id, valence: :positive)
168
+ initial = engine.calibration
169
+ engine.calibrate(sim_id: sim.id, actual_valence: :negative)
170
+ expect(engine.calibration).to be < initial
171
+ end
172
+
173
+ it 'returns nil for incomplete sim' do
174
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {})
175
+ expect(engine.calibrate(sim_id: sim.id, actual_valence: :positive)).to be_nil
176
+ end
177
+ end
178
+
179
+ describe '#decay_all' do
180
+ it 'decays fidelity on all simulations' do
181
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {}, fidelity: 0.3)
182
+ original = sim.fidelity
183
+ engine.decay_all
184
+ expect(sim.fidelity).to be < original
185
+ end
186
+
187
+ it 'removes faded completed simulations' do
188
+ sim = engine.create_simulation(simulation_type: :action_rehearsal, domain: :x, initial_state: {}, fidelity: 0.11)
189
+ engine.complete_simulation(sim_id: sim.id, valence: :neutral)
190
+ engine.decay_all
191
+ expect(engine.simulations).to be_empty
192
+ end
193
+ end
194
+
195
+ describe '#to_h' do
196
+ it 'returns expected keys' do
197
+ h = engine.to_h
198
+ expect(h).to include(:simulation_count, :active_count, :completed_count, :calibration, :history_size)
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Imagination::EmbodiedSimulation::Helpers::Simulation do
4
+ subject(:sim) do
5
+ described_class.new(
6
+ id: :sim_one, simulation_type: :action_rehearsal,
7
+ domain: :navigation, initial_state: { pos: 0 }
8
+ )
9
+ end
10
+
11
+ describe '#initialize' do
12
+ it 'sets id and type' do
13
+ expect(sim.id).to eq(:sim_one)
14
+ expect(sim.simulation_type).to eq(:action_rehearsal)
15
+ end
16
+
17
+ it 'starts in pending state' do
18
+ expect(sim.state).to eq(:pending)
19
+ end
20
+
21
+ it 'starts with empty steps' do
22
+ expect(sim.steps).to be_empty
23
+ end
24
+
25
+ it 'rejects invalid simulation type' do
26
+ expect do
27
+ described_class.new(id: :x, simulation_type: :bogus, domain: :d, initial_state: {})
28
+ end.to raise_error(ArgumentError)
29
+ end
30
+
31
+ it 'clamps fidelity to floor' do
32
+ s = described_class.new(id: :x, simulation_type: :predictive, domain: :d, initial_state: {}, fidelity: 0.0)
33
+ expect(s.fidelity).to eq(0.1)
34
+ end
35
+ end
36
+
37
+ describe '#add_step' do
38
+ it 'adds a step and transitions to running' do
39
+ step = sim.add_step(action: :go, expected_state: { pos: 1 })
40
+ expect(step).to be_a(Legion::Extensions::Agentic::Imagination::EmbodiedSimulation::Helpers::SimulationStep)
41
+ expect(sim.state).to eq(:running)
42
+ end
43
+
44
+ it 'enforces MAX_STEPS_PER_SIM' do
45
+ 20.times { |i| sim.add_step(action: :"step_#{i}", expected_state: {}) }
46
+ expect(sim.add_step(action: :overflow, expected_state: {})).to be_nil
47
+ end
48
+
49
+ it 'rejects steps after completion' do
50
+ sim.complete(valence: :positive)
51
+ expect(sim.add_step(action: :late, expected_state: {})).to be_nil
52
+ end
53
+ end
54
+
55
+ describe '#complete' do
56
+ it 'sets state to completed and records valence' do
57
+ sim.complete(valence: :positive)
58
+ expect(sim.completed?).to be true
59
+ expect(sim.outcome_valence).to eq(:positive)
60
+ end
61
+
62
+ it 'rejects invalid valence' do
63
+ expect(sim.complete(valence: :bogus)).to be_nil
64
+ end
65
+
66
+ it 'rejects completing an already completed simulation' do
67
+ sim.complete(valence: :positive)
68
+ expect(sim.complete(valence: :negative)).to be_nil
69
+ end
70
+ end
71
+
72
+ describe '#abort_simulation' do
73
+ it 'sets state to aborted' do
74
+ sim.abort_simulation
75
+ expect(sim.state).to eq(:aborted)
76
+ end
77
+
78
+ it 'does not abort completed sim' do
79
+ sim.complete(valence: :neutral)
80
+ expect(sim.abort_simulation).to be_nil
81
+ end
82
+ end
83
+
84
+ describe '#fail_simulation' do
85
+ it 'sets state to failed' do
86
+ sim.fail_simulation
87
+ expect(sim.state).to eq(:failed)
88
+ end
89
+ end
90
+
91
+ describe '#aggregate_somatic' do
92
+ it 'returns 0.0 for empty steps' do
93
+ expect(sim.aggregate_somatic).to eq(0.0)
94
+ end
95
+
96
+ it 'averages somatic signals' do
97
+ sim.add_step(action: :a, expected_state: {}, somatic_signal: 0.5)
98
+ sim.add_step(action: :b, expected_state: {}, somatic_signal: -0.5)
99
+ expect(sim.aggregate_somatic).to eq(0.0)
100
+ end
101
+ end
102
+
103
+ describe '#aggregate_confidence' do
104
+ it 'averages step confidences' do
105
+ sim.add_step(action: :a, expected_state: {}, confidence: 0.8)
106
+ sim.add_step(action: :b, expected_state: {}, confidence: 0.4)
107
+ expect(sim.aggregate_confidence).to be_within(0.001).of(0.6)
108
+ end
109
+ end
110
+
111
+ describe '#negative_signals?' do
112
+ it 'returns false without negative steps' do
113
+ sim.add_step(action: :a, expected_state: {}, somatic_signal: 0.5)
114
+ expect(sim.negative_signals?).to be false
115
+ end
116
+
117
+ it 'returns true with a negative step' do
118
+ sim.add_step(action: :a, expected_state: {}, somatic_signal: -0.5)
119
+ expect(sim.negative_signals?).to be true
120
+ end
121
+ end
122
+
123
+ describe '#successful?' do
124
+ it 'returns true for completed + positive' do
125
+ sim.complete(valence: :positive)
126
+ expect(sim.successful?).to be true
127
+ end
128
+
129
+ it 'returns false for completed + negative' do
130
+ sim.complete(valence: :negative)
131
+ expect(sim.successful?).to be false
132
+ end
133
+ end
134
+
135
+ describe 'type predicates' do
136
+ it 'rehearsal? for action_rehearsal' do
137
+ expect(sim.rehearsal?).to be true
138
+ expect(sim.counterfactual?).to be false
139
+ end
140
+
141
+ it 'counterfactual?' do
142
+ s = described_class.new(id: :x, simulation_type: :counterfactual, domain: :d, initial_state: {})
143
+ expect(s.counterfactual?).to be true
144
+ end
145
+
146
+ it 'empathic?' do
147
+ s = described_class.new(id: :x, simulation_type: :empathic, domain: :d, initial_state: {})
148
+ expect(s.empathic?).to be true
149
+ end
150
+ end
151
+
152
+ describe '#fidelity_label' do
153
+ it 'returns a symbol' do
154
+ expect(sim.fidelity_label).to be_a(Symbol)
155
+ end
156
+ end
157
+
158
+ describe '#decay_fidelity' do
159
+ it 'reduces fidelity' do
160
+ original = sim.fidelity
161
+ sim.decay_fidelity
162
+ expect(sim.fidelity).to be < original
163
+ end
164
+
165
+ it 'does not go below floor' do
166
+ 50.times { sim.decay_fidelity }
167
+ expect(sim.fidelity).to eq(0.1)
168
+ end
169
+ end
170
+
171
+ describe '#to_h' do
172
+ it 'returns expected keys' do
173
+ h = sim.to_h
174
+ expect(h).to include(:id, :simulation_type, :domain, :state, :step_count,
175
+ :outcome_valence, :fidelity, :fidelity_label)
176
+ end
177
+ end
178
+ end