lex-agentic-inference 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 (328) 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-inference.gemspec +30 -0
  7. data/lib/legion/extensions/agentic/inference/abductive/client.rb +25 -0
  8. data/lib/legion/extensions/agentic/inference/abductive/helpers/abduction_engine.rb +164 -0
  9. data/lib/legion/extensions/agentic/inference/abductive/helpers/constants.rb +39 -0
  10. data/lib/legion/extensions/agentic/inference/abductive/helpers/hypothesis.rb +106 -0
  11. data/lib/legion/extensions/agentic/inference/abductive/helpers/observation.rb +39 -0
  12. data/lib/legion/extensions/agentic/inference/abductive/runners/abductive_reasoning.rb +129 -0
  13. data/lib/legion/extensions/agentic/inference/abductive/version.rb +13 -0
  14. data/lib/legion/extensions/agentic/inference/abductive.rb +20 -0
  15. data/lib/legion/extensions/agentic/inference/affordance/actors/scan.rb +31 -0
  16. data/lib/legion/extensions/agentic/inference/affordance/client.rb +28 -0
  17. data/lib/legion/extensions/agentic/inference/affordance/helpers/affordance_field.rb +123 -0
  18. data/lib/legion/extensions/agentic/inference/affordance/helpers/affordance_item.rb +75 -0
  19. data/lib/legion/extensions/agentic/inference/affordance/helpers/constants.rb +42 -0
  20. data/lib/legion/extensions/agentic/inference/affordance/runners/affordance.rb +90 -0
  21. data/lib/legion/extensions/agentic/inference/affordance/version.rb +13 -0
  22. data/lib/legion/extensions/agentic/inference/affordance.rb +19 -0
  23. data/lib/legion/extensions/agentic/inference/analogical/client.rb +28 -0
  24. data/lib/legion/extensions/agentic/inference/analogical/helpers/analogy_engine.rb +209 -0
  25. data/lib/legion/extensions/agentic/inference/analogical/helpers/constants.rb +38 -0
  26. data/lib/legion/extensions/agentic/inference/analogical/helpers/structure_map.rb +113 -0
  27. data/lib/legion/extensions/agentic/inference/analogical/runners/analogical_reasoning.rb +106 -0
  28. data/lib/legion/extensions/agentic/inference/analogical/version.rb +13 -0
  29. data/lib/legion/extensions/agentic/inference/analogical.rb +19 -0
  30. data/lib/legion/extensions/agentic/inference/argument_mapping/client.rb +19 -0
  31. data/lib/legion/extensions/agentic/inference/argument_mapping/helpers/argument.rb +102 -0
  32. data/lib/legion/extensions/agentic/inference/argument_mapping/helpers/argument_engine.rb +131 -0
  33. data/lib/legion/extensions/agentic/inference/argument_mapping/helpers/constants.rb +44 -0
  34. data/lib/legion/extensions/agentic/inference/argument_mapping/runners/argument_mapping.rb +78 -0
  35. data/lib/legion/extensions/agentic/inference/argument_mapping/version.rb +13 -0
  36. data/lib/legion/extensions/agentic/inference/argument_mapping.rb +19 -0
  37. data/lib/legion/extensions/agentic/inference/bayesian/client.rb +28 -0
  38. data/lib/legion/extensions/agentic/inference/bayesian/helpers/belief.rb +96 -0
  39. data/lib/legion/extensions/agentic/inference/bayesian/helpers/belief_network.rb +147 -0
  40. data/lib/legion/extensions/agentic/inference/bayesian/helpers/constants.rb +36 -0
  41. data/lib/legion/extensions/agentic/inference/bayesian/runners/bayesian_belief.rb +125 -0
  42. data/lib/legion/extensions/agentic/inference/bayesian/version.rb +13 -0
  43. data/lib/legion/extensions/agentic/inference/bayesian.rb +19 -0
  44. data/lib/legion/extensions/agentic/inference/belief_revision/client.rb +19 -0
  45. data/lib/legion/extensions/agentic/inference/belief_revision/helpers/belief.rb +155 -0
  46. data/lib/legion/extensions/agentic/inference/belief_revision/helpers/belief_network.rb +193 -0
  47. data/lib/legion/extensions/agentic/inference/belief_revision/helpers/constants.rb +54 -0
  48. data/lib/legion/extensions/agentic/inference/belief_revision/helpers/evidence.rb +49 -0
  49. data/lib/legion/extensions/agentic/inference/belief_revision/runners/belief_revision.rb +89 -0
  50. data/lib/legion/extensions/agentic/inference/belief_revision/version.rb +13 -0
  51. data/lib/legion/extensions/agentic/inference/belief_revision.rb +21 -0
  52. data/lib/legion/extensions/agentic/inference/causal_attribution/client.rb +27 -0
  53. data/lib/legion/extensions/agentic/inference/causal_attribution/helpers/attribution.rb +92 -0
  54. data/lib/legion/extensions/agentic/inference/causal_attribution/helpers/attribution_engine.rb +159 -0
  55. data/lib/legion/extensions/agentic/inference/causal_attribution/runners/causal_attribution.rb +111 -0
  56. data/lib/legion/extensions/agentic/inference/causal_attribution/version.rb +13 -0
  57. data/lib/legion/extensions/agentic/inference/causal_attribution.rb +18 -0
  58. data/lib/legion/extensions/agentic/inference/causal_reasoning/client.rb +24 -0
  59. data/lib/legion/extensions/agentic/inference/causal_reasoning/helpers/causal_edge.rb +101 -0
  60. data/lib/legion/extensions/agentic/inference/causal_reasoning/helpers/causal_graph.rb +184 -0
  61. data/lib/legion/extensions/agentic/inference/causal_reasoning/helpers/constants.rb +40 -0
  62. data/lib/legion/extensions/agentic/inference/causal_reasoning/runners/causal_reasoning.rb +111 -0
  63. data/lib/legion/extensions/agentic/inference/causal_reasoning/version.rb +13 -0
  64. data/lib/legion/extensions/agentic/inference/causal_reasoning.rb +19 -0
  65. data/lib/legion/extensions/agentic/inference/coherence/client.rb +28 -0
  66. data/lib/legion/extensions/agentic/inference/coherence/helpers/coherence_engine.rb +170 -0
  67. data/lib/legion/extensions/agentic/inference/coherence/helpers/constants.rb +35 -0
  68. data/lib/legion/extensions/agentic/inference/coherence/helpers/proposition.rb +100 -0
  69. data/lib/legion/extensions/agentic/inference/coherence/runners/cognitive_coherence.rb +123 -0
  70. data/lib/legion/extensions/agentic/inference/coherence/version.rb +13 -0
  71. data/lib/legion/extensions/agentic/inference/coherence.rb +19 -0
  72. data/lib/legion/extensions/agentic/inference/counterfactual/client.rb +19 -0
  73. data/lib/legion/extensions/agentic/inference/counterfactual/helpers/constants.rb +40 -0
  74. data/lib/legion/extensions/agentic/inference/counterfactual/helpers/counterfactual_engine.rb +157 -0
  75. data/lib/legion/extensions/agentic/inference/counterfactual/helpers/scenario.rb +98 -0
  76. data/lib/legion/extensions/agentic/inference/counterfactual/runners/counterfactual.rb +106 -0
  77. data/lib/legion/extensions/agentic/inference/counterfactual/version.rb +13 -0
  78. data/lib/legion/extensions/agentic/inference/counterfactual.rb +19 -0
  79. data/lib/legion/extensions/agentic/inference/debugging/client.rb +30 -0
  80. data/lib/legion/extensions/agentic/inference/debugging/helpers/causal_trace.rb +51 -0
  81. data/lib/legion/extensions/agentic/inference/debugging/helpers/constants.rb +58 -0
  82. data/lib/legion/extensions/agentic/inference/debugging/helpers/correction.rb +56 -0
  83. data/lib/legion/extensions/agentic/inference/debugging/helpers/debugging_engine.rb +156 -0
  84. data/lib/legion/extensions/agentic/inference/debugging/helpers/reasoning_error.rb +97 -0
  85. data/lib/legion/extensions/agentic/inference/debugging/runners/cognitive_debugging.rb +178 -0
  86. data/lib/legion/extensions/agentic/inference/debugging/version.rb +13 -0
  87. data/lib/legion/extensions/agentic/inference/debugging.rb +21 -0
  88. data/lib/legion/extensions/agentic/inference/enactive_cognition/client.rb +27 -0
  89. data/lib/legion/extensions/agentic/inference/enactive_cognition/helpers/enaction_engine.rb +120 -0
  90. data/lib/legion/extensions/agentic/inference/enactive_cognition/helpers/sensorimotor_loop.rb +122 -0
  91. data/lib/legion/extensions/agentic/inference/enactive_cognition/runners/enactive_cognition.rb +124 -0
  92. data/lib/legion/extensions/agentic/inference/enactive_cognition/version.rb +13 -0
  93. data/lib/legion/extensions/agentic/inference/enactive_cognition.rb +18 -0
  94. data/lib/legion/extensions/agentic/inference/expectation_violation/helpers/client.rb +17 -0
  95. data/lib/legion/extensions/agentic/inference/expectation_violation/helpers/constants.rb +47 -0
  96. data/lib/legion/extensions/agentic/inference/expectation_violation/helpers/expectation.rb +82 -0
  97. data/lib/legion/extensions/agentic/inference/expectation_violation/helpers/violation_engine.rb +126 -0
  98. data/lib/legion/extensions/agentic/inference/expectation_violation/runners/expectation_violation.rb +76 -0
  99. data/lib/legion/extensions/agentic/inference/expectation_violation/version.rb +13 -0
  100. data/lib/legion/extensions/agentic/inference/expectation_violation.rb +19 -0
  101. data/lib/legion/extensions/agentic/inference/free_energy/client.rb +19 -0
  102. data/lib/legion/extensions/agentic/inference/free_energy/helpers/belief.rb +127 -0
  103. data/lib/legion/extensions/agentic/inference/free_energy/helpers/constants.rb +58 -0
  104. data/lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb +156 -0
  105. data/lib/legion/extensions/agentic/inference/free_energy/runners/free_energy.rb +97 -0
  106. data/lib/legion/extensions/agentic/inference/free_energy/version.rb +13 -0
  107. data/lib/legion/extensions/agentic/inference/free_energy.rb +19 -0
  108. data/lib/legion/extensions/agentic/inference/gravity/client.rb +29 -0
  109. data/lib/legion/extensions/agentic/inference/gravity/helpers/attractor.rb +77 -0
  110. data/lib/legion/extensions/agentic/inference/gravity/helpers/constants.rb +76 -0
  111. data/lib/legion/extensions/agentic/inference/gravity/helpers/gravity_engine.rb +164 -0
  112. data/lib/legion/extensions/agentic/inference/gravity/helpers/orbiting_thought.rb +64 -0
  113. data/lib/legion/extensions/agentic/inference/gravity/runners/gravity.rb +132 -0
  114. data/lib/legion/extensions/agentic/inference/gravity/version.rb +13 -0
  115. data/lib/legion/extensions/agentic/inference/gravity.rb +20 -0
  116. data/lib/legion/extensions/agentic/inference/horizon/actors/adjust.rb +45 -0
  117. data/lib/legion/extensions/agentic/inference/horizon/client.rb +28 -0
  118. data/lib/legion/extensions/agentic/inference/horizon/helpers/constants.rb +43 -0
  119. data/lib/legion/extensions/agentic/inference/horizon/helpers/horizon_engine.rb +110 -0
  120. data/lib/legion/extensions/agentic/inference/horizon/helpers/projection.rb +59 -0
  121. data/lib/legion/extensions/agentic/inference/horizon/runners/cognitive_horizon.rb +107 -0
  122. data/lib/legion/extensions/agentic/inference/horizon/version.rb +13 -0
  123. data/lib/legion/extensions/agentic/inference/horizon.rb +19 -0
  124. data/lib/legion/extensions/agentic/inference/hypothesis_testing/client.rb +28 -0
  125. data/lib/legion/extensions/agentic/inference/hypothesis_testing/helpers/constants.rb +37 -0
  126. data/lib/legion/extensions/agentic/inference/hypothesis_testing/helpers/hypothesis.rb +83 -0
  127. data/lib/legion/extensions/agentic/inference/hypothesis_testing/helpers/hypothesis_engine.rb +97 -0
  128. data/lib/legion/extensions/agentic/inference/hypothesis_testing/runners/hypothesis_testing.rb +115 -0
  129. data/lib/legion/extensions/agentic/inference/hypothesis_testing/version.rb +13 -0
  130. data/lib/legion/extensions/agentic/inference/hypothesis_testing.rb +19 -0
  131. data/lib/legion/extensions/agentic/inference/intuition/client.rb +19 -0
  132. data/lib/legion/extensions/agentic/inference/intuition/helpers/constants.rb +60 -0
  133. data/lib/legion/extensions/agentic/inference/intuition/helpers/heuristic.rb +66 -0
  134. data/lib/legion/extensions/agentic/inference/intuition/helpers/intuition_engine.rb +157 -0
  135. data/lib/legion/extensions/agentic/inference/intuition/helpers/pattern.rb +105 -0
  136. data/lib/legion/extensions/agentic/inference/intuition/runners/intuition.rb +87 -0
  137. data/lib/legion/extensions/agentic/inference/intuition/version.rb +13 -0
  138. data/lib/legion/extensions/agentic/inference/intuition.rb +20 -0
  139. data/lib/legion/extensions/agentic/inference/magnet/client.rb +29 -0
  140. data/lib/legion/extensions/agentic/inference/magnet/helpers/constants.rb +57 -0
  141. data/lib/legion/extensions/agentic/inference/magnet/helpers/field.rb +105 -0
  142. data/lib/legion/extensions/agentic/inference/magnet/helpers/magnet_engine.rb +179 -0
  143. data/lib/legion/extensions/agentic/inference/magnet/helpers/pole.rb +80 -0
  144. data/lib/legion/extensions/agentic/inference/magnet/runners/cognitive_magnet.rb +124 -0
  145. data/lib/legion/extensions/agentic/inference/magnet/version.rb +13 -0
  146. data/lib/legion/extensions/agentic/inference/magnet.rb +21 -0
  147. data/lib/legion/extensions/agentic/inference/momentum/helpers/client.rb +17 -0
  148. data/lib/legion/extensions/agentic/inference/momentum/helpers/constants.rb +65 -0
  149. data/lib/legion/extensions/agentic/inference/momentum/helpers/idea.rb +112 -0
  150. data/lib/legion/extensions/agentic/inference/momentum/helpers/momentum_engine.rb +127 -0
  151. data/lib/legion/extensions/agentic/inference/momentum/runners/cognitive_momentum.rb +101 -0
  152. data/lib/legion/extensions/agentic/inference/momentum/version.rb +13 -0
  153. data/lib/legion/extensions/agentic/inference/momentum.rb +19 -0
  154. data/lib/legion/extensions/agentic/inference/perceptual_inference/client.rb +28 -0
  155. data/lib/legion/extensions/agentic/inference/perceptual_inference/helpers/constants.rb +34 -0
  156. data/lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb +154 -0
  157. data/lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_hypothesis.rb +100 -0
  158. data/lib/legion/extensions/agentic/inference/perceptual_inference/runners/perceptual_inference.rb +120 -0
  159. data/lib/legion/extensions/agentic/inference/perceptual_inference/version.rb +13 -0
  160. data/lib/legion/extensions/agentic/inference/perceptual_inference.rb +19 -0
  161. data/lib/legion/extensions/agentic/inference/prediction/actors/expire_predictions.rb +45 -0
  162. data/lib/legion/extensions/agentic/inference/prediction/client.rb +27 -0
  163. data/lib/legion/extensions/agentic/inference/prediction/helpers/modes.rb +28 -0
  164. data/lib/legion/extensions/agentic/inference/prediction/helpers/prediction_store.rb +66 -0
  165. data/lib/legion/extensions/agentic/inference/prediction/runners/prediction.rb +146 -0
  166. data/lib/legion/extensions/agentic/inference/prediction/version.rb +13 -0
  167. data/lib/legion/extensions/agentic/inference/prediction.rb +18 -0
  168. data/lib/legion/extensions/agentic/inference/predictive_coding/actors/decay.rb +45 -0
  169. data/lib/legion/extensions/agentic/inference/predictive_coding/client.rb +28 -0
  170. data/lib/legion/extensions/agentic/inference/predictive_coding/helpers/constants.rb +46 -0
  171. data/lib/legion/extensions/agentic/inference/predictive_coding/helpers/generative_model.rb +187 -0
  172. data/lib/legion/extensions/agentic/inference/predictive_coding/helpers/prediction_error.rb +59 -0
  173. data/lib/legion/extensions/agentic/inference/predictive_coding/runners/predictive_coding.rb +171 -0
  174. data/lib/legion/extensions/agentic/inference/predictive_coding/version.rb +13 -0
  175. data/lib/legion/extensions/agentic/inference/predictive_coding.rb +20 -0
  176. data/lib/legion/extensions/agentic/inference/predictive_processing/client.rb +28 -0
  177. data/lib/legion/extensions/agentic/inference/predictive_processing/helpers/constants.rb +35 -0
  178. data/lib/legion/extensions/agentic/inference/predictive_processing/helpers/generative_model.rb +142 -0
  179. data/lib/legion/extensions/agentic/inference/predictive_processing/helpers/predictive_processor.rb +129 -0
  180. data/lib/legion/extensions/agentic/inference/predictive_processing/runners/predictive_processing.rb +104 -0
  181. data/lib/legion/extensions/agentic/inference/predictive_processing/version.rb +13 -0
  182. data/lib/legion/extensions/agentic/inference/predictive_processing.rb +19 -0
  183. data/lib/legion/extensions/agentic/inference/reality_testing/client.rb +28 -0
  184. data/lib/legion/extensions/agentic/inference/reality_testing/helpers/belief.rb +98 -0
  185. data/lib/legion/extensions/agentic/inference/reality_testing/helpers/constants.rb +41 -0
  186. data/lib/legion/extensions/agentic/inference/reality_testing/helpers/reality_engine.rb +104 -0
  187. data/lib/legion/extensions/agentic/inference/reality_testing/runners/reality_testing.rb +94 -0
  188. data/lib/legion/extensions/agentic/inference/reality_testing/version.rb +13 -0
  189. data/lib/legion/extensions/agentic/inference/reality_testing.rb +19 -0
  190. data/lib/legion/extensions/agentic/inference/schema/client.rb +26 -0
  191. data/lib/legion/extensions/agentic/inference/schema/helpers/causal_relation.rb +70 -0
  192. data/lib/legion/extensions/agentic/inference/schema/helpers/constants.rb +50 -0
  193. data/lib/legion/extensions/agentic/inference/schema/helpers/world_model.rb +173 -0
  194. data/lib/legion/extensions/agentic/inference/schema/runners/schema.rb +101 -0
  195. data/lib/legion/extensions/agentic/inference/schema/version.rb +13 -0
  196. data/lib/legion/extensions/agentic/inference/schema.rb +19 -0
  197. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance/client.rb +28 -0
  198. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance/helpers/constants.rb +42 -0
  199. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance/helpers/decision.rb +66 -0
  200. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance/helpers/tolerance_engine.rb +139 -0
  201. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance/runners/uncertainty_tolerance.rb +129 -0
  202. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance/version.rb +13 -0
  203. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance.rb +19 -0
  204. data/lib/legion/extensions/agentic/inference/version.rb +11 -0
  205. data/lib/legion/extensions/agentic/inference.rb +44 -0
  206. data/spec/legion/extensions/agentic/inference/abductive/client_spec.rb +25 -0
  207. data/spec/legion/extensions/agentic/inference/abductive/runners/abductive_reasoning_spec.rb +349 -0
  208. data/spec/legion/extensions/agentic/inference/affordance/client_spec.rb +26 -0
  209. data/spec/legion/extensions/agentic/inference/affordance/helpers/affordance_field_spec.rb +131 -0
  210. data/spec/legion/extensions/agentic/inference/affordance/helpers/affordance_item_spec.rb +107 -0
  211. data/spec/legion/extensions/agentic/inference/affordance/runners/affordance_spec.rb +78 -0
  212. data/spec/legion/extensions/agentic/inference/analogical/client_spec.rb +31 -0
  213. data/spec/legion/extensions/agentic/inference/analogical/helpers/analogy_engine_spec.rb +276 -0
  214. data/spec/legion/extensions/agentic/inference/analogical/helpers/structure_map_spec.rb +255 -0
  215. data/spec/legion/extensions/agentic/inference/analogical/runners/analogical_reasoning_spec.rb +213 -0
  216. data/spec/legion/extensions/agentic/inference/argument_mapping/client_spec.rb +18 -0
  217. data/spec/legion/extensions/agentic/inference/argument_mapping/helpers/argument_engine_spec.rb +218 -0
  218. data/spec/legion/extensions/agentic/inference/argument_mapping/helpers/argument_spec.rb +231 -0
  219. data/spec/legion/extensions/agentic/inference/argument_mapping/runners/argument_mapping_spec.rb +171 -0
  220. data/spec/legion/extensions/agentic/inference/bayesian/client_spec.rb +20 -0
  221. data/spec/legion/extensions/agentic/inference/bayesian/helpers/belief_network_spec.rb +178 -0
  222. data/spec/legion/extensions/agentic/inference/bayesian/helpers/belief_spec.rb +137 -0
  223. data/spec/legion/extensions/agentic/inference/bayesian/runners/bayesian_belief_spec.rb +176 -0
  224. data/spec/legion/extensions/agentic/inference/belief_revision/client_spec.rb +31 -0
  225. data/spec/legion/extensions/agentic/inference/belief_revision/helpers/belief_network_spec.rb +176 -0
  226. data/spec/legion/extensions/agentic/inference/belief_revision/helpers/belief_spec.rb +153 -0
  227. data/spec/legion/extensions/agentic/inference/belief_revision/helpers/evidence_spec.rb +51 -0
  228. data/spec/legion/extensions/agentic/inference/belief_revision/runners/belief_revision_spec.rb +106 -0
  229. data/spec/legion/extensions/agentic/inference/causal_attribution/client_spec.rb +24 -0
  230. data/spec/legion/extensions/agentic/inference/causal_attribution/helpers/attribution_engine_spec.rb +181 -0
  231. data/spec/legion/extensions/agentic/inference/causal_attribution/helpers/attribution_spec.rb +108 -0
  232. data/spec/legion/extensions/agentic/inference/causal_attribution/runners/causal_attribution_spec.rb +142 -0
  233. data/spec/legion/extensions/agentic/inference/causal_reasoning/client_spec.rb +35 -0
  234. data/spec/legion/extensions/agentic/inference/causal_reasoning/helpers/causal_edge_spec.rb +158 -0
  235. data/spec/legion/extensions/agentic/inference/causal_reasoning/helpers/causal_graph_spec.rb +259 -0
  236. data/spec/legion/extensions/agentic/inference/causal_reasoning/runners/causal_reasoning_spec.rb +161 -0
  237. data/spec/legion/extensions/agentic/inference/coherence/client_spec.rb +17 -0
  238. data/spec/legion/extensions/agentic/inference/coherence/runners/cognitive_coherence_spec.rb +267 -0
  239. data/spec/legion/extensions/agentic/inference/counterfactual/client_spec.rb +48 -0
  240. data/spec/legion/extensions/agentic/inference/counterfactual/helpers/constants_spec.rb +55 -0
  241. data/spec/legion/extensions/agentic/inference/counterfactual/helpers/counterfactual_engine_spec.rb +234 -0
  242. data/spec/legion/extensions/agentic/inference/counterfactual/helpers/scenario_spec.rb +193 -0
  243. data/spec/legion/extensions/agentic/inference/counterfactual/runners/counterfactual_spec.rb +179 -0
  244. data/spec/legion/extensions/agentic/inference/debugging/client_spec.rb +46 -0
  245. data/spec/legion/extensions/agentic/inference/debugging/helpers/causal_trace_spec.rb +84 -0
  246. data/spec/legion/extensions/agentic/inference/debugging/helpers/constants_spec.rb +97 -0
  247. data/spec/legion/extensions/agentic/inference/debugging/helpers/correction_spec.rb +98 -0
  248. data/spec/legion/extensions/agentic/inference/debugging/helpers/debugging_engine_spec.rb +290 -0
  249. data/spec/legion/extensions/agentic/inference/debugging/helpers/reasoning_error_spec.rb +164 -0
  250. data/spec/legion/extensions/agentic/inference/debugging/runners/cognitive_debugging_spec.rb +301 -0
  251. data/spec/legion/extensions/agentic/inference/enactive_cognition/client_spec.rb +19 -0
  252. data/spec/legion/extensions/agentic/inference/enactive_cognition/helpers/enaction_engine_spec.rb +181 -0
  253. data/spec/legion/extensions/agentic/inference/enactive_cognition/helpers/sensorimotor_loop_spec.rb +184 -0
  254. data/spec/legion/extensions/agentic/inference/enactive_cognition/runners/enactive_cognition_spec.rb +214 -0
  255. data/spec/legion/extensions/agentic/inference/expectation_violation/expectation_violation_spec.rb +11 -0
  256. data/spec/legion/extensions/agentic/inference/expectation_violation/helpers/expectation_spec.rb +102 -0
  257. data/spec/legion/extensions/agentic/inference/expectation_violation/helpers/violation_engine_spec.rb +121 -0
  258. data/spec/legion/extensions/agentic/inference/expectation_violation/runners/expectation_violation_spec.rb +59 -0
  259. data/spec/legion/extensions/agentic/inference/free_energy/client_spec.rb +46 -0
  260. data/spec/legion/extensions/agentic/inference/free_energy/helpers/belief_spec.rb +183 -0
  261. data/spec/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine_spec.rb +211 -0
  262. data/spec/legion/extensions/agentic/inference/free_energy/runners/free_energy_spec.rb +118 -0
  263. data/spec/legion/extensions/agentic/inference/gravity/client_spec.rb +24 -0
  264. data/spec/legion/extensions/agentic/inference/gravity/helpers/attractor_spec.rb +143 -0
  265. data/spec/legion/extensions/agentic/inference/gravity/helpers/constants_spec.rb +107 -0
  266. data/spec/legion/extensions/agentic/inference/gravity/helpers/gravity_engine_spec.rb +193 -0
  267. data/spec/legion/extensions/agentic/inference/gravity/helpers/orbiting_thought_spec.rb +103 -0
  268. data/spec/legion/extensions/agentic/inference/gravity/runners/gravity_spec.rb +159 -0
  269. data/spec/legion/extensions/agentic/inference/horizon/client_spec.rb +58 -0
  270. data/spec/legion/extensions/agentic/inference/horizon/helpers/constants_spec.rb +98 -0
  271. data/spec/legion/extensions/agentic/inference/horizon/helpers/horizon_engine_spec.rb +325 -0
  272. data/spec/legion/extensions/agentic/inference/horizon/helpers/projection_spec.rb +155 -0
  273. data/spec/legion/extensions/agentic/inference/horizon/runners/cognitive_horizon_spec.rb +269 -0
  274. data/spec/legion/extensions/agentic/inference/hypothesis_testing/helpers/constants_spec.rb +38 -0
  275. data/spec/legion/extensions/agentic/inference/hypothesis_testing/helpers/hypothesis_engine_spec.rb +182 -0
  276. data/spec/legion/extensions/agentic/inference/hypothesis_testing/helpers/hypothesis_spec.rb +172 -0
  277. data/spec/legion/extensions/agentic/inference/hypothesis_testing/hypothesis_testing_spec.rb +16 -0
  278. data/spec/legion/extensions/agentic/inference/hypothesis_testing/runners/hypothesis_testing_spec.rb +159 -0
  279. data/spec/legion/extensions/agentic/inference/intuition/client_spec.rb +33 -0
  280. data/spec/legion/extensions/agentic/inference/intuition/helpers/heuristic_spec.rb +82 -0
  281. data/spec/legion/extensions/agentic/inference/intuition/helpers/intuition_engine_spec.rb +163 -0
  282. data/spec/legion/extensions/agentic/inference/intuition/helpers/pattern_spec.rb +160 -0
  283. data/spec/legion/extensions/agentic/inference/intuition/runners/intuition_spec.rb +107 -0
  284. data/spec/legion/extensions/agentic/inference/magnet/client_spec.rb +30 -0
  285. data/spec/legion/extensions/agentic/inference/magnet/helpers/constants_spec.rb +120 -0
  286. data/spec/legion/extensions/agentic/inference/magnet/helpers/field_spec.rb +193 -0
  287. data/spec/legion/extensions/agentic/inference/magnet/helpers/magnet_engine_spec.rb +281 -0
  288. data/spec/legion/extensions/agentic/inference/magnet/helpers/pole_spec.rb +211 -0
  289. data/spec/legion/extensions/agentic/inference/magnet/runners/cognitive_magnet_spec.rb +201 -0
  290. data/spec/legion/extensions/agentic/inference/momentum/cognitive_momentum_spec.rb +11 -0
  291. data/spec/legion/extensions/agentic/inference/momentum/helpers/idea_spec.rb +152 -0
  292. data/spec/legion/extensions/agentic/inference/momentum/helpers/momentum_engine_spec.rb +154 -0
  293. data/spec/legion/extensions/agentic/inference/momentum/runners/cognitive_momentum_spec.rb +97 -0
  294. data/spec/legion/extensions/agentic/inference/perceptual_inference/client_spec.rb +39 -0
  295. data/spec/legion/extensions/agentic/inference/perceptual_inference/helpers/constants_spec.rb +97 -0
  296. data/spec/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field_spec.rb +270 -0
  297. data/spec/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_hypothesis_spec.rb +206 -0
  298. data/spec/legion/extensions/agentic/inference/perceptual_inference/runners/perceptual_inference_spec.rb +305 -0
  299. data/spec/legion/extensions/agentic/inference/prediction/actors/expire_predictions_spec.rb +46 -0
  300. data/spec/legion/extensions/agentic/inference/prediction/client_spec.rb +14 -0
  301. data/spec/legion/extensions/agentic/inference/prediction/helpers/modes_spec.rb +118 -0
  302. data/spec/legion/extensions/agentic/inference/prediction/helpers/prediction_store_spec.rb +262 -0
  303. data/spec/legion/extensions/agentic/inference/prediction/runners/prediction_spec.rb +116 -0
  304. data/spec/legion/extensions/agentic/inference/predictive_coding/client_spec.rb +74 -0
  305. data/spec/legion/extensions/agentic/inference/predictive_coding/helpers/generative_model_spec.rb +194 -0
  306. data/spec/legion/extensions/agentic/inference/predictive_coding/helpers/prediction_error_spec.rb +109 -0
  307. data/spec/legion/extensions/agentic/inference/predictive_coding/runners/predictive_coding_spec.rb +210 -0
  308. data/spec/legion/extensions/agentic/inference/predictive_processing/client_spec.rb +82 -0
  309. data/spec/legion/extensions/agentic/inference/predictive_processing/helpers/generative_model_spec.rb +220 -0
  310. data/spec/legion/extensions/agentic/inference/predictive_processing/helpers/predictive_processor_spec.rb +206 -0
  311. data/spec/legion/extensions/agentic/inference/predictive_processing/runners/predictive_processing_spec.rb +213 -0
  312. data/spec/legion/extensions/agentic/inference/reality_testing/client_spec.rb +29 -0
  313. data/spec/legion/extensions/agentic/inference/reality_testing/helpers/belief_spec.rb +197 -0
  314. data/spec/legion/extensions/agentic/inference/reality_testing/helpers/constants_spec.rb +78 -0
  315. data/spec/legion/extensions/agentic/inference/reality_testing/helpers/reality_engine_spec.rb +191 -0
  316. data/spec/legion/extensions/agentic/inference/reality_testing/runners/reality_testing_spec.rb +154 -0
  317. data/spec/legion/extensions/agentic/inference/schema/client_spec.rb +53 -0
  318. data/spec/legion/extensions/agentic/inference/schema/helpers/causal_relation_spec.rb +108 -0
  319. data/spec/legion/extensions/agentic/inference/schema/helpers/constants_spec.rb +54 -0
  320. data/spec/legion/extensions/agentic/inference/schema/helpers/world_model_spec.rb +179 -0
  321. data/spec/legion/extensions/agentic/inference/schema/runners/schema_spec.rb +146 -0
  322. data/spec/legion/extensions/agentic/inference/uncertainty_tolerance/client_spec.rb +18 -0
  323. data/spec/legion/extensions/agentic/inference/uncertainty_tolerance/helpers/constants_spec.rb +62 -0
  324. data/spec/legion/extensions/agentic/inference/uncertainty_tolerance/helpers/decision_spec.rb +125 -0
  325. data/spec/legion/extensions/agentic/inference/uncertainty_tolerance/helpers/tolerance_engine_spec.rb +184 -0
  326. data/spec/legion/extensions/agentic/inference/uncertainty_tolerance/runners/uncertainty_tolerance_spec.rb +157 -0
  327. data/spec/spec_helper.rb +46 -0
  328. metadata +412 -0
@@ -0,0 +1,213 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/inference/analogical/client'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Inference::Analogical::Runners::AnalogicalReasoning do
6
+ let(:client) { Legion::Extensions::Agentic::Inference::Analogical::Client.new }
7
+
8
+ let(:base_params) do
9
+ {
10
+ source_domain: :solar_system,
11
+ target_domain: :atom,
12
+ mappings: { sun: :nucleus, planet: :electron },
13
+ mapping_type: :relational
14
+ }
15
+ end
16
+
17
+ describe '#create_analogy' do
18
+ it 'creates an analogy and returns success hash' do
19
+ result = client.create_analogy(**base_params)
20
+ expect(result[:success]).to be true
21
+ expect(result[:analogy_id]).to match(/\A[0-9a-f-]{36}\z/)
22
+ expect(result[:source_domain]).to eq(:solar_system)
23
+ expect(result[:target_domain]).to eq(:atom)
24
+ end
25
+
26
+ it 'defaults mapping_type to relational' do
27
+ result = client.create_analogy(
28
+ source_domain: :water,
29
+ target_domain: :electricity,
30
+ mappings: { pressure: :voltage }
31
+ )
32
+ expect(result[:success]).to be true
33
+ expect(result[:mapping_type]).to eq(:relational)
34
+ end
35
+
36
+ it 'rejects invalid mapping type' do
37
+ result = client.create_analogy(
38
+ source_domain: :a, target_domain: :b, mappings: {}, mapping_type: :nonexistent
39
+ )
40
+ expect(result[:success]).to be false
41
+ expect(result[:error]).to eq(:invalid_mapping_type)
42
+ end
43
+
44
+ it 'accepts all valid mapping types' do
45
+ %i[attribute relational system].each do |type|
46
+ result = client.create_analogy(
47
+ source_domain: :src, target_domain: :tgt, mappings: {}, mapping_type: type
48
+ )
49
+ expect(result[:success]).to be true
50
+ end
51
+ end
52
+
53
+ it 'includes state in result' do
54
+ result = client.create_analogy(**base_params)
55
+ expect(Legion::Extensions::Agentic::Inference::Analogical::Helpers::Constants::ANALOGY_STATES)
56
+ .to include(result[:state])
57
+ end
58
+ end
59
+
60
+ describe '#find_analogies' do
61
+ it 'finds analogies by domain' do
62
+ client.create_analogy(**base_params)
63
+ result = client.find_analogies(domain: :solar_system)
64
+ expect(result[:success]).to be true
65
+ expect(result[:count]).to eq(1)
66
+ expect(result[:analogies]).to be_an(Array)
67
+ end
68
+
69
+ it 'returns empty when domain not found' do
70
+ result = client.find_analogies(domain: :unknown)
71
+ expect(result[:success]).to be true
72
+ expect(result[:count]).to eq(0)
73
+ end
74
+ end
75
+
76
+ describe '#apply_analogy' do
77
+ let(:analogy_id) do
78
+ client.create_analogy(**base_params)[:analogy_id]
79
+ end
80
+
81
+ it 'applies mapping successfully' do
82
+ result = client.apply_analogy(analogy_id: analogy_id, source_element: :sun)
83
+ expect(result[:success]).to be true
84
+ expect(result[:mapped]).to be true
85
+ expect(result[:target_element]).to eq(:nucleus)
86
+ end
87
+
88
+ it 'returns success: true with mapped: false for unknown element' do
89
+ result = client.apply_analogy(analogy_id: analogy_id, source_element: :asteroid)
90
+ expect(result[:success]).to be true
91
+ expect(result[:mapped]).to be false
92
+ end
93
+
94
+ it 'returns found: false for unknown analogy_id' do
95
+ result = client.apply_analogy(analogy_id: 'nope', source_element: :sun)
96
+ expect(result[:success]).to be true
97
+ expect(result[:found]).to be false
98
+ end
99
+ end
100
+
101
+ describe '#evaluate_similarity' do
102
+ it 'returns a similarity score' do
103
+ result = client.evaluate_similarity(
104
+ source: { role: :center, relation: :attracts },
105
+ target: { role: :center, relation: :attracts }
106
+ )
107
+ expect(result[:success]).to be true
108
+ expect(result[:similarity_score]).to be_a(Float)
109
+ end
110
+
111
+ it 'indicates when score is above threshold' do
112
+ result = client.evaluate_similarity(
113
+ source: { role: :center, relation: :attracts, type: :massive },
114
+ target: { role: :center, relation: :attracts, type: :massive }
115
+ )
116
+ expect(result[:above_threshold]).to be true
117
+ end
118
+
119
+ it 'indicates when score is below threshold' do
120
+ result = client.evaluate_similarity(
121
+ source: { alpha: :one },
122
+ target: { beta: :two }
123
+ )
124
+ expect(result[:above_threshold]).to be false
125
+ end
126
+
127
+ it 'includes threshold in result' do
128
+ result = client.evaluate_similarity(source: {}, target: {})
129
+ expect(result[:threshold]).to eq(Legion::Extensions::Agentic::Inference::Analogical::Helpers::Constants::SIMILARITY_THRESHOLD)
130
+ end
131
+ end
132
+
133
+ describe '#cross_domain_transfer' do
134
+ let(:analogy_id) { client.create_analogy(**base_params)[:analogy_id] }
135
+
136
+ it 'transfers knowledge across domains' do
137
+ result = client.cross_domain_transfer(
138
+ analogy_id: analogy_id,
139
+ source_knowledge: { sun: 'gravitational center' }
140
+ )
141
+ expect(result[:success]).to be true
142
+ expect(result[:transferred]).to be true
143
+ expect(result[:result][:nucleus]).to eq('gravitational center')
144
+ end
145
+
146
+ it 'returns success with transferred: false for unknown analogy' do
147
+ result = client.cross_domain_transfer(analogy_id: 'nope', source_knowledge: {})
148
+ expect(result[:success]).to be true
149
+ expect(result[:transferred]).to be false
150
+ end
151
+ end
152
+
153
+ describe '#reinforce_analogy' do
154
+ let(:analogy_id) { client.create_analogy(**base_params)[:analogy_id] }
155
+
156
+ it 'reinforces on success' do
157
+ result = client.reinforce_analogy(analogy_id: analogy_id, success: true)
158
+ expect(result[:success]).to be true
159
+ expect(result[:reinforced]).to be true
160
+ expect(result[:strength]).to be_a(Float)
161
+ end
162
+
163
+ it 'weakens on failure' do
164
+ create_result = client.create_analogy(**base_params)
165
+ initial_strength = create_result[:strength]
166
+ client.reinforce_analogy(analogy_id: create_result[:analogy_id], success: false)
167
+ find_result = client.find_analogies(domain: :solar_system)
168
+ final_strength = find_result[:analogies].first[:strength]
169
+ expect(final_strength).to be < initial_strength
170
+ end
171
+
172
+ it 'returns not_found for unknown analogy' do
173
+ result = client.reinforce_analogy(analogy_id: 'nope', success: true)
174
+ expect(result[:success]).to be true
175
+ expect(result[:reinforced]).to be false
176
+ end
177
+ end
178
+
179
+ describe '#productive_analogies' do
180
+ it 'returns only productive analogies' do
181
+ client.create_analogy(**base_params, strength: 0.9)
182
+ result = client.productive_analogies
183
+ expect(result[:success]).to be true
184
+ expect(result[:count]).to eq(1)
185
+ end
186
+
187
+ it 'returns empty when no productive analogies' do
188
+ client.create_analogy(**base_params)
189
+ result = client.productive_analogies
190
+ expect(result[:success]).to be true
191
+ expect(result[:count]).to eq(0)
192
+ end
193
+ end
194
+
195
+ describe '#update_analogical_reasoning' do
196
+ it 'performs decay and pruning' do
197
+ client.create_analogy(**base_params)
198
+ result = client.update_analogical_reasoning
199
+ expect(result[:success]).to be true
200
+ expect(result[:pruned]).to be_a(Integer)
201
+ end
202
+ end
203
+
204
+ describe '#analogical_reasoning_stats' do
205
+ it 'returns stats hash' do
206
+ client.create_analogy(**base_params)
207
+ result = client.analogical_reasoning_stats
208
+ expect(result[:success]).to be true
209
+ expect(result[:total_analogies]).to eq(1)
210
+ expect(result[:total_domains]).to eq(2)
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Inference::ArgumentMapping::Client do
4
+ let(:client) { described_class.new }
5
+
6
+ it 'responds to all runner methods' do
7
+ expect(client).to respond_to(:create_argument)
8
+ expect(client).to respond_to(:add_argument_ground)
9
+ expect(client).to respond_to(:add_argument_backing)
10
+ expect(client).to respond_to(:add_argument_rebuttal)
11
+ expect(client).to respond_to(:assess_argument_strength)
12
+ expect(client).to respond_to(:sound_arguments_report)
13
+ expect(client).to respond_to(:rebutted_arguments_report)
14
+ expect(client).to respond_to(:strongest_arguments_report)
15
+ expect(client).to respond_to(:update_argument_mapping)
16
+ expect(client).to respond_to(:argument_mapping_stats)
17
+ end
18
+ end
@@ -0,0 +1,218 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Inference::ArgumentMapping::Helpers::ArgumentEngine do
4
+ subject(:engine) { described_class.new }
5
+
6
+ describe '#initialize' do
7
+ it 'starts with empty arguments' do
8
+ expect(engine.arguments).to be_empty
9
+ end
10
+
11
+ it 'starts with empty history' do
12
+ expect(engine.history).to be_empty
13
+ end
14
+ end
15
+
16
+ describe '#create_argument' do
17
+ it 'creates an argument and returns success' do
18
+ result = engine.create_argument(claim: 'The sky is blue')
19
+ expect(result[:success]).to be true
20
+ expect(result[:argument][:claim]).to eq('The sky is blue')
21
+ end
22
+
23
+ it 'assigns a unique id' do
24
+ r1 = engine.create_argument(claim: 'Claim A')
25
+ r2 = engine.create_argument(claim: 'Claim B')
26
+ expect(r1[:argument][:id]).not_to eq(r2[:argument][:id])
27
+ end
28
+
29
+ it 'stores argument in @arguments' do
30
+ engine.create_argument(claim: 'Test claim')
31
+ expect(engine.arguments).not_to be_empty
32
+ end
33
+
34
+ it 'accepts warrant and qualifier' do
35
+ result = engine.create_argument(
36
+ claim: 'AI should be regulated',
37
+ warrant: 'Unregulated AI poses risks',
38
+ qualifier: :certainly
39
+ )
40
+ expect(result[:argument][:warrant]).to eq('Unregulated AI poses risks')
41
+ expect(result[:argument][:qualifier]).to eq(:certainly)
42
+ end
43
+
44
+ it 'returns failure when max arguments reached' do
45
+ Legion::Extensions::Agentic::Inference::ArgumentMapping::Helpers::Constants::MAX_ARGUMENTS.times do |i|
46
+ engine.create_argument(claim: "Claim #{i}")
47
+ end
48
+ result = engine.create_argument(claim: 'One more')
49
+ expect(result[:success]).to be false
50
+ expect(result[:reason]).to eq(:max_arguments_reached)
51
+ end
52
+
53
+ it 'adds an entry to history' do
54
+ engine.create_argument(claim: 'Some claim')
55
+ expect(engine.history).not_to be_empty
56
+ end
57
+ end
58
+
59
+ describe '#add_ground' do
60
+ let(:argument_id) { engine.create_argument(claim: 'Test')[:argument][:id] }
61
+
62
+ it 'adds a ground to the argument' do
63
+ result = engine.add_ground(argument_id: argument_id, ground: 'Evidence A')
64
+ expect(result[:success]).to be true
65
+ expect(result[:argument][:grounds]).to include('Evidence A')
66
+ end
67
+
68
+ it 'returns failure for unknown argument_id' do
69
+ result = engine.add_ground(argument_id: 'bad_id', ground: 'Evidence')
70
+ expect(result[:success]).to be false
71
+ expect(result[:reason]).to eq(:not_found)
72
+ end
73
+ end
74
+
75
+ describe '#add_backing' do
76
+ let(:argument_id) { engine.create_argument(claim: 'Test')[:argument][:id] }
77
+
78
+ it 'adds backing to the argument' do
79
+ result = engine.add_backing(argument_id: argument_id, backing: 'Source A')
80
+ expect(result[:success]).to be true
81
+ expect(result[:argument][:backing]).to include('Source A')
82
+ end
83
+
84
+ it 'returns failure for unknown argument_id' do
85
+ result = engine.add_backing(argument_id: 'bad_id', backing: 'Source')
86
+ expect(result[:success]).to be false
87
+ expect(result[:reason]).to eq(:not_found)
88
+ end
89
+ end
90
+
91
+ describe '#add_rebuttal' do
92
+ let(:argument_id) { engine.create_argument(claim: 'Test')[:argument][:id] }
93
+
94
+ it 'adds a rebuttal to the argument' do
95
+ result = engine.add_rebuttal(argument_id: argument_id, content: 'Counter-point', impact: 0.7)
96
+ expect(result[:success]).to be true
97
+ expect(result[:argument][:rebuttals].first[:content]).to eq('Counter-point')
98
+ end
99
+
100
+ it 'returns failure for unknown argument_id' do
101
+ result = engine.add_rebuttal(argument_id: 'bad_id', content: 'Counter')
102
+ expect(result[:success]).to be false
103
+ expect(result[:reason]).to eq(:not_found)
104
+ end
105
+ end
106
+
107
+ describe '#assess_argument' do
108
+ let(:argument_id) do
109
+ id = engine.create_argument(claim: 'Test', warrant: 'Because')[:argument][:id]
110
+ 3.times { |i| engine.add_ground(argument_id: id, ground: "G#{i}") }
111
+ id
112
+ end
113
+
114
+ it 'returns a full assessment for a known argument' do
115
+ result = engine.assess_argument(argument_id: argument_id)
116
+ expect(result[:success]).to be true
117
+ expect(result).to include(:strength, :strength_label, :sound, :rebutted)
118
+ expect(result[:ground_count]).to eq(3)
119
+ end
120
+
121
+ it 'returns failure for unknown argument' do
122
+ result = engine.assess_argument(argument_id: 'nope')
123
+ expect(result[:success]).to be false
124
+ expect(result[:reason]).to eq(:not_found)
125
+ end
126
+ end
127
+
128
+ describe '#sound_arguments' do
129
+ it 'returns only sound arguments' do
130
+ id = engine.create_argument(claim: 'Sound claim', warrant: 'Solid warrant')[:argument][:id]
131
+ 3.times { |i| engine.add_ground(argument_id: id, ground: "G#{i}") }
132
+ 2.times { |i| engine.add_backing(argument_id: id, backing: "B#{i}") }
133
+
134
+ engine.create_argument(claim: 'Weak claim')
135
+
136
+ expect(engine.sound_arguments.size).to eq(1)
137
+ expect(engine.sound_arguments.first.claim).to eq('Sound claim')
138
+ end
139
+ end
140
+
141
+ describe '#rebutted_arguments' do
142
+ it 'returns only rebutted arguments' do
143
+ id = engine.create_argument(claim: 'Test claim')[:argument][:id]
144
+ engine.add_rebuttal(argument_id: id, content: 'Major objection', impact: 0.9)
145
+
146
+ engine.create_argument(claim: 'Unrebutted claim')
147
+
148
+ expect(engine.rebutted_arguments.size).to eq(1)
149
+ end
150
+ end
151
+
152
+ describe '#arguments_by_domain' do
153
+ it 'returns arguments matching the given domain' do
154
+ engine.create_argument(claim: 'Policy claim', domain: :policy)
155
+ engine.create_argument(claim: 'Science claim', domain: :science)
156
+ engine.create_argument(claim: 'Another policy', domain: :policy)
157
+
158
+ results = engine.arguments_by_domain(domain: :policy)
159
+ expect(results.size).to eq(2)
160
+ results.each { |a| expect(a.domain).to eq(:policy) }
161
+ end
162
+ end
163
+
164
+ describe '#strongest_arguments' do
165
+ before do
166
+ 3.times do |i|
167
+ id = engine.create_argument(claim: "Claim #{i}", warrant: "Warrant #{i}")[:argument][:id]
168
+ i.times { |j| engine.add_ground(argument_id: id, ground: "G#{j}") }
169
+ end
170
+ end
171
+
172
+ it 'returns arguments sorted by descending strength' do
173
+ results = engine.strongest_arguments(limit: 3)
174
+ strengths = results.map(&:strength)
175
+ expect(strengths).to eq(strengths.sort.reverse)
176
+ end
177
+
178
+ it 'respects the limit parameter' do
179
+ results = engine.strongest_arguments(limit: 2)
180
+ expect(results.size).to be <= 2
181
+ end
182
+ end
183
+
184
+ describe '#weakest_arguments' do
185
+ before do
186
+ 3.times do |i|
187
+ id = engine.create_argument(claim: "Claim #{i}", warrant: "Warrant #{i}")[:argument][:id]
188
+ i.times { |j| engine.add_ground(argument_id: id, ground: "G#{j}") }
189
+ end
190
+ end
191
+
192
+ it 'returns arguments sorted by ascending strength' do
193
+ results = engine.weakest_arguments(limit: 3)
194
+ strengths = results.map(&:strength)
195
+ expect(strengths).to eq(strengths.sort)
196
+ end
197
+ end
198
+
199
+ describe '#decay_all' do
200
+ it 'returns the argument count' do
201
+ engine.create_argument(claim: 'A')
202
+ engine.create_argument(claim: 'B')
203
+ expect(engine.decay_all).to eq(2)
204
+ end
205
+ end
206
+
207
+ describe '#to_h' do
208
+ it 'returns stats summary' do
209
+ h = engine.to_h
210
+ expect(h).to include(:total_arguments, :sound_arguments, :rebutted_arguments, :history_entries)
211
+ end
212
+
213
+ it 'reflects current counts' do
214
+ engine.create_argument(claim: 'Test')
215
+ expect(engine.to_h[:total_arguments]).to eq(1)
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,231 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Inference::ArgumentMapping::Helpers::Argument do
4
+ subject(:argument) do
5
+ described_class.new(
6
+ id: 'arg_1',
7
+ claim: 'We should invest in renewable energy',
8
+ domain: :policy,
9
+ warrant: 'Renewable energy reduces carbon emissions',
10
+ qualifier: :probably
11
+ )
12
+ end
13
+
14
+ describe '#initialize' do
15
+ it 'sets id, claim, domain, warrant, qualifier' do
16
+ expect(argument.id).to eq('arg_1')
17
+ expect(argument.claim).to eq('We should invest in renewable energy')
18
+ expect(argument.domain).to eq(:policy)
19
+ expect(argument.warrant).to eq('Renewable energy reduces carbon emissions')
20
+ expect(argument.qualifier).to eq(:probably)
21
+ end
22
+
23
+ it 'starts with empty grounds, backing, and rebuttals' do
24
+ expect(argument.grounds).to be_empty
25
+ expect(argument.backing).to be_empty
26
+ expect(argument.rebuttals).to be_empty
27
+ end
28
+
29
+ it 'defaults qualifier to :presumably when not specified' do
30
+ a = described_class.new(id: 'x', claim: 'Some claim', domain: :general)
31
+ expect(a.qualifier).to eq(:presumably)
32
+ end
33
+
34
+ it 'defaults warrant to nil' do
35
+ a = described_class.new(id: 'x', claim: 'Some claim', domain: :general)
36
+ expect(a.warrant).to be_nil
37
+ end
38
+
39
+ it 'sets created_at' do
40
+ expect(argument.created_at).not_to be_nil
41
+ end
42
+ end
43
+
44
+ describe '#add_ground' do
45
+ it 'appends a ground to the grounds array' do
46
+ argument.add_ground(ground: 'Solar prices fell 90% in a decade')
47
+ expect(argument.grounds).to include('Solar prices fell 90% in a decade')
48
+ end
49
+
50
+ it 'accumulates multiple grounds' do
51
+ argument.add_ground(ground: 'Ground one')
52
+ argument.add_ground(ground: 'Ground two')
53
+ expect(argument.grounds.size).to eq(2)
54
+ end
55
+ end
56
+
57
+ describe '#add_backing' do
58
+ it 'appends backing to the backing array' do
59
+ argument.add_backing(backing: 'IPCC report 2023')
60
+ expect(argument.backing).to include('IPCC report 2023')
61
+ end
62
+
63
+ it 'accumulates multiple backing entries' do
64
+ argument.add_backing(backing: 'Study A')
65
+ argument.add_backing(backing: 'Study B')
66
+ expect(argument.backing.size).to eq(2)
67
+ end
68
+ end
69
+
70
+ describe '#add_rebuttal' do
71
+ it 'appends a rebuttal with content and impact' do
72
+ argument.add_rebuttal(content: 'High upfront costs', impact: 0.6)
73
+ expect(argument.rebuttals.size).to eq(1)
74
+ expect(argument.rebuttals.first[:content]).to eq('High upfront costs')
75
+ expect(argument.rebuttals.first[:impact]).to eq(0.6)
76
+ end
77
+
78
+ it 'defaults impact to 0.5' do
79
+ argument.add_rebuttal(content: 'Some objection')
80
+ expect(argument.rebuttals.first[:impact]).to eq(0.5)
81
+ end
82
+
83
+ it 'clamps impact above 1.0' do
84
+ argument.add_rebuttal(content: 'Too strong', impact: 1.5)
85
+ expect(argument.rebuttals.first[:impact]).to eq(1.0)
86
+ end
87
+
88
+ it 'clamps impact below 0.0' do
89
+ argument.add_rebuttal(content: 'Too weak', impact: -0.5)
90
+ expect(argument.rebuttals.first[:impact]).to eq(0.0)
91
+ end
92
+ end
93
+
94
+ describe '#strength' do
95
+ context 'with no grounds, no warrant, no backing' do
96
+ it 'returns 0.0 for bare argument' do
97
+ a = described_class.new(id: 'x', claim: 'Claim', domain: :general)
98
+ expect(a.strength).to eq(0.0)
99
+ end
100
+ end
101
+
102
+ context 'with warrant only' do
103
+ it 'contributes warrant_score * WARRANT_WEIGHT' do
104
+ a = described_class.new(id: 'x', claim: 'Claim', domain: :general, warrant: 'Because')
105
+ expected = 0.8 * Legion::Extensions::Agentic::Inference::ArgumentMapping::Helpers::Constants::WARRANT_WEIGHT
106
+ expect(a.strength).to be_within(0.001).of(expected)
107
+ end
108
+ end
109
+
110
+ context 'with full grounds (3+), warrant, full backing (2+)' do
111
+ before do
112
+ 3.times { |i| argument.add_ground(ground: "Ground #{i}") }
113
+ 2.times { |i| argument.add_backing(backing: "Backing #{i}") }
114
+ end
115
+
116
+ it 'reaches maximum non-rebutted score' do
117
+ consts = Legion::Extensions::Agentic::Inference::ArgumentMapping::Helpers::Constants
118
+ expected = (1.0 * consts::GROUND_WEIGHT) +
119
+ (0.8 * consts::WARRANT_WEIGHT) +
120
+ (1.0 * consts::BACKING_WEIGHT)
121
+ expect(argument.strength).to be_within(0.001).of(expected)
122
+ end
123
+ end
124
+
125
+ context 'with a devastating rebuttal' do
126
+ before do
127
+ 3.times { |i| argument.add_ground(ground: "Ground #{i}") }
128
+ argument.add_rebuttal(content: 'Fatal objection', impact: 1.0)
129
+ end
130
+
131
+ it 'reduces strength due to rebuttal penalty' do
132
+ a_no_rebuttal = described_class.new(
133
+ id: 'y', claim: 'Claim', domain: :general, warrant: 'Because'
134
+ )
135
+ 3.times { |i| a_no_rebuttal.add_ground(ground: "G#{i}") }
136
+ expect(argument.strength).to be < a_no_rebuttal.strength
137
+ end
138
+ end
139
+
140
+ it 'is clamped to 0..1' do
141
+ 3.times { |i| argument.add_ground(ground: "G#{i}") }
142
+ 2.times { |i| argument.add_backing(backing: "B#{i}") }
143
+ expect(argument.strength).to be >= 0.0
144
+ expect(argument.strength).to be <= 1.0
145
+ end
146
+ end
147
+
148
+ describe '#strength_label' do
149
+ it 'returns :compelling for strength >= 0.8' do
150
+ 3.times { |i| argument.add_ground(ground: "G#{i}") }
151
+ 2.times { |i| argument.add_backing(backing: "B#{i}") }
152
+ label = argument.strength_label
153
+ expect(%i[compelling strong]).to include(label)
154
+ end
155
+
156
+ it 'returns :fallacious for zero-strength argument' do
157
+ a = described_class.new(id: 'x', claim: 'Empty', domain: :general)
158
+ expect(a.strength_label).to eq(:fallacious)
159
+ end
160
+ end
161
+
162
+ describe '#sound?' do
163
+ context 'when strength >= 0.6, warrant present, grounds non-empty' do
164
+ before do
165
+ 3.times { |i| argument.add_ground(ground: "Ground #{i}") }
166
+ 2.times { |i| argument.add_backing(backing: "Backing #{i}") }
167
+ end
168
+
169
+ it 'returns true' do
170
+ expect(argument.sound?).to be true
171
+ end
172
+ end
173
+
174
+ context 'when warrant is nil' do
175
+ it 'returns false' do
176
+ a = described_class.new(id: 'x', claim: 'Claim', domain: :general)
177
+ 3.times { |i| a.add_ground(ground: "G#{i}") }
178
+ expect(a.sound?).to be false
179
+ end
180
+ end
181
+
182
+ context 'when grounds is empty' do
183
+ it 'returns false' do
184
+ a = described_class.new(id: 'x', claim: 'Claim', domain: :general, warrant: 'Because')
185
+ expect(a.sound?).to be false
186
+ end
187
+ end
188
+
189
+ context 'when strength is below 0.6' do
190
+ it 'returns false' do
191
+ a = described_class.new(id: 'x', claim: 'Claim', domain: :general, warrant: 'Because')
192
+ a.add_ground(ground: 'One ground')
193
+ a.add_rebuttal(content: 'Strong objection', impact: 0.9)
194
+ expect(a.sound?).to be false
195
+ end
196
+ end
197
+ end
198
+
199
+ describe '#rebutted?' do
200
+ it 'returns false when there are no rebuttals' do
201
+ expect(argument.rebutted?).to be false
202
+ end
203
+
204
+ it 'returns false when all rebuttals have impact <= 0.5' do
205
+ argument.add_rebuttal(content: 'Minor point', impact: 0.4)
206
+ expect(argument.rebutted?).to be false
207
+ end
208
+
209
+ it 'returns true when any rebuttal has impact > 0.5' do
210
+ argument.add_rebuttal(content: 'Major objection', impact: 0.8)
211
+ expect(argument.rebutted?).to be true
212
+ end
213
+ end
214
+
215
+ describe '#to_h' do
216
+ it 'returns a hash with all expected keys' do
217
+ h = argument.to_h
218
+ expect(h).to include(
219
+ :id, :claim, :domain, :grounds, :warrant, :backing,
220
+ :qualifier, :rebuttals, :strength, :strength_label,
221
+ :sound, :rebutted, :created_at
222
+ )
223
+ end
224
+
225
+ it 'reflects current state' do
226
+ argument.add_ground(ground: 'Evidence A')
227
+ h = argument.to_h
228
+ expect(h[:grounds]).to include('Evidence A')
229
+ end
230
+ end
231
+ end