Class: Legion::Gaia::CognitiveBus

Inherits:
Object
  • Object
show all
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

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

Returns:

  • (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

#iterationObject



150
151
152
# File 'lib/legion/gaia/cognitive_bus.rb', line 150

def iteration
  @mutex.synchronize { @iteration }
end

#losersObject



162
163
164
# File 'lib/legion/gaia/cognitive_bus.rb', line 162

def losers
  @mutex.synchronize { @losers.dup }
end

#max_prediction_errorObject

── 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_countObject



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

#resetObject



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

#snapshotObject



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

#winnersObject



158
159
160
# File 'lib/legion/gaia/cognitive_bus.rb', line 158

def winners
  @mutex.synchronize { @winners.dup }
end