lex-agentic-social 0.1.1 → 0.1.2
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 +4 -4
- data/CHANGELOG.md +7 -0
- data/lex-agentic-social.gemspec +8 -0
- data/lib/legion/extensions/agentic/social/apprenticeship/runners/cognitive_apprenticeship.rb +11 -11
- data/lib/legion/extensions/agentic/social/conflict/runners/conflict.rb +10 -10
- data/lib/legion/extensions/agentic/social/conscience/runners/conscience.rb +10 -10
- data/lib/legion/extensions/agentic/social/consent/runners/consent.rb +10 -10
- data/lib/legion/extensions/agentic/social/entrainment/runners/cognitive_entrainment.rb +15 -15
- data/lib/legion/extensions/agentic/social/governance/runners/governance.rb +8 -8
- data/lib/legion/extensions/agentic/social/joint_attention/runners/joint_attention.rb +12 -12
- data/lib/legion/extensions/agentic/social/mentalizing/runners/mentalizing.rb +9 -9
- data/lib/legion/extensions/agentic/social/mirror/runners/observe.rb +3 -3
- data/lib/legion/extensions/agentic/social/mirror/runners/resonance.rb +4 -4
- data/lib/legion/extensions/agentic/social/mirror/runners/simulate.rb +5 -5
- data/lib/legion/extensions/agentic/social/mirror_system/runners/mirror.rb +13 -13
- data/lib/legion/extensions/agentic/social/moral_reasoning/runners/moral_reasoning.rb +12 -12
- data/lib/legion/extensions/agentic/social/perspective_shifting/runners/perspective_shifting.rb +17 -17
- data/lib/legion/extensions/agentic/social/social/runners/social.rb +11 -11
- data/lib/legion/extensions/agentic/social/social_learning/runners/social_learning.rb +10 -10
- data/lib/legion/extensions/agentic/social/symbiosis/runners/cognitive_symbiosis.rb +6 -6
- data/lib/legion/extensions/agentic/social/theory_of_mind/runners/theory_of_mind.rb +9 -9
- data/lib/legion/extensions/agentic/social/trust/runners/trust.rb +7 -7
- data/lib/legion/extensions/agentic/social/version.rb +1 -1
- data/spec/spec_helper.rb +22 -29
- metadata +99 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fea8c58125ee47fd7ab9b975a69c4baf42e1724c351c556d2276ea754d98d366
|
|
4
|
+
data.tar.gz: ca7a2dd8d74dd64e94a9e4f0ea52693ca12190f49eeb77baba0643b3e13352a5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e2ad3f1f5a4329f7bd4c4185bb25dd028b17ea93a09a4399f415788b210a311f68b8c82f733762aaf8ef709b5e4eff2f35c366b00a86c91cdc65798160acf4bf
|
|
7
|
+
data.tar.gz: 4582a5327cf187c45e7b03bb7873776d4873a9d4a0b537e2aa09b76c2cef23a79189d3c6f705d11262f5863a2a38ae2fb2d9abdd3d57867f36d8b74d57b0ee8f
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.1.2] - 2026-03-22
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- Add legion-cache, legion-crypt, legion-data, legion-json, legion-logging, legion-settings, legion-transport as runtime dependencies
|
|
9
|
+
- Replace direct Legion::Logging calls with injected log helper in all runner modules
|
|
10
|
+
- Update spec_helper with real sub-gem helper stubs
|
|
11
|
+
|
|
5
12
|
## [0.1.1] - 2026-03-18
|
|
6
13
|
|
|
7
14
|
### Changed
|
data/lex-agentic-social.gemspec
CHANGED
|
@@ -24,6 +24,14 @@ Gem::Specification.new do |spec|
|
|
|
24
24
|
end
|
|
25
25
|
spec.require_paths = ['lib']
|
|
26
26
|
|
|
27
|
+
spec.add_dependency 'legion-cache', '>= 1.3.11'
|
|
28
|
+
spec.add_dependency 'legion-crypt', '>= 1.4.9'
|
|
29
|
+
spec.add_dependency 'legion-data', '>= 1.4.17'
|
|
30
|
+
spec.add_dependency 'legion-json', '>= 1.2.1'
|
|
31
|
+
spec.add_dependency 'legion-logging', '>= 1.3.2'
|
|
32
|
+
spec.add_dependency 'legion-settings', '>= 1.3.14'
|
|
33
|
+
spec.add_dependency 'legion-transport', '>= 1.3.9'
|
|
34
|
+
|
|
27
35
|
spec.add_development_dependency 'rspec', '~> 3.13'
|
|
28
36
|
spec.add_development_dependency 'rubocop', '~> 1.60'
|
|
29
37
|
spec.add_development_dependency 'rubocop-rspec', '~> 2.26'
|
data/lib/legion/extensions/agentic/social/apprenticeship/runners/cognitive_apprenticeship.rb
CHANGED
|
@@ -21,10 +21,10 @@ module Legion
|
|
|
21
21
|
)
|
|
22
22
|
|
|
23
23
|
if appr
|
|
24
|
-
|
|
24
|
+
log.info "[cognitive_apprenticeship] created id=#{appr.id} skill=#{skill_name} domain=#{domain}"
|
|
25
25
|
{ success: true, apprenticeship: appr.to_h }
|
|
26
26
|
else
|
|
27
|
-
|
|
27
|
+
log.warn '[cognitive_apprenticeship] create failed: capacity reached'
|
|
28
28
|
{ success: false, reason: :capacity_reached }
|
|
29
29
|
end
|
|
30
30
|
end
|
|
@@ -39,8 +39,8 @@ module Legion
|
|
|
39
39
|
)
|
|
40
40
|
|
|
41
41
|
if appr
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
log.debug "[cognitive_apprenticeship] session id=#{apprenticeship_id} method=#{method} " \
|
|
43
|
+
"success=#{success} mastery=#{appr.mastery.round(3)}"
|
|
44
44
|
{ success: true, apprenticeship: appr.to_h }
|
|
45
45
|
else
|
|
46
46
|
{ success: false, reason: :not_found }
|
|
@@ -51,7 +51,7 @@ module Legion
|
|
|
51
51
|
method = engine.recommend_method(apprenticeship_id: apprenticeship_id)
|
|
52
52
|
|
|
53
53
|
if method
|
|
54
|
-
|
|
54
|
+
log.debug "[cognitive_apprenticeship] recommend id=#{apprenticeship_id} method=#{method}"
|
|
55
55
|
{ success: true, apprenticeship_id: apprenticeship_id, recommended_method: method }
|
|
56
56
|
else
|
|
57
57
|
{ success: false, reason: :not_found }
|
|
@@ -60,31 +60,31 @@ module Legion
|
|
|
60
60
|
|
|
61
61
|
def graduated_apprenticeships(**)
|
|
62
62
|
list = engine.graduated_apprenticeships
|
|
63
|
-
|
|
63
|
+
log.debug "[cognitive_apprenticeship] graduated count=#{list.size}"
|
|
64
64
|
{ success: true, apprenticeships: list.map(&:to_h), count: list.size }
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def active_apprenticeships(**)
|
|
68
68
|
list = engine.active_apprenticeships
|
|
69
|
-
|
|
69
|
+
log.debug "[cognitive_apprenticeship] active count=#{list.size}"
|
|
70
70
|
{ success: true, apprenticeships: list.map(&:to_h), count: list.size }
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def mentor_apprenticeships(mentor_id:, **)
|
|
74
74
|
list = engine.by_mentor(mentor_id: mentor_id)
|
|
75
|
-
|
|
75
|
+
log.debug "[cognitive_apprenticeship] mentor=#{mentor_id} count=#{list.size}"
|
|
76
76
|
{ success: true, mentor_id: mentor_id, apprenticeships: list.map(&:to_h), count: list.size }
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def apprentice_apprenticeships(apprentice_id:, **)
|
|
80
80
|
list = engine.by_apprentice(apprentice_id: apprentice_id)
|
|
81
|
-
|
|
81
|
+
log.debug "[cognitive_apprenticeship] apprentice=#{apprentice_id} count=#{list.size}"
|
|
82
82
|
{ success: true, apprentice_id: apprentice_id, apprenticeships: list.map(&:to_h), count: list.size }
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def domain_apprenticeships(domain:, **)
|
|
86
86
|
list = engine.by_domain(domain: domain)
|
|
87
|
-
|
|
87
|
+
log.debug "[cognitive_apprenticeship] domain=#{domain} count=#{list.size}"
|
|
88
88
|
{ success: true, domain: domain, apprenticeships: list.map(&:to_h), count: list.size }
|
|
89
89
|
end
|
|
90
90
|
|
|
@@ -94,7 +94,7 @@ module Legion
|
|
|
94
94
|
|
|
95
95
|
def cognitive_apprenticeship_stats(**)
|
|
96
96
|
stats = engine.to_h
|
|
97
|
-
|
|
97
|
+
log.debug "[cognitive_apprenticeship] stats=#{stats.inspect}"
|
|
98
98
|
{ success: true }.merge(stats)
|
|
99
99
|
end
|
|
100
100
|
|
|
@@ -15,17 +15,17 @@ module Legion
|
|
|
15
15
|
|
|
16
16
|
id = conflict_log.record(parties: parties, severity: severity, description: description)
|
|
17
17
|
conflict = conflict_log.get(id)
|
|
18
|
-
|
|
18
|
+
log.info "[conflict] registered: id=#{id[0..7]} severity=#{severity} posture=#{conflict[:posture]} parties=#{parties.join(',')}"
|
|
19
19
|
{ conflict_id: id, severity: severity, posture: conflict[:posture] }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def add_exchange(conflict_id:, speaker:, message:, **)
|
|
23
23
|
result = conflict_log.add_exchange(conflict_id, speaker: speaker, message: message)
|
|
24
24
|
if result
|
|
25
|
-
|
|
25
|
+
log.debug "[conflict] exchange: id=#{conflict_id[0..7]} speaker=#{speaker}"
|
|
26
26
|
{ recorded: true }
|
|
27
27
|
else
|
|
28
|
-
|
|
28
|
+
log.debug "[conflict] exchange failed: id=#{conflict_id[0..7]} not found"
|
|
29
29
|
{ error: :not_found }
|
|
30
30
|
end
|
|
31
31
|
end
|
|
@@ -33,7 +33,7 @@ module Legion
|
|
|
33
33
|
def resolve_conflict(conflict_id:, outcome:, resolution_notes: nil, **)
|
|
34
34
|
conflict = conflict_log.get(conflict_id)
|
|
35
35
|
unless conflict
|
|
36
|
-
|
|
36
|
+
log.debug "[conflict] resolve failed: id=#{conflict_id[0..7]} not found"
|
|
37
37
|
return { error: :not_found }
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -48,23 +48,23 @@ module Legion
|
|
|
48
48
|
|
|
49
49
|
result = conflict_log.resolve(conflict_id, outcome: outcome, resolution_notes: resolution_notes)
|
|
50
50
|
if result
|
|
51
|
-
|
|
51
|
+
log.info "[conflict] resolved: id=#{conflict_id[0..7]} outcome=#{outcome}"
|
|
52
52
|
{ resolved: true, outcome: outcome }
|
|
53
53
|
else
|
|
54
|
-
|
|
54
|
+
log.debug "[conflict] resolve failed: id=#{conflict_id[0..7]} not found"
|
|
55
55
|
{ error: :not_found }
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def get_conflict(conflict_id:, **)
|
|
60
60
|
conflict = conflict_log.get(conflict_id)
|
|
61
|
-
|
|
61
|
+
log.debug "[conflict] get: id=#{conflict_id[0..7]} found=#{!conflict.nil?}"
|
|
62
62
|
conflict ? { found: true, conflict: conflict } : { found: false }
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
def active_conflicts(**)
|
|
66
66
|
conflicts = conflict_log.active_conflicts
|
|
67
|
-
|
|
67
|
+
log.debug "[conflict] active: count=#{conflicts.size}"
|
|
68
68
|
{ conflicts: conflicts, count: conflicts.size }
|
|
69
69
|
end
|
|
70
70
|
|
|
@@ -88,13 +88,13 @@ module Legion
|
|
|
88
88
|
conflict_log.add_exchange(c[:conflict_id], speaker: :system, message: message)
|
|
89
89
|
end
|
|
90
90
|
stale_ids = stale.map { |c| c[:conflict_id] }
|
|
91
|
-
|
|
91
|
+
log.debug "[conflict] stale check: active=#{active.size} stale=#{stale.size}"
|
|
92
92
|
{ checked: active.size, stale_count: stale.size, stale_ids: stale_ids }
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
def recommended_posture(severity:, **)
|
|
96
96
|
posture = Helpers::Severity.recommended_posture(severity)
|
|
97
|
-
|
|
97
|
+
log.debug "[conflict] posture: severity=#{severity} posture=#{posture}"
|
|
98
98
|
{ severity: severity, posture: posture }
|
|
99
99
|
end
|
|
100
100
|
|
|
@@ -17,8 +17,8 @@ module Legion
|
|
|
17
17
|
result = moral_store.evaluator.evaluate(action: action, context: context)
|
|
18
18
|
moral_store.record_evaluation(result)
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
log.debug "[conscience] action=#{action} verdict=#{result[:verdict]} " \
|
|
21
|
+
"score=#{result[:weighted_score]} dilemma=#{result[:dilemma]&.dig(:type)}"
|
|
22
22
|
|
|
23
23
|
result
|
|
24
24
|
end
|
|
@@ -28,8 +28,8 @@ module Legion
|
|
|
28
28
|
stats = moral_store.aggregate_stats
|
|
29
29
|
sensitivities = moral_store.foundation_sensitivities
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
log.debug "[conscience] consistency=#{stats[:consistency_score]} " \
|
|
32
|
+
"evaluations=#{stats[:total_evaluations]}"
|
|
33
33
|
|
|
34
34
|
{
|
|
35
35
|
sensitivities: sensitivities,
|
|
@@ -41,7 +41,7 @@ module Legion
|
|
|
41
41
|
# Recent moral evaluation history
|
|
42
42
|
def moral_history(limit: 20, **)
|
|
43
43
|
recent = moral_store.recent_evaluations(limit)
|
|
44
|
-
|
|
44
|
+
log.debug "[conscience] history: #{recent.size} entries"
|
|
45
45
|
|
|
46
46
|
{
|
|
47
47
|
history: recent,
|
|
@@ -57,9 +57,9 @@ module Legion
|
|
|
57
57
|
|
|
58
58
|
moral_store.record_follow_through(effective_verdict, outcome)
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
log.debug "[conscience] follow_through action=#{action} " \
|
|
61
|
+
"verdict=#{effective_verdict} outcome=#{outcome} " \
|
|
62
|
+
"consistency=#{moral_store.consistency_score}"
|
|
63
63
|
|
|
64
64
|
{
|
|
65
65
|
action: action,
|
|
@@ -72,7 +72,7 @@ module Legion
|
|
|
72
72
|
# List unresolved moral dilemmas (cases where foundations strongly disagreed)
|
|
73
73
|
def moral_dilemmas(**)
|
|
74
74
|
open = moral_store.open_dilemmas
|
|
75
|
-
|
|
75
|
+
log.debug "[conscience] dilemmas: #{open.size} open"
|
|
76
76
|
|
|
77
77
|
{
|
|
78
78
|
dilemmas: open,
|
|
@@ -83,7 +83,7 @@ module Legion
|
|
|
83
83
|
# Aggregate moral reasoning stats
|
|
84
84
|
def conscience_stats(**)
|
|
85
85
|
stats = moral_store.aggregate_stats
|
|
86
|
-
|
|
86
|
+
log.debug '[conscience] stats'
|
|
87
87
|
|
|
88
88
|
stats.merge(
|
|
89
89
|
verdict_distribution: verdict_distribution(stats[:verdict_counts]),
|
|
@@ -12,7 +12,7 @@ module Legion
|
|
|
12
12
|
|
|
13
13
|
def check_consent(domain:, _action_type: :general, **)
|
|
14
14
|
tier = consent_map.get_tier(domain)
|
|
15
|
-
|
|
15
|
+
log.debug "[consent] check: domain=#{domain} tier=#{tier} allowed=#{tier == :autonomous}"
|
|
16
16
|
|
|
17
17
|
{
|
|
18
18
|
domain: domain,
|
|
@@ -28,7 +28,7 @@ module Legion
|
|
|
28
28
|
consent_map.record_outcome(domain, success: success)
|
|
29
29
|
rate = consent_map.success_rate(domain)
|
|
30
30
|
total = consent_map.domains[domain][:total_actions]
|
|
31
|
-
|
|
31
|
+
log.info "[consent] action recorded: domain=#{domain} success=#{success} rate=#{rate.round(2)} total=#{total}"
|
|
32
32
|
|
|
33
33
|
{
|
|
34
34
|
domain: domain,
|
|
@@ -52,12 +52,12 @@ module Legion
|
|
|
52
52
|
case recommendation
|
|
53
53
|
when :promote
|
|
54
54
|
result[:proposed_tier] = Helpers::Tiers.promote(current)
|
|
55
|
-
|
|
55
|
+
log.info "[consent] tier change: domain=#{domain} recommend=promote from=#{current} to=#{result[:proposed_tier]}"
|
|
56
56
|
when :demote
|
|
57
57
|
result[:proposed_tier] = Helpers::Tiers.demote(current)
|
|
58
|
-
|
|
58
|
+
log.warn "[consent] tier change: domain=#{domain} recommend=demote from=#{current} to=#{result[:proposed_tier]}"
|
|
59
59
|
else
|
|
60
|
-
|
|
60
|
+
log.debug "[consent] tier eval: domain=#{domain} current=#{current} recommendation=#{recommendation}"
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
result
|
|
@@ -69,7 +69,7 @@ module Legion
|
|
|
69
69
|
old_tier = consent_map.get_tier(domain)
|
|
70
70
|
consent_map.set_tier(domain, new_tier)
|
|
71
71
|
changed = old_tier != new_tier
|
|
72
|
-
|
|
72
|
+
log.info "[consent] tier applied: domain=#{domain} old=#{old_tier} new=#{new_tier} changed=#{changed}"
|
|
73
73
|
{ domain: domain, old_tier: old_tier, new_tier: new_tier, changed: changed }
|
|
74
74
|
end
|
|
75
75
|
|
|
@@ -84,8 +84,8 @@ module Legion
|
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
evaluated = consent_map.domain_count
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
log.debug "[consent] tier evaluation sweep: domains=#{evaluated} " \
|
|
88
|
+
"promotions=#{promotions.size} demotions=#{demotions.size}"
|
|
89
89
|
|
|
90
90
|
{ evaluated: evaluated, promotions: promotions, demotions: demotions }
|
|
91
91
|
end
|
|
@@ -200,7 +200,7 @@ module Legion
|
|
|
200
200
|
def consent_status(domain: nil, **)
|
|
201
201
|
if domain
|
|
202
202
|
entry = consent_map.domains[domain]
|
|
203
|
-
|
|
203
|
+
log.debug "[consent] status: domain=#{domain} tier=#{entry[:tier]} total=#{entry[:total_actions]}"
|
|
204
204
|
{
|
|
205
205
|
domain: domain,
|
|
206
206
|
tier: entry[:tier],
|
|
@@ -209,7 +209,7 @@ module Legion
|
|
|
209
209
|
eligible: consent_map.eligible_for_change?(domain)
|
|
210
210
|
}
|
|
211
211
|
else
|
|
212
|
-
|
|
212
|
+
log.debug "[consent] status: domains=#{consent_map.domain_count}"
|
|
213
213
|
{ domains: consent_map.to_h, count: consent_map.domain_count }
|
|
214
214
|
end
|
|
215
215
|
end
|
|
@@ -12,51 +12,51 @@ module Legion
|
|
|
12
12
|
|
|
13
13
|
def create_entrainment_pairing(agent_a:, agent_b:, domain:, **)
|
|
14
14
|
pairing = engine.create_pairing(agent_a: agent_a, agent_b: agent_b, domain: domain)
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
log.debug '[cognitive_entrainment] pairing ' \
|
|
16
|
+
"#{agent_a}<->#{agent_b} domain=#{domain} id=#{pairing.id[0..7]}"
|
|
17
17
|
{ success: true, pairing_id: pairing.id, agent_a: agent_a,
|
|
18
18
|
agent_b: agent_b, domain: domain, synchrony: pairing.synchrony }
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def record_entrainment_interaction(pairing_id:, aligned:, **)
|
|
22
22
|
result = engine.record_interaction(pairing_id: pairing_id, aligned: aligned)
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
log.debug '[cognitive_entrainment] interaction ' \
|
|
24
|
+
"id=#{pairing_id[0..7]} aligned=#{aligned}"
|
|
25
25
|
result
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def pairings_for_agent(agent_id:, **)
|
|
29
29
|
pairings = engine.pairings_for(agent_id: agent_id)
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
log.debug '[cognitive_entrainment] pairings_for ' \
|
|
31
|
+
"agent=#{agent_id} count=#{pairings.size}"
|
|
32
32
|
{ success: true, agent_id: agent_id,
|
|
33
33
|
pairings: pairings.map(&:to_h), count: pairings.size }
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def entrained_partners(agent_id:, **)
|
|
37
37
|
partners = engine.entrained_partners(agent_id: agent_id)
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
log.debug '[cognitive_entrainment] entrained_partners ' \
|
|
39
|
+
"agent=#{agent_id} count=#{partners.size}"
|
|
40
40
|
{ success: true, agent_id: agent_id, partners: partners, count: partners.size }
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def strongest_entrainment_pairings(limit: 5, **)
|
|
44
44
|
pairings = engine.strongest_pairings(limit: limit)
|
|
45
|
-
|
|
45
|
+
log.debug "[cognitive_entrainment] strongest count=#{pairings.size}"
|
|
46
46
|
{ success: true, pairings: pairings.map(&:to_h), count: pairings.size }
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def domain_entrainment(domain:, **)
|
|
50
50
|
pairings = engine.by_domain(domain: domain)
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
log.debug "[cognitive_entrainment] domain=#{domain} " \
|
|
52
|
+
"count=#{pairings.size}"
|
|
53
53
|
{ success: true, domain: domain,
|
|
54
54
|
pairings: pairings.map(&:to_h), count: pairings.size }
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def overall_entrainment_level(**)
|
|
58
58
|
sync = engine.overall_entrainment
|
|
59
|
-
|
|
59
|
+
log.debug "[cognitive_entrainment] overall_sync=#{sync.round(3)}"
|
|
60
60
|
{ success: true, overall_synchrony: sync,
|
|
61
61
|
entrained_count: engine.entrained_pairings.size }
|
|
62
62
|
end
|
|
@@ -64,14 +64,14 @@ module Legion
|
|
|
64
64
|
def update_cognitive_entrainment(**)
|
|
65
65
|
engine.drift_all
|
|
66
66
|
pruned = engine.prune_independent
|
|
67
|
-
|
|
67
|
+
log.debug "[cognitive_entrainment] drift+prune pruned=#{pruned}"
|
|
68
68
|
{ success: true, pruned: pruned }
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def cognitive_entrainment_stats(**)
|
|
72
72
|
stats = engine.to_h
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
log.debug '[cognitive_entrainment] stats ' \
|
|
74
|
+
"total=#{stats[:total_pairings]}"
|
|
75
75
|
{ success: true }.merge(stats)
|
|
76
76
|
end
|
|
77
77
|
|
|
@@ -16,7 +16,7 @@ module Legion
|
|
|
16
16
|
size = council_size || Helpers::Layers::MIN_COUNCIL_SIZE
|
|
17
17
|
id = proposal_store.create(category: category, description: description,
|
|
18
18
|
proposer: proposer, council_size: size)
|
|
19
|
-
|
|
19
|
+
log.info "[governance] proposal created: id=#{id[0..7]} category=#{category} proposer=#{proposer} council=#{size}"
|
|
20
20
|
{ proposal_id: id, category: category, status: :open }
|
|
21
21
|
end
|
|
22
22
|
|
|
@@ -24,26 +24,26 @@ module Legion
|
|
|
24
24
|
result = proposal_store.vote(proposal_id, voter: voter, approve: approve)
|
|
25
25
|
case result
|
|
26
26
|
when nil
|
|
27
|
-
|
|
27
|
+
log.debug "[governance] vote failed: proposal=#{proposal_id[0..7]} not found or closed"
|
|
28
28
|
{ error: :not_found_or_closed }
|
|
29
29
|
when :already_voted
|
|
30
|
-
|
|
30
|
+
log.debug "[governance] vote failed: proposal=#{proposal_id[0..7]} voter=#{voter} already voted"
|
|
31
31
|
{ error: :already_voted }
|
|
32
32
|
else
|
|
33
|
-
|
|
33
|
+
log.info "[governance] vote: proposal=#{proposal_id[0..7]} voter=#{voter} approve=#{approve} resolution=#{result}"
|
|
34
34
|
{ voted: true, resolution: result }
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def get_proposal(proposal_id:, **)
|
|
39
39
|
prop = proposal_store.get(proposal_id)
|
|
40
|
-
|
|
40
|
+
log.debug "[governance] get: proposal=#{proposal_id[0..7]} found=#{!prop.nil?}"
|
|
41
41
|
prop ? { found: true, proposal: prop } : { found: false }
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def open_proposals(**)
|
|
45
45
|
props = proposal_store.open_proposals
|
|
46
|
-
|
|
46
|
+
log.debug "[governance] open proposals: count=#{props.size}"
|
|
47
47
|
{ proposals: props, count: props.size }
|
|
48
48
|
end
|
|
49
49
|
|
|
@@ -52,7 +52,7 @@ module Legion
|
|
|
52
52
|
timed = open.select { |p| Time.now.utc - p[:created_at] > Helpers::Layers::VOTE_TIMEOUT }
|
|
53
53
|
timed.each { |p| proposal_store.resolve_timed_out(p[:proposal_id]) }
|
|
54
54
|
timed_ids = timed.map { |p| p[:proposal_id] }
|
|
55
|
-
|
|
55
|
+
log.debug "[governance] vote timeout sweep: open=#{open.size} timed_out=#{timed.size}"
|
|
56
56
|
{ checked: open.size, timed_out: timed.size, timed_out_ids: timed_ids }
|
|
57
57
|
end
|
|
58
58
|
|
|
@@ -69,7 +69,7 @@ module Legion
|
|
|
69
69
|
when :transparency
|
|
70
70
|
{ allowed: true, layer: layer, reason: :logged, audit_required: true }
|
|
71
71
|
end
|
|
72
|
-
|
|
72
|
+
log.debug "[governance] validate: layer=#{layer} allowed=#{result[:allowed]} reason=#{result[:reason]}"
|
|
73
73
|
result
|
|
74
74
|
end
|
|
75
75
|
|
|
@@ -12,65 +12,65 @@ module Legion
|
|
|
12
12
|
|
|
13
13
|
def create_attention_target(name:, domain:, creator:, priority: 0.5, **)
|
|
14
14
|
target = joint_focus_manager.create_target(name: name, domain: domain, priority: priority, creator: creator)
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
log.debug "[joint_attention] create_target: name=#{name} domain=#{domain} priority=#{priority} " \
|
|
16
|
+
"creator=#{creator} id=#{target.id}"
|
|
17
17
|
{ success: true, target: target.to_h }
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def join_attention(target_id:, agent_id:, gaze: nil, **)
|
|
21
21
|
result = joint_focus_manager.join_target(target_id: target_id, agent_id: agent_id, gaze: gaze)
|
|
22
|
-
|
|
22
|
+
log.debug "[joint_attention] join: target_id=#{target_id} agent_id=#{agent_id} gaze=#{gaze} result=#{result}"
|
|
23
23
|
{ success: %i[joined already_attending].include?(result), result: result, target_id: target_id, agent_id: agent_id }
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def leave_attention(target_id:, agent_id:, **)
|
|
27
27
|
result = joint_focus_manager.leave_target(target_id: target_id, agent_id: agent_id)
|
|
28
|
-
|
|
28
|
+
log.debug "[joint_attention] leave: target_id=#{target_id} agent_id=#{agent_id} result=#{result}"
|
|
29
29
|
{ success: result == :removed, result: result, target_id: target_id, agent_id: agent_id }
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def direct_attention(from_agent:, to_agent:, target_id:, **)
|
|
33
33
|
result = joint_focus_manager.direct_attention(from_agent: from_agent, to_agent: to_agent, target_id: target_id)
|
|
34
|
-
|
|
34
|
+
log.debug "[joint_attention] direct: from=#{from_agent} to=#{to_agent} target_id=#{target_id} result=#{result}"
|
|
35
35
|
{ success: %i[directed already_attending].include?(result), result: result, target_id: target_id,
|
|
36
36
|
from_agent: from_agent, to_agent: to_agent }
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def establish_mutual_awareness(target_id:, agent_a:, agent_b:, **)
|
|
40
40
|
result = joint_focus_manager.establish_shared(target_id: target_id, agent_a: agent_a, agent_b: agent_b)
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
log.debug "[joint_attention] mutual_awareness: target_id=#{target_id} " \
|
|
42
|
+
"agent_a=#{agent_a} agent_b=#{agent_b} result=#{result}"
|
|
43
43
|
{ success: result == :established, result: result, target_id: target_id, agent_a: agent_a, agent_b: agent_b }
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def update_gaze(target_id:, agent_id:, gaze:, **)
|
|
47
47
|
result = joint_focus_manager.update_gaze(target_id: target_id, agent_id: agent_id, gaze: gaze)
|
|
48
|
-
|
|
48
|
+
log.debug "[joint_attention] update_gaze: target_id=#{target_id} agent_id=#{agent_id} gaze=#{gaze} result=#{result}"
|
|
49
49
|
{ success: result == :updated, result: result, target_id: target_id, agent_id: agent_id, gaze: gaze }
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def shared_focus(agent_a:, agent_b:, **)
|
|
53
53
|
targets = joint_focus_manager.shared_targets(agent_a: agent_a, agent_b: agent_b)
|
|
54
|
-
|
|
54
|
+
log.debug "[joint_attention] shared_focus: agent_a=#{agent_a} agent_b=#{agent_b} count=#{targets.size}"
|
|
55
55
|
{ success: true, agent_a: agent_a, agent_b: agent_b, shared_targets: targets.map(&:to_h), count: targets.size }
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def attention_targets_for(agent_id:, **)
|
|
59
59
|
targets = joint_focus_manager.targets_for_agent(agent_id: agent_id)
|
|
60
|
-
|
|
60
|
+
log.debug "[joint_attention] targets_for: agent_id=#{agent_id} count=#{targets.size}"
|
|
61
61
|
{ success: true, agent_id: agent_id, targets: targets.map(&:to_h), count: targets.size }
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def update_joint_attention(**)
|
|
65
65
|
joint_focus_manager.decay_all
|
|
66
66
|
stats = joint_focus_manager.to_h
|
|
67
|
-
|
|
67
|
+
log.debug "[joint_attention] decay_tick: targets=#{stats[:target_count]} agents=#{stats[:agent_count]}"
|
|
68
68
|
{ success: true, targets: stats[:target_count], agents: stats[:agent_count], history: stats[:history_size] }
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def joint_attention_stats(**)
|
|
72
72
|
stats = joint_focus_manager.to_h
|
|
73
|
-
|
|
73
|
+
log.debug "[joint_attention] stats: targets=#{stats[:target_count]} agents=#{stats[:agent_count]}"
|
|
74
74
|
{ success: true, stats: stats }
|
|
75
75
|
end
|
|
76
76
|
|
|
@@ -21,54 +21,54 @@ module Legion
|
|
|
21
21
|
depth: depth,
|
|
22
22
|
about_agent_id: about_agent_id
|
|
23
23
|
)
|
|
24
|
-
|
|
24
|
+
log.debug "[mentalizing] attribute agent=#{agent_id} subject=#{subject} depth=#{depth} conf=#{belief.confidence.round(2)}"
|
|
25
25
|
{ attributed: true, belief: belief.to_h }
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def project_belief(subject:, own_belief:, other_agent_id:, **)
|
|
29
29
|
belief = mental_model.project_self(subject: subject, own_belief: own_belief.to_f, other_agent_id: other_agent_id)
|
|
30
|
-
|
|
30
|
+
log.debug "[mentalizing] project subject=#{subject} other=#{other_agent_id} discounted_conf=#{belief.confidence.round(2)}"
|
|
31
31
|
{ projected: true, belief: belief.to_h }
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def check_alignment(agent_a:, agent_b:, subject:, **)
|
|
35
35
|
score = mental_model.alignment(agent_a: agent_a, agent_b: agent_b, subject: subject)
|
|
36
|
-
|
|
36
|
+
log.debug "[mentalizing] alignment agent_a=#{agent_a} agent_b=#{agent_b} subject=#{subject} score=#{score.round(2)}"
|
|
37
37
|
{ agent_a: agent_a, agent_b: agent_b, subject: subject, alignment: score.round(4) }
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def detect_false_belief(agent_id:, subject:, reality:, **)
|
|
41
41
|
result = mental_model.detect_false_belief(agent_id: agent_id, subject: subject, reality: reality)
|
|
42
|
-
|
|
42
|
+
log.info "[mentalizing] false_belief_check agent=#{agent_id} subject=#{subject} false=#{result[:false_belief]}"
|
|
43
43
|
result
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def beliefs_for_agent(agent_id:, **)
|
|
47
47
|
beliefs = mental_model.beliefs_for(agent_id: agent_id)
|
|
48
|
-
|
|
48
|
+
log.debug "[mentalizing] beliefs_for agent=#{agent_id} count=#{beliefs.size}"
|
|
49
49
|
{ agent_id: agent_id, beliefs: beliefs.map(&:to_h), count: beliefs.size }
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def beliefs_about_agent(about_agent_id:, **)
|
|
53
53
|
beliefs = mental_model.beliefs_about(about_agent_id: about_agent_id)
|
|
54
|
-
|
|
54
|
+
log.debug "[mentalizing] beliefs_about about=#{about_agent_id} count=#{beliefs.size}"
|
|
55
55
|
{ about_agent_id: about_agent_id, beliefs: beliefs.map(&:to_h), count: beliefs.size }
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def recursive_belief_lookup(agent_id:, about_agent_id:, subject:, **)
|
|
59
59
|
belief = mental_model.recursive_belief(agent_id: agent_id, about_agent_id: about_agent_id, subject: subject)
|
|
60
60
|
if belief
|
|
61
|
-
|
|
61
|
+
log.debug "[mentalizing] recursive agent=#{agent_id} about=#{about_agent_id} subject=#{subject} found=true"
|
|
62
62
|
{ found: true, belief: belief.to_h }
|
|
63
63
|
else
|
|
64
|
-
|
|
64
|
+
log.debug "[mentalizing] recursive agent=#{agent_id} about=#{about_agent_id} subject=#{subject} found=false"
|
|
65
65
|
{ found: false, agent_id: agent_id, about_agent_id: about_agent_id, subject: subject }
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
def update_mentalizing(**)
|
|
70
70
|
mental_model.decay_all
|
|
71
|
-
|
|
71
|
+
log.debug "[mentalizing] decay cycle agents=#{mental_model.agent_count} beliefs=#{mental_model.belief_count}"
|
|
72
72
|
{ decayed: true, agents: mental_model.agent_count, beliefs: mental_model.belief_count }
|
|
73
73
|
end
|
|
74
74
|
|
|
@@ -14,7 +14,7 @@ module Legion
|
|
|
14
14
|
eng = engine || mirror_engine
|
|
15
15
|
|
|
16
16
|
unless Helpers::Constants::ACTION_TYPES.include?(action_type.to_sym)
|
|
17
|
-
|
|
17
|
+
log.debug "[cognitive_mirror] unknown action_type=#{action_type}, mapping to :unknown"
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
event = eng.observe(
|
|
@@ -26,8 +26,8 @@ module Legion
|
|
|
26
26
|
|
|
27
27
|
resonance_label = Helpers::Constants.label_for(Helpers::Constants::RESONANCE_LABELS,
|
|
28
28
|
eng.empathic_resonance(agent_id))
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
log.debug "[cognitive_mirror] observed action=#{event.action_type} " \
|
|
30
|
+
"agent=#{agent_id} resonance_tier=#{resonance_label}"
|
|
31
31
|
|
|
32
32
|
{ success: true, event: event.to_h, resonance_tier: resonance_label }
|
|
33
33
|
end
|