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,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Imagination::MentalSimulation::Helpers::SimulationStep do
4
+ subject(:step) { described_class.new(action: 'deploy service') }
5
+
6
+ describe '#initialize' do
7
+ it 'generates a UUID id' do
8
+ expect(step.id).to match(/\A[0-9a-f-]{36}\z/)
9
+ end
10
+
11
+ it 'stores the action' do
12
+ expect(step.action).to eq('deploy service')
13
+ end
14
+
15
+ it 'defaults predicted_outcome to :success' do
16
+ expect(step.predicted_outcome).to eq(:success)
17
+ end
18
+
19
+ it 'defaults confidence to 0.5' do
20
+ expect(step.confidence).to eq(0.5)
21
+ end
22
+
23
+ it 'defaults risk to 0.1' do
24
+ expect(step.risk).to eq(0.1)
25
+ end
26
+
27
+ it 'defaults preconditions to empty array' do
28
+ expect(step.preconditions).to eq([])
29
+ end
30
+
31
+ it 'defaults postconditions to empty array' do
32
+ expect(step.postconditions).to eq([])
33
+ end
34
+
35
+ it 'records created_at' do
36
+ expect(step.created_at).to be_a(Time)
37
+ end
38
+
39
+ it 'clamps confidence above 1.0 to 1.0' do
40
+ s = described_class.new(action: 'test', confidence: 1.5)
41
+ expect(s.confidence).to eq(1.0)
42
+ end
43
+
44
+ it 'clamps confidence below 0.0 to 0.0' do
45
+ s = described_class.new(action: 'test', confidence: -0.5)
46
+ expect(s.confidence).to eq(0.0)
47
+ end
48
+
49
+ it 'clamps risk above 1.0 to 1.0' do
50
+ s = described_class.new(action: 'test', risk: 2.0)
51
+ expect(s.risk).to eq(1.0)
52
+ end
53
+ end
54
+
55
+ describe '#favorable?' do
56
+ it 'returns true for success with sufficient confidence' do
57
+ s = described_class.new(action: 'go', predicted_outcome: :success, confidence: 0.8)
58
+ expect(s.favorable?).to be true
59
+ end
60
+
61
+ it 'returns true for partial_success with sufficient confidence' do
62
+ s = described_class.new(action: 'go', predicted_outcome: :partial_success, confidence: 0.6)
63
+ expect(s.favorable?).to be true
64
+ end
65
+
66
+ it 'returns false for success with low confidence' do
67
+ s = described_class.new(action: 'go', predicted_outcome: :success, confidence: 0.4)
68
+ expect(s.favorable?).to be false
69
+ end
70
+
71
+ it 'returns false for failure regardless of confidence' do
72
+ s = described_class.new(action: 'go', predicted_outcome: :failure, confidence: 0.9)
73
+ expect(s.favorable?).to be false
74
+ end
75
+
76
+ it 'returns false for unknown outcome' do
77
+ s = described_class.new(action: 'go', predicted_outcome: :unknown, confidence: 0.9)
78
+ expect(s.favorable?).to be false
79
+ end
80
+ end
81
+
82
+ describe '#risky?' do
83
+ it 'returns true when risk >= 0.6' do
84
+ s = described_class.new(action: 'go', risk: 0.7)
85
+ expect(s.risky?).to be true
86
+ end
87
+
88
+ it 'returns false when risk < 0.6' do
89
+ s = described_class.new(action: 'go', risk: 0.4)
90
+ expect(s.risky?).to be false
91
+ end
92
+
93
+ it 'returns true at exactly 0.6' do
94
+ s = described_class.new(action: 'go', risk: 0.6)
95
+ expect(s.risky?).to be true
96
+ end
97
+ end
98
+
99
+ describe '#to_h' do
100
+ it 'returns a hash with all fields' do
101
+ h = step.to_h
102
+ expect(h).to include(:id, :action, :predicted_outcome, :confidence, :risk,
103
+ :preconditions, :postconditions, :created_at)
104
+ end
105
+
106
+ it 'includes stored preconditions' do
107
+ s = described_class.new(action: 'go', preconditions: ['service_up'])
108
+ expect(s.to_h[:preconditions]).to eq(['service_up'])
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/imagination/mental_simulation/helpers/client'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Imagination::MentalSimulation::Runners::MentalSimulation do
6
+ let(:client) { Legion::Extensions::Agentic::Imagination::MentalSimulation::Client.new }
7
+
8
+ def create_and_populate_simulation(favorable: true)
9
+ result = client.create_mental_simulation(label: 'test plan', domain: :infrastructure)
10
+ sim_id = result[:simulation_id]
11
+ if favorable
12
+ client.add_simulation_step(simulation_id: sim_id, action: 'check health', confidence: 0.9, risk: 0.05)
13
+ client.add_simulation_step(simulation_id: sim_id, action: 'deploy service', confidence: 0.85, risk: 0.05)
14
+ else
15
+ client.add_simulation_step(simulation_id: sim_id, action: 'low confidence step', confidence: 0.2, risk: 0.1)
16
+ end
17
+ sim_id
18
+ end
19
+
20
+ describe '#create_mental_simulation' do
21
+ it 'returns a simulation_id' do
22
+ result = client.create_mental_simulation(label: 'my plan', domain: :networking)
23
+ expect(result[:simulation_id]).to match(/\A[0-9a-f-]{36}\z/)
24
+ end
25
+
26
+ it 'returns the label' do
27
+ result = client.create_mental_simulation(label: 'my plan', domain: :networking)
28
+ expect(result[:label]).to eq('my plan')
29
+ end
30
+
31
+ it 'returns the domain' do
32
+ result = client.create_mental_simulation(label: 'my plan', domain: :networking)
33
+ expect(result[:domain]).to eq(:networking)
34
+ end
35
+
36
+ it 'starts in :pending state' do
37
+ result = client.create_mental_simulation(label: 'my plan', domain: :app)
38
+ expect(result[:state]).to eq(:pending)
39
+ end
40
+ end
41
+
42
+ describe '#add_simulation_step' do
43
+ it 'returns added: true' do
44
+ sim_result = client.create_mental_simulation(label: 'plan', domain: :app)
45
+ result = client.add_simulation_step(simulation_id: sim_result[:simulation_id], action: 'step 1')
46
+ expect(result[:added]).to be true
47
+ end
48
+
49
+ it 'returns a step_id' do
50
+ sim_result = client.create_mental_simulation(label: 'plan', domain: :app)
51
+ result = client.add_simulation_step(simulation_id: sim_result[:simulation_id], action: 'step 1')
52
+ expect(result[:step_id]).to match(/\A[0-9a-f-]{36}\z/)
53
+ end
54
+
55
+ it 'returns error for unknown simulation' do
56
+ result = client.add_simulation_step(simulation_id: 'bad-id', action: 'noop')
57
+ expect(result[:error]).to eq(:simulation_not_found)
58
+ end
59
+
60
+ it 'increments step_count' do
61
+ sim_result = client.create_mental_simulation(label: 'plan', domain: :app)
62
+ client.add_simulation_step(simulation_id: sim_result[:simulation_id], action: 'step 1')
63
+ result = client.add_simulation_step(simulation_id: sim_result[:simulation_id], action: 'step 2')
64
+ expect(result[:step_count]).to eq(2)
65
+ end
66
+ end
67
+
68
+ describe '#run_mental_simulation' do
69
+ it 'transitions state from pending' do
70
+ sim_id = create_and_populate_simulation
71
+ result = client.run_mental_simulation(simulation_id: sim_id)
72
+ expect(result[:state]).not_to eq(:pending)
73
+ end
74
+
75
+ it 'returns favorable: true for a well-configured plan' do
76
+ sim_id = create_and_populate_simulation(favorable: true)
77
+ result = client.run_mental_simulation(simulation_id: sim_id)
78
+ expect(result[:favorable]).to be true
79
+ end
80
+
81
+ it 'returns favorable: false for a low-confidence plan' do
82
+ sim_id = create_and_populate_simulation(favorable: false)
83
+ result = client.run_mental_simulation(simulation_id: sim_id)
84
+ expect(result[:favorable]).to be false
85
+ end
86
+
87
+ it 'returns error for unknown simulation' do
88
+ result = client.run_mental_simulation(simulation_id: 'ghost')
89
+ expect(result[:error]).to eq(:simulation_not_found)
90
+ end
91
+
92
+ it 'includes step_count in result' do
93
+ sim_id = create_and_populate_simulation
94
+ result = client.run_mental_simulation(simulation_id: sim_id)
95
+ expect(result[:step_count]).to eq(2)
96
+ end
97
+ end
98
+
99
+ describe '#abort_mental_simulation' do
100
+ it 'aborts a simulation' do
101
+ sim_result = client.create_mental_simulation(label: 'to abort', domain: :app)
102
+ result = client.abort_mental_simulation(simulation_id: sim_result[:simulation_id])
103
+ expect(result[:state]).to eq(:aborted)
104
+ expect(result[:aborted]).to be true
105
+ end
106
+
107
+ it 'returns error for unknown simulation' do
108
+ result = client.abort_mental_simulation(simulation_id: 'ghost')
109
+ expect(result[:error]).to eq(:simulation_not_found)
110
+ end
111
+ end
112
+
113
+ describe '#assess_mental_simulation' do
114
+ it 'returns assessment without running' do
115
+ sim_result = client.create_mental_simulation(label: 'assess me', domain: :security)
116
+ client.add_simulation_step(simulation_id: sim_result[:simulation_id], action: 'read logs',
117
+ confidence: 0.8, risk: 0.1)
118
+ result = client.assess_mental_simulation(simulation_id: sim_result[:simulation_id])
119
+ expect(result[:state]).to eq(:pending)
120
+ expect(result[:steps].size).to eq(1)
121
+ end
122
+
123
+ it 'returns error for unknown simulation' do
124
+ result = client.assess_mental_simulation(simulation_id: 'ghost')
125
+ expect(result[:error]).to eq(:simulation_not_found)
126
+ end
127
+ end
128
+
129
+ describe '#favorable_simulations_report' do
130
+ it 'returns a report with count' do
131
+ sim_id = create_and_populate_simulation(favorable: true)
132
+ client.run_mental_simulation(simulation_id: sim_id)
133
+ result = client.favorable_simulations_report
134
+ expect(result).to include(:simulations, :count)
135
+ expect(result[:count]).to be >= 1
136
+ end
137
+
138
+ it 'returns count: 0 when no favorable simulations exist' do
139
+ result = client.favorable_simulations_report
140
+ expect(result[:count]).to eq(0)
141
+ end
142
+ end
143
+
144
+ describe '#failed_simulations_report' do
145
+ it 'returns a report with count' do
146
+ sim_id = create_and_populate_simulation(favorable: false)
147
+ client.run_mental_simulation(simulation_id: sim_id)
148
+ result = client.failed_simulations_report
149
+ expect(result).to include(:simulations, :count)
150
+ expect(result[:count]).to be >= 1
151
+ end
152
+ end
153
+
154
+ describe '#riskiest_simulations_report' do
155
+ it 'returns a report with simulations and count' do
156
+ sim_id = create_and_populate_simulation
157
+ client.add_simulation_step(simulation_id: sim_id, action: 'risky op', risk: 0.9)
158
+ result = client.riskiest_simulations_report
159
+ expect(result).to include(:simulations, :count)
160
+ end
161
+
162
+ it 'accepts a limit parameter' do
163
+ 3.times { client.create_mental_simulation(label: 'sim', domain: :app) }
164
+ result = client.riskiest_simulations_report(limit: 2)
165
+ expect(result[:count]).to be <= 2
166
+ end
167
+ end
168
+
169
+ describe '#mental_simulation_stats' do
170
+ it 'returns stats hash without simulations list' do
171
+ client.create_mental_simulation(label: 'one', domain: :app)
172
+ result = client.mental_simulation_stats
173
+ expect(result).to include(:total_simulations, :history_size, :favorable_count, :failed_count)
174
+ expect(result).not_to have_key(:simulations)
175
+ end
176
+
177
+ it 'reflects created simulations' do
178
+ client.create_mental_simulation(label: 'a', domain: :app)
179
+ client.create_mental_simulation(label: 'b', domain: :app)
180
+ result = client.mental_simulation_stats
181
+ expect(result[:total_simulations]).to eq(2)
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Imagination::Origami::Client do
4
+ let(:client) { described_class.new }
5
+
6
+ describe '#initialize' do
7
+ it 'creates an OrigamiEngine by default' do
8
+ expect(client.engine).to be_a(Legion::Extensions::Agentic::Imagination::Origami::Helpers::OrigamiEngine)
9
+ end
10
+
11
+ it 'accepts an injected engine' do
12
+ custom_engine = Legion::Extensions::Agentic::Imagination::Origami::Helpers::OrigamiEngine.new
13
+ c = described_class.new(engine: custom_engine)
14
+ expect(c.engine).to eq(custom_engine)
15
+ end
16
+ end
17
+
18
+ describe '#create' do
19
+ it 'creates a figure through the client engine' do
20
+ result = client.create(domain: 'biology', content: 'cell division')
21
+ expect(result[:success]).to be true
22
+ expect(result[:figure][:domain]).to eq('biology')
23
+ end
24
+
25
+ it 'returns an error for invalid input' do
26
+ result = client.create(domain: '', content: 'test')
27
+ expect(result[:success]).to be false
28
+ end
29
+ end
30
+
31
+ describe '#fold' do
32
+ let(:figure_id) do
33
+ result = client.create(domain: 'physics', content: 'spacetime curvature')
34
+ result[:figure][:id]
35
+ end
36
+
37
+ it 'folds the figure' do
38
+ result = client.fold(id: figure_id, fold_type: :valley, axis: 'temporal')
39
+ expect(result[:success]).to be true
40
+ expect(result[:fold_count]).to eq(1)
41
+ end
42
+
43
+ it 'returns error for unknown figure' do
44
+ result = client.fold(id: 'unknown', fold_type: :valley, axis: 'x')
45
+ expect(result[:success]).to be false
46
+ end
47
+ end
48
+
49
+ describe '#unfold' do
50
+ let(:figure_id) do
51
+ result = client.create(domain: 'chemistry', content: 'molecular bonding')
52
+ id = result[:figure][:id]
53
+ client.fold(id: id, fold_type: :mountain, axis: 'spatial')
54
+ id
55
+ end
56
+
57
+ it 'unfolds the figure' do
58
+ result = client.unfold(id: figure_id)
59
+ expect(result[:success]).to be true
60
+ expect(result[:fully_unfolded]).to be true
61
+ end
62
+ end
63
+
64
+ describe '#list_figures' do
65
+ it 'lists all figures in the client engine' do
66
+ client.create(domain: 'art', content: 'color theory')
67
+ client.create(domain: 'music', content: 'harmony')
68
+ result = client.list_figures
69
+ expect(result[:success]).to be true
70
+ expect(result[:count]).to eq(2)
71
+ end
72
+ end
73
+
74
+ describe '#origami_status' do
75
+ it 'returns status report' do
76
+ client.create(domain: 'philosophy', content: 'epistemology')
77
+ result = client.origami_status
78
+ expect(result[:success]).to be true
79
+ expect(result[:report][:figure_count]).to eq(1)
80
+ end
81
+ end
82
+
83
+ describe 'full lifecycle' do
84
+ it 'creates, folds, status, unfolds, and verifies' do
85
+ create_result = client.create(domain: 'cognition', content: 'working memory')
86
+ id = create_result[:figure][:id]
87
+
88
+ 3.times { |i| client.fold(id: id, fold_type: :valley, axis: "axis#{i}") }
89
+ status = client.origami_status
90
+ expect(status[:report][:total_folds]).to eq(3)
91
+
92
+ client.unfold(id: id)
93
+ figures = client.list_figures
94
+ target = figures[:figures].find { |f| f[:id] == id }
95
+ expect(target[:fold_count]).to eq(2)
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Imagination::Origami::Helpers::Constants do
4
+ describe 'FOLD_TYPES' do
5
+ it 'contains the five fold types' do
6
+ expect(described_class::FOLD_TYPES).to eq(%i[valley mountain reverse squash petal])
7
+ end
8
+
9
+ it 'is frozen' do
10
+ expect(described_class::FOLD_TYPES).to be_frozen
11
+ end
12
+ end
13
+
14
+ describe 'MAX_FOLDS' do
15
+ it 'is 12' do
16
+ expect(described_class::MAX_FOLDS).to eq(12)
17
+ end
18
+ end
19
+
20
+ describe 'MAX_FIGURES' do
21
+ it 'is 100' do
22
+ expect(described_class::MAX_FIGURES).to eq(100)
23
+ end
24
+ end
25
+
26
+ describe 'COMPLEXITY_LABELS' do
27
+ it 'returns :simple for fold counts 0..2' do
28
+ (0..2).each do |n|
29
+ label = described_class::COMPLEXITY_LABELS.find { |range, _| range.include?(n) }
30
+ expect(label[1]).to eq(:simple)
31
+ end
32
+ end
33
+
34
+ it 'returns :moderate for fold counts 3..5' do
35
+ (3..5).each do |n|
36
+ label = described_class::COMPLEXITY_LABELS.find { |range, _| range.include?(n) }
37
+ expect(label[1]).to eq(:moderate)
38
+ end
39
+ end
40
+
41
+ it 'returns :complex for fold counts 6..8' do
42
+ (6..8).each do |n|
43
+ label = described_class::COMPLEXITY_LABELS.find { |range, _| range.include?(n) }
44
+ expect(label[1]).to eq(:complex)
45
+ end
46
+ end
47
+
48
+ it 'returns :intricate for fold counts 9..11' do
49
+ (9..11).each do |n|
50
+ label = described_class::COMPLEXITY_LABELS.find { |range, _| range.include?(n) }
51
+ expect(label[1]).to eq(:intricate)
52
+ end
53
+ end
54
+
55
+ it 'returns :transcendent for fold count 12' do
56
+ label = described_class::COMPLEXITY_LABELS.find { |range, _| range.include?(12) }
57
+ expect(label[1]).to eq(:transcendent)
58
+ end
59
+
60
+ it 'is frozen' do
61
+ expect(described_class::COMPLEXITY_LABELS).to be_frozen
62
+ end
63
+ end
64
+
65
+ describe 'CREASE_DECAY' do
66
+ it 'is 0.01' do
67
+ expect(described_class::CREASE_DECAY).to eq(0.01)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Imagination::Origami::Helpers::Crease do
4
+ let(:crease) { described_class.new(fold_type: :valley, axis: 'horizontal', depth: 1) }
5
+
6
+ describe '#initialize' do
7
+ it 'stores fold_type, axis, depth, and sharpness' do
8
+ expect(crease.fold_type).to eq(:valley)
9
+ expect(crease.axis).to eq('horizontal')
10
+ expect(crease.depth).to eq(1)
11
+ expect(crease.sharpness).to eq(1.0)
12
+ end
13
+
14
+ it 'accepts a custom sharpness' do
15
+ c = described_class.new(fold_type: :mountain, axis: 'diagonal', depth: 2, sharpness: 0.5)
16
+ expect(c.sharpness).to eq(0.5)
17
+ end
18
+
19
+ it 'clamps sharpness to 0.0..1.0' do
20
+ high = described_class.new(fold_type: :petal, axis: 'x', depth: 1, sharpness: 2.0)
21
+ low = described_class.new(fold_type: :petal, axis: 'x', depth: 1, sharpness: -1.0)
22
+ expect(high.sharpness).to eq(1.0)
23
+ expect(low.sharpness).to eq(0.0)
24
+ end
25
+
26
+ it 'raises ArgumentError for unknown fold_type' do
27
+ expect { described_class.new(fold_type: :invalid, axis: 'x', depth: 1) }
28
+ .to raise_error(ArgumentError, /Unknown fold_type/)
29
+ end
30
+
31
+ it 'raises ArgumentError for empty axis' do
32
+ expect { described_class.new(fold_type: :valley, axis: '', depth: 1) }
33
+ .to raise_error(ArgumentError, /axis/)
34
+ end
35
+
36
+ it 'raises ArgumentError for non-string axis' do
37
+ expect { described_class.new(fold_type: :valley, axis: :horizontal, depth: 1) }
38
+ .to raise_error(ArgumentError, /axis/)
39
+ end
40
+
41
+ it 'raises ArgumentError for depth zero' do
42
+ expect { described_class.new(fold_type: :valley, axis: 'x', depth: 0) }
43
+ .to raise_error(ArgumentError, /depth/)
44
+ end
45
+
46
+ it 'raises ArgumentError for negative depth' do
47
+ expect { described_class.new(fold_type: :valley, axis: 'x', depth: -1) }
48
+ .to raise_error(ArgumentError, /depth/)
49
+ end
50
+
51
+ it 'accepts all valid fold_types' do
52
+ Legion::Extensions::Agentic::Imagination::Origami::Helpers::Constants::FOLD_TYPES.each do |ft|
53
+ c = described_class.new(fold_type: ft, axis: 'test', depth: 1)
54
+ expect(c.fold_type).to eq(ft)
55
+ end
56
+ end
57
+ end
58
+
59
+ describe '#soften!' do
60
+ it 'reduces sharpness by CREASE_DECAY by default' do
61
+ rate = Legion::Extensions::Agentic::Imagination::Origami::Helpers::Constants::CREASE_DECAY
62
+ original = crease.sharpness
63
+ crease.soften!
64
+ expect(crease.sharpness).to be_within(0.0001).of(original - rate)
65
+ end
66
+
67
+ it 'accepts a custom rate' do
68
+ crease.soften!(0.1)
69
+ expect(crease.sharpness).to be_within(0.0001).of(0.9)
70
+ end
71
+
72
+ it 'clamps sharpness to 0.0' do
73
+ 10.times { crease.soften!(0.2) }
74
+ expect(crease.sharpness).to eq(0.0)
75
+ end
76
+
77
+ it 'returns self for chaining' do
78
+ expect(crease.soften!).to eq(crease)
79
+ end
80
+ end
81
+
82
+ describe '#sharp?' do
83
+ it 'returns true when sharpness >= 0.6' do
84
+ c = described_class.new(fold_type: :valley, axis: 'x', depth: 1, sharpness: 0.6)
85
+ expect(c.sharp?).to be true
86
+ end
87
+
88
+ it 'returns false when sharpness < 0.6' do
89
+ c = described_class.new(fold_type: :valley, axis: 'x', depth: 1, sharpness: 0.5)
90
+ expect(c.sharp?).to be false
91
+ end
92
+ end
93
+
94
+ describe '#faded?' do
95
+ it 'returns true when sharpness <= 0.1' do
96
+ c = described_class.new(fold_type: :valley, axis: 'x', depth: 1, sharpness: 0.1)
97
+ expect(c.faded?).to be true
98
+ end
99
+
100
+ it 'returns false when sharpness > 0.1' do
101
+ c = described_class.new(fold_type: :valley, axis: 'x', depth: 1, sharpness: 0.5)
102
+ expect(c.faded?).to be false
103
+ end
104
+ end
105
+
106
+ describe '#to_h' do
107
+ it 'returns a hash with all fields' do
108
+ h = crease.to_h
109
+ expect(h[:fold_type]).to eq(:valley)
110
+ expect(h[:axis]).to eq('horizontal')
111
+ expect(h[:depth]).to eq(1)
112
+ expect(h[:sharpness]).to eq(1.0)
113
+ end
114
+
115
+ it 'rounds sharpness to 10 decimal places' do
116
+ crease.soften!(0.333)
117
+ h = crease.to_h
118
+ expect(h[:sharpness].to_s.length).to be <= 12
119
+ end
120
+ end
121
+ end