@mindot/will 0.4.0 → 0.6.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.
Files changed (135) hide show
  1. package/README.md +32 -12
  2. package/dist/channels/discord.d.ts +2 -11
  3. package/dist/channels/discord.js.map +1 -1
  4. package/dist/channels/whatsapp.d.ts +72 -0
  5. package/dist/channels/whatsapp.js +252 -0
  6. package/dist/channels/whatsapp.js.map +1 -0
  7. package/dist/cli.js +837 -91
  8. package/dist/cli.js.map +1 -1
  9. package/dist/index.d.ts +2 -2
  10. package/dist/index.js +620 -79
  11. package/dist/index.js.map +1 -1
  12. package/dist/mcp/effectors.d.ts +1 -1
  13. package/dist/mcp/effectors.js.map +1 -1
  14. package/dist/types-E9-HV-SW.d.ts +11 -0
  15. package/dist/{will-D-slky1N.d.ts → will-Bikuk4s2.d.ts} +56 -12
  16. package/package.json +12 -3
  17. package/src/channels/discord.ts +11 -11
  18. package/src/channels/roster.ts +1 -1
  19. package/src/channels/types.ts +1 -1
  20. package/src/channels/whatsapp.ts +318 -0
  21. package/src/cli.ts +46 -23
  22. package/src/cognition/acp.ts +28 -0
  23. package/src/cognition/agency/consequence.ts +174 -0
  24. package/src/cognition/agency/engines/action.selector.ts +301 -48
  25. package/src/cognition/agency/engines/affordance.synthesizer.ts +26 -16
  26. package/src/cognition/agency/engines/deliberation.engine.ts +28 -14
  27. package/src/cognition/agency/engines/motor.schema.executor.ts +86 -14
  28. package/src/cognition/agency/engines/reafference.engine.ts +122 -18
  29. package/src/cognition/agency/execution.primitives.ts +13 -13
  30. package/src/cognition/agency/proactive.communicator.ts +1 -1
  31. package/src/cognition/agency/reconcile.learning.ts +1 -1
  32. package/src/cognition/agency/revocation.ts +79 -0
  33. package/src/cognition/agency/schemas/repertoire.ts +2 -2
  34. package/src/cognition/agency/selection.scoring.ts +25 -9
  35. package/src/cognition/bus.ts +2 -2
  36. package/src/cognition/completion.inbox.ts +1 -1
  37. package/src/cognition/config.mirror.entities.ts +5 -5
  38. package/src/cognition/event.log.ts +2 -2
  39. package/src/cognition/event.schemas.ts +67 -67
  40. package/src/cognition/faculties/aesthetic.evaluator.ts +6 -6
  41. package/src/cognition/faculties/affective.blender.ts +36 -4
  42. package/src/cognition/faculties/attachment.evaluator.ts +6 -6
  43. package/src/cognition/faculties/attention.allocator.ts +63 -8
  44. package/src/cognition/faculties/autobiographical.narrator.ts +3 -3
  45. package/src/cognition/faculties/bias.detector.ts +7 -7
  46. package/src/cognition/faculties/circadian.oscillator.ts +3 -3
  47. package/src/cognition/faculties/confidence.calibrator.ts +7 -7
  48. package/src/cognition/faculties/dream.simulator.ts +5 -5
  49. package/src/cognition/faculties/empathy.simulator.ts +7 -7
  50. package/src/cognition/faculties/energy.regulator.ts +4 -4
  51. package/src/cognition/faculties/episodic.consolidator.ts +6 -6
  52. package/src/cognition/faculties/executive.engine/commands.ts +6 -6
  53. package/src/cognition/faculties/executive.engine/context.ts +42 -42
  54. package/src/cognition/faculties/executive.engine/deferred.effects.ts +2 -2
  55. package/src/cognition/faculties/executive.engine/engine.ts +27 -26
  56. package/src/cognition/faculties/executive.engine/facet.supervisor.ts +12 -12
  57. package/src/cognition/faculties/executive.engine/facet.ts +18 -18
  58. package/src/cognition/faculties/executive.engine/gating.ts +2 -2
  59. package/src/cognition/faculties/executive.engine/messages.ts +3 -3
  60. package/src/cognition/faculties/executive.engine/parser.ts +11 -11
  61. package/src/cognition/faculties/executive.engine/prompt.factory.ts +55 -55
  62. package/src/cognition/faculties/exteroception.ts +99 -5
  63. package/src/cognition/faculties/forgetting.curve.ts +3 -3
  64. package/src/cognition/faculties/frustration.evaluator.ts +6 -6
  65. package/src/cognition/faculties/goal.manager.ts +15 -15
  66. package/src/cognition/faculties/inhibition.controller.ts +3 -3
  67. package/src/cognition/faculties/interoception.ts +3 -3
  68. package/src/cognition/faculties/introspection.engine.ts +3 -3
  69. package/src/cognition/faculties/known.entity.tracker.ts +15 -15
  70. package/src/cognition/faculties/loss.evaluator.ts +2 -2
  71. package/src/cognition/faculties/moral.evaluator.ts +4 -4
  72. package/src/cognition/faculties/novelty.detector.ts +4 -4
  73. package/src/cognition/faculties/persona.consolidator.ts +12 -12
  74. package/src/cognition/faculties/planning.engine/engine.ts +47 -47
  75. package/src/cognition/faculties/planning.engine/plan.frontier.ts +5 -5
  76. package/src/cognition/faculties/planning.engine/plan.store.ts +1 -1
  77. package/src/cognition/faculties/planning.engine/plan.supervision.ts +20 -20
  78. package/src/cognition/faculties/reputation.tracker.ts +6 -6
  79. package/src/cognition/faculties/reward.evaluator.ts +4 -4
  80. package/src/cognition/faculties/self.model.updater.ts +8 -8
  81. package/src/cognition/faculties/semantic.engine/integrator.ts +15 -15
  82. package/src/cognition/faculties/sleep.pressure.regulator.ts +4 -4
  83. package/src/cognition/faculties/social.perception.ts +3 -3
  84. package/src/cognition/faculties/spaced.repetition.ts +2 -2
  85. package/src/cognition/faculties/stress.regulator.ts +27 -4
  86. package/src/cognition/faculties/task.switcher.ts +11 -6
  87. package/src/cognition/faculties/theory.of.mind.ts +6 -6
  88. package/src/cognition/faculties/threat.evaluator.ts +3 -3
  89. package/src/cognition/faculties/working.memory.ts +8 -8
  90. package/src/cognition/generative.model.ts +2 -2
  91. package/src/cognition/memory/vector.adapter.ts +5 -5
  92. package/src/cognition/memory/vector.content.ts +4 -4
  93. package/src/cognition/memory/vector.embedder.ts +9 -9
  94. package/src/cognition/persona.prior.ts +1 -1
  95. package/src/cognition/schema.registry.ts +2 -2
  96. package/src/cognition/senses/audition.engine/engine.ts +2 -2
  97. package/src/cognition/senses/base.sense.engine.ts +1 -1
  98. package/src/cognition/utilities/token.tracker.ts +11 -5
  99. package/src/core/abstracts.ts +1 -1
  100. package/src/core/completion.recorder.ts +2 -2
  101. package/src/core/serialization.ts +3 -3
  102. package/src/core/snapshot.manager.ts +1 -1
  103. package/src/core/state.manager.ts +1 -1
  104. package/src/core/utils.ts +1 -1
  105. package/src/host/boot.ts +59 -37
  106. package/src/host/utterances.ts +1 -1
  107. package/src/llm/index.ts +84 -34
  108. package/src/llm/summarizer.ts +4 -4
  109. package/src/llm/wire.contracts.ts +1 -1
  110. package/src/mcp/effectors.ts +10 -10
  111. package/src/mcp/server.ts +11 -11
  112. package/src/pma/eval.ts +1 -1
  113. package/src/pma/index.ts +21 -21
  114. package/src/runners/outreach.runner.ts +3 -3
  115. package/src/runners/social.runner.ts +1 -1
  116. package/src/runners/thin-shim.runner.ts +1 -1
  117. package/src/sdk/will.ts +20 -11
  118. package/src/serve/server.ts +12 -12
  119. package/src/stem/assembly.audit.ts +3 -3
  120. package/src/stem/guards/identity.coherence.ts +13 -12
  121. package/src/stem/guards/identity.guard.ts +22 -22
  122. package/src/stem/index.ts +11 -11
  123. package/src/stem/mind.ts +12 -12
  124. package/src/stem/tracts/biography.writer.ts +3 -3
  125. package/src/stem/tracts/effector.controller.ts +4 -4
  126. package/src/stem/tracts/health.reporter.ts +1 -1
  127. package/src/stem/tracts/outbox.controller.ts +4 -0
  128. package/src/stem/tracts/outbox.writer.ts +4 -4
  129. package/src/stem/tracts/pma.controller.ts +1 -1
  130. package/src/stem/tracts/replay.controller.ts +10 -10
  131. package/src/stem/tracts/sensory.controller.ts +2 -2
  132. package/src/stem/tracts/session.logger.ts +4 -4
  133. package/src/stem/tracts/transport/socketio.transport.ts +7 -7
  134. package/src/stem/tracts/transport/stream.transport.ts +2 -2
  135. package/src/stem/tracts/transport.controller.ts +15 -15
@@ -31,6 +31,11 @@ import type { SimulationEngine, EngineResult, CognitiveEngine } from '#cognition
31
31
  import type { CognitiveEventSchema } from '#cognition/schema.registry'
32
32
  import type { CognitiveEvent, CognitiveBus } from '#cognition/bus'
33
33
  import { GenerativeModel } from '#cognition/generative.model'
34
+ import {
35
+ CONSEQUENCE_TYPE, ATTENUATION, CORRESPONDENCE_ATTENUATION,
36
+ liveConsequences, matchConsequenceText, matchConsequenceEntity,
37
+ } from '#agency/consequence'
38
+ import { REVOCATION_TYPE } from '#agency/revocation'
34
39
 
35
40
  export interface ExteroceptionConfig {
36
41
  /** Maximum percepts to produce per tick */
@@ -50,6 +55,12 @@ interface RawPercept {
50
55
  salience: number
51
56
  category: string
52
57
  summary: string
58
+ /** Text the corollary-discharge matcher inspects (entity content ≻ description ≻ summary). */
59
+ matchText?: string
60
+ /** Felt valence carried with the percept (affect→percept seam, registry #5). */
61
+ valence?: number
62
+ /** Where that valence came from — per-entity appraisal, or ambient mood. */
63
+ valenceSource?: 'entity' | 'ambient'
53
64
  }
54
65
 
55
66
  // Skip internal entities — they're not external percepts.
@@ -65,6 +76,11 @@ const internalTypes = new Set([
65
76
  'theory_of_mind', 'reputation', 'episodic_memory',
66
77
  // Internal state entities written by our own engines — not external events
67
78
  'affect.blends', 'executive.summary',
79
+ // The agency's own forward-model records (EXAFFERENCE P1/P2): perceiving our
80
+ // expected-consequence descriptors would be a self-noise loop.
81
+ CONSEQUENCE_TYPE,
82
+ // The agency's own revocation tombstones (EXAFFERENCE P4) — internal bookkeeping.
83
+ REVOCATION_TYPE,
68
84
  ])
69
85
 
70
86
  export class Exteroception implements SimulationEngine, CognitiveEngine {
@@ -101,10 +117,10 @@ export class Exteroception implements SimulationEngine, CognitiveEngine {
101
117
 
102
118
  onCognitiveEvent( e: CognitiveEvent ): StateCommands | void {
103
119
  this._model.observe( e.type, e.salience )
104
- if( e.type === 'executive.prediction.formed' ){
120
+ if( e.type === 'executive.prediction.formed'){
105
121
  const p = e.payload as { predictedDomains: string[]; confidence: number }
106
122
  if( p.predictedDomains.includes('perception') )
107
- this._model.setPrecision( 'percept.rate', 1.0 + p.confidence * 0.5 )
123
+ this._model.setPrecision('percept.rate', 1.0 + p.confidence * 0.5 )
108
124
  }
109
125
  }
110
126
 
@@ -125,19 +141,46 @@ export class Exteroception implements SimulationEngine, CognitiveEngine {
125
141
  // Cap percepts per tick
126
142
  const capped = rawPercepts.slice( 0, this._maxPerceptsPerTick )
127
143
 
144
+ // Corollary discharge (EXAFFERENCE P2): everything this engine perceives is
145
+ // world-ingress afference — split it. A percept matching a live expected-
146
+ // consequence descriptor is *reafferent* (our own action's sensory footprint:
147
+ // the channel echo, a quote-back) and its salience is attenuated, not zeroed;
148
+ // everything else is *exafferent* — the world moved on its own. Endogenous
149
+ // percepts (working memory, escalations) are created elsewhere and stay
150
+ // untagged: they are neither.
151
+ const consequences = liveConsequences( state.entities, tick )
152
+
128
153
  // Convert raw percepts to entities
129
154
  for( let i = 0; i < capped.length; i++ ){
130
155
  const rp = capped[i]!
131
156
 
157
+ const textHit = consequences.length > 0 && rp.matchText
158
+ ? matchConsequenceText( consequences, rp.matchText )
159
+ : null
160
+ // ACP-P1 (entity correspondence): when the text path misses, a change on
161
+ // exactly the entity a live external descriptor targets is still our
162
+ // footprint — claimed at gentler attenuation (we're less certain).
163
+ const entityHit = !textHit && consequences.length > 0
164
+ ? matchConsequenceEntity( consequences, rp.entityId, rp.changeType )
165
+ : null
166
+ const hit = textHit ?? entityHit
167
+ const salience = textHit ? rp.salience * ATTENUATION
168
+ : entityHit ? rp.salience * CORRESPONDENCE_ATTENUATION
169
+ : rp.salience
170
+
132
171
  const perceptEntity = {
133
172
  id: `percept-${tick}-${i}`,
134
173
  type: 'percept',
135
174
  metadata: {
136
175
  entityId: rp.entityId,
137
176
  changeType: rp.changeType,
138
- salience: rp.salience,
177
+ salience,
139
178
  category: rp.category,
140
179
  summary: rp.summary,
180
+ provenance: hit ? 'reafferent' : 'exafferent',
181
+ ...( hit ? { sourceIntentId: hit.intentId } : {} ),
182
+ // affect→percept seam (registry #5): what this percept FEELS like
183
+ ...( rp.valence !== undefined ? { valence: rp.valence, valenceSource: rp.valenceSource } : {} ),
141
184
  tick,
142
185
  },
143
186
  }
@@ -151,7 +194,7 @@ export class Exteroception implements SimulationEngine, CognitiveEngine {
151
194
  source: this.name,
152
195
  payload: {
153
196
  entityId: rp.entityId,
154
- salience: rp.salience,
197
+ salience,
155
198
  category: rp.category,
156
199
  summary: rp.summary,
157
200
  },
@@ -171,7 +214,7 @@ export class Exteroception implements SimulationEngine, CognitiveEngine {
171
214
  // Phase C + F: publish cognitive event — gated by prediction error
172
215
  const _bus = this._bus
173
216
  if( _bus && capped.length > 0 ){
174
- const predErr = this._model.observe( 'percept.rate', capped.length )
217
+ const predErr = this._model.observe('percept.rate', capped.length )
175
218
  if( !predErr.gated )
176
219
  _bus.publish({ type: 'percept.batch.ingested', version: 1, sourceEngine: this.name, salience: Math.max( 0.2, predErr.salience ), payload: { count: capped.length } })
177
220
  }
@@ -220,6 +263,8 @@ private _scanWorld( state: ReadonlySimulationState ): RawPercept[] {
220
263
  salience: this._computeSalience( entity, 'appeared', state.time ),
221
264
  category: entity.type,
222
265
  summary: this._summarizeEntity( entity, 'appeared'),
266
+ matchText: this._matchText( entity ),
267
+ ...this._valenceOf( id, state ),
223
268
  })
224
269
  }
225
270
  else if( entity.updatedAt > previousVersion ){
@@ -229,6 +274,8 @@ private _scanWorld( state: ReadonlySimulationState ): RawPercept[] {
229
274
  salience: this._computeSalience( entity, 'modified', state.time ),
230
275
  category: entity.type,
231
276
  summary: this._summarizeEntity( entity, 'modified'),
277
+ matchText: this._matchText( entity ),
278
+ ...this._valenceOf( id, state ),
232
279
  })
233
280
  }
234
281
 
@@ -268,6 +315,53 @@ private _scanWorld( state: ReadonlySimulationState ): RawPercept[] {
268
315
  * Generate a meaningful summary for an entity.
269
316
  * Instead of "New percept: percept-54-0", produce something useful.
270
317
  */
318
+ /**
319
+ * The text the corollary-discharge matcher inspects for this entity — its
320
+ * content (a message body) over its description over its summary. Where our
321
+ * own delivered words would surface if the world echoes them back.
322
+ */
323
+ /**
324
+ * The affect→percept valence seam (registry #5). A percept carries how the
325
+ * mind *feels* about what it is a percept OF, resolved most-specific-first:
326
+ *
327
+ * 1. the KnownEntityTracker's dossier for this entity (`ke-<id>.valence`) —
328
+ * a real per-entity felt valence, the honest signal;
329
+ * 2. otherwise the ambient `affect.valence` — the felt tone at perception
330
+ * time. Weaker evidence, so it is tagged `'ambient'` and consumers
331
+ * weight it down (mood is context, not appraisal of this thing).
332
+ *
333
+ * Absent both, no valence is stamped and every consumer keeps its
334
+ * pre-seam behaviour.
335
+ */
336
+ /** Spread-friendly form of `_valenceFor` for percept construction. */
337
+ private _valenceOf( entityId: string, state: ReadonlySimulationState ):
338
+ { valence?: number; valenceSource?: 'entity' | 'ambient' } {
339
+ const v = this._valenceFor( entityId, state )
340
+ return v ? { valence: v.valence, valenceSource: v.source } : {}
341
+ }
342
+
343
+ private _valenceFor( entityId: string, state: ReadonlySimulationState ):
344
+ { valence: number; source: 'entity' | 'ambient' } | undefined {
345
+ const dossier = state.entities.get(`ke-${ entityId }`)
346
+ const felt = dossier?.metadata?.['valence']
347
+ if( typeof felt === 'number' && Number.isFinite( felt ) )
348
+ return { valence: felt, source: 'entity' }
349
+
350
+ const ambient = state.metrics.get('affect.valence')
351
+ if( typeof ambient === 'number' && Number.isFinite( ambient ) )
352
+ return { valence: ambient, source: 'ambient' }
353
+
354
+ return undefined
355
+ }
356
+
357
+ private _matchText( entity: Readonly<SimulationEntity> ): string | undefined {
358
+ const m = entity.metadata as Record<string, unknown> | undefined
359
+ const content = typeof m?.['content'] === 'string' ? m['content'] as string : undefined
360
+ const description = typeof m?.['description'] === 'string' ? m['description'] as string : undefined
361
+ const summary = typeof m?.['summary'] === 'string' ? m['summary'] as string : undefined
362
+ return content ?? description ?? summary
363
+ }
364
+
271
365
  private _summarizeEntity(
272
366
  entity: Readonly<SimulationEntity>,
273
367
  changeType: string
@@ -94,10 +94,10 @@ export class ForgettingCurve implements SimulationEngine, CognitiveEngine {
94
94
 
95
95
  onCognitiveEvent( e: CognitiveEvent ): StateCommands | void {
96
96
  this._model.observe( e.type, e.salience )
97
- if( e.type === 'executive.prediction.formed' ){
97
+ if( e.type === 'executive.prediction.formed'){
98
98
  const p = e.payload as { predictedDomains: string[]; confidence: number }
99
99
  if( p.predictedDomains.includes('memory') )
100
- this._model.setPrecision( 'memory.decay_rate', 1.0 + p.confidence * 0.5 )
100
+ this._model.setPrecision('memory.decay_rate', 1.0 + p.confidence * 0.5 )
101
101
  }
102
102
  }
103
103
 
@@ -189,7 +189,7 @@ export class ForgettingCurve implements SimulationEngine, CognitiveEngine {
189
189
  // Phase C: publish cognitive event
190
190
  const _bus = this._bus
191
191
  if( _bus && decayedCount > 0 )
192
- _bus.publish({ type: 'memory.decay.applied', version: 1, sourceEngine: this.name, salience: this._model.observe( 'memory.decay_rate', decayedCount ).salience, payload: { decayed: decayedCount } })
192
+ _bus.publish({ type: 'memory.decay.applied', version: 1, sourceEngine: this.name, salience: this._model.observe('memory.decay_rate', decayedCount ).salience, payload: { decayed: decayedCount } })
193
193
 
194
194
  return { commands }
195
195
  }
@@ -100,20 +100,20 @@ export class FrustrationEvaluator implements SimulationEngine, CognitiveEngine {
100
100
  onCognitiveEvent( e: CognitiveEvent ): StateCommands | void {
101
101
  this._model.observe( e.type, e.salience )
102
102
 
103
- if( e.type === 'executive.prediction.formed' ){
103
+ if( e.type === 'executive.prediction.formed'){
104
104
  const p = e.payload as { predictedDomains: string[]; confidence: number }
105
105
  if( p.predictedDomains.includes('affect') )
106
- this._model.setPrecision( 'emotion.frustration', 1.0 + p.confidence * 0.5 )
106
+ this._model.setPrecision('emotion.frustration', 1.0 + p.confidence * 0.5 )
107
107
  this._cachedConfidence = p.confidence
108
108
  }
109
109
 
110
- if( e.type === 'goal.blocked' ){
110
+ if( e.type === 'goal.blocked'){
111
111
  const p = e.payload as { goalId: string; ticksStuck: number; priority: number }
112
112
  this._blockedGoals.set( p.goalId, { ticksStuck: p.ticksStuck, priority: p.priority, refreshedAt: this._reactCount } )
113
113
  this._goalBlockedCounts.set( p.goalId, ( this._goalBlockedCounts.get( p.goalId ) ?? 0 ) + 1 )
114
114
  }
115
115
 
116
- if( e.type === 'interaction.occurred' ){
116
+ if( e.type === 'interaction.occurred'){
117
117
  const p = e.payload as { keid: string; valence: number; intensity: number; directedAtSelf: boolean }
118
118
  if( p.directedAtSelf && p.valence < -0.5 )
119
119
  this._unfairnessSignal = Math.min( 1, this._unfairnessSignal + 0.3 )
@@ -137,7 +137,7 @@ export class FrustrationEvaluator implements SimulationEngine, CognitiveEngine {
137
137
  // steady affect develops a lower build-rate here, so it stays even-keeled longer —
138
138
  // distinct from resilience's frustrationTolerance (how much is *tolerated*). Pure +
139
139
  // deterministic; falls back to the constructor default when no seed/prior is present.
140
- const frustrationCfg = readEffectiveParams( state, 'engine-config-frustration' )
140
+ const frustrationCfg = readEffectiveParams( state, 'engine-config-frustration')
141
141
  const irritabilityRate = frustrationCfg.irritabilityRate ?? this._irritabilityRate
142
142
 
143
143
  // Channel A (agreeableness — "yielding in conflict"): how strongly provocation
@@ -236,7 +236,7 @@ export class FrustrationEvaluator implements SimulationEngine, CognitiveEngine {
236
236
  // Phase C + F: publish cognitive event — gated by prediction error
237
237
  const _bus = this._bus
238
238
  if( _bus && frustration > 0.5 ){
239
- const predErr = this._model.observe( 'emotion.frustration', frustration )
239
+ const predErr = this._model.observe('emotion.frustration', frustration )
240
240
  if( !predErr.gated )
241
241
  _bus.publish({ type: 'emotion.frustration.elevated', version: 1, sourceEngine: this.name, salience: Math.min(1, frustration), payload: { frustration } })
242
242
  }
@@ -223,7 +223,7 @@ export class GoalManager implements SimulationEngine, CognitiveEngine {
223
223
  break
224
224
  case 'belief.updated':
225
225
  // Salience model only — authoritative count always read from state.metrics.
226
- this._model.observe( 'belief.count', ( e.payload as Record<string,number> )['total'] ?? 0 )
226
+ this._model.observe('belief.count', ( e.payload as Record<string,number> )['total'] ?? 0 )
227
227
  break
228
228
  case 'executive.goal.proposed':
229
229
  // Track that executive proposed goals — prioritize executive-sourced goals slightly higher
@@ -272,7 +272,7 @@ export class GoalManager implements SimulationEngine, CognitiveEngine {
272
272
 
273
273
  if( payload.goalId && payload.goalProgress !== undefined ){
274
274
  const goal = this._goals.get( payload.goalId )
275
- if( goal?.status === 'active' ){
275
+ if( goal?.status === 'active'){
276
276
  goal.progress = Math.max( goal.progress, payload.goalProgress ) // forward-only
277
277
  if( goal.progress >= 0.95 )
278
278
  goal.status = 'pending_verification'
@@ -286,7 +286,7 @@ export class GoalManager implements SimulationEngine, CognitiveEngine {
286
286
  p = e.payload as { goalId: string },
287
287
  goal = this._goals.get( p.goalId )
288
288
 
289
- if( goal?.status === 'active' )
289
+ if( goal?.status === 'active')
290
290
  goal.status = 'pending_verification' // queued for condition eval next tick
291
291
 
292
292
  break
@@ -392,7 +392,7 @@ export class GoalManager implements SimulationEngine, CognitiveEngine {
392
392
  type: 'goal.state.changed',
393
393
  version: 1,
394
394
  sourceEngine: this.name,
395
- salience: Math.max( 0.4, this._model.observe( 'goal.active_count', activeGoals.length ).salience ),
395
+ salience: Math.max( 0.4, this._model.observe('goal.active_count', activeGoals.length ).salience ),
396
396
  payload: { activeCount: activeGoals.length }
397
397
  })
398
398
 
@@ -563,7 +563,7 @@ export class GoalManager implements SimulationEngine, CognitiveEngine {
563
563
  */
564
564
  abandonGoal( goalId: string, reason?: string ): void {
565
565
  const goal = this._goals.get( goalId )
566
- if( goal && goal.status === 'active' ){
566
+ if( goal && goal.status === 'active'){
567
567
  goal.status = 'abandoned'
568
568
  // Optionally store the reason (if GoalState had a reason field; we can add it or store in tags)
569
569
  reason && goal.tags.push(`abandoned:${reason.slice(0,50)}`)
@@ -683,7 +683,7 @@ export class GoalManager implements SimulationEngine, CognitiveEngine {
683
683
  const cType = ( m.goalCompletionType as GoalState['completionType'] ) ?? 'action'
684
684
  const cCond = m.goalCompletionCondition as string | undefined
685
685
  // Dedup by the referent (keid: tag) when present, else by description.
686
- const keidTag = tags.find( t => t.startsWith( 'keid:' ) )
686
+ const keidTag = tags.find( t => t.startsWith('keid:') )
687
687
  const existing = Array.from( this._goals.values() ).find( g =>
688
688
  g.status === 'active' && ( keidTag ? g.tags.includes( keidTag ) : g.description === desc ) )
689
689
 
@@ -698,10 +698,10 @@ export class GoalManager implements SimulationEngine, CognitiveEngine {
698
698
  private _updatePriorities( state: ReadonlySimulationState ): void {
699
699
  // Task-persistence: which goal the Will is focused on + how committed (task.switcher)
700
700
  // and the (developable) cost of switching away. Drives the commitment boost below.
701
- const focusMeta = state.entities.get( 'task-switch-focus' )?.metadata as Record<string, unknown> | undefined
701
+ const focusMeta = state.entities.get('task-switch-focus')?.metadata as Record<string, unknown> | undefined
702
702
  const focusedGoalId = focusMeta?.goalId as string | undefined
703
703
  const focusTicks = ( focusMeta?.focusTicks as number ) ?? 0
704
- const switchCost = state.metrics.get( 'task_switch.switch_cost' ) ?? 0
704
+ const switchCost = state.metrics.get('task_switch.switch_cost') ?? 0
705
705
 
706
706
  for( const goal of this._goals.values() ){
707
707
  if( goal.status !== 'active') continue
@@ -764,7 +764,7 @@ export class GoalManager implements SimulationEngine, CognitiveEngine {
764
764
  if( e.type !== 'plan' || e.metadata?.goalId !== goalId ) continue
765
765
  const steps = ( e.metadata?.steps as Array<{ status?: string }> | undefined ) ?? []
766
766
  if( steps.length === 0 ) continue
767
- const done = steps.filter( s => s.status === 'completed' || s.status === 'skipped' ).length
767
+ const done = steps.filter( s => s.status === 'completed' || s.status === 'skipped').length
768
768
  return done / steps.length
769
769
  }
770
770
  return 0
@@ -792,14 +792,14 @@ export class GoalManager implements SimulationEngine, CognitiveEngine {
792
792
  // (defence-in-depth beyond the already-satisfied creation guard in _activateFromDrives).
793
793
  if( goal.activatedAt === tick ) continue
794
794
 
795
- if( goal.status === 'pending_verification' ){
795
+ if( goal.status === 'pending_verification'){
796
796
  const met = this._evaluateMetricProgress( goal, state ) >= 1
797
- met ? this.completeGoal( goal.id ) : ( goal.status = 'active' )
797
+ met ? this.completeGoal( goal.id ) : ( goal.status = 'active')
798
798
 
799
799
  continue // skip completionType switch entirely
800
800
  }
801
801
 
802
- if( goal.status !== 'active' && goal.status !== 'blocked' ) continue
802
+ if( goal.status !== 'active' && goal.status !== 'blocked') continue
803
803
 
804
804
  switch( goal.completionType ){
805
805
  case 'metric':
@@ -859,8 +859,8 @@ export class GoalManager implements SimulationEngine, CognitiveEngine {
859
859
  || dLow === 'communication'
860
860
 
861
861
  for( const goal of this._goals.values() ){
862
- if( goal.status !== 'active' && goal.status !== 'blocked' ) continue
863
- if( goal.completionType !== 'action' ) continue
862
+ if( goal.status !== 'active' && goal.status !== 'blocked') continue
863
+ if( goal.completionType !== 'action') continue
864
864
 
865
865
  const hasMatch = goal.tags.some( tag => {
866
866
  const t = tag.toLowerCase()
@@ -940,7 +940,7 @@ export class GoalManager implements SimulationEngine, CognitiveEngine {
940
940
  * seeded by the PMA and developed by the metacognition cycle — not a constant.
941
941
  */
942
942
  private _readConfigFromState( state: ReadonlySimulationState ): void {
943
- const p = readEffectiveParams( state, 'engine-config-goal-manager' )
943
+ const p = readEffectiveParams( state, 'engine-config-goal-manager')
944
944
  if( p.gritPriority != null ) this._gritPriority = p.gritPriority
945
945
  if( p.gritPatienceScale != null ) this._gritPatienceScale = p.gritPatienceScale
946
946
  if( p.frustrationTolerance != null ) this._frustrationTolerance = p.frustrationTolerance
@@ -93,7 +93,7 @@ export class InhibitionController implements SimulationEngine, CognitiveEngine {
93
93
  // Effective config = base engine-config-inhibition ⊕ persona-prior (single-source).
94
94
  // The persona-consolidator raises baseInhibitionStrength when reasoning bias
95
95
  // recurs (edge 6) → more self-restraint while the bias is being worked through.
96
- const p = readEffectiveParams( state, 'engine-config-inhibition' )
96
+ const p = readEffectiveParams( state, 'engine-config-inhibition')
97
97
  if( p.baseInhibitionStrength != null ) this._baseInhibitionStrength = p.baseInhibitionStrength
98
98
  if( p.arousalThreshold != null ) this._arousalThreshold = p.arousalThreshold
99
99
  if( p.maxDeferralsPerTick != null ) this._maxDeferralsPerTick = p.maxDeferralsPerTick
@@ -132,7 +132,7 @@ export class InhibitionController implements SimulationEngine, CognitiveEngine {
132
132
  case 'executive.prediction.formed': {
133
133
  const p = e.payload as { predictedDomains: string[]; confidence: number }
134
134
  if( p.predictedDomains.includes('executive') )
135
- this._model.setPrecision( 'inhibition.strength', 1.0 + p.confidence * 0.5 )
135
+ this._model.setPrecision('inhibition.strength', 1.0 + p.confidence * 0.5 )
136
136
  break
137
137
  }
138
138
  }
@@ -253,7 +253,7 @@ export class InhibitionController implements SimulationEngine, CognitiveEngine {
253
253
  // Phase C + F: publish cognitive event — gated by prediction error
254
254
  const _bus = this._bus
255
255
  if( _bus && vetoedActions.length > 0 ){
256
- const predErr = this._model.observe( 'inhibition.strength', inhibitionStrength )
256
+ const predErr = this._model.observe('inhibition.strength', inhibitionStrength )
257
257
  if( !predErr.gated )
258
258
  _bus.publish({ type: 'inhibition.vetoed', version: 1, sourceEngine: this.name, salience: 0.7, payload: { vetoedActions, inhibitionStrength } })
259
259
  }
@@ -101,7 +101,7 @@ export class Interoception implements SimulationEngine, CognitiveEngine {
101
101
  case 'executive.prediction.formed': {
102
102
  const p = e.payload as { predictedDomains: string[]; confidence: number }
103
103
  if( p.predictedDomains.includes('interoception') )
104
- this._model.setPrecision( 'interoception.intensity', 1.0 + p.confidence * 0.5 )
104
+ this._model.setPrecision('interoception.intensity', 1.0 + p.confidence * 0.5 )
105
105
  break
106
106
  }
107
107
  }
@@ -142,7 +142,7 @@ export class Interoception implements SimulationEngine, CognitiveEngine {
142
142
  // Blend of the direct circadian mood set-point and holistic homeostatic comfort.
143
143
  // Comfort dominates (0.65) because energy/sleep/stress drive moment-to-moment
144
144
  // mood more strongly than the slow-moving circadian baseline.
145
- const moodBaseline = signals.find( s => s.metric === 'circadian.mood_baseline' )?.value ?? 0.5
145
+ const moodBaseline = signals.find( s => s.metric === 'circadian.mood_baseline')?.value ?? 0.5
146
146
  const interoMood = moodBaseline * 0.35 + comfortLevel * 0.65
147
147
 
148
148
  // Percept entity — the unified "how I feel" snapshot
@@ -202,7 +202,7 @@ export class Interoception implements SimulationEngine, CognitiveEngine {
202
202
  _bus.publish({ type: 'interoception.state.updated', version: 1, sourceEngine: this.name, salience: Math.abs(comfortLevel - 0.5) * 0.8, payload: { comfort: comfortLevel, intensity: overallIntensity } })
203
203
  // Phase D + F: rich state-change event — gated by prediction error
204
204
  if( _bus ){
205
- const predErr = this._model.observe( 'interoception.intensity', overallIntensity )
205
+ const predErr = this._model.observe('interoception.intensity', overallIntensity )
206
206
  if( !predErr.gated )
207
207
  _bus.publish({ type: 'interoception.state.changed', version: 1, sourceEngine: this.name, salience: predErr.salience, payload: { comfort: comfortLevel, intensity: overallIntensity } })
208
208
  }
@@ -183,7 +183,7 @@ export class IntrospectionEngine implements SimulationEngine, CognitiveEngine {
183
183
  // mismatched: precision set on .significance, salience read off .total).
184
184
  const _bus = this._bus
185
185
  if( _bus && introspectedThisTick )
186
- _bus.publish({ type: 'introspection.insight', version: 1, sourceEngine: this.name, salience: Math.max( 0.3, this._model.observe( 'introspection.significance', significance ).salience ), payload: { total: this._introspectionHistory.length, significance } })
186
+ _bus.publish({ type: 'introspection.insight', version: 1, sourceEngine: this.name, salience: Math.max( 0.3, this._model.observe('introspection.significance', significance ).salience ), payload: { total: this._introspectionHistory.length, significance } })
187
187
  return { events: events.length > 0 ? events : undefined, commands }
188
188
  }
189
189
 
@@ -200,7 +200,7 @@ export class IntrospectionEngine implements SimulationEngine, CognitiveEngine {
200
200
  // that observation stays.)
201
201
  const detectedBiases: string[] = []
202
202
  for( const entity of state.entities.values() )
203
- if( entity.type === 'cognitive_bias' )
203
+ if( entity.type === 'cognitive_bias')
204
204
  detectedBiases.push(
205
205
  ( entity.metadata?.description as string )
206
206
  ?? ( entity.metadata?.type as string )
@@ -234,7 +234,7 @@ export class IntrospectionEngine implements SimulationEngine, CognitiveEngine {
234
234
  * drift — so reading base⊕prior is safe here.)
235
235
  */
236
236
  private _readConfigFromState( state: ReadonlySimulationState ): void {
237
- const p = readEffectiveParams( state, 'engine-config-introspection' )
237
+ const p = readEffectiveParams( state, 'engine-config-introspection')
238
238
  if( p.cooldownTicks != null ) this._cooldownTicks = p.cooldownTicks
239
239
  if( p.significanceThreshold != null ) this._significanceThreshold = p.significanceThreshold
240
240
  }
@@ -134,7 +134,7 @@ export class KnownEntityTracker implements SimulationEngine, CognitiveEngine {
134
134
  * the curiosity pull; analytical sharpens how fast reliability judgments are revised.
135
135
  */
136
136
  private _readConfigFromState( state: ReadonlySimulationState ): void {
137
- const p = readEffectiveParams( state, 'engine-config-known-entity' )
137
+ const p = readEffectiveParams( state, 'engine-config-known-entity')
138
138
  if( p.familiarityGrowthRate != null ) this._growthRate = p.familiarityGrowthRate
139
139
  if( p.curiosityGain != null ) this._curiosityGain = p.curiosityGain
140
140
  if( p.reliabilityRate != null ) this._reliabilityRate = p.reliabilityRate
@@ -149,17 +149,17 @@ export class KnownEntityTracker implements SimulationEngine, CognitiveEngine {
149
149
  this._model.observe( e.type, e.salience )
150
150
 
151
151
  // Conscious learning (the reasoning write-path): a learned name + felt valence.
152
- if( e.type === 'known.entity.learned' ){
152
+ if( e.type === 'known.entity.learned'){
153
153
  const u = e.payload as { keid?: string; name?: string; feeling?: number }
154
- if( u?.keid && u.keid !== 'agent-self' )
154
+ if( u?.keid && u.keid !== 'agent-self')
155
155
  this._pendingConscious.push({ keid: u.keid, name: u.name, feeling: u.feeling })
156
156
  return
157
157
  }
158
158
 
159
159
  // Acting on/with an entity and seeing how it went — the reliability track-record.
160
- if( e.type === 'action.outcome' ){
160
+ if( e.type === 'action.outcome'){
161
161
  const o = e.payload as { targetEntityId?: string; success?: boolean; outcomeQuality?: number }
162
- if( o?.targetEntityId && o.targetEntityId !== 'agent-self' )
162
+ if( o?.targetEntityId && o.targetEntityId !== 'agent-self')
163
163
  this._pendingOutcomes.push({ keid: o.targetEntityId, signal: o.success ? 1 : 0 })
164
164
  return
165
165
  }
@@ -167,7 +167,7 @@ export class KnownEntityTracker implements SimulationEngine, CognitiveEngine {
167
167
  // Otherwise a senses.<domain>.percept — bind the perceived entity (sourceEntityId).
168
168
  const p = e.payload as Percept | undefined
169
169
  const keid = p?.sourceEntityId
170
- if( !keid || keid === 'agent-self' ) return
170
+ if( !keid || keid === 'agent-self') return
171
171
 
172
172
  // A channel-supplied display name rides on the raw input (e.g. TextMessage.speakerName).
173
173
  const raw = p?.raw as { speakerName?: unknown } | undefined
@@ -252,7 +252,7 @@ export class KnownEntityTracker implements SimulationEngine, CognitiveEngine {
252
252
  for( const d of [ ...this._dossiers.values() ] )
253
253
  if( d.familiarity < FORGET_FLOOR && !d.name && d.resolutionConfidence < CURIOUS_RESOLUTION ){
254
254
  this._dossiers.delete( d.keid )
255
- commands.delete!.push( `ke-${d.keid}` )
255
+ commands.delete!.push(`ke-${d.keid}`)
256
256
  }
257
257
 
258
258
  // Persist dossiers (the perceptual layer of the known-entity node).
@@ -296,7 +296,7 @@ export class KnownEntityTracker implements SimulationEngine, CognitiveEngine {
296
296
  // which only accepts [\w.] names — keids may contain ':' e.g. web:42.)
297
297
  for( const d of this._dossiers.values() ){
298
298
  if( d.familiarity < CURIOUS_FAMILIARITY ) continue // only ones that matter
299
- const skeid = d.keid.replace( /[^\w.]/g, '_' )
299
+ const skeid = d.keid.replace( /[^\w.]/g, '_')
300
300
  commands.metrics!.push([ `known_entity.${skeid}.resolution`, d.resolutionConfidence ])
301
301
 
302
302
  if( d.resolutionConfidence < CURIOUS_RESOLUTION )
@@ -312,12 +312,12 @@ export class KnownEntityTracker implements SimulationEngine, CognitiveEngine {
312
312
  goalCompletionCondition: `known_entity.${skeid}.resolution >= ${CURIOUS_RESOLVED}`,
313
313
  },
314
314
  })
315
- else if( state.entities.has( `curiosity-${d.keid}` ) )
316
- commands.delete!.push( `curiosity-${d.keid}` ) // resolved → the pull subsides
315
+ else if( state.entities.has(`curiosity-${d.keid}`) )
316
+ commands.delete!.push(`curiosity-${d.keid}`) // resolved → the pull subsides
317
317
  }
318
318
 
319
319
  if( touched && this._bus ){
320
- const predErr = this._model.observe( 'known_entity.count', this._dossiers.size )
320
+ const predErr = this._model.observe('known_entity.count', this._dossiers.size )
321
321
  if( !predErr.gated )
322
322
  this._bus.publish({ type: 'known.entity.updated', version: 1, sourceEngine: this.name,
323
323
  salience: Math.max( 0.2, predErr.salience ), payload: { tracked: this._dossiers.size } })
@@ -373,7 +373,7 @@ export class KnownEntityTracker implements SimulationEngine, CognitiveEngine {
373
373
 
374
374
  this._dossiers.delete( alias.keid )
375
375
  this._aliases.set( alias.keid, canon.keid )
376
- commands.delete!.push( `ke-${alias.keid}` )
376
+ commands.delete!.push(`ke-${alias.keid}`)
377
377
  commands.set!.push({ id: `kea-${alias.keid}`, type: 'known-entity-alias',
378
378
  metadata: { aliasKeid: alias.keid, canonicalKeid: canon.keid } })
379
379
  merged = true
@@ -411,21 +411,21 @@ export class KnownEntityTracker implements SimulationEngine, CognitiveEngine {
411
411
  private _restoreFromState( state: ReadonlySimulationState ): void {
412
412
  // Recognised aliases first, so incoming references redirect to the canonical referent.
413
413
  for( const entity of state.entities.values() )
414
- if( entity.type === 'known-entity-alias' ){
414
+ if( entity.type === 'known-entity-alias'){
415
415
  const a = entity.metadata?.['aliasKeid'] as string | undefined
416
416
  const c = entity.metadata?.['canonicalKeid'] as string | undefined
417
417
  if( a && c ) this._aliases.set( a, c )
418
418
  }
419
419
 
420
420
  for( const entity of state.entities.values() ){
421
- if( entity.type !== 'known-entity' ) continue
421
+ if( entity.type !== 'known-entity') continue
422
422
  const m = entity.metadata ?? {}
423
423
  const keid = m['keid'] as string | undefined
424
424
  if( !keid || this._dossiers.has( keid ) ) continue
425
425
 
426
426
  this._dossiers.set( keid, {
427
427
  keid,
428
- kind: ( m['kind'] as 'sentient' | 'thing' ) ?? 'sentient',
428
+ kind: ( m['kind'] as 'sentient' | 'thing') ?? 'sentient',
429
429
  name: ( m['name'] as string | undefined ),
430
430
  familiarity: ( m['familiarity'] as number ) ?? 0,
431
431
  valence: ( m['valence'] as number ) ?? 0,
@@ -155,7 +155,7 @@ export class LossEvaluator implements SimulationEngine, CognitiveEngine {
155
155
 
156
156
  // Publish cognitive event — gated by prediction error
157
157
  if( sadness > 0.4 ){
158
- const predErr = this._model.observe( 'emotion.sadness', sadness )
158
+ const predErr = this._model.observe('emotion.sadness', sadness )
159
159
  if( !predErr.gated )
160
160
  _bus.publish({ type: 'emotion.sadness.elevated', version: 1, sourceEngine: this.name, salience: Math.min(1, sadness * 1.5), payload: { sadness } })
161
161
  }
@@ -168,7 +168,7 @@ export class LossEvaluator implements SimulationEngine, CognitiveEngine {
168
168
  const p = e.payload as { predictedDomains: string[]; confidence: number }
169
169
 
170
170
  if( p.predictedDomains.includes('affect') )
171
- this._model.setPrecision( 'emotion.sadness', 1.0 + p.confidence * 0.5 )
171
+ this._model.setPrecision('emotion.sadness', 1.0 + p.confidence * 0.5 )
172
172
 
173
173
  // Approximate goal loss from prediction confidence:
174
174
  // Low confidence in domains signals uncertain/failing goals
@@ -114,7 +114,7 @@ export class MoralEvaluator implements SimulationEngine, CognitiveEngine {
114
114
  // Effective config = base engine-config-moral ⊕ persona-prior. Channel A: a
115
115
  // conscientious Will develops a lower eventThreshold and so registers moral
116
116
  // self-evaluations (guilt/shame/pride) more readily — the dutifulness facet.
117
- const p = readEffectiveParams( state, 'engine-config-moral' )
117
+ const p = readEffectiveParams( state, 'engine-config-moral')
118
118
 
119
119
  if( p.eventThreshold != null ) this._eventThreshold = p.eventThreshold
120
120
  if( p.decayRate != null ) this._decayRate = p.decayRate
@@ -150,10 +150,10 @@ export class MoralEvaluator implements SimulationEngine, CognitiveEngine {
150
150
 
151
151
  onCognitiveEvent( e: CognitiveEvent ): StateCommands | void {
152
152
  this._model.observe( e.type, e.salience )
153
- if( e.type === 'executive.prediction.formed' ){
153
+ if( e.type === 'executive.prediction.formed'){
154
154
  const p = e.payload as { predictedDomains: string[]; confidence: number }
155
155
  if( p.predictedDomains.includes('moral') )
156
- this._model.setPrecision( 'emotion.guilt', 1.0 + p.confidence * 0.5 )
156
+ this._model.setPrecision('emotion.guilt', 1.0 + p.confidence * 0.5 )
157
157
  }
158
158
  }
159
159
 
@@ -251,7 +251,7 @@ export class MoralEvaluator implements SimulationEngine, CognitiveEngine {
251
251
  // Phase C + F: publish cognitive event — gated by prediction error
252
252
  const _bus = this._bus
253
253
  if( _bus && ( guilt > 0.4 || shame > 0.4 ) ){
254
- const predErr = this._model.observe( 'emotion.guilt', guilt )
254
+ const predErr = this._model.observe('emotion.guilt', guilt )
255
255
  if( !predErr.gated )
256
256
  _bus.publish({ type: 'emotion.guilt.elevated', version: 1, sourceEngine: this.name, salience: Math.min(1, guilt * 1.5), payload: { guilt, shame, pride } })
257
257
  }
@@ -81,7 +81,7 @@ export class NoveltyDetector implements SimulationEngine, CognitiveEngine {
81
81
  private _readConfigFromState( state: ReadonlySimulationState ): void {
82
82
  // Effective config = base engine-config-novelty ⊕ persona-prior. Channel A: an open
83
83
  // Will develops a lower significanceThreshold and so registers novelty more readily.
84
- const p = readEffectiveParams( state, 'engine-config-novelty' )
84
+ const p = readEffectiveParams( state, 'engine-config-novelty')
85
85
  if( p.learningRate != null ) this._learningRate = p.learningRate
86
86
  if( p.windowSize != null ) this._windowSize = p.windowSize
87
87
  if( p.significanceThreshold != null ) this._significanceThreshold = p.significanceThreshold
@@ -93,10 +93,10 @@ export class NoveltyDetector implements SimulationEngine, CognitiveEngine {
93
93
 
94
94
  onCognitiveEvent( e: CognitiveEvent ): StateCommands | void {
95
95
  this._model.observe( e.type, e.salience )
96
- if( e.type === 'executive.prediction.formed' ){
96
+ if( e.type === 'executive.prediction.formed'){
97
97
  const p = e.payload as { predictedDomains: string[]; confidence: number }
98
98
  if( p.predictedDomains.includes('perception') )
99
- this._model.setPrecision( 'novelty.score', 1.0 + p.confidence * 0.5 )
99
+ this._model.setPrecision('novelty.score', 1.0 + p.confidence * 0.5 )
100
100
  }
101
101
  }
102
102
 
@@ -171,7 +171,7 @@ export class NoveltyDetector implements SimulationEngine, CognitiveEngine {
171
171
  _bus.publish({ type: 'perception.novelty.spike', version: 1, sourceEngine: this.name, salience: Math.min(1, overallNovelty * 2), payload: { novelty: overallNovelty } })
172
172
  // Phase D + F: rich state-change event — gated by prediction error
173
173
  if( _bus ){
174
- const predErr = this._model.observe( 'novelty.score', overallNovelty )
174
+ const predErr = this._model.observe('novelty.score', overallNovelty )
175
175
  if( !predErr.gated )
176
176
  _bus.publish({ type: 'novelty.state.changed', version: 1, sourceEngine: this.name, salience: predErr.salience, payload: { novelty: overallNovelty, socialEvaluationThreat: state.metrics.get('social.evaluation_threat') ?? 0, activeAgents: state.metrics.get('social.active_agents') ?? 0, fearLevel: state.metrics.get('emotion.fear') ?? 0 } })
177
177
  }