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,228 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Social
7
+ module Consent
8
+ module Runners
9
+ module Consent
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex)
12
+
13
+ def check_consent(domain:, _action_type: :general, **)
14
+ tier = consent_map.get_tier(domain)
15
+ Legion::Logging.debug "[consent] check: domain=#{domain} tier=#{tier} allowed=#{tier == :autonomous}"
16
+
17
+ {
18
+ domain: domain,
19
+ tier: tier,
20
+ allowed: tier == :autonomous,
21
+ needs_notify: tier == :act_notify,
22
+ needs_consult: tier == :consult,
23
+ human_only: tier == :human_only
24
+ }
25
+ end
26
+
27
+ def record_action(domain:, success:, **)
28
+ consent_map.record_outcome(domain, success: success)
29
+ rate = consent_map.success_rate(domain)
30
+ total = consent_map.domains[domain][:total_actions]
31
+ Legion::Logging.info "[consent] action recorded: domain=#{domain} success=#{success} rate=#{rate.round(2)} total=#{total}"
32
+
33
+ {
34
+ domain: domain,
35
+ success: success,
36
+ success_rate: rate,
37
+ total: total
38
+ }
39
+ end
40
+
41
+ def evaluate_tier_change(domain:, **)
42
+ recommendation = consent_map.evaluate_promotion(domain)
43
+ current = consent_map.get_tier(domain)
44
+
45
+ result = {
46
+ domain: domain,
47
+ current_tier: current,
48
+ recommendation: recommendation,
49
+ success_rate: consent_map.success_rate(domain)
50
+ }
51
+
52
+ case recommendation
53
+ when :promote
54
+ result[:proposed_tier] = Helpers::Tiers.promote(current)
55
+ Legion::Logging.info "[consent] tier change: domain=#{domain} recommend=promote from=#{current} to=#{result[:proposed_tier]}"
56
+ when :demote
57
+ result[:proposed_tier] = Helpers::Tiers.demote(current)
58
+ Legion::Logging.warn "[consent] tier change: domain=#{domain} recommend=demote from=#{current} to=#{result[:proposed_tier]}"
59
+ else
60
+ Legion::Logging.debug "[consent] tier eval: domain=#{domain} current=#{current} recommendation=#{recommendation}"
61
+ end
62
+
63
+ result
64
+ end
65
+
66
+ def apply_tier_change(domain:, new_tier:, **)
67
+ return { error: :invalid_tier, valid_tiers: Helpers::Tiers::TIERS } unless Helpers::Tiers.valid_tier?(new_tier)
68
+
69
+ old_tier = consent_map.get_tier(domain)
70
+ consent_map.set_tier(domain, new_tier)
71
+ changed = old_tier != new_tier
72
+ Legion::Logging.info "[consent] tier applied: domain=#{domain} old=#{old_tier} new=#{new_tier} changed=#{changed}"
73
+ { domain: domain, old_tier: old_tier, new_tier: new_tier, changed: changed }
74
+ end
75
+
76
+ def evaluate_all_tiers(**)
77
+ promotions = []
78
+ demotions = []
79
+
80
+ consent_map.domains.each_key do |domain|
81
+ result = consent_map.evaluate_promotion(domain)
82
+ promotions << domain if result == :promote
83
+ demotions << domain if result == :demote
84
+ end
85
+
86
+ evaluated = consent_map.domain_count
87
+ Legion::Logging.debug "[consent] tier evaluation sweep: domains=#{evaluated} " \
88
+ "promotions=#{promotions.size} demotions=#{demotions.size}"
89
+
90
+ { evaluated: evaluated, promotions: promotions, demotions: demotions }
91
+ end
92
+
93
+ def request_autonomous_approval(domain:, **)
94
+ map = consent_map
95
+ current_tier = map.get_tier(domain)
96
+
97
+ return { requested: false, error: 'already_autonomous' } if current_tier == :autonomous
98
+ return { requested: false, error: 'already_pending' } if map.pending?(domain)
99
+
100
+ map.set_pending(domain, proposed_tier: :autonomous, requested_by: 'tier_evaluation')
101
+
102
+ if defined?(Legion::Events)
103
+ rate = map.success_rate(domain)
104
+ total = map.domains[domain][:total_actions]
105
+ Legion::Events.emit('consent.approval_required', {
106
+ domain: domain,
107
+ current_tier: current_tier,
108
+ proposed_tier: :autonomous,
109
+ success_rate: rate,
110
+ total_actions: total,
111
+ requested_at: Time.now.utc
112
+ })
113
+ end
114
+
115
+ { requested: true, domain: domain, current_tier: current_tier, proposed_tier: :autonomous }
116
+ end
117
+
118
+ def approve_promotion(domain:, approved_by:, **)
119
+ map = consent_map
120
+ return { approved: false, error: 'no_pending_approval' } unless map.pending?(domain)
121
+
122
+ pending_tier = map.domains[domain][:pending_tier]
123
+ old_tier = map.get_tier(domain)
124
+ map.clear_pending(domain)
125
+ map.set_tier(domain, pending_tier)
126
+
127
+ if defined?(Legion::Events)
128
+ Legion::Events.emit('consent.promotion_approved', {
129
+ domain: domain, old_tier: old_tier, new_tier: pending_tier,
130
+ approved_by: approved_by, at: Time.now.utc
131
+ })
132
+ end
133
+
134
+ { approved: true, domain: domain, old_tier: old_tier, new_tier: pending_tier, approved_by: approved_by }
135
+ end
136
+
137
+ def reject_promotion(domain:, rejected_by:, reason: nil, **)
138
+ map = consent_map
139
+ return { rejected: false, error: 'no_pending_approval' } unless map.pending?(domain)
140
+
141
+ map.clear_pending(domain)
142
+
143
+ if defined?(Legion::Events)
144
+ Legion::Events.emit('consent.promotion_rejected', {
145
+ domain: domain, rejected_by: rejected_by, reason: reason, at: Time.now.utc
146
+ })
147
+ end
148
+
149
+ { rejected: true, domain: domain, rejected_by: rejected_by, reason: reason }
150
+ end
151
+
152
+ def expire_pending_approvals(timeout: Helpers::ConsentMap::APPROVAL_TIMEOUT, **)
153
+ map = consent_map
154
+ expired = 0
155
+
156
+ map.domains.each_key do |domain|
157
+ next unless map.pending?(domain)
158
+ next unless map.pending_expired?(domain, timeout: timeout)
159
+
160
+ map.clear_pending(domain)
161
+ expired += 1
162
+ end
163
+
164
+ { expired: expired }
165
+ end
166
+
167
+ def evaluate_and_apply_tiers(**)
168
+ candidates = evaluate_all_tiers
169
+ applied_promotions = 0
170
+ applied_demotions = 0
171
+ approval_requests = 0
172
+
173
+ Array(candidates[:promotions]).each do |domain|
174
+ current = consent_map.get_tier(domain)
175
+ proposed = Helpers::Tiers.promote(current)
176
+
177
+ if proposed == :autonomous
178
+ result = request_autonomous_approval(domain: domain)
179
+ approval_requests += 1 if result[:requested]
180
+ else
181
+ apply_tier_change(domain: domain, new_tier: proposed)
182
+ applied_promotions += 1
183
+ end
184
+ end
185
+
186
+ Array(candidates[:demotions]).each do |domain|
187
+ current = consent_map.get_tier(domain)
188
+ proposed = Helpers::Tiers.demote(current)
189
+ apply_tier_change(domain: domain, new_tier: proposed)
190
+ applied_demotions += 1
191
+ end
192
+
193
+ expired = expire_pending_approvals
194
+
195
+ { evaluated: candidates[:evaluated], applied_promotions: applied_promotions,
196
+ applied_demotions: applied_demotions, approval_requests: approval_requests,
197
+ expired_approvals: expired[:expired] }
198
+ end
199
+
200
+ def consent_status(domain: nil, **)
201
+ if domain
202
+ entry = consent_map.domains[domain]
203
+ Legion::Logging.debug "[consent] status: domain=#{domain} tier=#{entry[:tier]} total=#{entry[:total_actions]}"
204
+ {
205
+ domain: domain,
206
+ tier: entry[:tier],
207
+ success_rate: consent_map.success_rate(domain),
208
+ total: entry[:total_actions],
209
+ eligible: consent_map.eligible_for_change?(domain)
210
+ }
211
+ else
212
+ Legion::Logging.debug "[consent] status: domains=#{consent_map.domain_count}"
213
+ { domains: consent_map.to_h, count: consent_map.domain_count }
214
+ end
215
+ end
216
+
217
+ private
218
+
219
+ def consent_map
220
+ @consent_map ||= Helpers::ConsentMap.new
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end
228
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Social
7
+ module Consent
8
+ VERSION = '0.2.0'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/social/consent/version'
4
+ require 'legion/extensions/agentic/social/consent/helpers/tiers'
5
+ require 'legion/extensions/agentic/social/consent/helpers/consent_map'
6
+ require 'legion/extensions/agentic/social/consent/runners/consent'
7
+ require 'legion/extensions/agentic/social/consent/client'
8
+
9
+ module Legion
10
+ module Extensions
11
+ module Agentic
12
+ module Social
13
+ module Consent
14
+ end
15
+ end
16
+ end
17
+
18
+ if defined?(Legion::Data::Local)
19
+ Legion::Data::Local.register_migrations(
20
+ name: :consent,
21
+ path: File.join(__dir__, 'consent', 'local_migrations')
22
+ )
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Social
7
+ module Entrainment
8
+ class Client
9
+ include Runners::CognitiveEntrainment
10
+
11
+ def initialize(engine: nil)
12
+ @engine = engine || Helpers::EntrainmentEngine.new
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Social
7
+ module Entrainment
8
+ module Helpers
9
+ module Constants
10
+ MAX_PAIRINGS = 200
11
+ MAX_SIGNALS = 500
12
+ MAX_HISTORY = 300
13
+
14
+ DEFAULT_SYNC = 0.0
15
+ SYNC_FLOOR = 0.0
16
+ SYNC_CEILING = 1.0
17
+
18
+ COUPLING_RATE = 0.1
19
+ DECOUPLING_RATE = 0.05
20
+ NATURAL_DRIFT = 0.02
21
+
22
+ ENTRAINED_THRESHOLD = 0.7
23
+ PARTIAL_THRESHOLD = 0.4
24
+
25
+ SYNC_LABELS = {
26
+ (0.8..) => :locked,
27
+ (0.6...0.8) => :entrained,
28
+ (0.4...0.6) => :partial,
29
+ (0.2...0.4) => :drifting,
30
+ (..0.2) => :independent
31
+ }.freeze
32
+
33
+ SIGNAL_TYPES = %i[rhythm timing phase amplitude].freeze
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Social
7
+ module Entrainment
8
+ module Helpers
9
+ class EntrainmentEngine
10
+ include Constants
11
+
12
+ attr_reader :history
13
+
14
+ def initialize
15
+ @pairings = {}
16
+ @history = []
17
+ end
18
+
19
+ def create_pairing(agent_a:, agent_b:, domain:)
20
+ evict_oldest if @pairings.size >= MAX_PAIRINGS
21
+
22
+ existing = find_pairing(agent_a: agent_a, agent_b: agent_b, domain: domain)
23
+ return existing if existing
24
+
25
+ pairing = Pairing.new(agent_a: agent_a, agent_b: agent_b, domain: domain)
26
+ @pairings[pairing.id] = pairing
27
+ record_history(:created, pairing.id)
28
+ pairing
29
+ end
30
+
31
+ def record_interaction(pairing_id:, aligned:)
32
+ pairing = @pairings[pairing_id]
33
+ return { success: false, reason: :not_found } unless pairing
34
+
35
+ pairing.interact!(aligned: aligned)
36
+ record_history(:interacted, pairing_id)
37
+ {
38
+ success: true,
39
+ synchrony: pairing.synchrony,
40
+ entrained: pairing.entrained?,
41
+ sync_label: pairing.sync_label
42
+ }
43
+ end
44
+
45
+ def pairings_for(agent_id:)
46
+ @pairings.values.select { |p| p.involves?(agent_id) }
47
+ end
48
+
49
+ def entrained_pairings
50
+ @pairings.values.select(&:entrained?)
51
+ end
52
+
53
+ def entrained_partners(agent_id:)
54
+ pairings_for(agent_id: agent_id)
55
+ .select(&:entrained?)
56
+ .map { |p| p.partner_of(agent_id) }
57
+ end
58
+
59
+ def strongest_pairings(limit: 5)
60
+ @pairings.values.sort_by { |p| -p.synchrony }.first(limit)
61
+ end
62
+
63
+ def by_domain(domain:)
64
+ @pairings.values.select { |p| p.domain == domain }
65
+ end
66
+
67
+ def overall_entrainment
68
+ return 0.0 if @pairings.empty?
69
+
70
+ @pairings.values.sum(&:synchrony) / @pairings.size
71
+ end
72
+
73
+ def drift_all
74
+ @pairings.each_value(&:drift!)
75
+ end
76
+
77
+ def prune_independent
78
+ ids = @pairings.select { |_id, p| p.synchrony <= 0.02 }.keys
79
+ ids.each { |id| @pairings.delete(id) }
80
+ ids.size
81
+ end
82
+
83
+ def to_h
84
+ {
85
+ total_pairings: @pairings.size,
86
+ entrained_count: entrained_pairings.size,
87
+ overall_sync: overall_entrainment,
88
+ history_count: @history.size
89
+ }
90
+ end
91
+
92
+ private
93
+
94
+ def find_pairing(agent_a:, agent_b:, domain:)
95
+ @pairings.values.find do |p|
96
+ p.domain == domain && pair_match?(p, agent_a, agent_b)
97
+ end
98
+ end
99
+
100
+ def pair_match?(pairing, agent_a, agent_b)
101
+ (pairing.agent_a == agent_a && pairing.agent_b == agent_b) ||
102
+ (pairing.agent_a == agent_b && pairing.agent_b == agent_a)
103
+ end
104
+
105
+ def evict_oldest
106
+ oldest_id = @pairings.min_by { |_id, p| p.last_interaction_at }&.first
107
+ @pairings.delete(oldest_id) if oldest_id
108
+ end
109
+
110
+ def record_history(event, pairing_id)
111
+ @history << { event: event, pairing_id: pairing_id, at: Time.now.utc }
112
+ @history.shift while @history.size > MAX_HISTORY
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Social
9
+ module Entrainment
10
+ module Helpers
11
+ class Pairing
12
+ include Constants
13
+
14
+ attr_reader :id, :agent_a, :agent_b, :domain, :synchrony,
15
+ :interaction_count, :created_at, :last_interaction_at
16
+
17
+ def initialize(agent_a:, agent_b:, domain:)
18
+ @id = SecureRandom.uuid
19
+ @agent_a = agent_a
20
+ @agent_b = agent_b
21
+ @domain = domain
22
+ @synchrony = DEFAULT_SYNC
23
+ @interaction_count = 0
24
+ @created_at = Time.now.utc
25
+ @last_interaction_at = @created_at
26
+ end
27
+
28
+ def interact!(aligned:)
29
+ @interaction_count += 1
30
+ @last_interaction_at = Time.now.utc
31
+
32
+ @synchrony = if aligned
33
+ (@synchrony + COUPLING_RATE).clamp(SYNC_FLOOR, SYNC_CEILING)
34
+ else
35
+ (@synchrony - DECOUPLING_RATE).clamp(SYNC_FLOOR, SYNC_CEILING)
36
+ end
37
+ end
38
+
39
+ def drift!
40
+ @synchrony = (@synchrony - NATURAL_DRIFT).clamp(SYNC_FLOOR, SYNC_CEILING)
41
+ end
42
+
43
+ def entrained?
44
+ @synchrony >= ENTRAINED_THRESHOLD
45
+ end
46
+
47
+ def partially_entrained?
48
+ @synchrony >= PARTIAL_THRESHOLD && @synchrony < ENTRAINED_THRESHOLD
49
+ end
50
+
51
+ def sync_label
52
+ SYNC_LABELS.find { |range, _| range.cover?(@synchrony) }&.last || :unknown
53
+ end
54
+
55
+ def involves?(agent_id)
56
+ [@agent_a, @agent_b].include?(agent_id)
57
+ end
58
+
59
+ def partner_of(agent_id)
60
+ return @agent_b if @agent_a == agent_id
61
+ return @agent_a if @agent_b == agent_id
62
+
63
+ nil
64
+ end
65
+
66
+ def to_h
67
+ {
68
+ id: @id,
69
+ agent_a: @agent_a,
70
+ agent_b: @agent_b,
71
+ domain: @domain,
72
+ synchrony: @synchrony,
73
+ sync_label: sync_label,
74
+ entrained: entrained?,
75
+ interaction_count: @interaction_count,
76
+ created_at: @created_at,
77
+ last_interaction_at: @last_interaction_at
78
+ }
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Social
7
+ module Entrainment
8
+ module Runners
9
+ module CognitiveEntrainment
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex)
12
+
13
+ def create_entrainment_pairing(agent_a:, agent_b:, domain:, **)
14
+ pairing = engine.create_pairing(agent_a: agent_a, agent_b: agent_b, domain: domain)
15
+ Legion::Logging.debug '[cognitive_entrainment] pairing ' \
16
+ "#{agent_a}<->#{agent_b} domain=#{domain} id=#{pairing.id[0..7]}"
17
+ { success: true, pairing_id: pairing.id, agent_a: agent_a,
18
+ agent_b: agent_b, domain: domain, synchrony: pairing.synchrony }
19
+ end
20
+
21
+ def record_entrainment_interaction(pairing_id:, aligned:, **)
22
+ result = engine.record_interaction(pairing_id: pairing_id, aligned: aligned)
23
+ Legion::Logging.debug '[cognitive_entrainment] interaction ' \
24
+ "id=#{pairing_id[0..7]} aligned=#{aligned}"
25
+ result
26
+ end
27
+
28
+ def pairings_for_agent(agent_id:, **)
29
+ pairings = engine.pairings_for(agent_id: agent_id)
30
+ Legion::Logging.debug '[cognitive_entrainment] pairings_for ' \
31
+ "agent=#{agent_id} count=#{pairings.size}"
32
+ { success: true, agent_id: agent_id,
33
+ pairings: pairings.map(&:to_h), count: pairings.size }
34
+ end
35
+
36
+ def entrained_partners(agent_id:, **)
37
+ partners = engine.entrained_partners(agent_id: agent_id)
38
+ Legion::Logging.debug '[cognitive_entrainment] entrained_partners ' \
39
+ "agent=#{agent_id} count=#{partners.size}"
40
+ { success: true, agent_id: agent_id, partners: partners, count: partners.size }
41
+ end
42
+
43
+ def strongest_entrainment_pairings(limit: 5, **)
44
+ pairings = engine.strongest_pairings(limit: limit)
45
+ Legion::Logging.debug "[cognitive_entrainment] strongest count=#{pairings.size}"
46
+ { success: true, pairings: pairings.map(&:to_h), count: pairings.size }
47
+ end
48
+
49
+ def domain_entrainment(domain:, **)
50
+ pairings = engine.by_domain(domain: domain)
51
+ Legion::Logging.debug "[cognitive_entrainment] domain=#{domain} " \
52
+ "count=#{pairings.size}"
53
+ { success: true, domain: domain,
54
+ pairings: pairings.map(&:to_h), count: pairings.size }
55
+ end
56
+
57
+ def overall_entrainment_level(**)
58
+ sync = engine.overall_entrainment
59
+ Legion::Logging.debug "[cognitive_entrainment] overall_sync=#{sync.round(3)}"
60
+ { success: true, overall_synchrony: sync,
61
+ entrained_count: engine.entrained_pairings.size }
62
+ end
63
+
64
+ def update_cognitive_entrainment(**)
65
+ engine.drift_all
66
+ pruned = engine.prune_independent
67
+ Legion::Logging.debug "[cognitive_entrainment] drift+prune pruned=#{pruned}"
68
+ { success: true, pruned: pruned }
69
+ end
70
+
71
+ def cognitive_entrainment_stats(**)
72
+ stats = engine.to_h
73
+ Legion::Logging.debug '[cognitive_entrainment] stats ' \
74
+ "total=#{stats[:total_pairings]}"
75
+ { success: true }.merge(stats)
76
+ end
77
+
78
+ private
79
+
80
+ def engine
81
+ @engine ||= Helpers::EntrainmentEngine.new
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Social
7
+ module Entrainment
8
+ VERSION = '0.1.0'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/social/entrainment/version'
4
+ require 'legion/extensions/agentic/social/entrainment/helpers/constants'
5
+ require 'legion/extensions/agentic/social/entrainment/helpers/pairing'
6
+ require 'legion/extensions/agentic/social/entrainment/helpers/entrainment_engine'
7
+ require 'legion/extensions/agentic/social/entrainment/runners/cognitive_entrainment'
8
+ require 'legion/extensions/agentic/social/entrainment/client'
9
+
10
+ module Legion
11
+ module Extensions
12
+ module Agentic
13
+ module Social
14
+ module Entrainment
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Social
7
+ module Governance
8
+ module Actors
9
+ class ShadowAiScan < Legion::Extensions::Actors::Every
10
+ def runner_class = Runners::ShadowAi
11
+ def runner_function = 'full_scan'
12
+ def time = 86_400
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end