lex-cognitive-dissonance-resolution 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d72d6983434957dfbd52c3215b1e0530ee36b7aad5c77fa4771ab1a36dba77da
4
+ data.tar.gz: c6920d4a58f990183cdb0265e86e3c86ff252d3e30c523b9bfd6d6fb6ba5dab3
5
+ SHA512:
6
+ metadata.gz: b3ba90f088180c4cefedf3db2cea4026b26aba7ec5b747054214d792f55b7d2e5d14a6362412ae6c49d18ff29700381c2e70990d46af7623f4fdb349a0d7bc16
7
+ data.tar.gz: c359e66b35cbf3b35b114ce5ff3ff8cb3ee398e1442f878387b529aaabba29079d30323fb9d010363e382bc9c2f6c6af67cd6bd50bbd3f565c7a2d710bdf04a4
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveDissonanceResolution
6
+ class Client
7
+ include Runners::CognitiveDissonanceResolution
8
+
9
+ def engine
10
+ @engine ||= Helpers::ResolutionEngine.new
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveDissonanceResolution
6
+ module Helpers
7
+ module Constants
8
+ MAX_CONFLICTS = 200
9
+ MAX_STRATEGIES = 50
10
+
11
+ DEFAULT_TENSION = 0.5
12
+ TENSION_DECAY = 0.03
13
+ RESOLUTION_THRESHOLD = 0.2
14
+
15
+ STRATEGIES = %i[
16
+ belief_change behavior_change add_consonant
17
+ trivialize reframe seek_information
18
+ compartmentalize rationalize avoid
19
+ ].freeze
20
+
21
+ TENSION_LABELS = {
22
+ (0.8..) => :agonizing,
23
+ (0.6...0.8) => :distressing,
24
+ (0.4...0.6) => :uncomfortable,
25
+ (0.2...0.4) => :mild,
26
+ (..0.2) => :resolved
27
+ }.freeze
28
+
29
+ OUTCOME_LABELS = %i[resolved partially_resolved ongoing escalated abandoned].freeze
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module CognitiveDissonanceResolution
8
+ module Helpers
9
+ class DissonanceConflict
10
+ include Constants
11
+
12
+ attr_reader :id, :belief_a, :belief_b, :domain, :tension,
13
+ :strategy_used, :outcome, :attempts, :created_at, :resolved_at
14
+
15
+ def initialize(belief_a:, belief_b:, domain: :general, tension: DEFAULT_TENSION)
16
+ @id = SecureRandom.uuid
17
+ @belief_a = belief_a
18
+ @belief_b = belief_b
19
+ @domain = domain.to_sym
20
+ @tension = tension.to_f.clamp(0.0, 1.0)
21
+ @strategy_used = nil
22
+ @outcome = :ongoing
23
+ @attempts = 0
24
+ @created_at = Time.now.utc
25
+ @resolved_at = nil
26
+ end
27
+
28
+ def tension_label
29
+ match = TENSION_LABELS.find { |range, _| range.cover?(@tension) }
30
+ match ? match.last : :resolved
31
+ end
32
+
33
+ def resolved?
34
+ @tension <= RESOLUTION_THRESHOLD
35
+ end
36
+
37
+ def apply_strategy!(strategy:, effectiveness: 0.3)
38
+ @strategy_used = strategy.to_sym
39
+ @attempts += 1
40
+ reduction = effectiveness.to_f.clamp(0.0, 0.5)
41
+ @tension = (@tension - reduction).clamp(0.0, 1.0).round(10)
42
+ @outcome = :resolved if resolved?
43
+ @resolved_at = Time.now.utc if resolved?
44
+ self
45
+ end
46
+
47
+ def escalate!(amount: 0.15)
48
+ @tension = (@tension + amount).clamp(0.0, 1.0).round(10)
49
+ @outcome = :escalated if @tension >= 0.9
50
+ self
51
+ end
52
+
53
+ def decay!
54
+ @tension = (@tension - TENSION_DECAY).clamp(0.0, 1.0).round(10)
55
+ @outcome = :resolved if resolved? && @outcome == :ongoing
56
+ @resolved_at = Time.now.utc if resolved? && @resolved_at.nil?
57
+ self
58
+ end
59
+
60
+ def abandon!
61
+ @outcome = :abandoned
62
+ @resolved_at = Time.now.utc
63
+ self
64
+ end
65
+
66
+ def to_h
67
+ {
68
+ id: @id,
69
+ belief_a: @belief_a,
70
+ belief_b: @belief_b,
71
+ domain: @domain,
72
+ tension: @tension,
73
+ tension_label: tension_label,
74
+ resolved: resolved?,
75
+ strategy_used: @strategy_used,
76
+ outcome: @outcome,
77
+ attempts: @attempts,
78
+ created_at: @created_at,
79
+ resolved_at: @resolved_at
80
+ }
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveDissonanceResolution
6
+ module Helpers
7
+ class ResolutionEngine
8
+ include Constants
9
+
10
+ def initialize
11
+ @conflicts = {}
12
+ @strategy_history = Hash.new(0)
13
+ @strategy_successes = Hash.new(0)
14
+ end
15
+
16
+ def create_conflict(belief_a:, belief_b:, domain: :general, tension: DEFAULT_TENSION)
17
+ prune_if_needed
18
+ conflict = DissonanceConflict.new(
19
+ belief_a: belief_a,
20
+ belief_b: belief_b,
21
+ domain: domain,
22
+ tension: tension
23
+ )
24
+ @conflicts[conflict.id] = conflict
25
+ conflict
26
+ end
27
+
28
+ def apply_strategy(conflict_id:, strategy:, effectiveness: 0.3)
29
+ conflict = @conflicts[conflict_id]
30
+ return nil unless conflict
31
+
32
+ strat = strategy.to_sym
33
+ @strategy_history[strat] += 1
34
+ conflict.apply_strategy!(strategy: strat, effectiveness: effectiveness)
35
+ @strategy_successes[strat] += 1 if conflict.resolved?
36
+ conflict
37
+ end
38
+
39
+ def escalate_conflict(conflict_id:, amount: 0.15)
40
+ conflict = @conflicts[conflict_id]
41
+ return nil unless conflict
42
+
43
+ conflict.escalate!(amount: amount)
44
+ end
45
+
46
+ def abandon_conflict(conflict_id:)
47
+ conflict = @conflicts[conflict_id]
48
+ return nil unless conflict
49
+
50
+ conflict.abandon!
51
+ end
52
+
53
+ def decay_all
54
+ @conflicts.each_value(&:decay!)
55
+ @conflicts.size
56
+ end
57
+
58
+ def best_strategy
59
+ return nil if @strategy_history.empty?
60
+
61
+ @strategy_history.max_by do |strat, uses|
62
+ rate = uses.positive? ? @strategy_successes[strat].to_f / uses : 0.0
63
+ rate
64
+ end&.first
65
+ end
66
+
67
+ def strategy_report
68
+ STRATEGIES.map do |strat|
69
+ uses = @strategy_history[strat]
70
+ successes = @strategy_successes[strat]
71
+ {
72
+ strategy: strat,
73
+ uses: uses,
74
+ successes: successes,
75
+ success_rate: uses.positive? ? (successes.to_f / uses).round(4) : 0.0
76
+ }
77
+ end
78
+ end
79
+
80
+ def ongoing_conflicts
81
+ @conflicts.values.select { |c| c.outcome == :ongoing }
82
+ end
83
+
84
+ def resolved_conflicts
85
+ @conflicts.values.select { |c| c.outcome == :resolved }
86
+ end
87
+
88
+ def conflicts_by_domain(domain:)
89
+ d = domain.to_sym
90
+ @conflicts.values.select { |c| c.domain == d }
91
+ end
92
+
93
+ def most_tense(limit: 5)
94
+ @conflicts.values.sort_by { |c| -c.tension }.first(limit)
95
+ end
96
+
97
+ def resolution_rate
98
+ total = @conflicts.size
99
+ return 0.0 if total.zero?
100
+
101
+ resolved = resolved_conflicts.size
102
+ (resolved.to_f / total).round(4)
103
+ end
104
+
105
+ def average_tension
106
+ return 0.0 if @conflicts.empty?
107
+
108
+ tensions = @conflicts.values.map(&:tension)
109
+ (tensions.sum / tensions.size).round(10)
110
+ end
111
+
112
+ def dissonance_report
113
+ {
114
+ total_conflicts: @conflicts.size,
115
+ ongoing: ongoing_conflicts.size,
116
+ resolved: resolved_conflicts.size,
117
+ resolution_rate: resolution_rate,
118
+ average_tension: average_tension,
119
+ best_strategy: best_strategy,
120
+ most_tense: most_tense(limit: 3).map(&:to_h)
121
+ }
122
+ end
123
+
124
+ def to_h
125
+ {
126
+ total_conflicts: @conflicts.size,
127
+ ongoing: ongoing_conflicts.size,
128
+ resolved: resolved_conflicts.size,
129
+ resolution_rate: resolution_rate,
130
+ average_tension: average_tension
131
+ }
132
+ end
133
+
134
+ private
135
+
136
+ def prune_if_needed
137
+ return if @conflicts.size < MAX_CONFLICTS
138
+
139
+ oldest_resolved = resolved_conflicts.min_by(&:created_at)
140
+ if oldest_resolved
141
+ @conflicts.delete(oldest_resolved.id)
142
+ else
143
+ lowest = @conflicts.values.min_by(&:tension)
144
+ @conflicts.delete(lowest.id) if lowest
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveDissonanceResolution
6
+ module Runners
7
+ module CognitiveDissonanceResolution
8
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
9
+
10
+ def create_dissonance_conflict(belief_a:, belief_b:, domain: :general,
11
+ tension: nil, **)
12
+ t = tension || Helpers::Constants::DEFAULT_TENSION
13
+ conflict = engine.create_conflict(belief_a: belief_a, belief_b: belief_b,
14
+ domain: domain, tension: t)
15
+ { success: true }.merge(conflict.to_h)
16
+ end
17
+
18
+ def apply_resolution_strategy(conflict_id:, strategy:, effectiveness: 0.3, **)
19
+ result = engine.apply_strategy(conflict_id: conflict_id, strategy: strategy,
20
+ effectiveness: effectiveness)
21
+ return { success: false, error: 'conflict not found' } unless result
22
+
23
+ { success: true }.merge(result.to_h)
24
+ end
25
+
26
+ def escalate_dissonance(conflict_id:, amount: 0.15, **)
27
+ result = engine.escalate_conflict(conflict_id: conflict_id, amount: amount)
28
+ return { success: false, error: 'conflict not found' } unless result
29
+
30
+ { success: true }.merge(result.to_h)
31
+ end
32
+
33
+ def abandon_dissonance(conflict_id:, **)
34
+ result = engine.abandon_conflict(conflict_id: conflict_id)
35
+ return { success: false, error: 'conflict not found' } unless result
36
+
37
+ { success: true }.merge(result.to_h)
38
+ end
39
+
40
+ def ongoing_dissonance_report(**)
41
+ conflicts = engine.ongoing_conflicts
42
+ { success: true, count: conflicts.size, conflicts: conflicts.map(&:to_h) }
43
+ end
44
+
45
+ def most_tense_report(limit: 5, **)
46
+ conflicts = engine.most_tense(limit: limit)
47
+ { success: true, limit: limit, conflicts: conflicts.map(&:to_h) }
48
+ end
49
+
50
+ def strategy_effectiveness_report(**)
51
+ { success: true, strategies: engine.strategy_report, best: engine.best_strategy }
52
+ end
53
+
54
+ def dissonance_report(**)
55
+ engine.dissonance_report
56
+ end
57
+
58
+ def update_dissonance_resolution(**)
59
+ decayed = engine.decay_all
60
+ { success: true, decayed: decayed, stats: engine.to_h }
61
+ end
62
+
63
+ def dissonance_resolution_stats(**)
64
+ engine.to_h
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveDissonanceResolution
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'cognitive_dissonance_resolution/version'
4
+ require_relative 'cognitive_dissonance_resolution/helpers/constants'
5
+ require_relative 'cognitive_dissonance_resolution/helpers/dissonance_conflict'
6
+ require_relative 'cognitive_dissonance_resolution/helpers/resolution_engine'
7
+ require_relative 'cognitive_dissonance_resolution/runners/cognitive_dissonance_resolution'
8
+ require_relative 'cognitive_dissonance_resolution/client'
9
+
10
+ module Legion
11
+ module Extensions
12
+ module CognitiveDissonanceResolution
13
+ extend Legion::Extensions::Core if defined?(Legion::Extensions::Core)
14
+ end
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-cognitive-dissonance-resolution
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Esity
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: legion-gaia
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ description: Models dissonance conflicts between beliefs and applies resolution strategies
27
+ (belief change, rationalization, reframing) with effectiveness tracking.
28
+ email:
29
+ - matthewdiverson@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - lib/legion/extensions/cognitive_dissonance_resolution.rb
35
+ - lib/legion/extensions/cognitive_dissonance_resolution/client.rb
36
+ - lib/legion/extensions/cognitive_dissonance_resolution/helpers/constants.rb
37
+ - lib/legion/extensions/cognitive_dissonance_resolution/helpers/dissonance_conflict.rb
38
+ - lib/legion/extensions/cognitive_dissonance_resolution/helpers/resolution_engine.rb
39
+ - lib/legion/extensions/cognitive_dissonance_resolution/runners/cognitive_dissonance_resolution.rb
40
+ - lib/legion/extensions/cognitive_dissonance_resolution/version.rb
41
+ homepage: https://github.com/LegionIO/lex-cognitive-dissonance-resolution
42
+ licenses:
43
+ - MIT
44
+ metadata:
45
+ homepage_uri: https://github.com/LegionIO/lex-cognitive-dissonance-resolution
46
+ source_code_uri: https://github.com/LegionIO/lex-cognitive-dissonance-resolution
47
+ documentation_uri: https://github.com/LegionIO/lex-cognitive-dissonance-resolution
48
+ changelog_uri: https://github.com/LegionIO/lex-cognitive-dissonance-resolution/blob/main/CHANGELOG.md
49
+ bug_tracker_uri: https://github.com/LegionIO/lex-cognitive-dissonance-resolution/issues
50
+ rubygems_mfa_required: 'true'
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '3.4'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubygems_version: 3.6.9
66
+ specification_version: 4
67
+ summary: Cognitive dissonance resolution strategies for LegionIO
68
+ test_files: []