Class: Legion::Gaia::CognitiveBus
- Inherits:
-
Object
- Object
- Legion::Gaia::CognitiveBus
- Includes:
- Logging::Helper
- Defined in:
- lib/legion/gaia/cognitive_bus.rb
Overview
The CognitiveBus is the shared signal substrate through which all cognitive processes communicate. It implements competitive broadcasting: processes submit signals with precision-weighted salience, and only the top N signals win workspace access (consciousness). The rest run in subconscious mode.
Neuromodulators control who gets heard: acetylcholine gates attention, norepinephrine controls global arousal, dopamine boosts reward signals, serotonin modulates social signal weighting.
Defined Under Namespace
Classes: Signal
Constant Summary collapse
- DEFAULT_BROADCAST_SLOTS =
3
Instance Method Summary collapse
- #converged?(threshold: 0.05) ⇒ Boolean
- #history(limit: 50) ⇒ Object
-
#initialize(broadcast_slots: DEFAULT_BROADCAST_SLOTS) ⇒ CognitiveBus
constructor
A new instance of CognitiveBus.
- #iteration ⇒ Object
- #losers ⇒ Object
-
#max_prediction_error ⇒ Object
── State ───────────────────────────────────────────────────────.
- #pending_count ⇒ Object
-
#propagate(neuromodulators: {}) ⇒ Object
Run competitive broadcasting: sort signals by weighted salience, apply neuromodulator weighting, select winners.
- #reset ⇒ Object
- #snapshot ⇒ Object
-
#submit(type:, data:, precision:, salience:, source:) ⇒ Object
A process submits a signal with precision-weighted salience.
- #winners ⇒ Object
Constructor Details
#initialize(broadcast_slots: DEFAULT_BROADCAST_SLOTS) ⇒ CognitiveBus
Returns a new instance of CognitiveBus.
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/legion/gaia/cognitive_bus.rb', line 52 def initialize(broadcast_slots: DEFAULT_BROADCAST_SLOTS) @mutex = Mutex.new @broadcast_slots = broadcast_slots @signals = [] @iteration = 0 @winners = [] @losers = [] @history = [] @max_history = 200 end |
Instance Method Details
#converged?(threshold: 0.05) ⇒ Boolean
146 147 148 |
# File 'lib/legion/gaia/cognitive_bus.rb', line 146 def converged?(threshold: 0.05) @mutex.synchronize { __max_prediction_error_unlocked } < threshold end |
#history(limit: 50) ⇒ Object
166 167 168 |
# File 'lib/legion/gaia/cognitive_bus.rb', line 166 def history(limit: 50) @mutex.synchronize { @history.last(limit).dup } end |
#iteration ⇒ Object
150 151 152 |
# File 'lib/legion/gaia/cognitive_bus.rb', line 150 def iteration @mutex.synchronize { @iteration } end |
#losers ⇒ Object
162 163 164 |
# File 'lib/legion/gaia/cognitive_bus.rb', line 162 def losers @mutex.synchronize { @losers.dup } end |
#max_prediction_error ⇒ Object
── State ───────────────────────────────────────────────────────
128 129 130 131 132 |
# File 'lib/legion/gaia/cognitive_bus.rb', line 128 def max_prediction_error @mutex.synchronize do __max_prediction_error_unlocked end end |
#pending_count ⇒ Object
154 155 156 |
# File 'lib/legion/gaia/cognitive_bus.rb', line 154 def pending_count @mutex.synchronize { @signals.size } end |
#propagate(neuromodulators: {}) ⇒ Object
Run competitive broadcasting: sort signals by weighted salience, apply neuromodulator weighting, select winners.
neuromodulators should be a hash with :dopamine, :norepinephrine, :serotonin, :acetylcholine, :oxytocin (each 0.0-1.0 level).
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/legion/gaia/cognitive_bus.rb', line 93 def propagate(neuromodulators: {}) @mutex.synchronize do @iteration += 1 @winners = [] @losers = [] return propagation_result if @signals.empty? # Apply neuromodulator weighting to salience apply_neuromodulation(@signals, neuromodulators) # Sort by weighted salience (descending) ranked = @signals.sort_by { |s| -s.weighted_salience } # Winner-take-most @winners = ranked.first(@broadcast_slots) @winners.each { |s| s.status = :broadcast } @losers = ranked - @winners @losers.each { |s| s.status = :suppressed } # Record and clear record_iteration @signals.clear log.debug("[bus] iterate##{@iteration} signals=#{ranked.size} " \ "winners=#{@winners.size} losers=#{@losers.size} " \ "max_weighted=#{ranked.first&.weighted_salience&.round(3) || 0}") propagation_result end end |
#reset ⇒ Object
170 171 172 173 174 175 176 |
# File 'lib/legion/gaia/cognitive_bus.rb', line 170 def reset @mutex.synchronize do @signals.clear @winners.clear @losers.clear end end |
#snapshot ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/legion/gaia/cognitive_bus.rb', line 134 def snapshot @mutex.synchronize do { iteration: @iteration, pending: @signals.map(&:to_h), last_winners: @winners.map(&:to_h), last_losers: @losers.map(&:to_h), max_error: __max_prediction_error_unlocked } end end |
#submit(type:, data:, precision:, salience:, source:) ⇒ Object
A process submits a signal with precision-weighted salience. type: symbol describing signal category (:prediction_error, :reward, :social, etc.) data: arbitrary payload hash precision: 0.0-1.0, how much to trust this signal (set by neuromodulators) salience: 0.0-1.0, raw importance magnitude source: which process submitted this signal
71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/legion/gaia/cognitive_bus.rb', line 71 def submit(type:, data:, precision:, salience:, source:) signal = Signal.new( type: type, data: data, precision: precision.clamp(0.0, 1.0), salience: salience.clamp(0.0, 1.0), source: source ) @mutex.synchronize { @signals << signal } log.debug("[bus] submit type=#{type} source=#{source} precision=#{precision.round(3)} " \ "salience=#{salience.round(3)} weighted=#{signal.weighted_salience.round(3)}") signal end |
#winners ⇒ Object
158 159 160 |
# File 'lib/legion/gaia/cognitive_bus.rb', line 158 def winners @mutex.synchronize { @winners.dup } end |