lex-agentic-social 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 (235) 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-social.gemspec +30 -0
  7. data/lib/legion/extensions/agentic/social/apprenticeship/client.rb +28 -0
  8. data/lib/legion/extensions/agentic/social/apprenticeship/helpers/apprenticeship.rb +90 -0
  9. data/lib/legion/extensions/agentic/social/apprenticeship/helpers/apprenticeship_engine.rb +109 -0
  10. data/lib/legion/extensions/agentic/social/apprenticeship/helpers/apprenticeship_model.rb +93 -0
  11. data/lib/legion/extensions/agentic/social/apprenticeship/runners/cognitive_apprenticeship.rb +112 -0
  12. data/lib/legion/extensions/agentic/social/apprenticeship/version.rb +13 -0
  13. data/lib/legion/extensions/agentic/social/apprenticeship.rb +19 -0
  14. data/lib/legion/extensions/agentic/social/conflict/actors/stale_check.rb +45 -0
  15. data/lib/legion/extensions/agentic/social/conflict/client.rb +27 -0
  16. data/lib/legion/extensions/agentic/social/conflict/helpers/conflict_log.rb +70 -0
  17. data/lib/legion/extensions/agentic/social/conflict/helpers/llm_enhancer.rb +130 -0
  18. data/lib/legion/extensions/agentic/social/conflict/helpers/severity.rb +47 -0
  19. data/lib/legion/extensions/agentic/social/conflict/runners/conflict.rb +112 -0
  20. data/lib/legion/extensions/agentic/social/conflict/version.rb +13 -0
  21. data/lib/legion/extensions/agentic/social/conflict.rb +19 -0
  22. data/lib/legion/extensions/agentic/social/conscience/client.rb +26 -0
  23. data/lib/legion/extensions/agentic/social/conscience/helpers/constants.rb +53 -0
  24. data/lib/legion/extensions/agentic/social/conscience/helpers/moral_evaluator.rb +178 -0
  25. data/lib/legion/extensions/agentic/social/conscience/helpers/moral_store.rb +116 -0
  26. data/lib/legion/extensions/agentic/social/conscience/runners/conscience.rb +117 -0
  27. data/lib/legion/extensions/agentic/social/conscience/version.rb +13 -0
  28. data/lib/legion/extensions/agentic/social/conscience.rb +19 -0
  29. data/lib/legion/extensions/agentic/social/consent/actors/tier_evaluation.rb +45 -0
  30. data/lib/legion/extensions/agentic/social/consent/client.rb +27 -0
  31. data/lib/legion/extensions/agentic/social/consent/helpers/consent_map.rb +199 -0
  32. data/lib/legion/extensions/agentic/social/consent/helpers/tiers.rb +54 -0
  33. data/lib/legion/extensions/agentic/social/consent/local_migrations/20260316000010_create_consent_domains.rb +16 -0
  34. data/lib/legion/extensions/agentic/social/consent/runners/consent.rb +228 -0
  35. data/lib/legion/extensions/agentic/social/consent/version.rb +13 -0
  36. data/lib/legion/extensions/agentic/social/consent.rb +25 -0
  37. data/lib/legion/extensions/agentic/social/entrainment/client.rb +19 -0
  38. data/lib/legion/extensions/agentic/social/entrainment/helpers/constants.rb +40 -0
  39. data/lib/legion/extensions/agentic/social/entrainment/helpers/entrainment_engine.rb +120 -0
  40. data/lib/legion/extensions/agentic/social/entrainment/helpers/pairing.rb +86 -0
  41. data/lib/legion/extensions/agentic/social/entrainment/runners/cognitive_entrainment.rb +89 -0
  42. data/lib/legion/extensions/agentic/social/entrainment/version.rb +13 -0
  43. data/lib/legion/extensions/agentic/social/entrainment.rb +19 -0
  44. data/lib/legion/extensions/agentic/social/governance/actors/shadow_ai_scan.rb +19 -0
  45. data/lib/legion/extensions/agentic/social/governance/actors/vote_timeout.rb +45 -0
  46. data/lib/legion/extensions/agentic/social/governance/client.rb +27 -0
  47. data/lib/legion/extensions/agentic/social/governance/helpers/layers.rb +40 -0
  48. data/lib/legion/extensions/agentic/social/governance/helpers/proposal.rb +94 -0
  49. data/lib/legion/extensions/agentic/social/governance/runners/governance.rb +87 -0
  50. data/lib/legion/extensions/agentic/social/governance/runners/shadow_ai.rb +93 -0
  51. data/lib/legion/extensions/agentic/social/governance/version.rb +13 -0
  52. data/lib/legion/extensions/agentic/social/governance.rb +20 -0
  53. data/lib/legion/extensions/agentic/social/joint_attention/actors/decay.rb +45 -0
  54. data/lib/legion/extensions/agentic/social/joint_attention/client.rb +28 -0
  55. data/lib/legion/extensions/agentic/social/joint_attention/helpers/attention_target.rb +124 -0
  56. data/lib/legion/extensions/agentic/social/joint_attention/helpers/constants.rb +34 -0
  57. data/lib/legion/extensions/agentic/social/joint_attention/helpers/joint_focus_manager.rb +157 -0
  58. data/lib/legion/extensions/agentic/social/joint_attention/runners/joint_attention.rb +88 -0
  59. data/lib/legion/extensions/agentic/social/joint_attention/version.rb +13 -0
  60. data/lib/legion/extensions/agentic/social/joint_attention.rb +20 -0
  61. data/lib/legion/extensions/agentic/social/mentalizing/actors/decay.rb +45 -0
  62. data/lib/legion/extensions/agentic/social/mentalizing/client.rb +28 -0
  63. data/lib/legion/extensions/agentic/social/mentalizing/helpers/belief_attribution.rb +58 -0
  64. data/lib/legion/extensions/agentic/social/mentalizing/helpers/constants.rb +33 -0
  65. data/lib/legion/extensions/agentic/social/mentalizing/helpers/mental_model.rb +137 -0
  66. data/lib/legion/extensions/agentic/social/mentalizing/runners/mentalizing.rb +93 -0
  67. data/lib/legion/extensions/agentic/social/mentalizing/version.rb +13 -0
  68. data/lib/legion/extensions/agentic/social/mentalizing.rb +20 -0
  69. data/lib/legion/extensions/agentic/social/mirror/client.rb +33 -0
  70. data/lib/legion/extensions/agentic/social/mirror/helpers/constants.rb +65 -0
  71. data/lib/legion/extensions/agentic/social/mirror/helpers/mirror_engine.rb +132 -0
  72. data/lib/legion/extensions/agentic/social/mirror/helpers/mirror_event.rb +46 -0
  73. data/lib/legion/extensions/agentic/social/mirror/helpers/simulation.rb +43 -0
  74. data/lib/legion/extensions/agentic/social/mirror/runners/observe.rb +52 -0
  75. data/lib/legion/extensions/agentic/social/mirror/runners/resonance.rb +79 -0
  76. data/lib/legion/extensions/agentic/social/mirror/runners/simulate.rb +63 -0
  77. data/lib/legion/extensions/agentic/social/mirror/version.rb +13 -0
  78. data/lib/legion/extensions/agentic/social/mirror.rb +22 -0
  79. data/lib/legion/extensions/agentic/social/mirror_system/actors/decay.rb +45 -0
  80. data/lib/legion/extensions/agentic/social/mirror_system/client.rb +28 -0
  81. data/lib/legion/extensions/agentic/social/mirror_system/helpers/constants.rb +62 -0
  82. data/lib/legion/extensions/agentic/social/mirror_system/helpers/mirror_system.rb +162 -0
  83. data/lib/legion/extensions/agentic/social/mirror_system/helpers/observed_behavior.rb +67 -0
  84. data/lib/legion/extensions/agentic/social/mirror_system/runners/mirror.rb +99 -0
  85. data/lib/legion/extensions/agentic/social/mirror_system/version.rb +13 -0
  86. data/lib/legion/extensions/agentic/social/mirror_system.rb +20 -0
  87. data/lib/legion/extensions/agentic/social/moral_reasoning/client.rb +19 -0
  88. data/lib/legion/extensions/agentic/social/moral_reasoning/helpers/constants.rb +49 -0
  89. data/lib/legion/extensions/agentic/social/moral_reasoning/helpers/dilemma.rb +68 -0
  90. data/lib/legion/extensions/agentic/social/moral_reasoning/helpers/llm_enhancer.rb +140 -0
  91. data/lib/legion/extensions/agentic/social/moral_reasoning/helpers/moral_engine.rb +239 -0
  92. data/lib/legion/extensions/agentic/social/moral_reasoning/helpers/moral_foundation.rb +45 -0
  93. data/lib/legion/extensions/agentic/social/moral_reasoning/runners/moral_reasoning.rb +121 -0
  94. data/lib/legion/extensions/agentic/social/moral_reasoning/version.rb +13 -0
  95. data/lib/legion/extensions/agentic/social/moral_reasoning.rb +21 -0
  96. data/lib/legion/extensions/agentic/social/perspective_shifting/client.rb +29 -0
  97. data/lib/legion/extensions/agentic/social/perspective_shifting/helpers/constants.rb +67 -0
  98. data/lib/legion/extensions/agentic/social/perspective_shifting/helpers/perspective.rb +45 -0
  99. data/lib/legion/extensions/agentic/social/perspective_shifting/helpers/perspective_view.rb +57 -0
  100. data/lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb +166 -0
  101. data/lib/legion/extensions/agentic/social/perspective_shifting/runners/perspective_shifting.rb +167 -0
  102. data/lib/legion/extensions/agentic/social/perspective_shifting/version.rb +13 -0
  103. data/lib/legion/extensions/agentic/social/perspective_shifting.rb +20 -0
  104. data/lib/legion/extensions/agentic/social/social/client.rb +25 -0
  105. data/lib/legion/extensions/agentic/social/social/helpers/constants.rb +84 -0
  106. data/lib/legion/extensions/agentic/social/social/helpers/social_graph.rb +172 -0
  107. data/lib/legion/extensions/agentic/social/social/runners/social.rb +146 -0
  108. data/lib/legion/extensions/agentic/social/social/version.rb +13 -0
  109. data/lib/legion/extensions/agentic/social/social.rb +18 -0
  110. data/lib/legion/extensions/agentic/social/social_learning/client.rb +25 -0
  111. data/lib/legion/extensions/agentic/social/social_learning/helpers/constants.rb +42 -0
  112. data/lib/legion/extensions/agentic/social/social_learning/helpers/model_agent.rb +82 -0
  113. data/lib/legion/extensions/agentic/social/social_learning/helpers/observed_behavior.rb +61 -0
  114. data/lib/legion/extensions/agentic/social/social_learning/helpers/social_learning_engine.rb +134 -0
  115. data/lib/legion/extensions/agentic/social/social_learning/runners/social_learning.rb +105 -0
  116. data/lib/legion/extensions/agentic/social/social_learning/version.rb +13 -0
  117. data/lib/legion/extensions/agentic/social/social_learning.rb +20 -0
  118. data/lib/legion/extensions/agentic/social/symbiosis/client.rb +23 -0
  119. data/lib/legion/extensions/agentic/social/symbiosis/helpers/constants.rb +50 -0
  120. data/lib/legion/extensions/agentic/social/symbiosis/helpers/ecosystem.rb +113 -0
  121. data/lib/legion/extensions/agentic/social/symbiosis/helpers/symbiosis_engine.rb +104 -0
  122. data/lib/legion/extensions/agentic/social/symbiosis/helpers/symbiotic_bond.rb +112 -0
  123. data/lib/legion/extensions/agentic/social/symbiosis/runners/cognitive_symbiosis.rb +101 -0
  124. data/lib/legion/extensions/agentic/social/symbiosis/version.rb +13 -0
  125. data/lib/legion/extensions/agentic/social/symbiosis.rb +22 -0
  126. data/lib/legion/extensions/agentic/social/theory_of_mind/client.rb +26 -0
  127. data/lib/legion/extensions/agentic/social/theory_of_mind/helpers/agent_model.rb +173 -0
  128. data/lib/legion/extensions/agentic/social/theory_of_mind/helpers/constants.rb +70 -0
  129. data/lib/legion/extensions/agentic/social/theory_of_mind/helpers/mental_state_tracker.rb +169 -0
  130. data/lib/legion/extensions/agentic/social/theory_of_mind/runners/theory_of_mind.rb +159 -0
  131. data/lib/legion/extensions/agentic/social/theory_of_mind/version.rb +13 -0
  132. data/lib/legion/extensions/agentic/social/theory_of_mind.rb +19 -0
  133. data/lib/legion/extensions/agentic/social/trust/actors/decay.rb +45 -0
  134. data/lib/legion/extensions/agentic/social/trust/client.rb +27 -0
  135. data/lib/legion/extensions/agentic/social/trust/helpers/trust_map.rb +160 -0
  136. data/lib/legion/extensions/agentic/social/trust/helpers/trust_model.rb +52 -0
  137. data/lib/legion/extensions/agentic/social/trust/local_migrations/20260316000020_create_trust_entries.rb +23 -0
  138. data/lib/legion/extensions/agentic/social/trust/runners/trust.rb +80 -0
  139. data/lib/legion/extensions/agentic/social/trust/version.rb +13 -0
  140. data/lib/legion/extensions/agentic/social/trust.rb +25 -0
  141. data/lib/legion/extensions/agentic/social/version.rb +11 -0
  142. data/lib/legion/extensions/agentic/social.rb +34 -0
  143. data/spec/legion/extensions/agentic/social/apprenticeship/client_spec.rb +20 -0
  144. data/spec/legion/extensions/agentic/social/apprenticeship/cognitive_apprenticeship_spec.rb +11 -0
  145. data/spec/legion/extensions/agentic/social/apprenticeship/helpers/apprenticeship_engine_spec.rb +146 -0
  146. data/spec/legion/extensions/agentic/social/apprenticeship/helpers/apprenticeship_model_spec.rb +124 -0
  147. data/spec/legion/extensions/agentic/social/apprenticeship/helpers/apprenticeship_spec.rb +136 -0
  148. data/spec/legion/extensions/agentic/social/apprenticeship/runners/cognitive_apprenticeship_spec.rb +154 -0
  149. data/spec/legion/extensions/agentic/social/conflict/actors/stale_check_spec.rb +45 -0
  150. data/spec/legion/extensions/agentic/social/conflict/client_spec.rb +15 -0
  151. data/spec/legion/extensions/agentic/social/conflict/helpers/conflict_log_spec.rb +232 -0
  152. data/spec/legion/extensions/agentic/social/conflict/helpers/llm_enhancer_spec.rb +189 -0
  153. data/spec/legion/extensions/agentic/social/conflict/helpers/severity_spec.rb +215 -0
  154. data/spec/legion/extensions/agentic/social/conflict/runners/conflict_spec.rb +151 -0
  155. data/spec/legion/extensions/agentic/social/conscience/client_spec.rb +58 -0
  156. data/spec/legion/extensions/agentic/social/conscience/helpers/constants_spec.rb +124 -0
  157. data/spec/legion/extensions/agentic/social/conscience/helpers/moral_evaluator_spec.rb +253 -0
  158. data/spec/legion/extensions/agentic/social/conscience/helpers/moral_store_spec.rb +230 -0
  159. data/spec/legion/extensions/agentic/social/conscience/runners/conscience_spec.rb +239 -0
  160. data/spec/legion/extensions/agentic/social/consent/actors/tier_evaluation_spec.rb +46 -0
  161. data/spec/legion/extensions/agentic/social/consent/client_spec.rb +33 -0
  162. data/spec/legion/extensions/agentic/social/consent/helpers/tiers_spec.rb +49 -0
  163. data/spec/legion/extensions/agentic/social/consent/local_persistence_spec.rb +234 -0
  164. data/spec/legion/extensions/agentic/social/consent/runners/consent_spec.rb +224 -0
  165. data/spec/legion/extensions/agentic/social/entrainment/client_spec.rb +21 -0
  166. data/spec/legion/extensions/agentic/social/entrainment/helpers/entrainment_engine_spec.rb +116 -0
  167. data/spec/legion/extensions/agentic/social/entrainment/helpers/pairing_spec.rb +103 -0
  168. data/spec/legion/extensions/agentic/social/entrainment/runners/cognitive_entrainment_spec.rb +87 -0
  169. data/spec/legion/extensions/agentic/social/governance/actors/vote_timeout_spec.rb +45 -0
  170. data/spec/legion/extensions/agentic/social/governance/client_spec.rb +14 -0
  171. data/spec/legion/extensions/agentic/social/governance/helpers/layers_spec.rb +190 -0
  172. data/spec/legion/extensions/agentic/social/governance/helpers/proposal_spec.rb +188 -0
  173. data/spec/legion/extensions/agentic/social/governance/runners/governance_spec.rb +101 -0
  174. data/spec/legion/extensions/agentic/social/governance/runners/shadow_ai_spec.rb +65 -0
  175. data/spec/legion/extensions/agentic/social/joint_attention/client_spec.rb +36 -0
  176. data/spec/legion/extensions/agentic/social/joint_attention/helpers/attention_target_spec.rb +258 -0
  177. data/spec/legion/extensions/agentic/social/joint_attention/helpers/joint_focus_manager_spec.rb +238 -0
  178. data/spec/legion/extensions/agentic/social/joint_attention/runners/joint_attention_spec.rb +228 -0
  179. data/spec/legion/extensions/agentic/social/mentalizing/client_spec.rb +19 -0
  180. data/spec/legion/extensions/agentic/social/mentalizing/helpers/belief_attribution_spec.rb +108 -0
  181. data/spec/legion/extensions/agentic/social/mentalizing/helpers/mental_model_spec.rb +179 -0
  182. data/spec/legion/extensions/agentic/social/mentalizing/runners/mentalizing_spec.rb +162 -0
  183. data/spec/legion/extensions/agentic/social/mirror/client_spec.rb +92 -0
  184. data/spec/legion/extensions/agentic/social/mirror/helpers/constants_spec.rb +123 -0
  185. data/spec/legion/extensions/agentic/social/mirror/helpers/mirror_engine_spec.rb +217 -0
  186. data/spec/legion/extensions/agentic/social/mirror/helpers/mirror_event_spec.rb +102 -0
  187. data/spec/legion/extensions/agentic/social/mirror/helpers/simulation_spec.rb +100 -0
  188. data/spec/legion/extensions/agentic/social/mirror/runners/observe_spec.rb +77 -0
  189. data/spec/legion/extensions/agentic/social/mirror/runners/resonance_spec.rb +123 -0
  190. data/spec/legion/extensions/agentic/social/mirror/runners/simulate_spec.rb +103 -0
  191. data/spec/legion/extensions/agentic/social/mirror_system/client_spec.rb +40 -0
  192. data/spec/legion/extensions/agentic/social/mirror_system/helpers/mirror_system_spec.rb +144 -0
  193. data/spec/legion/extensions/agentic/social/mirror_system/helpers/observed_behavior_spec.rb +98 -0
  194. data/spec/legion/extensions/agentic/social/mirror_system/runners/mirror_spec.rb +122 -0
  195. data/spec/legion/extensions/agentic/social/moral_reasoning/client_spec.rb +34 -0
  196. data/spec/legion/extensions/agentic/social/moral_reasoning/helpers/dilemma_spec.rb +108 -0
  197. data/spec/legion/extensions/agentic/social/moral_reasoning/helpers/llm_enhancer_spec.rb +232 -0
  198. data/spec/legion/extensions/agentic/social/moral_reasoning/helpers/moral_engine_spec.rb +266 -0
  199. data/spec/legion/extensions/agentic/social/moral_reasoning/helpers/moral_foundation_spec.rb +70 -0
  200. data/spec/legion/extensions/agentic/social/moral_reasoning/runners/moral_reasoning_spec.rb +275 -0
  201. data/spec/legion/extensions/agentic/social/perspective_shifting/client_spec.rb +30 -0
  202. data/spec/legion/extensions/agentic/social/perspective_shifting/helpers/constants_spec.rb +99 -0
  203. data/spec/legion/extensions/agentic/social/perspective_shifting/helpers/perspective_spec.rb +77 -0
  204. data/spec/legion/extensions/agentic/social/perspective_shifting/helpers/perspective_view_spec.rb +105 -0
  205. data/spec/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine_spec.rb +246 -0
  206. data/spec/legion/extensions/agentic/social/perspective_shifting/runners/perspective_shifting_spec.rb +277 -0
  207. data/spec/legion/extensions/agentic/social/social/client_spec.rb +72 -0
  208. data/spec/legion/extensions/agentic/social/social/helpers/constants_spec.rb +99 -0
  209. data/spec/legion/extensions/agentic/social/social/helpers/social_graph_spec.rb +322 -0
  210. data/spec/legion/extensions/agentic/social/social/runners/social_spec.rb +220 -0
  211. data/spec/legion/extensions/agentic/social/social_learning/client_spec.rb +25 -0
  212. data/spec/legion/extensions/agentic/social/social_learning/helpers/constants_spec.rb +44 -0
  213. data/spec/legion/extensions/agentic/social/social_learning/helpers/model_agent_spec.rb +120 -0
  214. data/spec/legion/extensions/agentic/social/social_learning/helpers/observed_behavior_spec.rb +81 -0
  215. data/spec/legion/extensions/agentic/social/social_learning/helpers/social_learning_engine_spec.rb +196 -0
  216. data/spec/legion/extensions/agentic/social/social_learning/runners/social_learning_spec.rb +150 -0
  217. data/spec/legion/extensions/agentic/social/symbiosis/client_spec.rb +45 -0
  218. data/spec/legion/extensions/agentic/social/symbiosis/helpers/constants_spec.rb +73 -0
  219. data/spec/legion/extensions/agentic/social/symbiosis/helpers/ecosystem_spec.rb +185 -0
  220. data/spec/legion/extensions/agentic/social/symbiosis/helpers/symbiosis_engine_spec.rb +182 -0
  221. data/spec/legion/extensions/agentic/social/symbiosis/helpers/symbiotic_bond_spec.rb +209 -0
  222. data/spec/legion/extensions/agentic/social/symbiosis/runners/cognitive_symbiosis_spec.rb +182 -0
  223. data/spec/legion/extensions/agentic/social/theory_of_mind/client_spec.rb +63 -0
  224. data/spec/legion/extensions/agentic/social/theory_of_mind/helpers/agent_model_spec.rb +244 -0
  225. data/spec/legion/extensions/agentic/social/theory_of_mind/helpers/constants_spec.rb +71 -0
  226. data/spec/legion/extensions/agentic/social/theory_of_mind/helpers/mental_state_tracker_spec.rb +228 -0
  227. data/spec/legion/extensions/agentic/social/theory_of_mind/runners/theory_of_mind_spec.rb +221 -0
  228. data/spec/legion/extensions/agentic/social/trust/actors/decay_spec.rb +62 -0
  229. data/spec/legion/extensions/agentic/social/trust/client_spec.rb +17 -0
  230. data/spec/legion/extensions/agentic/social/trust/helpers/trust_map_spec.rb +299 -0
  231. data/spec/legion/extensions/agentic/social/trust/helpers/trust_model_spec.rb +179 -0
  232. data/spec/legion/extensions/agentic/social/trust/local_persistence_spec.rb +359 -0
  233. data/spec/legion/extensions/agentic/social/trust/runners/trust_spec.rb +84 -0
  234. data/spec/spec_helper.rb +54 -0
  235. metadata +319 -0
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/social/symbiosis/client'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Social::Symbiosis::Runners::CognitiveSymbiosis do
6
+ let(:client) { Legion::Extensions::Agentic::Social::Symbiosis::Client.new }
7
+ let(:engine) { Legion::Extensions::Agentic::Social::Symbiosis::Helpers::SymbiosisEngine.new }
8
+
9
+ describe '#create_bond' do
10
+ it 'creates a mutualistic bond' do
11
+ result = client.create_bond(subsystem_a: 'memory', subsystem_b: 'emotion', relationship_type: :mutualistic)
12
+ expect(result[:success]).to be true
13
+ expect(result[:bond][:relationship_type]).to eq(:mutualistic)
14
+ end
15
+
16
+ it 'creates a parasitic bond' do
17
+ result = client.create_bond(subsystem_a: 'cortex', subsystem_b: 'tick', relationship_type: :parasitic)
18
+ expect(result[:success]).to be true
19
+ end
20
+
21
+ it 'creates a commensal bond' do
22
+ result = client.create_bond(subsystem_a: 'trust', subsystem_b: 'identity', relationship_type: :commensal)
23
+ expect(result[:success]).to be true
24
+ end
25
+
26
+ it 'returns success: false for duplicate bond' do
27
+ client.create_bond(subsystem_a: 'memory', subsystem_b: 'emotion', relationship_type: :mutualistic)
28
+ result = client.create_bond(subsystem_a: 'memory', subsystem_b: 'emotion', relationship_type: :mutualistic)
29
+ expect(result[:success]).to be false
30
+ end
31
+
32
+ it 'returns success: false for invalid relationship_type' do
33
+ result = client.create_bond(subsystem_a: 'a', subsystem_b: 'b', relationship_type: :invalid)
34
+ expect(result[:success]).to be false
35
+ expect(result[:error]).to be_a(String)
36
+ end
37
+
38
+ it 'uses injected engine' do
39
+ result = client.create_bond(subsystem_a: 'a', subsystem_b: 'b', relationship_type: :mutualistic, engine: engine)
40
+ expect(result[:success]).to be true
41
+ end
42
+
43
+ it 'ignores extra keyword arguments via ** splat' do
44
+ result = client.create_bond(subsystem_a: 'x', subsystem_b: 'y', relationship_type: :commensal, extra: :ignored)
45
+ expect(result[:success]).to be true
46
+ end
47
+ end
48
+
49
+ describe '#activate' do
50
+ before { client.create_bond(subsystem_a: 'memory', subsystem_b: 'emotion', relationship_type: :mutualistic) }
51
+
52
+ it 'activates an existing bond' do
53
+ result = client.activate(subsystem_a: 'memory', subsystem_b: 'emotion')
54
+ expect(result[:success]).to be true
55
+ end
56
+
57
+ it 'returns success: false for unknown pair' do
58
+ result = client.activate(subsystem_a: 'x', subsystem_b: 'y')
59
+ expect(result[:success]).to be false
60
+ end
61
+
62
+ it 'includes relationship_type in result' do
63
+ result = client.activate(subsystem_a: 'memory', subsystem_b: 'emotion')
64
+ expect(result[:relationship_type]).to eq(:mutualistic)
65
+ end
66
+
67
+ it 'clamps amount to 1.0' do
68
+ result = client.activate(subsystem_a: 'memory', subsystem_b: 'emotion', amount: 99.0)
69
+ expect(result[:success]).to be true
70
+ end
71
+
72
+ it 'uses injected engine' do
73
+ engine.create_bond(subsystem_a: 'p', subsystem_b: 'q', relationship_type: :commensal)
74
+ result = client.activate(subsystem_a: 'p', subsystem_b: 'q', engine: engine)
75
+ expect(result[:success]).to be true
76
+ end
77
+ end
78
+
79
+ describe '#health_status' do
80
+ it 'returns success: true' do
81
+ result = client.health_status
82
+ expect(result[:success]).to be true
83
+ end
84
+
85
+ it 'includes score and label' do
86
+ result = client.health_status
87
+ expect(result).to include(:score, :label)
88
+ end
89
+
90
+ it 'label improves after adding mutualistic bonds' do
91
+ client.create_bond(subsystem_a: 'a', subsystem_b: 'b', relationship_type: :mutualistic)
92
+ result = client.health_status
93
+ expect(result[:score]).to be >= 0
94
+ end
95
+ end
96
+
97
+ describe '#list_bonds' do
98
+ before do
99
+ client.create_bond(subsystem_a: 'memory', subsystem_b: 'emotion', relationship_type: :mutualistic)
100
+ client.create_bond(subsystem_a: 'cortex', subsystem_b: 'tick', relationship_type: :parasitic)
101
+ client.create_bond(subsystem_a: 'memory', subsystem_b: 'trust', relationship_type: :commensal)
102
+ end
103
+
104
+ it 'returns all bonds when no filter' do
105
+ result = client.list_bonds
106
+ expect(result[:success]).to be true
107
+ expect(result[:count]).to eq(3)
108
+ end
109
+
110
+ it 'filters by subsystem_id' do
111
+ result = client.list_bonds(subsystem_id: 'memory')
112
+ expect(result[:count]).to eq(2)
113
+ end
114
+
115
+ it 'filters by relationship_type' do
116
+ result = client.list_bonds(relationship_type: :mutualistic)
117
+ types = result[:bonds].map { |b| b[:relationship_type] }
118
+ expect(types).to all(eq(:mutualistic))
119
+ end
120
+
121
+ it 'returns empty bonds for unknown subsystem' do
122
+ result = client.list_bonds(subsystem_id: 'nobody')
123
+ expect(result[:count]).to eq(0)
124
+ end
125
+ end
126
+
127
+ describe '#detect_parasites' do
128
+ before do
129
+ client.create_bond(subsystem_a: 'cortex', subsystem_b: 'emotion', relationship_type: :parasitic)
130
+ client.create_bond(subsystem_a: 'memory', subsystem_b: 'trust', relationship_type: :mutualistic)
131
+ end
132
+
133
+ it 'returns success: true' do
134
+ result = client.detect_parasites
135
+ expect(result[:success]).to be true
136
+ end
137
+
138
+ it 'returns only parasitic bonds' do
139
+ result = client.detect_parasites
140
+ types = result[:parasites].map { |b| b[:relationship_type] }
141
+ expect(types).to all(eq(:parasitic))
142
+ end
143
+
144
+ it 'includes count' do
145
+ result = client.detect_parasites
146
+ expect(result[:count]).to be_a(Integer)
147
+ end
148
+
149
+ it 'filters by strength_threshold' do
150
+ result = client.detect_parasites(strength_threshold: 0.99)
151
+ expect(result[:count]).to eq(0)
152
+ end
153
+ end
154
+
155
+ describe '#ecosystem_report' do
156
+ before do
157
+ client.create_bond(subsystem_a: 'memory', subsystem_b: 'emotion', relationship_type: :mutualistic)
158
+ end
159
+
160
+ it 'returns success: true' do
161
+ result = client.ecosystem_report
162
+ expect(result[:success]).to be true
163
+ end
164
+
165
+ it 'includes bonds_by_type for all three types' do
166
+ result = client.ecosystem_report
167
+ expect(result[:bonds_by_type].keys).to include(:mutualistic, :parasitic, :commensal)
168
+ end
169
+
170
+ it 'total_bonds is correct' do
171
+ result = client.ecosystem_report
172
+ expect(result[:total_bonds]).to eq(1)
173
+ end
174
+
175
+ it 'uses injected engine' do
176
+ engine.create_bond(subsystem_a: 'p', subsystem_b: 'q', relationship_type: :commensal)
177
+ result = client.ecosystem_report(engine: engine)
178
+ expect(result[:success]).to be true
179
+ expect(result[:total_bonds]).to eq(1)
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Social::TheoryOfMind::Client do
6
+ describe '#initialize' do
7
+ it 'creates a default mental state tracker' do
8
+ client = described_class.new
9
+ expect(client.tracker).to be_a(Legion::Extensions::Agentic::Social::TheoryOfMind::Helpers::MentalStateTracker)
10
+ end
11
+
12
+ it 'accepts an injected tracker' do
13
+ tracker = Legion::Extensions::Agentic::Social::TheoryOfMind::Helpers::MentalStateTracker.new
14
+ client = described_class.new(tracker: tracker)
15
+ expect(client.tracker).to equal(tracker)
16
+ end
17
+
18
+ it 'ignores unknown keyword arguments' do
19
+ expect { described_class.new(unknown: true) }.not_to raise_error
20
+ end
21
+ end
22
+
23
+ describe 'runner integration' do
24
+ subject(:client) { described_class.new }
25
+
26
+ it 'responds to observe_agent' do
27
+ expect(client).to respond_to(:observe_agent)
28
+ end
29
+
30
+ it 'responds to predict_behavior' do
31
+ expect(client).to respond_to(:predict_behavior)
32
+ end
33
+
34
+ it 'responds to check_false_beliefs' do
35
+ expect(client).to respond_to(:check_false_beliefs)
36
+ end
37
+
38
+ it 'responds to perspective_take' do
39
+ expect(client).to respond_to(:perspective_take)
40
+ end
41
+
42
+ it 'can perform a full ToM workflow' do
43
+ client.observe_agent(agent_id: :bob, observations: { domain: :location, belief: 'office', confidence: 0.9 })
44
+ client.observe_agent(agent_id: :bob, observations: { goal: 'finish_report', goal_priority: :high })
45
+ client.observe_agent(agent_id: :bob, observations: { action: :typing, action_confidence: :certain })
46
+
47
+ prediction = client.predict_behavior(agent_id: :bob)
48
+ expect(prediction[:predicted_action]).to eq(:typing)
49
+ expect(prediction[:underlying_desire]).to eq('finish_report')
50
+
51
+ false_beliefs = client.check_false_beliefs(agent_id: :bob, known_truths: { location: 'home' })
52
+ expect(false_beliefs[:count]).to eq(1)
53
+ expect(false_beliefs[:false_beliefs][:location][:agent_believes]).to eq('office')
54
+
55
+ perspective = client.perspective_take(agent_id: :bob)
56
+ expect(perspective[:perspective][:knowledge][:location]).to eq('office')
57
+
58
+ client.record_outcome(agent_id: :bob, outcome: :correct)
59
+ state = client.mental_state(agent_id: :bob)
60
+ expect(state[:accuracy]).to be > 0.5
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,244 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Social::TheoryOfMind::Helpers::AgentModel do
6
+ subject(:model) { described_class.new(:agent_alpha) }
7
+
8
+ describe '#initialize' do
9
+ it 'sets the agent_id' do
10
+ expect(model.agent_id).to eq(:agent_alpha)
11
+ end
12
+
13
+ it 'starts with empty beliefs' do
14
+ expect(model.beliefs).to be_empty
15
+ end
16
+
17
+ it 'starts with empty desires' do
18
+ expect(model.desires).to be_empty
19
+ end
20
+
21
+ it 'starts with empty intentions' do
22
+ expect(model.intentions).to be_empty
23
+ end
24
+
25
+ it 'starts with 0.5 prediction accuracy' do
26
+ expect(model.prediction_accuracy).to eq(0.5)
27
+ end
28
+ end
29
+
30
+ describe '#update_belief' do
31
+ it 'stores a belief for the domain' do
32
+ model.update_belief(domain: :location, content: 'office', confidence: 0.8)
33
+ expect(model.beliefs[:location][:content]).to eq('office')
34
+ end
35
+
36
+ it 'clamps confidence to 0..1' do
37
+ model.update_belief(domain: :mood, content: 'happy', confidence: 5.0)
38
+ expect(model.beliefs[:mood][:confidence]).to eq(1.0)
39
+ end
40
+
41
+ it 'records the source' do
42
+ model.update_belief(domain: :role, content: 'leader', confidence: 0.7, source: :direct_observation)
43
+ expect(model.beliefs[:role][:source]).to eq(:direct_observation)
44
+ end
45
+
46
+ it 'overwrites existing belief for same domain' do
47
+ model.update_belief(domain: :location, content: 'office', confidence: 0.8)
48
+ model.update_belief(domain: :location, content: 'home', confidence: 0.9)
49
+ expect(model.beliefs[:location][:content]).to eq('home')
50
+ end
51
+
52
+ it 'trims beliefs beyond MAX_BELIEFS_PER_AGENT' do
53
+ max = Legion::Extensions::Agentic::Social::TheoryOfMind::Helpers::Constants::MAX_BELIEFS_PER_AGENT
54
+ (max + 5).times { |i| model.update_belief(domain: :"domain_#{i}", content: "val_#{i}", confidence: 0.5 + (i * 0.001)) }
55
+ expect(model.beliefs.size).to eq(max)
56
+ end
57
+ end
58
+
59
+ describe '#update_desire' do
60
+ it 'adds a new desire' do
61
+ model.update_desire(goal: 'complete_task')
62
+ expect(model.desires.size).to eq(1)
63
+ end
64
+
65
+ it 'defaults priority to medium' do
66
+ model.update_desire(goal: 'learn')
67
+ expect(model.desires.first[:priority]).to eq(:medium)
68
+ end
69
+
70
+ it 'updates existing desire priority' do
71
+ model.update_desire(goal: 'learn', priority: :low)
72
+ model.update_desire(goal: 'learn', priority: :critical)
73
+ expect(model.desires.size).to eq(1)
74
+ expect(model.desires.first[:priority]).to eq(:critical)
75
+ end
76
+
77
+ it 'trims desires beyond MAX_DESIRES_PER_AGENT' do
78
+ max = Legion::Extensions::Agentic::Social::TheoryOfMind::Helpers::Constants::MAX_DESIRES_PER_AGENT
79
+ (max + 5).times { |i| model.update_desire(goal: "goal_#{i}") }
80
+ expect(model.desires.size).to eq(max)
81
+ end
82
+ end
83
+
84
+ describe '#update_intention' do
85
+ it 'adds a new intention' do
86
+ model.update_intention(action: :send_message, confidence: :likely)
87
+ expect(model.intentions.size).to eq(1)
88
+ end
89
+
90
+ it 'updates existing intention confidence' do
91
+ model.update_intention(action: :send_message, confidence: :possible)
92
+ model.update_intention(action: :send_message, confidence: :certain)
93
+ expect(model.intentions.size).to eq(1)
94
+ expect(model.intentions.first[:confidence]).to eq(:certain)
95
+ end
96
+
97
+ it 'trims intentions beyond MAX_INTENTIONS_PER_AGENT' do
98
+ max = Legion::Extensions::Agentic::Social::TheoryOfMind::Helpers::Constants::MAX_INTENTIONS_PER_AGENT
99
+ (max + 3).times { |i| model.update_intention(action: :"action_#{i}") }
100
+ expect(model.intentions.size).to eq(max)
101
+ end
102
+ end
103
+
104
+ describe '#belief_for' do
105
+ it 'returns the belief for a domain' do
106
+ model.update_belief(domain: :location, content: 'lab', confidence: 0.9)
107
+ expect(model.belief_for(:location)[:content]).to eq('lab')
108
+ end
109
+
110
+ it 'returns nil for unknown domain' do
111
+ expect(model.belief_for(:unknown)).to be_nil
112
+ end
113
+ end
114
+
115
+ describe '#strongest_desire' do
116
+ it 'returns the highest-priority desire' do
117
+ model.update_desire(goal: 'rest', priority: :low)
118
+ model.update_desire(goal: 'work', priority: :critical)
119
+ model.update_desire(goal: 'eat', priority: :medium)
120
+ expect(model.strongest_desire[:goal]).to eq('work')
121
+ end
122
+
123
+ it 'returns nil when no desires' do
124
+ expect(model.strongest_desire).to be_nil
125
+ end
126
+ end
127
+
128
+ describe '#most_likely_intention' do
129
+ it 'returns the highest-confidence intention' do
130
+ model.update_intention(action: :wait, confidence: :unlikely)
131
+ model.update_intention(action: :attack, confidence: :certain)
132
+ model.update_intention(action: :flee, confidence: :possible)
133
+ expect(model.most_likely_intention[:action]).to eq(:attack)
134
+ end
135
+
136
+ it 'returns nil when no intentions' do
137
+ expect(model.most_likely_intention).to be_nil
138
+ end
139
+ end
140
+
141
+ describe '#false_beliefs' do
142
+ before do
143
+ model.update_belief(domain: :weather, content: 'sunny', confidence: 0.8)
144
+ model.update_belief(domain: :time, content: 'morning', confidence: 0.7)
145
+ end
146
+
147
+ it 'identifies beliefs that contradict known truths' do
148
+ truths = { weather: 'rainy', time: 'morning' }
149
+ result = model.false_beliefs(truths)
150
+ expect(result).to have_key(:weather)
151
+ expect(result[:weather][:agent_believes]).to eq('sunny')
152
+ expect(result[:weather][:actual_truth]).to eq('rainy')
153
+ end
154
+
155
+ it 'does not flag correct beliefs' do
156
+ truths = { weather: 'sunny' }
157
+ result = model.false_beliefs(truths)
158
+ expect(result).to be_empty
159
+ end
160
+
161
+ it 'ignores domains not in known truths' do
162
+ truths = { unrelated: 'value' }
163
+ result = model.false_beliefs(truths)
164
+ expect(result).to be_empty
165
+ end
166
+ end
167
+
168
+ describe '#update_prediction_accuracy' do
169
+ it 'increases accuracy on correct predictions' do
170
+ initial = model.prediction_accuracy
171
+ model.update_prediction_accuracy(:correct)
172
+ expect(model.prediction_accuracy).to be > initial
173
+ end
174
+
175
+ it 'decreases accuracy on incorrect predictions' do
176
+ initial = model.prediction_accuracy
177
+ model.update_prediction_accuracy(:incorrect)
178
+ expect(model.prediction_accuracy).to be < initial
179
+ end
180
+
181
+ it 'increments interaction count' do
182
+ model.update_prediction_accuracy(:correct)
183
+ expect(model.interaction_count).to eq(1)
184
+ end
185
+
186
+ it 'ignores unknown outcomes' do
187
+ model.update_prediction_accuracy(:nonsense)
188
+ expect(model.interaction_count).to eq(0)
189
+ end
190
+ end
191
+
192
+ describe '#decay_beliefs' do
193
+ it 'reduces belief confidence' do
194
+ model.update_belief(domain: :test, content: 'val', confidence: 0.5)
195
+ initial = model.beliefs[:test][:confidence]
196
+ model.decay_beliefs
197
+ expect(model.beliefs[:test][:confidence]).to be < initial
198
+ end
199
+
200
+ it 'removes beliefs below CONFIDENCE_THRESHOLD' do
201
+ threshold = Legion::Extensions::Agentic::Social::TheoryOfMind::Helpers::Constants::CONFIDENCE_THRESHOLD
202
+ model.update_belief(domain: :weak, content: 'val', confidence: threshold + 0.005)
203
+ model.decay_beliefs
204
+ expect(model.beliefs).not_to have_key(:weak)
205
+ end
206
+ end
207
+
208
+ describe '#perspective' do
209
+ before do
210
+ model.update_belief(domain: :location, content: 'office', confidence: 0.9)
211
+ model.update_desire(goal: 'finish_report', priority: :high)
212
+ model.update_intention(action: :write, confidence: :likely)
213
+ end
214
+
215
+ it 'returns knowledge from beliefs' do
216
+ expect(model.perspective[:knowledge][:location]).to eq('office')
217
+ end
218
+
219
+ it 'returns goals from desires' do
220
+ expect(model.perspective[:goals]).to include('finish_report')
221
+ end
222
+
223
+ it 'returns recent actions from intentions' do
224
+ expect(model.perspective[:recent_actions]).to include(:write)
225
+ end
226
+
227
+ it 'includes emotional state' do
228
+ expect(model.perspective[:emotional_state]).to be_a(Symbol)
229
+ end
230
+
231
+ it 'includes constraints' do
232
+ expect(model.perspective[:constraints]).to have_key(:uncertain_domains)
233
+ end
234
+ end
235
+
236
+ describe '#to_h' do
237
+ it 'returns a summary hash' do
238
+ result = model.to_h
239
+ expect(result[:agent_id]).to eq(:agent_alpha)
240
+ expect(result).to have_key(:belief_count)
241
+ expect(result).to have_key(:prediction_accuracy)
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Social::TheoryOfMind::Helpers::Constants do
6
+ describe 'PERSPECTIVE_DIMENSIONS' do
7
+ it 'contains 5 dimensions' do
8
+ expect(described_class::PERSPECTIVE_DIMENSIONS.size).to eq(5)
9
+ end
10
+
11
+ it 'is frozen' do
12
+ expect(described_class::PERSPECTIVE_DIMENSIONS).to be_frozen
13
+ end
14
+ end
15
+
16
+ describe 'BELIEF_SOURCES' do
17
+ it 'contains 5 sources' do
18
+ expect(described_class::BELIEF_SOURCES.size).to eq(5)
19
+ end
20
+
21
+ it 'is frozen' do
22
+ expect(described_class::BELIEF_SOURCES).to be_frozen
23
+ end
24
+ end
25
+
26
+ describe 'INTENTION_CONFIDENCE_LEVELS' do
27
+ it 'is ordered from highest to lowest' do
28
+ thresholds = described_class::INTENTION_CONFIDENCE_LEVELS.values
29
+ expect(thresholds).to eq(thresholds.sort.reverse)
30
+ end
31
+ end
32
+
33
+ describe 'DESIRE_PRIORITIES' do
34
+ it 'is ordered from highest to lowest' do
35
+ thresholds = described_class::DESIRE_PRIORITIES.values
36
+ expect(thresholds).to eq(thresholds.sort.reverse)
37
+ end
38
+ end
39
+
40
+ describe 'PREDICTION_OUTCOMES' do
41
+ it 'contains 4 outcomes' do
42
+ expect(described_class::PREDICTION_OUTCOMES.size).to eq(4)
43
+ end
44
+
45
+ it 'is frozen' do
46
+ expect(described_class::PREDICTION_OUTCOMES).to be_frozen
47
+ end
48
+ end
49
+
50
+ describe 'scalar constants' do
51
+ it 'has positive MAX_AGENT_MODELS' do
52
+ expect(described_class::MAX_AGENT_MODELS).to be > 0
53
+ end
54
+
55
+ it 'has positive MAX_BELIEFS_PER_AGENT' do
56
+ expect(described_class::MAX_BELIEFS_PER_AGENT).to be > 0
57
+ end
58
+
59
+ it 'has BELIEF_DECAY_RATE between 0 and 1' do
60
+ expect(described_class::BELIEF_DECAY_RATE).to be_between(0.0, 1.0)
61
+ end
62
+
63
+ it 'has CONFIDENCE_THRESHOLD between 0 and 1' do
64
+ expect(described_class::CONFIDENCE_THRESHOLD).to be_between(0.0, 1.0)
65
+ end
66
+
67
+ it 'has PREDICTION_ALPHA between 0 and 1' do
68
+ expect(described_class::PREDICTION_ALPHA).to be_between(0.0, 1.0)
69
+ end
70
+ end
71
+ end