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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +5 -0
- data/LICENSE +21 -0
- data/README.md +13 -0
- data/lex-agentic-social.gemspec +30 -0
- data/lib/legion/extensions/agentic/social/apprenticeship/client.rb +28 -0
- data/lib/legion/extensions/agentic/social/apprenticeship/helpers/apprenticeship.rb +90 -0
- data/lib/legion/extensions/agentic/social/apprenticeship/helpers/apprenticeship_engine.rb +109 -0
- data/lib/legion/extensions/agentic/social/apprenticeship/helpers/apprenticeship_model.rb +93 -0
- data/lib/legion/extensions/agentic/social/apprenticeship/runners/cognitive_apprenticeship.rb +112 -0
- data/lib/legion/extensions/agentic/social/apprenticeship/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/apprenticeship.rb +19 -0
- data/lib/legion/extensions/agentic/social/conflict/actors/stale_check.rb +45 -0
- data/lib/legion/extensions/agentic/social/conflict/client.rb +27 -0
- data/lib/legion/extensions/agentic/social/conflict/helpers/conflict_log.rb +70 -0
- data/lib/legion/extensions/agentic/social/conflict/helpers/llm_enhancer.rb +130 -0
- data/lib/legion/extensions/agentic/social/conflict/helpers/severity.rb +47 -0
- data/lib/legion/extensions/agentic/social/conflict/runners/conflict.rb +112 -0
- data/lib/legion/extensions/agentic/social/conflict/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/conflict.rb +19 -0
- data/lib/legion/extensions/agentic/social/conscience/client.rb +26 -0
- data/lib/legion/extensions/agentic/social/conscience/helpers/constants.rb +53 -0
- data/lib/legion/extensions/agentic/social/conscience/helpers/moral_evaluator.rb +178 -0
- data/lib/legion/extensions/agentic/social/conscience/helpers/moral_store.rb +116 -0
- data/lib/legion/extensions/agentic/social/conscience/runners/conscience.rb +117 -0
- data/lib/legion/extensions/agentic/social/conscience/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/conscience.rb +19 -0
- data/lib/legion/extensions/agentic/social/consent/actors/tier_evaluation.rb +45 -0
- data/lib/legion/extensions/agentic/social/consent/client.rb +27 -0
- data/lib/legion/extensions/agentic/social/consent/helpers/consent_map.rb +199 -0
- data/lib/legion/extensions/agentic/social/consent/helpers/tiers.rb +54 -0
- data/lib/legion/extensions/agentic/social/consent/local_migrations/20260316000010_create_consent_domains.rb +16 -0
- data/lib/legion/extensions/agentic/social/consent/runners/consent.rb +228 -0
- data/lib/legion/extensions/agentic/social/consent/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/consent.rb +25 -0
- data/lib/legion/extensions/agentic/social/entrainment/client.rb +19 -0
- data/lib/legion/extensions/agentic/social/entrainment/helpers/constants.rb +40 -0
- data/lib/legion/extensions/agentic/social/entrainment/helpers/entrainment_engine.rb +120 -0
- data/lib/legion/extensions/agentic/social/entrainment/helpers/pairing.rb +86 -0
- data/lib/legion/extensions/agentic/social/entrainment/runners/cognitive_entrainment.rb +89 -0
- data/lib/legion/extensions/agentic/social/entrainment/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/entrainment.rb +19 -0
- data/lib/legion/extensions/agentic/social/governance/actors/shadow_ai_scan.rb +19 -0
- data/lib/legion/extensions/agentic/social/governance/actors/vote_timeout.rb +45 -0
- data/lib/legion/extensions/agentic/social/governance/client.rb +27 -0
- data/lib/legion/extensions/agentic/social/governance/helpers/layers.rb +40 -0
- data/lib/legion/extensions/agentic/social/governance/helpers/proposal.rb +94 -0
- data/lib/legion/extensions/agentic/social/governance/runners/governance.rb +87 -0
- data/lib/legion/extensions/agentic/social/governance/runners/shadow_ai.rb +93 -0
- data/lib/legion/extensions/agentic/social/governance/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/governance.rb +20 -0
- data/lib/legion/extensions/agentic/social/joint_attention/actors/decay.rb +45 -0
- data/lib/legion/extensions/agentic/social/joint_attention/client.rb +28 -0
- data/lib/legion/extensions/agentic/social/joint_attention/helpers/attention_target.rb +124 -0
- data/lib/legion/extensions/agentic/social/joint_attention/helpers/constants.rb +34 -0
- data/lib/legion/extensions/agentic/social/joint_attention/helpers/joint_focus_manager.rb +157 -0
- data/lib/legion/extensions/agentic/social/joint_attention/runners/joint_attention.rb +88 -0
- data/lib/legion/extensions/agentic/social/joint_attention/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/joint_attention.rb +20 -0
- data/lib/legion/extensions/agentic/social/mentalizing/actors/decay.rb +45 -0
- data/lib/legion/extensions/agentic/social/mentalizing/client.rb +28 -0
- data/lib/legion/extensions/agentic/social/mentalizing/helpers/belief_attribution.rb +58 -0
- data/lib/legion/extensions/agentic/social/mentalizing/helpers/constants.rb +33 -0
- data/lib/legion/extensions/agentic/social/mentalizing/helpers/mental_model.rb +137 -0
- data/lib/legion/extensions/agentic/social/mentalizing/runners/mentalizing.rb +93 -0
- data/lib/legion/extensions/agentic/social/mentalizing/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/mentalizing.rb +20 -0
- data/lib/legion/extensions/agentic/social/mirror/client.rb +33 -0
- data/lib/legion/extensions/agentic/social/mirror/helpers/constants.rb +65 -0
- data/lib/legion/extensions/agentic/social/mirror/helpers/mirror_engine.rb +132 -0
- data/lib/legion/extensions/agentic/social/mirror/helpers/mirror_event.rb +46 -0
- data/lib/legion/extensions/agentic/social/mirror/helpers/simulation.rb +43 -0
- data/lib/legion/extensions/agentic/social/mirror/runners/observe.rb +52 -0
- data/lib/legion/extensions/agentic/social/mirror/runners/resonance.rb +79 -0
- data/lib/legion/extensions/agentic/social/mirror/runners/simulate.rb +63 -0
- data/lib/legion/extensions/agentic/social/mirror/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/mirror.rb +22 -0
- data/lib/legion/extensions/agentic/social/mirror_system/actors/decay.rb +45 -0
- data/lib/legion/extensions/agentic/social/mirror_system/client.rb +28 -0
- data/lib/legion/extensions/agentic/social/mirror_system/helpers/constants.rb +62 -0
- data/lib/legion/extensions/agentic/social/mirror_system/helpers/mirror_system.rb +162 -0
- data/lib/legion/extensions/agentic/social/mirror_system/helpers/observed_behavior.rb +67 -0
- data/lib/legion/extensions/agentic/social/mirror_system/runners/mirror.rb +99 -0
- data/lib/legion/extensions/agentic/social/mirror_system/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/mirror_system.rb +20 -0
- data/lib/legion/extensions/agentic/social/moral_reasoning/client.rb +19 -0
- data/lib/legion/extensions/agentic/social/moral_reasoning/helpers/constants.rb +49 -0
- data/lib/legion/extensions/agentic/social/moral_reasoning/helpers/dilemma.rb +68 -0
- data/lib/legion/extensions/agentic/social/moral_reasoning/helpers/llm_enhancer.rb +140 -0
- data/lib/legion/extensions/agentic/social/moral_reasoning/helpers/moral_engine.rb +239 -0
- data/lib/legion/extensions/agentic/social/moral_reasoning/helpers/moral_foundation.rb +45 -0
- data/lib/legion/extensions/agentic/social/moral_reasoning/runners/moral_reasoning.rb +121 -0
- data/lib/legion/extensions/agentic/social/moral_reasoning/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/moral_reasoning.rb +21 -0
- data/lib/legion/extensions/agentic/social/perspective_shifting/client.rb +29 -0
- data/lib/legion/extensions/agentic/social/perspective_shifting/helpers/constants.rb +67 -0
- data/lib/legion/extensions/agentic/social/perspective_shifting/helpers/perspective.rb +45 -0
- data/lib/legion/extensions/agentic/social/perspective_shifting/helpers/perspective_view.rb +57 -0
- data/lib/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine.rb +166 -0
- data/lib/legion/extensions/agentic/social/perspective_shifting/runners/perspective_shifting.rb +167 -0
- data/lib/legion/extensions/agentic/social/perspective_shifting/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/perspective_shifting.rb +20 -0
- data/lib/legion/extensions/agentic/social/social/client.rb +25 -0
- data/lib/legion/extensions/agentic/social/social/helpers/constants.rb +84 -0
- data/lib/legion/extensions/agentic/social/social/helpers/social_graph.rb +172 -0
- data/lib/legion/extensions/agentic/social/social/runners/social.rb +146 -0
- data/lib/legion/extensions/agentic/social/social/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/social.rb +18 -0
- data/lib/legion/extensions/agentic/social/social_learning/client.rb +25 -0
- data/lib/legion/extensions/agentic/social/social_learning/helpers/constants.rb +42 -0
- data/lib/legion/extensions/agentic/social/social_learning/helpers/model_agent.rb +82 -0
- data/lib/legion/extensions/agentic/social/social_learning/helpers/observed_behavior.rb +61 -0
- data/lib/legion/extensions/agentic/social/social_learning/helpers/social_learning_engine.rb +134 -0
- data/lib/legion/extensions/agentic/social/social_learning/runners/social_learning.rb +105 -0
- data/lib/legion/extensions/agentic/social/social_learning/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/social_learning.rb +20 -0
- data/lib/legion/extensions/agentic/social/symbiosis/client.rb +23 -0
- data/lib/legion/extensions/agentic/social/symbiosis/helpers/constants.rb +50 -0
- data/lib/legion/extensions/agentic/social/symbiosis/helpers/ecosystem.rb +113 -0
- data/lib/legion/extensions/agentic/social/symbiosis/helpers/symbiosis_engine.rb +104 -0
- data/lib/legion/extensions/agentic/social/symbiosis/helpers/symbiotic_bond.rb +112 -0
- data/lib/legion/extensions/agentic/social/symbiosis/runners/cognitive_symbiosis.rb +101 -0
- data/lib/legion/extensions/agentic/social/symbiosis/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/symbiosis.rb +22 -0
- data/lib/legion/extensions/agentic/social/theory_of_mind/client.rb +26 -0
- data/lib/legion/extensions/agentic/social/theory_of_mind/helpers/agent_model.rb +173 -0
- data/lib/legion/extensions/agentic/social/theory_of_mind/helpers/constants.rb +70 -0
- data/lib/legion/extensions/agentic/social/theory_of_mind/helpers/mental_state_tracker.rb +169 -0
- data/lib/legion/extensions/agentic/social/theory_of_mind/runners/theory_of_mind.rb +159 -0
- data/lib/legion/extensions/agentic/social/theory_of_mind/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/theory_of_mind.rb +19 -0
- data/lib/legion/extensions/agentic/social/trust/actors/decay.rb +45 -0
- data/lib/legion/extensions/agentic/social/trust/client.rb +27 -0
- data/lib/legion/extensions/agentic/social/trust/helpers/trust_map.rb +160 -0
- data/lib/legion/extensions/agentic/social/trust/helpers/trust_model.rb +52 -0
- data/lib/legion/extensions/agentic/social/trust/local_migrations/20260316000020_create_trust_entries.rb +23 -0
- data/lib/legion/extensions/agentic/social/trust/runners/trust.rb +80 -0
- data/lib/legion/extensions/agentic/social/trust/version.rb +13 -0
- data/lib/legion/extensions/agentic/social/trust.rb +25 -0
- data/lib/legion/extensions/agentic/social/version.rb +11 -0
- data/lib/legion/extensions/agentic/social.rb +34 -0
- data/spec/legion/extensions/agentic/social/apprenticeship/client_spec.rb +20 -0
- data/spec/legion/extensions/agentic/social/apprenticeship/cognitive_apprenticeship_spec.rb +11 -0
- data/spec/legion/extensions/agentic/social/apprenticeship/helpers/apprenticeship_engine_spec.rb +146 -0
- data/spec/legion/extensions/agentic/social/apprenticeship/helpers/apprenticeship_model_spec.rb +124 -0
- data/spec/legion/extensions/agentic/social/apprenticeship/helpers/apprenticeship_spec.rb +136 -0
- data/spec/legion/extensions/agentic/social/apprenticeship/runners/cognitive_apprenticeship_spec.rb +154 -0
- data/spec/legion/extensions/agentic/social/conflict/actors/stale_check_spec.rb +45 -0
- data/spec/legion/extensions/agentic/social/conflict/client_spec.rb +15 -0
- data/spec/legion/extensions/agentic/social/conflict/helpers/conflict_log_spec.rb +232 -0
- data/spec/legion/extensions/agentic/social/conflict/helpers/llm_enhancer_spec.rb +189 -0
- data/spec/legion/extensions/agentic/social/conflict/helpers/severity_spec.rb +215 -0
- data/spec/legion/extensions/agentic/social/conflict/runners/conflict_spec.rb +151 -0
- data/spec/legion/extensions/agentic/social/conscience/client_spec.rb +58 -0
- data/spec/legion/extensions/agentic/social/conscience/helpers/constants_spec.rb +124 -0
- data/spec/legion/extensions/agentic/social/conscience/helpers/moral_evaluator_spec.rb +253 -0
- data/spec/legion/extensions/agentic/social/conscience/helpers/moral_store_spec.rb +230 -0
- data/spec/legion/extensions/agentic/social/conscience/runners/conscience_spec.rb +239 -0
- data/spec/legion/extensions/agentic/social/consent/actors/tier_evaluation_spec.rb +46 -0
- data/spec/legion/extensions/agentic/social/consent/client_spec.rb +33 -0
- data/spec/legion/extensions/agentic/social/consent/helpers/tiers_spec.rb +49 -0
- data/spec/legion/extensions/agentic/social/consent/local_persistence_spec.rb +234 -0
- data/spec/legion/extensions/agentic/social/consent/runners/consent_spec.rb +224 -0
- data/spec/legion/extensions/agentic/social/entrainment/client_spec.rb +21 -0
- data/spec/legion/extensions/agentic/social/entrainment/helpers/entrainment_engine_spec.rb +116 -0
- data/spec/legion/extensions/agentic/social/entrainment/helpers/pairing_spec.rb +103 -0
- data/spec/legion/extensions/agentic/social/entrainment/runners/cognitive_entrainment_spec.rb +87 -0
- data/spec/legion/extensions/agentic/social/governance/actors/vote_timeout_spec.rb +45 -0
- data/spec/legion/extensions/agentic/social/governance/client_spec.rb +14 -0
- data/spec/legion/extensions/agentic/social/governance/helpers/layers_spec.rb +190 -0
- data/spec/legion/extensions/agentic/social/governance/helpers/proposal_spec.rb +188 -0
- data/spec/legion/extensions/agentic/social/governance/runners/governance_spec.rb +101 -0
- data/spec/legion/extensions/agentic/social/governance/runners/shadow_ai_spec.rb +65 -0
- data/spec/legion/extensions/agentic/social/joint_attention/client_spec.rb +36 -0
- data/spec/legion/extensions/agentic/social/joint_attention/helpers/attention_target_spec.rb +258 -0
- data/spec/legion/extensions/agentic/social/joint_attention/helpers/joint_focus_manager_spec.rb +238 -0
- data/spec/legion/extensions/agentic/social/joint_attention/runners/joint_attention_spec.rb +228 -0
- data/spec/legion/extensions/agentic/social/mentalizing/client_spec.rb +19 -0
- data/spec/legion/extensions/agentic/social/mentalizing/helpers/belief_attribution_spec.rb +108 -0
- data/spec/legion/extensions/agentic/social/mentalizing/helpers/mental_model_spec.rb +179 -0
- data/spec/legion/extensions/agentic/social/mentalizing/runners/mentalizing_spec.rb +162 -0
- data/spec/legion/extensions/agentic/social/mirror/client_spec.rb +92 -0
- data/spec/legion/extensions/agentic/social/mirror/helpers/constants_spec.rb +123 -0
- data/spec/legion/extensions/agentic/social/mirror/helpers/mirror_engine_spec.rb +217 -0
- data/spec/legion/extensions/agentic/social/mirror/helpers/mirror_event_spec.rb +102 -0
- data/spec/legion/extensions/agentic/social/mirror/helpers/simulation_spec.rb +100 -0
- data/spec/legion/extensions/agentic/social/mirror/runners/observe_spec.rb +77 -0
- data/spec/legion/extensions/agentic/social/mirror/runners/resonance_spec.rb +123 -0
- data/spec/legion/extensions/agentic/social/mirror/runners/simulate_spec.rb +103 -0
- data/spec/legion/extensions/agentic/social/mirror_system/client_spec.rb +40 -0
- data/spec/legion/extensions/agentic/social/mirror_system/helpers/mirror_system_spec.rb +144 -0
- data/spec/legion/extensions/agentic/social/mirror_system/helpers/observed_behavior_spec.rb +98 -0
- data/spec/legion/extensions/agentic/social/mirror_system/runners/mirror_spec.rb +122 -0
- data/spec/legion/extensions/agentic/social/moral_reasoning/client_spec.rb +34 -0
- data/spec/legion/extensions/agentic/social/moral_reasoning/helpers/dilemma_spec.rb +108 -0
- data/spec/legion/extensions/agentic/social/moral_reasoning/helpers/llm_enhancer_spec.rb +232 -0
- data/spec/legion/extensions/agentic/social/moral_reasoning/helpers/moral_engine_spec.rb +266 -0
- data/spec/legion/extensions/agentic/social/moral_reasoning/helpers/moral_foundation_spec.rb +70 -0
- data/spec/legion/extensions/agentic/social/moral_reasoning/runners/moral_reasoning_spec.rb +275 -0
- data/spec/legion/extensions/agentic/social/perspective_shifting/client_spec.rb +30 -0
- data/spec/legion/extensions/agentic/social/perspective_shifting/helpers/constants_spec.rb +99 -0
- data/spec/legion/extensions/agentic/social/perspective_shifting/helpers/perspective_spec.rb +77 -0
- data/spec/legion/extensions/agentic/social/perspective_shifting/helpers/perspective_view_spec.rb +105 -0
- data/spec/legion/extensions/agentic/social/perspective_shifting/helpers/shifting_engine_spec.rb +246 -0
- data/spec/legion/extensions/agentic/social/perspective_shifting/runners/perspective_shifting_spec.rb +277 -0
- data/spec/legion/extensions/agentic/social/social/client_spec.rb +72 -0
- data/spec/legion/extensions/agentic/social/social/helpers/constants_spec.rb +99 -0
- data/spec/legion/extensions/agentic/social/social/helpers/social_graph_spec.rb +322 -0
- data/spec/legion/extensions/agentic/social/social/runners/social_spec.rb +220 -0
- data/spec/legion/extensions/agentic/social/social_learning/client_spec.rb +25 -0
- data/spec/legion/extensions/agentic/social/social_learning/helpers/constants_spec.rb +44 -0
- data/spec/legion/extensions/agentic/social/social_learning/helpers/model_agent_spec.rb +120 -0
- data/spec/legion/extensions/agentic/social/social_learning/helpers/observed_behavior_spec.rb +81 -0
- data/spec/legion/extensions/agentic/social/social_learning/helpers/social_learning_engine_spec.rb +196 -0
- data/spec/legion/extensions/agentic/social/social_learning/runners/social_learning_spec.rb +150 -0
- data/spec/legion/extensions/agentic/social/symbiosis/client_spec.rb +45 -0
- data/spec/legion/extensions/agentic/social/symbiosis/helpers/constants_spec.rb +73 -0
- data/spec/legion/extensions/agentic/social/symbiosis/helpers/ecosystem_spec.rb +185 -0
- data/spec/legion/extensions/agentic/social/symbiosis/helpers/symbiosis_engine_spec.rb +182 -0
- data/spec/legion/extensions/agentic/social/symbiosis/helpers/symbiotic_bond_spec.rb +209 -0
- data/spec/legion/extensions/agentic/social/symbiosis/runners/cognitive_symbiosis_spec.rb +182 -0
- data/spec/legion/extensions/agentic/social/theory_of_mind/client_spec.rb +63 -0
- data/spec/legion/extensions/agentic/social/theory_of_mind/helpers/agent_model_spec.rb +244 -0
- data/spec/legion/extensions/agentic/social/theory_of_mind/helpers/constants_spec.rb +71 -0
- data/spec/legion/extensions/agentic/social/theory_of_mind/helpers/mental_state_tracker_spec.rb +228 -0
- data/spec/legion/extensions/agentic/social/theory_of_mind/runners/theory_of_mind_spec.rb +221 -0
- data/spec/legion/extensions/agentic/social/trust/actors/decay_spec.rb +62 -0
- data/spec/legion/extensions/agentic/social/trust/client_spec.rb +17 -0
- data/spec/legion/extensions/agentic/social/trust/helpers/trust_map_spec.rb +299 -0
- data/spec/legion/extensions/agentic/social/trust/helpers/trust_model_spec.rb +179 -0
- data/spec/legion/extensions/agentic/social/trust/local_persistence_spec.rb +359 -0
- data/spec/legion/extensions/agentic/social/trust/runners/trust_spec.rb +84 -0
- data/spec/spec_helper.rb +54 -0
- 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,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,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
|