@mindot/will 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.
- package/LICENSE +202 -0
- package/README.md +777 -0
- package/dist/index.d.ts +8144 -0
- package/dist/index.js +26231 -0
- package/dist/index.js.map +1 -0
- package/package.json +73 -0
- package/src/cognition/agency/access.grants.ts +59 -0
- package/src/cognition/agency/competence.codec.ts +89 -0
- package/src/cognition/agency/engines/action.selector.ts +462 -0
- package/src/cognition/agency/engines/affordance.synthesizer.ts +384 -0
- package/src/cognition/agency/engines/deliberation.engine.ts +241 -0
- package/src/cognition/agency/engines/instruction.intake.ts +54 -0
- package/src/cognition/agency/engines/motor.schema.executor.ts +532 -0
- package/src/cognition/agency/engines/reafference.engine.ts +241 -0
- package/src/cognition/agency/execution.primitives.ts +118 -0
- package/src/cognition/agency/index.ts +58 -0
- package/src/cognition/agency/proactive.communicator.ts +274 -0
- package/src/cognition/agency/reconcile.learning.ts +82 -0
- package/src/cognition/agency/schemas/external.ts +59 -0
- package/src/cognition/agency/schemas/innate.ts +111 -0
- package/src/cognition/agency/schemas/repertoire.ts +246 -0
- package/src/cognition/agency/selection.scoring.ts +191 -0
- package/src/cognition/agency/types.ts +165 -0
- package/src/cognition/bus.ts +391 -0
- package/src/cognition/completion.inbox.ts +86 -0
- package/src/cognition/config.mirror.entities.ts +475 -0
- package/src/cognition/conversation.memory.ts +81 -0
- package/src/cognition/event.log.ts +116 -0
- package/src/cognition/event.schemas.ts +568 -0
- package/src/cognition/faculties/aesthetic.evaluator.ts +313 -0
- package/src/cognition/faculties/affective.blender.ts +562 -0
- package/src/cognition/faculties/attachment.evaluator.ts +432 -0
- package/src/cognition/faculties/attention.allocator.ts +422 -0
- package/src/cognition/faculties/autobiographical.narrator.ts +300 -0
- package/src/cognition/faculties/bias.detector.ts +363 -0
- package/src/cognition/faculties/circadian.oscillator.ts +294 -0
- package/src/cognition/faculties/confidence.calibrator.ts +324 -0
- package/src/cognition/faculties/dream.simulator.ts +251 -0
- package/src/cognition/faculties/empathy.simulator.ts +253 -0
- package/src/cognition/faculties/energy.regulator.ts +320 -0
- package/src/cognition/faculties/episodic.consolidator.ts +728 -0
- package/src/cognition/faculties/executive.engine/commands.ts +459 -0
- package/src/cognition/faculties/executive.engine/config.ts +46 -0
- package/src/cognition/faculties/executive.engine/context.ts +605 -0
- package/src/cognition/faculties/executive.engine/deferred.effects.ts +104 -0
- package/src/cognition/faculties/executive.engine/deliberate.reasoning.ts +60 -0
- package/src/cognition/faculties/executive.engine/effort.gate.ts +114 -0
- package/src/cognition/faculties/executive.engine/engine.ts +1028 -0
- package/src/cognition/faculties/executive.engine/escalation.buffer.ts +90 -0
- package/src/cognition/faculties/executive.engine/facet.supervisor.ts +271 -0
- package/src/cognition/faculties/executive.engine/facet.ts +628 -0
- package/src/cognition/faculties/executive.engine/gating.ts +222 -0
- package/src/cognition/faculties/executive.engine/index.ts +6 -0
- package/src/cognition/faculties/executive.engine/messages.ts +102 -0
- package/src/cognition/faculties/executive.engine/parser.ts +380 -0
- package/src/cognition/faculties/executive.engine/prompt.factory.ts +1053 -0
- package/src/cognition/faculties/executive.engine/types.ts +323 -0
- package/src/cognition/faculties/exteroception.ts +338 -0
- package/src/cognition/faculties/forgetting.curve.ts +202 -0
- package/src/cognition/faculties/frustration.evaluator.ts +280 -0
- package/src/cognition/faculties/goal.manager.ts +1008 -0
- package/src/cognition/faculties/inhibition.controller.ts +351 -0
- package/src/cognition/faculties/interoception.ts +417 -0
- package/src/cognition/faculties/introspection.engine.ts +246 -0
- package/src/cognition/faculties/known.entity.tracker.ts +439 -0
- package/src/cognition/faculties/loss.evaluator.ts +224 -0
- package/src/cognition/faculties/moral.evaluator.ts +437 -0
- package/src/cognition/faculties/novelty.detector.ts +254 -0
- package/src/cognition/faculties/persona.consolidator.ts +845 -0
- package/src/cognition/faculties/planning.engine/engine.ts +859 -0
- package/src/cognition/faculties/planning.engine/plan.frontier.ts +83 -0
- package/src/cognition/faculties/planning.engine/plan.store.ts +174 -0
- package/src/cognition/faculties/planning.engine/plan.supervision.ts +494 -0
- package/src/cognition/faculties/planning.engine/types.ts +143 -0
- package/src/cognition/faculties/reputation.tracker.ts +294 -0
- package/src/cognition/faculties/reward.evaluator.ts +304 -0
- package/src/cognition/faculties/self.model.updater.ts +677 -0
- package/src/cognition/faculties/semantic.engine/clustering.ts +673 -0
- package/src/cognition/faculties/semantic.engine/index.ts +6 -0
- package/src/cognition/faculties/semantic.engine/integrator.ts +750 -0
- package/src/cognition/faculties/semantic.engine/types.ts +53 -0
- package/src/cognition/faculties/sleep.pressure.regulator.ts +262 -0
- package/src/cognition/faculties/social.perception.ts +333 -0
- package/src/cognition/faculties/spaced.repetition.ts +605 -0
- package/src/cognition/faculties/stress.regulator.ts +375 -0
- package/src/cognition/faculties/task.switcher.ts +239 -0
- package/src/cognition/faculties/theory.of.mind.ts +333 -0
- package/src/cognition/faculties/threat.evaluator.ts +312 -0
- package/src/cognition/faculties/working.memory.ts +406 -0
- package/src/cognition/generative.model.ts +344 -0
- package/src/cognition/heartbeat.ts +70 -0
- package/src/cognition/index.ts +291 -0
- package/src/cognition/instruction.handler.ts +146 -0
- package/src/cognition/memory/index.ts +35 -0
- package/src/cognition/memory/vector.adapter.ts +316 -0
- package/src/cognition/memory/vector.content.ts +47 -0
- package/src/cognition/memory/vector.embedder.ts +212 -0
- package/src/cognition/memory/vector.index.ts +459 -0
- package/src/cognition/memory/vector.types.ts +65 -0
- package/src/cognition/orchestrator.ts +142 -0
- package/src/cognition/persona.prior.ts +265 -0
- package/src/cognition/schema.registry.ts +145 -0
- package/src/cognition/senses/audition.engine/engine.ts +976 -0
- package/src/cognition/senses/audition.engine/salience.ts +59 -0
- package/src/cognition/senses/base.sense.engine.ts +117 -0
- package/src/cognition/senses/gustation.engine.ts +24 -0
- package/src/cognition/senses/index.ts +172 -0
- package/src/cognition/senses/olfaction.engine.ts +24 -0
- package/src/cognition/senses/somatosensation.engine.ts +23 -0
- package/src/cognition/senses/vision.engine.ts +23 -0
- package/src/cognition/types.ts +63 -0
- package/src/cognition/utilities/token.tracker.ts +492 -0
- package/src/core/abstracts.ts +60 -0
- package/src/core/async.engine.ts +539 -0
- package/src/core/clock.ts +196 -0
- package/src/core/completion.recorder.ts +122 -0
- package/src/core/conflict.detector.ts +140 -0
- package/src/core/distributed.ts +626 -0
- package/src/core/event.bus.ts +292 -0
- package/src/core/inbound.recorder.ts +100 -0
- package/src/core/index.ts +167 -0
- package/src/core/logger.ts +85 -0
- package/src/core/metrics.ts +107 -0
- package/src/core/orchestrator.ts +625 -0
- package/src/core/replay.ts +589 -0
- package/src/core/scenario.ts +120 -0
- package/src/core/serialization.ts +448 -0
- package/src/core/simulation.ts +197 -0
- package/src/core/snapshot.manager.ts +293 -0
- package/src/core/state.manager.ts +283 -0
- package/src/core/types.ts +274 -0
- package/src/core/utils.ts +82 -0
- package/src/core/wall.clock.ts +23 -0
- package/src/extensions/livestream.ext.ts +570 -0
- package/src/extensions/time.ext.ts +339 -0
- package/src/index.ts +91 -0
- package/src/llm/gate.ts +140 -0
- package/src/llm/index.ts +716 -0
- package/src/llm/summarizer.ts +170 -0
- package/src/llm/wire.contracts.ts +67 -0
- package/src/pma/eval.ts +651 -0
- package/src/pma/index.ts +1082 -0
- package/src/profiles/built-in.ts +7 -0
- package/src/profiles/companion.ts +28 -0
- package/src/profiles/company-brain.ts +54 -0
- package/src/profiles/customer-service.ts +30 -0
- package/src/profiles/game-npc.ts +20 -0
- package/src/profiles/index.ts +42 -0
- package/src/profiles/smart-home.ts +34 -0
- package/src/runners/coherence.runner.ts +49 -0
- package/src/runners/outreach.runner.ts +158 -0
- package/src/runners/social.runner.ts +182 -0
- package/src/runners/thin-shim.runner.ts +195 -0
- package/src/sdk/will.ts +334 -0
- package/src/stem/assembly.audit.ts +88 -0
- package/src/stem/distribution.ts +203 -0
- package/src/stem/guards/identity.coherence.ts +152 -0
- package/src/stem/guards/identity.guard.ts +227 -0
- package/src/stem/index.ts +1145 -0
- package/src/stem/mind.ts +1090 -0
- package/src/stem/tracts/ack.reconciler.ts +55 -0
- package/src/stem/tracts/biography.writer.ts +190 -0
- package/src/stem/tracts/effector.controller.ts +143 -0
- package/src/stem/tracts/health.reporter.ts +113 -0
- package/src/stem/tracts/inbound.queue.ts +54 -0
- package/src/stem/tracts/outbox.controller.ts +167 -0
- package/src/stem/tracts/outbox.writer.ts +133 -0
- package/src/stem/tracts/pma.controller.ts +109 -0
- package/src/stem/tracts/replay.controller.ts +177 -0
- package/src/stem/tracts/sensory.controller.ts +168 -0
- package/src/stem/tracts/session.logger.ts +157 -0
- package/src/stem/tracts/transport/index.ts +38 -0
- package/src/stem/tracts/transport/loopback.transport.ts +86 -0
- package/src/stem/tracts/transport/socketio.transport.ts +200 -0
- package/src/stem/tracts/transport/stream.transport.ts +152 -0
- package/src/stem/tracts/transport/types.ts +193 -0
- package/src/stem/tracts/transport.controller.ts +380 -0
- package/src/types.ts +116 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────────────────────
|
|
2
|
+
// src/cognition/faculties/energy.regulator.ts
|
|
3
|
+
// ─────────────────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* EnergyRegulator — maintains the mind's energy pool.
|
|
7
|
+
*
|
|
8
|
+
* Energy decays continuously (cognitive work consumes resources).
|
|
9
|
+
* It replenishes during rest states or when external replenishment
|
|
10
|
+
* events occur. Depletion triggers hunger-like drive signals and
|
|
11
|
+
* degrades cognitive performance via modulation.
|
|
12
|
+
*
|
|
13
|
+
* NEW: Enforces hard system collapse when energy drops below 1.
|
|
14
|
+
* This is the biological equivalent of losing consciousness —
|
|
15
|
+
* the body forces recovery regardless of the Will's decisions.
|
|
16
|
+
* The forced rest state clears when energy recovers past 15.
|
|
17
|
+
*
|
|
18
|
+
* Part of Shard 0 (Regulatory Layer) — runs every tick, synchronous.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { logger } from '#core/logger'
|
|
22
|
+
import type {
|
|
23
|
+
Duration,
|
|
24
|
+
Tick,
|
|
25
|
+
SimulationContext,
|
|
26
|
+
ReadonlySimulationState,
|
|
27
|
+
StateCommands,
|
|
28
|
+
SimulationEvent,
|
|
29
|
+
DriveSignal,
|
|
30
|
+
ModulationSignal,
|
|
31
|
+
} from '#core/types'
|
|
32
|
+
import type { SimulationEngine, EngineResult, CognitiveEngine } from '#cognition/types'
|
|
33
|
+
import type { CognitiveEventSchema } from '#cognition/schema.registry'
|
|
34
|
+
import type { CognitiveEvent, CognitiveBus } from '#cognition/bus'
|
|
35
|
+
import { GenerativeModel, type GenerativeModelSnapshot } from '#cognition/generative.model'
|
|
36
|
+
|
|
37
|
+
export interface EnergyRegulatorConfig {
|
|
38
|
+
maxEnergy?: number
|
|
39
|
+
baseDecayRate?: number
|
|
40
|
+
restReplenishRate?: number
|
|
41
|
+
lowEnergyThreshold?: number
|
|
42
|
+
criticalEnergyThreshold?: number
|
|
43
|
+
/** Energy level below which the system forces unconscious recovery */
|
|
44
|
+
collapseThreshold?: number
|
|
45
|
+
/** Energy level at which forced recovery ends and consciousness returns */
|
|
46
|
+
recoveryThreshold?: number
|
|
47
|
+
bus?: CognitiveBus
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ── Cognitive metabolic cost ──────────────────────────────────────────────────
|
|
51
|
+
// Being awake costs energy; attending to more (cognitive load) and voluntarily
|
|
52
|
+
// engaging harder (effort) cost more. This is the continuous counterpart to the
|
|
53
|
+
// `focus` effector's one-shot energyCost — it makes sustained focus self-limiting
|
|
54
|
+
// against the energy pool, closing the attention→energy half of the homeostatic
|
|
55
|
+
// loop (energy already caps the AttentionAllocator's capacity ceiling). Both
|
|
56
|
+
// inputs are read from SimulationState metrics, so they need no engine snapshot.
|
|
57
|
+
const LOAD_DECAY_GAIN = 0.5 // ×base decay per unit cognitive load (attention.usage, 0–1)
|
|
58
|
+
const EFFORT_DECAY_GAIN = 1.0 // ×base decay per unit effort above the homeostatic baseline
|
|
59
|
+
const EFFORT_BASELINE = 0.7 // attention's homeostatic effort set-point — cost-neutral
|
|
60
|
+
// (mirrors EFFORT_BASELINE in attention.allocator.ts)
|
|
61
|
+
|
|
62
|
+
export class EnergyRegulator implements SimulationEngine, CognitiveEngine {
|
|
63
|
+
readonly name = 'energy-regulator'
|
|
64
|
+
|
|
65
|
+
private _maxEnergy: number
|
|
66
|
+
private _baseDecayRate: number
|
|
67
|
+
private _restReplenishRate: number
|
|
68
|
+
private _lowThreshold: number
|
|
69
|
+
private _criticalThreshold: number
|
|
70
|
+
private _collapseThreshold: number
|
|
71
|
+
private _recoveryThreshold: number
|
|
72
|
+
|
|
73
|
+
private _bus: CognitiveBus | null = null
|
|
74
|
+
|
|
75
|
+
private readonly _model = new GenerativeModel()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
constructor( config: EnergyRegulatorConfig = {} ){
|
|
79
|
+
this._bus = config.bus ?? null
|
|
80
|
+
this._maxEnergy = config.maxEnergy ?? 100
|
|
81
|
+
this._baseDecayRate = config.baseDecayRate ?? 0.02
|
|
82
|
+
this._restReplenishRate = config.restReplenishRate ?? 0.15
|
|
83
|
+
this._lowThreshold = config.lowEnergyThreshold ?? 30
|
|
84
|
+
this._criticalThreshold = config.criticalEnergyThreshold ?? 10
|
|
85
|
+
this._collapseThreshold = config.collapseThreshold ?? 1
|
|
86
|
+
this._recoveryThreshold = config.recoveryThreshold ?? 15
|
|
87
|
+
}
|
|
88
|
+
attachBus( bus: CognitiveBus ): void { this._bus = bus }
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
subscribes(): string[] { return ["executive.prediction.formed"] }
|
|
92
|
+
publishes(): CognitiveEventSchema[] { return [] }
|
|
93
|
+
|
|
94
|
+
onCognitiveEvent( e: CognitiveEvent ): StateCommands | void {
|
|
95
|
+
this._model.observe( e.type, e.salience )
|
|
96
|
+
if( e.type === 'executive.prediction.formed' ){
|
|
97
|
+
const p = e.payload as { predictedDomains: string[]; confidence: number }
|
|
98
|
+
if( p.predictedDomains.includes('energy') )
|
|
99
|
+
this._model.setPrecision( 'energy.level', 1.0 + p.confidence * 0.5 )
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
snapshot(): Record<string, unknown> {
|
|
104
|
+
// FN9: cognitive load + effort are now read from SimulationState metrics
|
|
105
|
+
// (already captured by the event-sourced state), and the activity multiplier
|
|
106
|
+
// is recomputed from them each tick — so the only durable engine-internal
|
|
107
|
+
// state left to capture is the GenerativeModel prediction baseline.
|
|
108
|
+
return { model: this._model.snapshot() }
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
restore( snap: Record<string, unknown> ): void {
|
|
112
|
+
if( !snap ) return
|
|
113
|
+
if( snap.model ) this._model.restore( snap.model as GenerativeModelSnapshot )
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async react(
|
|
117
|
+
delta: Duration,
|
|
118
|
+
tick: Tick,
|
|
119
|
+
state: ReadonlySimulationState,
|
|
120
|
+
context: SimulationContext
|
|
121
|
+
): Promise<EngineResult> {
|
|
122
|
+
this._readConfigFromState( state )
|
|
123
|
+
|
|
124
|
+
const
|
|
125
|
+
currentEnergy = state.metrics.get('energy.level') ?? this._maxEnergy,
|
|
126
|
+
isResting = state.metrics.get('state.resting') ?? 0,
|
|
127
|
+
isSleeping = state.metrics.get('state.sleeping') ?? 0,
|
|
128
|
+
isForcedRest = state.metrics.get('state.forced_rest') ?? 0,
|
|
129
|
+
// Cognitive load (how much is being attended) and voluntary effort (how hard
|
|
130
|
+
// the mind is engaging its capacity ceiling) are read straight from the
|
|
131
|
+
// attention metrics. effort's homeostatic baseline is cost-neutral; focusing
|
|
132
|
+
// above it burns the energy pool faster, standing down (rest) slower.
|
|
133
|
+
cognitiveLoad = state.metrics.get('attention.usage') ?? 0,
|
|
134
|
+
effort = state.metrics.get('attention.effort') ?? EFFORT_BASELINE,
|
|
135
|
+
events: Array<Omit<SimulationEvent, 'id' | 'timestamp' | 'tick'>> = [],
|
|
136
|
+
commands: StateCommands = { metrics: [] }
|
|
137
|
+
|
|
138
|
+
// Metabolic cost of cognition: cognitive load and sustained effort both raise
|
|
139
|
+
// the rate at which being awake drains energy. Clamped ≥ 0.5 so a calm, idle
|
|
140
|
+
// mind still ticks down at roughly half the base rate.
|
|
141
|
+
const activityMultiplier = Math.max(
|
|
142
|
+
0.5,
|
|
143
|
+
1.0 + cognitiveLoad * LOAD_DECAY_GAIN + ( effort - EFFORT_BASELINE ) * EFFORT_DECAY_GAIN
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
let newEnergy: number
|
|
147
|
+
|
|
148
|
+
// ── Forced rest (system collapse) — guaranteed recovery ──
|
|
149
|
+
if( isForcedRest > 0 || currentEnergy < this._collapseThreshold ){
|
|
150
|
+
// Body is forcing recovery. Energy always increases during forced rest.
|
|
151
|
+
// This is stronger than normal rest — the system is unconscious.
|
|
152
|
+
newEnergy = Math.min(
|
|
153
|
+
this._maxEnergy,
|
|
154
|
+
currentEnergy + this._restReplenishRate * 1.5 * ( delta / 1000 )
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
// Ensure forced_rest stays set
|
|
158
|
+
commands.metrics!.push([ 'state.forced_rest', 1 ])
|
|
159
|
+
commands.metrics!.push([ 'state.resting', 1 ])
|
|
160
|
+
|
|
161
|
+
// Clear forced rest when recovered past the recovery threshold
|
|
162
|
+
if( newEnergy >= this._recoveryThreshold ){
|
|
163
|
+
commands.metrics!.push([ 'state.forced_rest', 0 ])
|
|
164
|
+
commands.metrics!.push([ 'state.resting', 0 ])
|
|
165
|
+
|
|
166
|
+
events.push({
|
|
167
|
+
type: 'energy.consciousness_regained',
|
|
168
|
+
source: this.name,
|
|
169
|
+
payload: { energy: newEnergy, recoveryThreshold: this._recoveryThreshold },
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Periodic log during forced rest
|
|
174
|
+
if( tick % 100 === 0 ){
|
|
175
|
+
logger.info(`[energy] forced recovery — unconscious (energy=${newEnergy.toFixed(0)}, target=${this._recoveryThreshold})`)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// ── Voluntary rest or sleep ─────────────────────────────
|
|
179
|
+
else if( isSleeping > 0 ){
|
|
180
|
+
// Deep rest — rapid dissipation
|
|
181
|
+
newEnergy = Math.min(
|
|
182
|
+
this._maxEnergy,
|
|
183
|
+
currentEnergy + this._restReplenishRate * 2 * ( delta / 1000 )
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
if( currentEnergy < this._maxEnergy * 0.5 && newEnergy >= this._maxEnergy * 0.8 )
|
|
187
|
+
events.push({
|
|
188
|
+
type: 'energy.replenished',
|
|
189
|
+
source: this.name,
|
|
190
|
+
payload: { previous: currentEnergy, current: newEnergy },
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
else if( isResting > 0 ){
|
|
194
|
+
// Light rest — moderate dissipation
|
|
195
|
+
newEnergy = Math.min(
|
|
196
|
+
this._maxEnergy,
|
|
197
|
+
currentEnergy + this._restReplenishRate * ( delta / 1000 )
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
if( currentEnergy < this._maxEnergy * 0.5 && newEnergy >= this._maxEnergy * 0.8 )
|
|
201
|
+
events.push({
|
|
202
|
+
type: 'energy.replenished',
|
|
203
|
+
source: this.name,
|
|
204
|
+
payload: { previous: currentEnergy, current: newEnergy },
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
// Awake — accumulate pressure
|
|
209
|
+
const decay = this._baseDecayRate * activityMultiplier * ( delta / 1000 )
|
|
210
|
+
const passiveRecovery = currentEnergy <= this._criticalThreshold
|
|
211
|
+
? this._baseDecayRate * 0.5 * ( delta / 1000 )
|
|
212
|
+
: 0
|
|
213
|
+
newEnergy = Math.max( 0, currentEnergy - decay + passiveRecovery )
|
|
214
|
+
|
|
215
|
+
// ── System collapse event ───────────────────────────
|
|
216
|
+
if( currentEnergy > this._collapseThreshold && newEnergy <= this._collapseThreshold ){
|
|
217
|
+
events.push({
|
|
218
|
+
type: 'energy.system_collapse',
|
|
219
|
+
source: this.name,
|
|
220
|
+
payload: {
|
|
221
|
+
energy: newEnergy,
|
|
222
|
+
reason: 'Energy depleted below critical threshold. Body forcing recovery.',
|
|
223
|
+
collapseThreshold: this._collapseThreshold,
|
|
224
|
+
},
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
// Immediately enter forced rest
|
|
228
|
+
commands.metrics!.push([ 'state.forced_rest', 1 ])
|
|
229
|
+
commands.metrics!.push([ 'state.resting', 1 ])
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Critical depletion event
|
|
233
|
+
if( currentEnergy > this._criticalThreshold && newEnergy <= this._criticalThreshold )
|
|
234
|
+
events.push({
|
|
235
|
+
type: 'energy.critical',
|
|
236
|
+
source: this.name,
|
|
237
|
+
payload: { level: newEnergy, threshold: this._criticalThreshold },
|
|
238
|
+
})
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Clamp and store
|
|
242
|
+
newEnergy = Math.max( 0, Math.min( this._maxEnergy, newEnergy ) )
|
|
243
|
+
commands.metrics!.push([ 'energy.level', newEnergy ])
|
|
244
|
+
|
|
245
|
+
// ── Drive signal ──────────────────────────────────────
|
|
246
|
+
const
|
|
247
|
+
energyRatio = newEnergy / this._maxEnergy,
|
|
248
|
+
intensity = 1 - energyRatio,
|
|
249
|
+
urgency = newEnergy <= this._criticalThreshold
|
|
250
|
+
? 1.0
|
|
251
|
+
: newEnergy <= this._lowThreshold
|
|
252
|
+
? ( this._lowThreshold - newEnergy ) / ( this._lowThreshold - this._criticalThreshold )
|
|
253
|
+
: 0
|
|
254
|
+
|
|
255
|
+
const driveIntensity = Math.min( 1, Math.max( 0, intensity ) )
|
|
256
|
+
commands.metrics!.push([ 'drive.energy', driveIntensity ])
|
|
257
|
+
|
|
258
|
+
events.push({
|
|
259
|
+
type: 'drive.energy',
|
|
260
|
+
source: this.name,
|
|
261
|
+
payload: {
|
|
262
|
+
name: 'energy',
|
|
263
|
+
intensity: driveIntensity,
|
|
264
|
+
urgency: Math.min( 1, Math.max( 0, urgency ) ),
|
|
265
|
+
source: this.name,
|
|
266
|
+
} satisfies DriveSignal,
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
// ── Modulation signals ────────────────────────────────
|
|
270
|
+
// Don't modulate during forced rest — the system is unconscious
|
|
271
|
+
if( isForcedRest === 0 && newEnergy <= this._lowThreshold ){
|
|
272
|
+
const degradationFactor = Math.max(
|
|
273
|
+
0.3,
|
|
274
|
+
1 - ( ( this._lowThreshold - newEnergy ) / this._lowThreshold ) * 0.7
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
events.push({
|
|
278
|
+
type: 'modulation.cognitive_degradation',
|
|
279
|
+
source: this.name,
|
|
280
|
+
payload: {
|
|
281
|
+
target: '*',
|
|
282
|
+
parameter: 'energy_degradation',
|
|
283
|
+
factor: degradationFactor,
|
|
284
|
+
source: this.name,
|
|
285
|
+
} satisfies ModulationSignal,
|
|
286
|
+
})
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
// Phase C: publish cognitive event
|
|
291
|
+
const _bus = this._bus
|
|
292
|
+
if( _bus && newEnergy < 20 )
|
|
293
|
+
_bus.publish({ type: 'energy.level.critical', version: 1, sourceEngine: this.name, salience: Math.max( 0.8, this._model.observe( 'energy.critical', 1 - newEnergy / 100 ).salience ), payload: { level: newEnergy } })
|
|
294
|
+
// Phase D + F: rich state-change event — gated by prediction error
|
|
295
|
+
if( _bus ){
|
|
296
|
+
const zoneCode = newEnergy < this._criticalThreshold ? 0 : newEnergy < this._lowThreshold ? 1 : 2
|
|
297
|
+
const predErr = this._model.observe( 'energy.level', newEnergy )
|
|
298
|
+
if( !predErr.gated )
|
|
299
|
+
_bus.publish({ type: 'energy.state.changed', version: 1, sourceEngine: this.name, salience: predErr.salience, payload: { level: newEnergy, zoneCode, stressLoad: state.metrics.get('stress.load') ?? 0, interoceptionComfort: state.metrics.get('interoception.comfort') ?? 0.5 } })
|
|
300
|
+
}
|
|
301
|
+
return { events: events.length > 0 ? events : undefined, commands }
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// ── Config hot-reload ────────────────────────────────────
|
|
305
|
+
|
|
306
|
+
private _readConfigFromState( state: ReadonlySimulationState ): void {
|
|
307
|
+
const cfg = state.entities.get('engine-config-energy')
|
|
308
|
+
if( !cfg ) return
|
|
309
|
+
|
|
310
|
+
const p = cfg.metadata?.params as Record<string, number> | undefined
|
|
311
|
+
if( !p ) return
|
|
312
|
+
|
|
313
|
+
if( p.baseDecayRate != null ) this._baseDecayRate = p.baseDecayRate
|
|
314
|
+
if( p.restReplenishRate != null ) this._restReplenishRate = p.restReplenishRate
|
|
315
|
+
if( p.lowEnergyThreshold != null ) this._lowThreshold = p.lowEnergyThreshold
|
|
316
|
+
if( p.criticalEnergyThreshold != null ) this._criticalThreshold = p.criticalEnergyThreshold
|
|
317
|
+
if( p.collapseThreshold != null ) this._collapseThreshold = p.collapseThreshold
|
|
318
|
+
if( p.recoveryThreshold != null ) this._recoveryThreshold = p.recoveryThreshold
|
|
319
|
+
}
|
|
320
|
+
}
|