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,277 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/social/perspective_shifting/client'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Social::PerspectiveShifting::Runners::PerspectiveShifting do
6
+ let(:client) { Legion::Extensions::Agentic::Social::PerspectiveShifting::Client.new }
7
+
8
+ let(:ceo_id) do
9
+ client.add_perspective(name: 'CEO', type: :stakeholder, priorities: %i[growth])[:perspective][:id]
10
+ end
11
+
12
+ let(:engineer_id) do
13
+ client.add_perspective(name: 'Engineer', type: :pragmatic, priorities: %i[stability])[:perspective][:id]
14
+ end
15
+
16
+ let(:ethicist_id) do
17
+ client.add_perspective(name: 'Ethicist', type: :ethical, empathy: 0.9)[:perspective][:id]
18
+ end
19
+
20
+ let(:situation_id) do
21
+ client.add_situation(content: 'Deploy AI hiring tool')[:situation_id]
22
+ end
23
+
24
+ # --- Perspective management ---
25
+
26
+ describe '#add_perspective' do
27
+ it 'returns success: true with perspective hash' do
28
+ result = client.add_perspective(name: 'Manager', type: :stakeholder)
29
+ expect(result[:success]).to be true
30
+ expect(result[:perspective][:name]).to eq('Manager')
31
+ end
32
+
33
+ it 'returns success: false for invalid type' do
34
+ result = client.add_perspective(name: 'x', type: :unknown)
35
+ expect(result[:success]).to be false
36
+ expect(result[:error]).to eq(:invalid_type)
37
+ end
38
+
39
+ it 'stores empathy_level on the perspective' do
40
+ result = client.add_perspective(name: 'Doctor', type: :emotional, empathy: 0.9)
41
+ expect(result[:perspective][:empathy_level]).to be_within(0.001).of(0.9)
42
+ end
43
+
44
+ it 'stores bias_toward when provided' do
45
+ result = client.add_perspective(name: 'Lawyer', type: :ethical, bias: :caution)
46
+ expect(result[:perspective][:bias_toward]).to eq(:caution)
47
+ end
48
+
49
+ it 'stores expertise_domains' do
50
+ result = client.add_perspective(name: 'Scientist', type: :pragmatic,
51
+ expertise_domains: %w[biology data])
52
+ expect(result[:perspective][:expertise_domains]).to eq(%w[biology data])
53
+ end
54
+ end
55
+
56
+ describe '#list_perspectives' do
57
+ it 'returns success: true with empty list initially' do
58
+ result = client.list_perspectives
59
+ expect(result[:success]).to be true
60
+ expect(result[:count]).to eq(0)
61
+ end
62
+
63
+ it 'returns all added perspectives' do
64
+ ceo_id
65
+ engineer_id
66
+ result = client.list_perspectives
67
+ expect(result[:count]).to eq(2)
68
+ end
69
+ end
70
+
71
+ describe '#get_perspective' do
72
+ it 'returns found: true for known perspective' do
73
+ id = ceo_id
74
+ result = client.get_perspective(perspective_id: id)
75
+ expect(result[:found]).to be true
76
+ expect(result[:perspective][:name]).to eq('CEO')
77
+ end
78
+
79
+ it 'returns found: false for unknown perspective' do
80
+ result = client.get_perspective(perspective_id: 'nope')
81
+ expect(result[:found]).to be false
82
+ end
83
+ end
84
+
85
+ # --- Situation management ---
86
+
87
+ describe '#add_situation' do
88
+ it 'returns success: true with situation_id' do
89
+ result = client.add_situation(content: 'new deployment')
90
+ expect(result[:success]).to be true
91
+ expect(result[:situation_id]).to match(/\A[0-9a-f-]{36}\z/)
92
+ end
93
+ end
94
+
95
+ describe '#list_situations' do
96
+ it 'returns all added situations' do
97
+ situation_id
98
+ result = client.list_situations
99
+ expect(result[:count]).to eq(1)
100
+ expect(result[:situations].first[:content]).to eq('Deploy AI hiring tool')
101
+ end
102
+ end
103
+
104
+ # --- View generation ---
105
+
106
+ describe '#generate_view' do
107
+ it 'returns success: true with view hash' do
108
+ result = client.generate_view(
109
+ situation_id: situation_id,
110
+ perspective_id: ceo_id,
111
+ valence: 0.7,
112
+ concerns: ['cost'],
113
+ opportunities: ['efficiency'],
114
+ confidence: 0.85
115
+ )
116
+ expect(result[:success]).to be true
117
+ expect(result[:view][:valence]).to be_within(0.001).of(0.7)
118
+ end
119
+
120
+ it 'returns error for unknown situation' do
121
+ result = client.generate_view(situation_id: 'nope', perspective_id: ceo_id)
122
+ expect(result[:success]).to be false
123
+ expect(result[:error]).to eq(:situation_not_found)
124
+ end
125
+
126
+ it 'returns error for unknown perspective' do
127
+ result = client.generate_view(situation_id: situation_id, perspective_id: 'nope')
128
+ expect(result[:success]).to be false
129
+ expect(result[:error]).to eq(:perspective_not_found)
130
+ end
131
+ end
132
+
133
+ describe '#views_for_situation' do
134
+ it 'returns empty list when no views exist' do
135
+ result = client.views_for_situation(situation_id: situation_id)
136
+ expect(result[:count]).to eq(0)
137
+ end
138
+
139
+ it 'returns all views after generating them' do
140
+ client.generate_view(situation_id: situation_id, perspective_id: ceo_id, valence: 0.5)
141
+ client.generate_view(situation_id: situation_id, perspective_id: engineer_id, valence: -0.3)
142
+ result = client.views_for_situation(situation_id: situation_id)
143
+ expect(result[:count]).to eq(2)
144
+ end
145
+ end
146
+
147
+ # --- Analysis ---
148
+
149
+ describe '#perspective_agreement' do
150
+ it 'returns 0.0 with fewer than 2 views' do
151
+ client.generate_view(situation_id: situation_id, perspective_id: ceo_id, valence: 0.5)
152
+ result = client.perspective_agreement(situation_id: situation_id)
153
+ expect(result[:agreement]).to eq(0.0)
154
+ end
155
+
156
+ it 'returns label alongside score' do
157
+ client.generate_view(situation_id: situation_id, perspective_id: ceo_id, valence: 0.5, confidence: 0.8)
158
+ client.generate_view(situation_id: situation_id, perspective_id: engineer_id, valence: 0.5, confidence: 0.7)
159
+ result = client.perspective_agreement(situation_id: situation_id)
160
+ expect(result[:label]).to be_a(Symbol)
161
+ end
162
+
163
+ it 'returns low agreement when views conflict' do
164
+ client.generate_view(situation_id: situation_id, perspective_id: ceo_id, valence: 1.0, confidence: 0.8)
165
+ client.generate_view(situation_id: situation_id, perspective_id: engineer_id, valence: -1.0, confidence: 0.7)
166
+ result = client.perspective_agreement(situation_id: situation_id)
167
+ expect(result[:agreement]).to be < 0.1
168
+ expect(result[:label]).to eq(:conflict)
169
+ end
170
+ end
171
+
172
+ describe '#blind_spots' do
173
+ it 'returns all perspective types as blind spots when no views' do
174
+ result = client.blind_spots(situation_id: situation_id)
175
+ expect(result[:blind_spots]).to eq(Legion::Extensions::Agentic::Social::PerspectiveShifting::Helpers::Constants::PERSPECTIVE_TYPES)
176
+ end
177
+
178
+ it 'excludes covered perspective types' do
179
+ client.generate_view(situation_id: situation_id, perspective_id: ceo_id, valence: 0.5)
180
+ result = client.blind_spots(situation_id: situation_id)
181
+ expect(result[:blind_spots]).not_to include(:stakeholder)
182
+ expect(result[:blind_spots]).to include(:ethical)
183
+ end
184
+ end
185
+
186
+ describe '#coverage_score' do
187
+ it 'returns 0.0 when no views' do
188
+ result = client.coverage_score(situation_id: situation_id)
189
+ expect(result[:coverage]).to eq(0.0)
190
+ end
191
+
192
+ it 'returns label alongside score' do
193
+ ceo_id
194
+ result = client.coverage_score(situation_id: situation_id)
195
+ expect(result[:label]).to be_a(Symbol)
196
+ end
197
+
198
+ it 'increases as more perspectives are applied' do
199
+ ceo_id
200
+ before = client.coverage_score(situation_id: situation_id)[:coverage]
201
+ client.generate_view(situation_id: situation_id, perspective_id: ceo_id)
202
+ after = client.coverage_score(situation_id: situation_id)[:coverage]
203
+ expect(after).to be > before
204
+ end
205
+ end
206
+
207
+ describe '#dominant_view' do
208
+ it 'returns found: false when no views' do
209
+ result = client.dominant_view(situation_id: situation_id)
210
+ expect(result[:found]).to be false
211
+ end
212
+
213
+ it 'returns the highest confidence view' do
214
+ client.generate_view(situation_id: situation_id, perspective_id: ceo_id, confidence: 0.4)
215
+ client.generate_view(situation_id: situation_id, perspective_id: engineer_id, confidence: 0.9)
216
+ result = client.dominant_view(situation_id: situation_id)
217
+ expect(result[:found]).to be true
218
+ expect(result[:view][:confidence]).to be_within(0.001).of(0.9)
219
+ end
220
+ end
221
+
222
+ describe '#synthesize' do
223
+ it 'returns error when fewer than 2 views' do
224
+ client.generate_view(situation_id: situation_id, perspective_id: ceo_id, valence: 0.5)
225
+ result = client.synthesize(situation_id: situation_id)
226
+ expect(result[:success]).to be false
227
+ end
228
+
229
+ it 'returns success: true with weighted_valence' do
230
+ client.generate_view(situation_id: situation_id, perspective_id: ceo_id,
231
+ valence: 0.8, confidence: 1.0)
232
+ client.generate_view(situation_id: situation_id, perspective_id: engineer_id,
233
+ valence: -0.2, confidence: 1.0)
234
+ result = client.synthesize(situation_id: situation_id)
235
+ expect(result[:success]).to be true
236
+ expect(result[:weighted_valence]).to be_within(0.001).of(0.3)
237
+ end
238
+
239
+ it 'merges concerns and opportunities across all views' do
240
+ client.generate_view(situation_id: situation_id, perspective_id: ceo_id,
241
+ concerns: ['budget'], opportunities: ['scale'], confidence: 0.8)
242
+ client.generate_view(situation_id: situation_id, perspective_id: engineer_id,
243
+ concerns: ['tech debt'], opportunities: ['automation'], confidence: 0.7)
244
+ result = client.synthesize(situation_id: situation_id)
245
+ expect(result[:concerns]).to include('budget', 'tech debt')
246
+ expect(result[:opportunities]).to include('scale', 'automation')
247
+ end
248
+ end
249
+
250
+ describe '#most_divergent_pair' do
251
+ it 'returns found: false with fewer than 2 views' do
252
+ client.generate_view(situation_id: situation_id, perspective_id: ceo_id, valence: 0.5)
253
+ result = client.most_divergent_pair(situation_id: situation_id)
254
+ expect(result[:found]).to be false
255
+ end
256
+
257
+ it 'returns found: true with divergence value' do
258
+ client.generate_view(situation_id: situation_id, perspective_id: ceo_id, valence: 0.9)
259
+ client.generate_view(situation_id: situation_id, perspective_id: engineer_id, valence: -0.8)
260
+ result = client.most_divergent_pair(situation_id: situation_id)
261
+ expect(result[:found]).to be true
262
+ expect(result[:divergence]).to be_within(0.001).of(1.7)
263
+ expect(result[:views].size).to eq(2)
264
+ end
265
+ end
266
+
267
+ describe '#engine_status' do
268
+ it 'returns success: true with perspective and situation counts' do
269
+ ceo_id
270
+ situation_id
271
+ result = client.engine_status
272
+ expect(result[:success]).to be true
273
+ expect(result[:perspective_count]).to eq(1)
274
+ expect(result[:situation_count]).to eq(1)
275
+ end
276
+ end
277
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Social::Social::Client do
6
+ describe '#initialize' do
7
+ it 'creates a default social graph' do
8
+ client = described_class.new
9
+ expect(client.social_graph).to be_a(Legion::Extensions::Agentic::Social::Social::Helpers::SocialGraph)
10
+ end
11
+
12
+ it 'accepts an injected social graph' do
13
+ graph = Legion::Extensions::Agentic::Social::Social::Helpers::SocialGraph.new
14
+ client = described_class.new(social_graph: graph)
15
+ expect(client.social_graph).to equal(graph)
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 join_group' do
27
+ expect(client).to respond_to(:join_group)
28
+ end
29
+
30
+ it 'responds to leave_group' do
31
+ expect(client).to respond_to(:leave_group)
32
+ end
33
+
34
+ it 'responds to update_reputation' do
35
+ expect(client).to respond_to(:update_reputation)
36
+ end
37
+
38
+ it 'responds to agent_reputation' do
39
+ expect(client).to respond_to(:agent_reputation)
40
+ end
41
+
42
+ it 'responds to social_status' do
43
+ expect(client).to respond_to(:social_status)
44
+ end
45
+
46
+ it 'responds to social_stats' do
47
+ expect(client).to respond_to(:social_stats)
48
+ end
49
+
50
+ it 'responds to report_violation' do
51
+ expect(client).to respond_to(:report_violation)
52
+ end
53
+
54
+ it 'responds to record_exchange' do
55
+ expect(client).to respond_to(:record_exchange)
56
+ end
57
+
58
+ it 'can perform a full workflow' do
59
+ client.join_group(group_id: :team, role: :contributor, members: %w[a1])
60
+ client.update_reputation(agent_id: :a1, dimension: :reliability, signal: 0.9)
61
+ client.record_exchange(agent_id: :a1, action: :helped, direction: :given)
62
+
63
+ status = client.group_status(group_id: :team)
64
+ expect(status[:group_id]).to eq(:team)
65
+
66
+ stats = client.social_stats
67
+ expect(stats[:groups]).to eq(1)
68
+ expect(stats[:agents_tracked]).to eq(1)
69
+ expect(stats[:ledger_size]).to eq(1)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Social::Social::Helpers::Constants do
6
+ describe 'ROLES' do
7
+ it 'contains exactly 6 roles' do
8
+ expect(described_class::ROLES.size).to eq(6)
9
+ end
10
+
11
+ it 'is frozen' do
12
+ expect(described_class::ROLES).to be_frozen
13
+ end
14
+
15
+ %i[leader contributor specialist observer mentor newcomer].each do |role|
16
+ it "includes #{role}" do
17
+ expect(described_class::ROLES).to include(role)
18
+ end
19
+ end
20
+ end
21
+
22
+ describe 'RELATIONSHIP_TYPES' do
23
+ it 'contains exactly 5 types' do
24
+ expect(described_class::RELATIONSHIP_TYPES.size).to eq(5)
25
+ end
26
+
27
+ it 'is frozen' do
28
+ expect(described_class::RELATIONSHIP_TYPES).to be_frozen
29
+ end
30
+ end
31
+
32
+ describe 'REPUTATION_DIMENSIONS' do
33
+ it 'contains exactly 5 dimensions' do
34
+ expect(described_class::REPUTATION_DIMENSIONS.size).to eq(5)
35
+ end
36
+
37
+ it 'has weights summing to 1.0' do
38
+ total = described_class::REPUTATION_DIMENSIONS.values.sum { |c| c[:weight] }
39
+ expect(total).to be_within(0.001).of(1.0)
40
+ end
41
+
42
+ it 'has descriptions for every dimension' do
43
+ described_class::REPUTATION_DIMENSIONS.each_value do |config|
44
+ expect(config[:description]).to be_a(String)
45
+ expect(config[:description]).not_to be_empty
46
+ end
47
+ end
48
+ end
49
+
50
+ describe 'STANDING_LEVELS' do
51
+ it 'is ordered from highest to lowest threshold' do
52
+ thresholds = described_class::STANDING_LEVELS.values
53
+ expect(thresholds).to eq(thresholds.sort.reverse)
54
+ end
55
+
56
+ it 'has exemplary as the highest standing' do
57
+ expect(described_class::STANDING_LEVELS.keys.first).to eq(:exemplary)
58
+ end
59
+ end
60
+
61
+ describe 'COHESION_LEVELS' do
62
+ it 'is ordered from highest to lowest threshold' do
63
+ thresholds = described_class::COHESION_LEVELS.values
64
+ expect(thresholds).to eq(thresholds.sort.reverse)
65
+ end
66
+ end
67
+
68
+ describe 'NORM_VIOLATIONS' do
69
+ it 'contains exactly 5 violation types' do
70
+ expect(described_class::NORM_VIOLATIONS.size).to eq(5)
71
+ end
72
+
73
+ it 'is frozen' do
74
+ expect(described_class::NORM_VIOLATIONS).to be_frozen
75
+ end
76
+ end
77
+
78
+ describe 'scalar constants' do
79
+ it 'has REPUTATION_ALPHA between 0 and 1' do
80
+ expect(described_class::REPUTATION_ALPHA).to be_between(0.0, 1.0)
81
+ end
82
+
83
+ it 'has positive MAX_GROUPS' do
84
+ expect(described_class::MAX_GROUPS).to be > 0
85
+ end
86
+
87
+ it 'has positive MAX_GROUP_MEMBERS' do
88
+ expect(described_class::MAX_GROUP_MEMBERS).to be > 0
89
+ end
90
+
91
+ it 'has positive RECIPROCITY_WINDOW' do
92
+ expect(described_class::RECIPROCITY_WINDOW).to be > 0
93
+ end
94
+
95
+ it 'has INFLUENCE_DECAY between 0 and 1' do
96
+ expect(described_class::INFLUENCE_DECAY).to be_between(0.0, 1.0)
97
+ end
98
+ end
99
+ end