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,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Imagination::Lucidity::Runners::CognitiveLucidity do
4
+ let(:engine) { Legion::Extensions::Agentic::Imagination::Lucidity::Helpers::LucidityEngine.new }
5
+ let(:client) { Legion::Extensions::Agentic::Imagination::Lucidity::Client.new(engine: engine) }
6
+
7
+ describe '#begin_dream' do
8
+ it 'returns success: true' do
9
+ result = client.begin_dream(theme: :space, content: 'floating among stars', engine: engine)
10
+ expect(result[:success]).to be true
11
+ end
12
+
13
+ it 'returns a dream_id' do
14
+ result = client.begin_dream(theme: :space, content: 'floating', engine: engine)
15
+ expect(result[:dream_id]).to match(/\A[0-9a-f-]{36}\z/)
16
+ end
17
+
18
+ it 'returns the theme' do
19
+ result = client.begin_dream(theme: :jungle, content: 'tall trees', engine: engine)
20
+ expect(result[:theme]).to eq(:jungle)
21
+ end
22
+
23
+ it 'uses injected engine via keyword arg' do
24
+ custom_engine = Legion::Extensions::Agentic::Imagination::Lucidity::Helpers::LucidityEngine.new
25
+ result = client.begin_dream(theme: :test, content: 'x', engine: custom_engine)
26
+ expect(custom_engine.all_dreams.map(&:id)).to include(result[:dream_id])
27
+ end
28
+ end
29
+
30
+ describe '#reality_test' do
31
+ let(:dream_id) do
32
+ client.begin_dream(theme: :clouds, content: 'drifting', engine: engine)[:dream_id]
33
+ end
34
+
35
+ it 'returns a result hash' do
36
+ result = client.reality_test(dream_id: dream_id, test_type: :hand_check, engine: engine)
37
+ expect(result).to be_a(Hash)
38
+ end
39
+
40
+ it 'returns success: false for unknown test type' do
41
+ result = client.reality_test(dream_id: dream_id, test_type: :bogus, engine: engine)
42
+ expect(result[:success]).to be false
43
+ end
44
+
45
+ it 'returns success: false for unknown dream' do
46
+ result = client.reality_test(dream_id: 'no-such-id', test_type: :hand_check, engine: engine)
47
+ expect(result[:success]).to be false
48
+ end
49
+
50
+ it 'includes lucidity_level in result for valid test' do
51
+ result = client.reality_test(dream_id: dream_id, test_type: :logic_check, engine: engine)
52
+ expect(result).to have_key(:lucidity_level)
53
+ end
54
+ end
55
+
56
+ describe '#steer_dream' do
57
+ it 'returns success: false when lucidity too low' do
58
+ dream_id = client.begin_dream(theme: :test, content: 'x', lucidity_level: 0.0, engine: engine)[:dream_id]
59
+ result = client.steer_dream(dream_id: dream_id, direction: :fly, engine: engine)
60
+ expect(result[:success]).to be false
61
+ end
62
+
63
+ it 'succeeds when lucidity is sufficient' do
64
+ dream_id = client.begin_dream(theme: :test, content: 'x', lucidity_level: 0.7, engine: engine)[:dream_id]
65
+ result = client.steer_dream(dream_id: dream_id, direction: :transform, engine: engine)
66
+ expect(result[:success]).to be true
67
+ end
68
+
69
+ it 'returns success: false for unknown dream' do
70
+ result = client.steer_dream(dream_id: 'nope', direction: :fly, engine: engine)
71
+ expect(result[:success]).to be false
72
+ end
73
+ end
74
+
75
+ describe '#end_dream' do
76
+ let(:dream_id) do
77
+ client.begin_dream(theme: :ocean, content: 'waves', engine: engine)[:dream_id]
78
+ end
79
+
80
+ it 'returns success: true' do
81
+ result = client.end_dream(dream_id: dream_id, engine: engine)
82
+ expect(result[:success]).to be true
83
+ end
84
+
85
+ it 'creates a journal entry' do
86
+ client.end_dream(dream_id: dream_id, engine: engine)
87
+ expect(engine.journal).not_to be_empty
88
+ end
89
+
90
+ it 'returns success: false for already-ended dream' do
91
+ client.end_dream(dream_id: dream_id, engine: engine)
92
+ result = client.end_dream(dream_id: dream_id, engine: engine)
93
+ expect(result[:success]).to be false
94
+ end
95
+
96
+ it 'accepts insights keyword' do
97
+ client.end_dream(dream_id: dream_id, insights: ['lucidity felt natural'], engine: engine)
98
+ expect(engine.journal.last.insights).to include('lucidity felt natural')
99
+ end
100
+ end
101
+
102
+ describe '#lucidity_status' do
103
+ it 'returns success: true' do
104
+ result = client.lucidity_status(engine: engine)
105
+ expect(result[:success]).to be true
106
+ end
107
+
108
+ it 'returns nil active_dream when none active' do
109
+ result = client.lucidity_status(engine: engine)
110
+ expect(result[:active_dream]).to be_nil
111
+ end
112
+
113
+ it 'returns active_dream info when a dream is running' do
114
+ client.begin_dream(theme: :starfield, content: 'infinite', engine: engine)
115
+ result = client.lucidity_status(engine: engine)
116
+ expect(result[:active_dream]).not_to be_nil
117
+ expect(result[:active_dream]).to have_key(:lucidity_label)
118
+ end
119
+
120
+ it 'includes report with total_dreams' do
121
+ result = client.lucidity_status(engine: engine)
122
+ expect(result[:report]).to have_key(:total_dreams)
123
+ end
124
+ end
125
+
126
+ describe '#journal_entries' do
127
+ before do
128
+ dream_id = client.begin_dream(theme: :wind, content: 'rustling', engine: engine)[:dream_id]
129
+ client.end_dream(dream_id: dream_id, engine: engine)
130
+ end
131
+
132
+ it 'returns success: true' do
133
+ result = client.journal_entries(engine: engine)
134
+ expect(result[:success]).to be true
135
+ end
136
+
137
+ it 'returns a count' do
138
+ result = client.journal_entries(engine: engine)
139
+ expect(result[:count]).to eq(1)
140
+ end
141
+
142
+ it 'returns entries array' do
143
+ result = client.journal_entries(engine: engine)
144
+ expect(result[:entries]).to be_an(Array)
145
+ end
146
+
147
+ it 'respects limit param' do
148
+ 3.times do
149
+ id = client.begin_dream(theme: :extra, content: 'x', engine: engine)[:dream_id]
150
+ client.end_dream(dream_id: id, engine: engine)
151
+ end
152
+ result = client.journal_entries(limit: 2, engine: engine)
153
+ expect(result[:entries].size).to be <= 2
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Imagination::MentalSimulation::Helpers::Constants do
4
+ describe 'SIMULATION_STATES' do
5
+ it 'is frozen' do
6
+ expect(described_class::SIMULATION_STATES).to be_frozen
7
+ end
8
+
9
+ it 'contains expected states' do
10
+ expect(described_class::SIMULATION_STATES).to include(:pending, :running, :completed, :failed, :aborted)
11
+ end
12
+ end
13
+
14
+ describe 'STEP_OUTCOMES' do
15
+ it 'is frozen' do
16
+ expect(described_class::STEP_OUTCOMES).to be_frozen
17
+ end
18
+
19
+ it 'contains expected outcomes' do
20
+ expect(described_class::STEP_OUTCOMES).to include(:success, :partial_success, :failure, :unknown)
21
+ end
22
+ end
23
+
24
+ describe 'CONFIDENCE_LABELS' do
25
+ it 'labels 0.9 as very_confident' do
26
+ match = described_class::CONFIDENCE_LABELS.find { |r, _| r.cover?(0.9) }&.last
27
+ expect(match).to eq(:very_confident)
28
+ end
29
+
30
+ it 'labels 0.7 as confident' do
31
+ match = described_class::CONFIDENCE_LABELS.find { |r, _| r.cover?(0.7) }&.last
32
+ expect(match).to eq(:confident)
33
+ end
34
+
35
+ it 'labels 0.5 as uncertain' do
36
+ match = described_class::CONFIDENCE_LABELS.find { |r, _| r.cover?(0.5) }&.last
37
+ expect(match).to eq(:uncertain)
38
+ end
39
+
40
+ it 'labels 0.3 as doubtful' do
41
+ match = described_class::CONFIDENCE_LABELS.find { |r, _| r.cover?(0.3) }&.last
42
+ expect(match).to eq(:doubtful)
43
+ end
44
+
45
+ it 'labels 0.1 as very_doubtful' do
46
+ match = described_class::CONFIDENCE_LABELS.find { |r, _| r.cover?(0.1) }&.last
47
+ expect(match).to eq(:very_doubtful)
48
+ end
49
+ end
50
+
51
+ describe 'RISK_LABELS' do
52
+ it 'labels 0.9 as critical' do
53
+ match = described_class::RISK_LABELS.find { |r, _| r.cover?(0.9) }&.last
54
+ expect(match).to eq(:critical)
55
+ end
56
+
57
+ it 'labels 0.7 as high' do
58
+ match = described_class::RISK_LABELS.find { |r, _| r.cover?(0.7) }&.last
59
+ expect(match).to eq(:high)
60
+ end
61
+
62
+ it 'labels 0.5 as moderate' do
63
+ match = described_class::RISK_LABELS.find { |r, _| r.cover?(0.5) }&.last
64
+ expect(match).to eq(:moderate)
65
+ end
66
+
67
+ it 'labels 0.3 as low' do
68
+ match = described_class::RISK_LABELS.find { |r, _| r.cover?(0.3) }&.last
69
+ expect(match).to eq(:low)
70
+ end
71
+
72
+ it 'labels 0.1 as negligible' do
73
+ match = described_class::RISK_LABELS.find { |r, _| r.cover?(0.1) }&.last
74
+ expect(match).to eq(:negligible)
75
+ end
76
+ end
77
+
78
+ describe 'numeric constants' do
79
+ it 'MAX_SIMULATIONS is 100' do
80
+ expect(described_class::MAX_SIMULATIONS).to eq(100)
81
+ end
82
+
83
+ it 'MAX_STEPS_PER_SIM is 50' do
84
+ expect(described_class::MAX_STEPS_PER_SIM).to eq(50)
85
+ end
86
+
87
+ it 'MAX_HISTORY is 500' do
88
+ expect(described_class::MAX_HISTORY).to eq(500)
89
+ end
90
+
91
+ it 'DEFAULT_CONFIDENCE is 0.5' do
92
+ expect(described_class::DEFAULT_CONFIDENCE).to eq(0.5)
93
+ end
94
+
95
+ it 'CONFIDENCE_BOOST is 0.1' do
96
+ expect(described_class::CONFIDENCE_BOOST).to eq(0.1)
97
+ end
98
+
99
+ it 'CONFIDENCE_PENALTY is 0.15' do
100
+ expect(described_class::CONFIDENCE_PENALTY).to eq(0.15)
101
+ end
102
+
103
+ it 'RISK_ACCUMULATION_RATE is 0.1' do
104
+ expect(described_class::RISK_ACCUMULATION_RATE).to eq(0.1)
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Imagination::MentalSimulation::Helpers::SimulationEngine do
4
+ subject(:engine) { described_class.new }
5
+
6
+ let(:label) { 'deploy pipeline' }
7
+ let(:domain) { :infrastructure }
8
+
9
+ def build_favorable_simulation
10
+ sim = engine.create_simulation(label: label, domain: domain)
11
+ engine.add_simulation_step(simulation_id: sim.id, action: 'check', confidence: 0.9, risk: 0.05)
12
+ engine.add_simulation_step(simulation_id: sim.id, action: 'deploy', confidence: 0.85, risk: 0.05)
13
+ sim
14
+ end
15
+
16
+ def build_risky_simulation
17
+ sim = engine.create_simulation(label: 'risky plan', domain: :security)
18
+ engine.add_simulation_step(simulation_id: sim.id, action: 'dangerous op', confidence: 0.9, risk: 0.8)
19
+ sim
20
+ end
21
+
22
+ describe '#create_simulation' do
23
+ it 'creates a simulation and returns it' do
24
+ sim = engine.create_simulation(label: label, domain: domain)
25
+ expect(sim).to be_a(Legion::Extensions::Agentic::Imagination::MentalSimulation::Helpers::Simulation)
26
+ end
27
+
28
+ it 'stores the simulation internally' do
29
+ sim = engine.create_simulation(label: label, domain: domain)
30
+ expect(engine.assess_simulation(simulation_id: sim.id)[:label]).to eq(label)
31
+ end
32
+ end
33
+
34
+ describe '#add_simulation_step' do
35
+ it 'returns added: true on success' do
36
+ sim = engine.create_simulation(label: label, domain: domain)
37
+ result = engine.add_simulation_step(simulation_id: sim.id, action: 'check prereqs')
38
+ expect(result[:added]).to be true
39
+ end
40
+
41
+ it 'returns step_id' do
42
+ sim = engine.create_simulation(label: label, domain: domain)
43
+ result = engine.add_simulation_step(simulation_id: sim.id, action: 'check')
44
+ expect(result[:step_id]).to match(/\A[0-9a-f-]{36}\z/)
45
+ end
46
+
47
+ it 'returns error for unknown simulation_id' do
48
+ result = engine.add_simulation_step(simulation_id: 'no-such-id', action: 'go')
49
+ expect(result[:error]).to eq(:simulation_not_found)
50
+ end
51
+
52
+ it 'returns error when max steps reached' do
53
+ sim = engine.create_simulation(label: label, domain: domain)
54
+ Legion::Extensions::Agentic::Imagination::MentalSimulation::Helpers::Constants::MAX_STEPS_PER_SIM.times do |i|
55
+ engine.add_simulation_step(simulation_id: sim.id, action: "step #{i}")
56
+ end
57
+ result = engine.add_simulation_step(simulation_id: sim.id, action: 'one too many')
58
+ expect(result[:error]).to eq(:max_steps_reached)
59
+ end
60
+ end
61
+
62
+ describe '#run_simulation' do
63
+ it 'returns state after running' do
64
+ sim = build_favorable_simulation
65
+ result = engine.run_simulation(simulation_id: sim.id)
66
+ expect(result[:state]).to be_a(Symbol)
67
+ end
68
+
69
+ it 'returns favorable: true for a good plan' do
70
+ sim = build_favorable_simulation
71
+ result = engine.run_simulation(simulation_id: sim.id)
72
+ expect(result[:favorable]).to be true
73
+ end
74
+
75
+ it 'returns error for unknown simulation' do
76
+ result = engine.run_simulation(simulation_id: 'ghost')
77
+ expect(result[:error]).to eq(:simulation_not_found)
78
+ end
79
+
80
+ it 'returns overall_confidence in result' do
81
+ sim = build_favorable_simulation
82
+ result = engine.run_simulation(simulation_id: sim.id)
83
+ expect(result[:overall_confidence]).to be > 0
84
+ end
85
+
86
+ it 'returns cumulative_risk in result' do
87
+ sim = build_favorable_simulation
88
+ result = engine.run_simulation(simulation_id: sim.id)
89
+ expect(result[:cumulative_risk]).to be >= 0
90
+ end
91
+ end
92
+
93
+ describe '#abort_simulation' do
94
+ it 'aborts a simulation and returns aborted: true' do
95
+ sim = engine.create_simulation(label: label, domain: domain)
96
+ result = engine.abort_simulation(simulation_id: sim.id)
97
+ expect(result[:aborted]).to be true
98
+ expect(result[:state]).to eq(:aborted)
99
+ end
100
+
101
+ it 'returns error for unknown simulation' do
102
+ result = engine.abort_simulation(simulation_id: 'ghost')
103
+ expect(result[:error]).to eq(:simulation_not_found)
104
+ end
105
+ end
106
+
107
+ describe '#assess_simulation' do
108
+ it 'returns full assessment without running' do
109
+ sim = engine.create_simulation(label: label, domain: domain)
110
+ engine.add_simulation_step(simulation_id: sim.id, action: 'assess me')
111
+ result = engine.assess_simulation(simulation_id: sim.id)
112
+ expect(result[:state]).to eq(:pending)
113
+ expect(result[:steps].size).to eq(1)
114
+ end
115
+
116
+ it 'returns error for unknown simulation' do
117
+ result = engine.assess_simulation(simulation_id: 'ghost')
118
+ expect(result[:error]).to eq(:simulation_not_found)
119
+ end
120
+
121
+ it 'includes confidence and risk in assessment' do
122
+ sim = engine.create_simulation(label: label, domain: domain)
123
+ engine.add_simulation_step(simulation_id: sim.id, action: 'step', confidence: 0.7, risk: 0.2)
124
+ result = engine.assess_simulation(simulation_id: sim.id)
125
+ expect(result[:overall_confidence]).to eq(0.7)
126
+ expect(result[:cumulative_risk]).to be_within(0.001).of(0.2)
127
+ end
128
+ end
129
+
130
+ describe '#favorable_simulations' do
131
+ it 'returns only favorable simulations' do
132
+ sim = build_favorable_simulation
133
+ engine.run_simulation(simulation_id: sim.id)
134
+ favs = engine.favorable_simulations
135
+ expect(favs).not_to be_empty
136
+ expect(favs.all?(&:favorable?)).to be true
137
+ end
138
+
139
+ it 'excludes non-favorable simulations' do
140
+ sim = engine.create_simulation(label: label, domain: domain)
141
+ engine.add_simulation_step(simulation_id: sim.id, action: 'low conf', confidence: 0.2, risk: 0.1)
142
+ engine.run_simulation(simulation_id: sim.id)
143
+ favs = engine.favorable_simulations
144
+ expect(favs.map(&:id)).not_to include(sim.id)
145
+ end
146
+ end
147
+
148
+ describe '#failed_simulations' do
149
+ it 'returns simulations in :failed state' do
150
+ sim = engine.create_simulation(label: label, domain: domain)
151
+ engine.add_simulation_step(simulation_id: sim.id, action: 'low conf', confidence: 0.2, risk: 0.1)
152
+ engine.run_simulation(simulation_id: sim.id)
153
+ failed = engine.failed_simulations
154
+ expect(failed.map(&:id)).to include(sim.id)
155
+ end
156
+ end
157
+
158
+ describe '#simulations_by_domain' do
159
+ it 'returns simulations for the specified domain' do
160
+ sim_a = engine.create_simulation(label: 'a', domain: :networking)
161
+ sim_b = engine.create_simulation(label: 'b', domain: :security)
162
+ result = engine.simulations_by_domain(domain: :networking)
163
+ expect(result.map(&:id)).to include(sim_a.id)
164
+ expect(result.map(&:id)).not_to include(sim_b.id)
165
+ end
166
+
167
+ it 'handles domain as string by converting to symbol' do
168
+ sim = engine.create_simulation(label: 'str domain', domain: :cloud)
169
+ result = engine.simulations_by_domain(domain: 'cloud')
170
+ expect(result.map(&:id)).to include(sim.id)
171
+ end
172
+ end
173
+
174
+ describe '#riskiest_simulations' do
175
+ it 'returns simulations sorted by descending cumulative_risk' do
176
+ low_risk_sim = engine.create_simulation(label: 'safe', domain: :app)
177
+ engine.add_simulation_step(simulation_id: low_risk_sim.id, action: 'safe', risk: 0.1)
178
+
179
+ high_risk_sim = build_risky_simulation
180
+
181
+ result = engine.riskiest_simulations(limit: 2)
182
+ expect(result.first.id).to eq(high_risk_sim.id)
183
+ end
184
+
185
+ it 'respects the limit parameter' do
186
+ 3.times { |i| engine.create_simulation(label: "sim #{i}", domain: :test) }
187
+ expect(engine.riskiest_simulations(limit: 2).size).to be <= 2
188
+ end
189
+ end
190
+
191
+ describe '#most_confident' do
192
+ it 'returns simulations sorted by descending overall_confidence' do
193
+ low_conf_sim = engine.create_simulation(label: 'uncertain', domain: :app)
194
+ engine.add_simulation_step(simulation_id: low_conf_sim.id, action: 'maybe', confidence: 0.2)
195
+
196
+ high_conf_sim = engine.create_simulation(label: 'sure', domain: :app)
197
+ engine.add_simulation_step(simulation_id: high_conf_sim.id, action: 'definitely', confidence: 0.95)
198
+
199
+ result = engine.most_confident(limit: 2)
200
+ expect(result.first.id).to eq(high_conf_sim.id)
201
+ end
202
+
203
+ it 'respects the limit parameter' do
204
+ 4.times { |i| engine.create_simulation(label: "sim #{i}", domain: :test) }
205
+ expect(engine.most_confident(limit: 2).size).to be <= 2
206
+ end
207
+ end
208
+
209
+ describe '#to_h' do
210
+ it 'returns engine summary hash' do
211
+ engine.create_simulation(label: label, domain: domain)
212
+ h = engine.to_h
213
+ expect(h).to include(:total_simulations, :history_size, :favorable_count, :failed_count, :simulations)
214
+ expect(h[:total_simulations]).to eq(1)
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,223 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Imagination::MentalSimulation::Helpers::Simulation do
4
+ subject(:sim) { described_class.new(label: 'test plan', domain: :infrastructure) }
5
+
6
+ describe '#initialize' do
7
+ it 'generates a UUID id' do
8
+ expect(sim.id).to match(/\A[0-9a-f-]{36}\z/)
9
+ end
10
+
11
+ it 'stores the label' do
12
+ expect(sim.label).to eq('test plan')
13
+ end
14
+
15
+ it 'stores the domain as a symbol' do
16
+ expect(sim.domain).to eq(:infrastructure)
17
+ end
18
+
19
+ it 'starts with no steps' do
20
+ expect(sim.steps).to be_empty
21
+ end
22
+
23
+ it 'starts in :pending state' do
24
+ expect(sim.state).to eq(:pending)
25
+ end
26
+
27
+ it 'records created_at' do
28
+ expect(sim.created_at).to be_a(Time)
29
+ end
30
+
31
+ it 'has nil completed_at initially' do
32
+ expect(sim.completed_at).to be_nil
33
+ end
34
+ end
35
+
36
+ describe '#add_step' do
37
+ it 'adds a SimulationStep and returns it' do
38
+ step = sim.add_step(action: 'check health')
39
+ expect(step).to be_a(Legion::Extensions::Agentic::Imagination::MentalSimulation::Helpers::SimulationStep)
40
+ end
41
+
42
+ it 'increments step_count' do
43
+ sim.add_step(action: 'step one')
44
+ sim.add_step(action: 'step two')
45
+ expect(sim.step_count).to eq(2)
46
+ end
47
+
48
+ it 'passes parameters through to the step' do
49
+ step = sim.add_step(action: 'deploy', predicted_outcome: :failure, confidence: 0.3, risk: 0.8)
50
+ expect(step.predicted_outcome).to eq(:failure)
51
+ expect(step.confidence).to eq(0.3)
52
+ expect(step.risk).to eq(0.8)
53
+ end
54
+ end
55
+
56
+ describe '#overall_confidence' do
57
+ it 'returns 0.0 when no steps' do
58
+ expect(sim.overall_confidence).to eq(0.0)
59
+ end
60
+
61
+ it 'returns product of step confidences' do
62
+ sim.add_step(action: 'a', confidence: 0.8)
63
+ sim.add_step(action: 'b', confidence: 0.5)
64
+ expect(sim.overall_confidence).to be_within(0.001).of(0.4)
65
+ end
66
+
67
+ it 'returns single step confidence when only one step' do
68
+ sim.add_step(action: 'a', confidence: 0.75)
69
+ expect(sim.overall_confidence).to eq(0.75)
70
+ end
71
+ end
72
+
73
+ describe '#cumulative_risk' do
74
+ it 'returns 0.0 when no steps' do
75
+ expect(sim.cumulative_risk).to eq(0.0)
76
+ end
77
+
78
+ it 'computes combined risk correctly' do
79
+ sim.add_step(action: 'a', risk: 0.2)
80
+ sim.add_step(action: 'b', risk: 0.3)
81
+ # 1 - (0.8 * 0.7) = 1 - 0.56 = 0.44
82
+ expect(sim.cumulative_risk).to be_within(0.001).of(0.44)
83
+ end
84
+
85
+ it 'returns high risk when steps have high individual risk' do
86
+ sim.add_step(action: 'a', risk: 0.9)
87
+ sim.add_step(action: 'b', risk: 0.9)
88
+ expect(sim.cumulative_risk).to be > 0.9
89
+ end
90
+ end
91
+
92
+ describe '#run!' do
93
+ context 'with favorable steps' do
94
+ before do
95
+ sim.add_step(action: 'check prereqs', confidence: 0.9, risk: 0.1)
96
+ sim.add_step(action: 'deploy', confidence: 0.8, risk: 0.1)
97
+ end
98
+
99
+ it 'sets state to :completed' do
100
+ sim.run!
101
+ expect(sim.state).to eq(:completed)
102
+ end
103
+
104
+ it 'sets completed_at' do
105
+ sim.run!
106
+ expect(sim.completed_at).to be_a(Time)
107
+ end
108
+ end
109
+
110
+ context 'when a step predicts failure with high confidence' do
111
+ before do
112
+ sim.add_step(action: 'safe step', confidence: 0.9, risk: 0.1)
113
+ sim.add_step(action: 'dangerous step', predicted_outcome: :failure, confidence: 0.8, risk: 0.5)
114
+ end
115
+
116
+ it 'aborts the simulation' do
117
+ sim.run!
118
+ expect(sim.state).to eq(:aborted)
119
+ end
120
+ end
121
+
122
+ context 'with low overall confidence' do
123
+ before do
124
+ sim.add_step(action: 'a', confidence: 0.3, risk: 0.1)
125
+ sim.add_step(action: 'b', confidence: 0.3, risk: 0.1)
126
+ end
127
+
128
+ it 'sets state to :failed' do
129
+ sim.run!
130
+ expect(sim.state).to eq(:failed)
131
+ end
132
+ end
133
+
134
+ context 'with high cumulative risk' do
135
+ before do
136
+ sim.add_step(action: 'a', confidence: 0.9, risk: 0.7)
137
+ sim.add_step(action: 'b', confidence: 0.9, risk: 0.7)
138
+ end
139
+
140
+ it 'sets state to :failed when cumulative risk >= 0.6' do
141
+ sim.run!
142
+ expect(sim.state).to eq(:failed)
143
+ end
144
+ end
145
+
146
+ it 'sets state to :running briefly and transitions' do
147
+ sim.add_step(action: 'a', confidence: 0.9, risk: 0.1)
148
+ sim.run!
149
+ expect(%i[completed failed aborted]).to include(sim.state)
150
+ end
151
+ end
152
+
153
+ describe '#abort!' do
154
+ it 'sets state to :aborted' do
155
+ sim.abort!
156
+ expect(sim.state).to eq(:aborted)
157
+ end
158
+
159
+ it 'sets completed_at' do
160
+ sim.abort!
161
+ expect(sim.completed_at).to be_a(Time)
162
+ end
163
+ end
164
+
165
+ describe '#favorable?' do
166
+ it 'returns false for pending simulation' do
167
+ sim.add_step(action: 'a', confidence: 0.9, risk: 0.1)
168
+ expect(sim.favorable?).to be false
169
+ end
170
+
171
+ it 'returns true for completed simulation with good confidence and low risk' do
172
+ sim.add_step(action: 'a', confidence: 0.9, risk: 0.1)
173
+ sim.add_step(action: 'b', confidence: 0.9, risk: 0.1)
174
+ sim.run!
175
+ expect(sim.favorable?).to be true
176
+ end
177
+
178
+ it 'returns false for aborted simulation' do
179
+ sim.add_step(action: 'a', predicted_outcome: :failure, confidence: 0.9, risk: 0.5)
180
+ sim.run!
181
+ expect(sim.favorable?).to be false
182
+ end
183
+ end
184
+
185
+ describe '#confidence_label' do
186
+ it 'returns :very_confident for high overall confidence' do
187
+ sim.add_step(action: 'a', confidence: 0.95)
188
+ expect(sim.confidence_label).to eq(:very_confident)
189
+ end
190
+
191
+ it 'returns :very_doubtful when no steps' do
192
+ expect(sim.confidence_label).to eq(:very_doubtful)
193
+ end
194
+ end
195
+
196
+ describe '#risk_label' do
197
+ it 'returns :negligible for low risk' do
198
+ sim.add_step(action: 'a', risk: 0.1)
199
+ expect(sim.risk_label).to eq(:negligible)
200
+ end
201
+
202
+ it 'returns :critical for very high risk' do
203
+ sim.add_step(action: 'a', risk: 0.95)
204
+ sim.add_step(action: 'b', risk: 0.95)
205
+ expect(sim.risk_label).to eq(:critical)
206
+ end
207
+ end
208
+
209
+ describe '#to_h' do
210
+ it 'returns a complete hash' do
211
+ sim.add_step(action: 'test step')
212
+ h = sim.to_h
213
+ expect(h).to include(:id, :label, :domain, :state, :step_count, :overall_confidence,
214
+ :cumulative_risk, :confidence_label, :risk_label, :favorable, :steps)
215
+ end
216
+
217
+ it 'includes step hashes' do
218
+ sim.add_step(action: 'step one')
219
+ h = sim.to_h
220
+ expect(h[:steps].first[:action]).to eq('step one')
221
+ end
222
+ end
223
+ end