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,359 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'sequel'
5
+ require 'tmpdir'
6
+
7
+ RSpec.describe 'lex-trust local SQLite persistence' do
8
+ let(:db_path) { File.join(Dir.tmpdir, "trust_test_#{Process.pid}_#{rand(9999)}.db") }
9
+ let(:db) { Sequel.sqlite(db_path) }
10
+
11
+ before do
12
+ db.create_table(:trust_entries) do
13
+ primary_key :id
14
+ String :agent_id, null: false
15
+ String :domain, null: false
16
+ Float :reliability, default: 0.3
17
+ Float :competence, default: 0.3
18
+ Float :integrity, default: 0.3
19
+ Float :benevolence, default: 0.3
20
+ Float :composite, default: 0.3
21
+ Integer :interaction_count, default: 0
22
+ Integer :positive_count, default: 0
23
+ Integer :negative_count, default: 0
24
+ DateTime :last_interaction
25
+ DateTime :created_at, null: false
26
+ unique %i[agent_id domain]
27
+ index [:agent_id]
28
+ end
29
+
30
+ stub_const('Legion::Data::Local', Module.new do
31
+ def self.connected?
32
+ true
33
+ end
34
+
35
+ def self.connection
36
+ @_connection
37
+ end
38
+
39
+ def self._set_connection(conn)
40
+ @_connection = conn
41
+ end
42
+ end)
43
+
44
+ Legion::Data::Local._set_connection(db)
45
+ end
46
+
47
+ after do
48
+ db.disconnect
49
+ FileUtils.rm_f(db_path)
50
+ end
51
+
52
+ describe 'save_to_local' do
53
+ it 'writes an entry to the database' do
54
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
55
+ map.record_interaction('agent-001', positive: true)
56
+ map.save_to_local
57
+
58
+ row = db[:trust_entries].where(agent_id: 'agent-001', domain: 'general').first
59
+ expect(row).not_to be_nil
60
+ expect(row[:agent_id]).to eq('agent-001')
61
+ expect(row[:domain]).to eq('general')
62
+ expect(row[:positive_count]).to eq(1)
63
+ expect(row[:interaction_count]).to eq(1)
64
+ end
65
+
66
+ it 'updates an existing row on second save' do
67
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
68
+ map.record_interaction('agent-001', positive: true)
69
+ map.save_to_local
70
+
71
+ map.record_interaction('agent-001', positive: false)
72
+ map.save_to_local
73
+
74
+ rows = db[:trust_entries].where(agent_id: 'agent-001', domain: 'general').all
75
+ expect(rows.size).to eq(1)
76
+ expect(rows.first[:negative_count]).to eq(1)
77
+ expect(rows.first[:interaction_count]).to eq(2)
78
+ end
79
+
80
+ it 'persists composite score' do
81
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
82
+ map.record_interaction('agent-001', positive: true)
83
+ map.save_to_local
84
+
85
+ row = db[:trust_entries].where(agent_id: 'agent-001', domain: 'general').first
86
+ expect(row[:composite]).to be > 0.3
87
+ end
88
+
89
+ it 'persists all four dimension scores' do
90
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
91
+ map.record_interaction('agent-001', positive: true)
92
+ map.save_to_local
93
+
94
+ row = db[:trust_entries].where(agent_id: 'agent-001', domain: 'general').first
95
+ expect(row[:reliability]).to be > 0.3
96
+ expect(row[:competence]).to be > 0.3
97
+ expect(row[:integrity]).to be > 0.3
98
+ expect(row[:benevolence]).to be > 0.3
99
+ end
100
+
101
+ it 'persists entries for multiple agents' do
102
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
103
+ map.record_interaction('agent-a', positive: true)
104
+ map.record_interaction('agent-b', positive: false)
105
+ map.save_to_local
106
+
107
+ expect(db[:trust_entries].count).to eq(2)
108
+ end
109
+
110
+ it 'persists entries for multiple domains of the same agent' do
111
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
112
+ map.record_interaction('agent-001', positive: true, domain: :code)
113
+ map.record_interaction('agent-001', positive: false, domain: :ops)
114
+ map.save_to_local
115
+
116
+ expect(db[:trust_entries].where(agent_id: 'agent-001').count).to eq(2)
117
+ end
118
+
119
+ it 'removes DB rows for entries removed from memory' do
120
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
121
+ map.get_or_create('agent-a')
122
+ map.get_or_create('agent-b')
123
+ map.save_to_local
124
+
125
+ expect(db[:trust_entries].count).to eq(2)
126
+
127
+ # Simulate removal: build new map with only agent-a, then save
128
+ map2 = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
129
+ map2.save_to_local # loaded agent-a and agent-b from DB, both still in memory
130
+ expect(db[:trust_entries].count).to eq(2) # nothing deleted yet
131
+
132
+ # Remove agent-b from memory then save
133
+ map2.entries.delete_if { |k, _| k.start_with?('agent-b') }
134
+ map2.save_to_local
135
+
136
+ expect(db[:trust_entries].count).to eq(1)
137
+ expect(db[:trust_entries].first[:agent_id]).to eq('agent-a')
138
+ end
139
+ end
140
+
141
+ describe 'load_from_local' do
142
+ it 'restores entries from the database on initialize' do
143
+ db[:trust_entries].insert(
144
+ agent_id: 'agent-001',
145
+ domain: 'general',
146
+ reliability: 0.45,
147
+ competence: 0.45,
148
+ integrity: 0.45,
149
+ benevolence: 0.45,
150
+ composite: 0.45,
151
+ interaction_count: 3,
152
+ positive_count: 3,
153
+ negative_count: 0,
154
+ created_at: Time.now.utc
155
+ )
156
+
157
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
158
+ entry = map.get('agent-001')
159
+ expect(entry).not_to be_nil
160
+ expect(entry[:composite]).to be_within(0.0001).of(0.45)
161
+ expect(entry[:interaction_count]).to eq(3)
162
+ expect(entry[:positive_count]).to eq(3)
163
+ end
164
+
165
+ it 'restores domain as a symbol' do
166
+ db[:trust_entries].insert(
167
+ agent_id: 'agent-001',
168
+ domain: 'code',
169
+ reliability: 0.3,
170
+ competence: 0.3,
171
+ integrity: 0.3,
172
+ benevolence: 0.3,
173
+ composite: 0.3,
174
+ interaction_count: 0,
175
+ positive_count: 0,
176
+ negative_count: 0,
177
+ created_at: Time.now.utc
178
+ )
179
+
180
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
181
+ entry = map.get('agent-001', domain: :code)
182
+ expect(entry).not_to be_nil
183
+ expect(entry[:domain]).to eq(:code)
184
+ end
185
+
186
+ it 'restores all four dimension values' do
187
+ db[:trust_entries].insert(
188
+ agent_id: 'agent-001',
189
+ domain: 'general',
190
+ reliability: 0.6,
191
+ competence: 0.5,
192
+ integrity: 0.4,
193
+ benevolence: 0.3,
194
+ composite: 0.45,
195
+ interaction_count: 0,
196
+ positive_count: 0,
197
+ negative_count: 0,
198
+ created_at: Time.now.utc
199
+ )
200
+
201
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
202
+ entry = map.get('agent-001')
203
+ expect(entry[:dimensions][:reliability]).to be_within(0.0001).of(0.6)
204
+ expect(entry[:dimensions][:competence]).to be_within(0.0001).of(0.5)
205
+ expect(entry[:dimensions][:integrity]).to be_within(0.0001).of(0.4)
206
+ expect(entry[:dimensions][:benevolence]).to be_within(0.0001).of(0.3)
207
+ end
208
+
209
+ it 'restores multiple entries' do
210
+ db[:trust_entries].insert(
211
+ agent_id: 'agent-a', domain: 'general',
212
+ reliability: 0.3, competence: 0.3, integrity: 0.3, benevolence: 0.3,
213
+ composite: 0.3, interaction_count: 0, positive_count: 0, negative_count: 0,
214
+ created_at: Time.now.utc
215
+ )
216
+ db[:trust_entries].insert(
217
+ agent_id: 'agent-b', domain: 'ops',
218
+ reliability: 0.3, competence: 0.3, integrity: 0.3, benevolence: 0.3,
219
+ composite: 0.3, interaction_count: 0, positive_count: 0, negative_count: 0,
220
+ created_at: Time.now.utc
221
+ )
222
+
223
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
224
+ expect(map.count).to eq(2)
225
+ end
226
+
227
+ it 'allows normal operations on restored entries' do
228
+ db[:trust_entries].insert(
229
+ agent_id: 'agent-001',
230
+ domain: 'general',
231
+ reliability: 0.4,
232
+ competence: 0.4,
233
+ integrity: 0.4,
234
+ benevolence: 0.4,
235
+ composite: 0.4,
236
+ interaction_count: 2,
237
+ positive_count: 2,
238
+ negative_count: 0,
239
+ created_at: Time.now.utc
240
+ )
241
+
242
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
243
+ map.record_interaction('agent-001', positive: true)
244
+ entry = map.get('agent-001')
245
+ expect(entry[:interaction_count]).to eq(3)
246
+ expect(entry[:positive_count]).to eq(3)
247
+ end
248
+ end
249
+
250
+ describe 'round-trip persistence' do
251
+ it 'saves and restores trust score across instances' do
252
+ map1 = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
253
+ 5.times { map1.record_interaction('agent-001', positive: true) }
254
+ composite_before = map1.get('agent-001')[:composite]
255
+ map1.save_to_local
256
+
257
+ map2 = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
258
+ expect(map2.get('agent-001')[:composite]).to be_within(0.0001).of(composite_before)
259
+ end
260
+
261
+ it 'round-trips interaction counts accurately' do
262
+ map1 = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
263
+ 3.times { map1.record_interaction('agent-001', positive: true) }
264
+ 2.times { map1.record_interaction('agent-001', positive: false) }
265
+ map1.save_to_local
266
+
267
+ map2 = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
268
+ entry = map2.get('agent-001')
269
+ expect(entry[:interaction_count]).to eq(5)
270
+ expect(entry[:positive_count]).to eq(3)
271
+ expect(entry[:negative_count]).to eq(2)
272
+ end
273
+
274
+ it 'round-trips multiple agents independently' do
275
+ map1 = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
276
+ 5.times { map1.record_interaction('agent-high', positive: true) }
277
+ map1.record_interaction('agent-low', positive: false)
278
+ map1.save_to_local
279
+
280
+ map2 = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
281
+ expect(map2.get('agent-high')[:composite]).to be > map2.get('agent-low')[:composite]
282
+ end
283
+
284
+ it 'round-trips domain-scoped entries independently' do
285
+ map1 = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
286
+ 5.times { map1.record_interaction('agent-001', positive: true, domain: :code) }
287
+ map1.record_interaction('agent-001', positive: false, domain: :ops)
288
+ map1.save_to_local
289
+
290
+ map2 = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
291
+ code_entry = map2.get('agent-001', domain: :code)
292
+ ops_entry = map2.get('agent-001', domain: :ops)
293
+ expect(code_entry[:composite]).to be > ops_entry[:composite]
294
+ end
295
+
296
+ it 'trusted_agents works correctly after round-trip' do
297
+ map1 = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
298
+ 5.times { map1.record_interaction('agent-001', positive: true) }
299
+ map1.save_to_local
300
+
301
+ map2 = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
302
+ trusted = map2.trusted_agents
303
+ expect(trusted).not_to be_empty
304
+ expect(trusted.first[:agent_id]).to eq('agent-001')
305
+ end
306
+ end
307
+
308
+ describe 'graceful no-op when Legion::Data::Local is unavailable' do
309
+ before do
310
+ hide_const('Legion::Data::Local')
311
+ end
312
+
313
+ it 'initialize completes without raising' do
314
+ expect { Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new }.not_to raise_error
315
+ end
316
+
317
+ it 'save_to_local does nothing without raising' do
318
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
319
+ map.record_interaction('agent-001', positive: true)
320
+ expect { map.save_to_local }.not_to raise_error
321
+ end
322
+
323
+ it 'starts with empty in-memory state' do
324
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
325
+ expect(map.count).to eq(0)
326
+ end
327
+
328
+ it 'operates normally in memory when DB unavailable' do
329
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
330
+ map.record_interaction('agent-001', positive: true)
331
+ expect(map.get('agent-001')[:positive_count]).to eq(1)
332
+ end
333
+ end
334
+
335
+ describe 'graceful no-op when Legion::Data::Local is defined but not connected' do
336
+ before do
337
+ stub_const('Legion::Data::Local', Module.new do
338
+ def self.connected?
339
+ false
340
+ end
341
+ end)
342
+ end
343
+
344
+ it 'initialize completes without raising' do
345
+ expect { Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new }.not_to raise_error
346
+ end
347
+
348
+ it 'save_to_local does nothing without raising' do
349
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
350
+ map.record_interaction('agent-001', positive: true)
351
+ expect { map.save_to_local }.not_to raise_error
352
+ end
353
+
354
+ it 'starts with empty in-memory state' do
355
+ map = Legion::Extensions::Agentic::Social::Trust::Helpers::TrustMap.new
356
+ expect(map.count).to eq(0)
357
+ end
358
+ end
359
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/social/trust/client'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Social::Trust::Runners::Trust do
6
+ let(:client) { Legion::Extensions::Agentic::Social::Trust::Client.new }
7
+
8
+ describe '#get_trust' do
9
+ it 'returns found: false for unknown agent' do
10
+ result = client.get_trust(agent_id: 'unknown')
11
+ expect(result[:found]).to be false
12
+ end
13
+ end
14
+
15
+ describe '#record_trust_interaction' do
16
+ it 'creates entry and records positive interaction' do
17
+ result = client.record_trust_interaction(agent_id: 'agent-1', positive: true)
18
+ expect(result[:positive]).to be true
19
+ expect(result[:composite]).to be > 0.3 # above neutral
20
+ end
21
+
22
+ it 'creates entry and records negative interaction' do
23
+ result = client.record_trust_interaction(agent_id: 'agent-1', positive: false)
24
+ expect(result[:composite]).to be < 0.3 # below neutral
25
+ end
26
+
27
+ it 'asymmetric: penalty > reinforcement' do
28
+ client.record_trust_interaction(agent_id: 'agent-1', positive: true)
29
+ client.get_trust(agent_id: 'agent-1')[:trust][:composite]
30
+
31
+ client.record_trust_interaction(agent_id: 'agent-1', positive: false)
32
+ after_negative = client.get_trust(agent_id: 'agent-1')[:trust][:composite]
33
+
34
+ # Net of one positive + one negative should be below starting point
35
+ expect(after_negative).to be < 0.3
36
+ end
37
+
38
+ it 'tracks per domain' do
39
+ client.record_trust_interaction(agent_id: 'agent-1', domain: :code, positive: true)
40
+ client.record_trust_interaction(agent_id: 'agent-1', domain: :ops, positive: false)
41
+
42
+ code_trust = client.get_trust(agent_id: 'agent-1', domain: :code)
43
+ ops_trust = client.get_trust(agent_id: 'agent-1', domain: :ops)
44
+
45
+ expect(code_trust[:trust][:composite]).to be > ops_trust[:trust][:composite]
46
+ end
47
+ end
48
+
49
+ describe '#reinforce_trust_dimension' do
50
+ it 'reinforces specific dimension' do
51
+ client.record_trust_interaction(agent_id: 'agent-1', positive: true)
52
+ client.reinforce_trust_dimension(agent_id: 'agent-1', dimension: :competence, amount: 0.2)
53
+ entry = client.get_trust(agent_id: 'agent-1')[:trust]
54
+ expect(entry[:dimensions][:competence]).to be > entry[:dimensions][:reliability]
55
+ end
56
+ end
57
+
58
+ describe '#decay_trust' do
59
+ it 'decays all entries' do
60
+ client.record_trust_interaction(agent_id: 'agent-1', positive: true)
61
+ before = client.get_trust(agent_id: 'agent-1')[:trust][:composite]
62
+ client.decay_trust
63
+ after = client.get_trust(agent_id: 'agent-1')[:trust][:composite]
64
+ expect(after).to be < before
65
+ end
66
+ end
67
+
68
+ describe '#trusted_agents' do
69
+ it 'returns agents above threshold' do
70
+ 5.times { client.record_trust_interaction(agent_id: 'agent-1', positive: true) }
71
+ result = client.trusted_agents
72
+ expect(result[:count]).to eq(1)
73
+ end
74
+ end
75
+
76
+ describe '#delegatable_agents' do
77
+ it 'requires higher trust for delegation' do
78
+ 3.times { client.record_trust_interaction(agent_id: 'agent-1', positive: true) }
79
+ trusted = client.trusted_agents
80
+ delegatable = client.delegatable_agents
81
+ expect(delegatable[:count]).to be <= trusted[:count]
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ module Legion
6
+ module Logging
7
+ def self.debug(_msg); end
8
+ def self.info(_msg); end
9
+ def self.warn(_msg); end
10
+ def self.error(_msg); end
11
+ def self.fatal(_msg); end
12
+ end
13
+
14
+ module Extensions
15
+ module Core
16
+ def self.extended(_base); end
17
+ end
18
+
19
+ module Helpers
20
+ module Lex
21
+ def self.included(_base); end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ # rubocop:disable Lint/EmptyClass, Style/OneClassPerFile
28
+ module Legion
29
+ module Extensions
30
+ module Actors
31
+ class Every; end
32
+ class Once; end
33
+ end
34
+ end
35
+ end
36
+ $LOADED_FEATURES << 'legion/extensions/actors/every'
37
+ $LOADED_FEATURES << 'legion/extensions/actors/once'
38
+ # rubocop:enable Lint/EmptyClass, Style/OneClassPerFile
39
+
40
+ # rubocop:disable Style/OneClassPerFile
41
+ module Legion
42
+ module Settings
43
+ def self.[](_key) = nil
44
+ end
45
+ end
46
+ # rubocop:enable Style/OneClassPerFile
47
+
48
+ require 'legion/extensions/agentic/social'
49
+
50
+ RSpec.configure do |config|
51
+ config.example_status_persistence_file_path = '.rspec_status'
52
+ config.disable_monkey_patching!
53
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
54
+ end