@mindot/will 0.5.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 (132) hide show
  1. package/dist/channels/discord.d.ts +1 -1
  2. package/dist/channels/discord.js.map +1 -1
  3. package/dist/channels/whatsapp.d.ts +1 -1
  4. package/dist/channels/whatsapp.js.map +1 -1
  5. package/dist/cli.js +567 -51
  6. package/dist/cli.js.map +1 -1
  7. package/dist/index.d.ts +2 -2
  8. package/dist/index.js +567 -51
  9. package/dist/index.js.map +1 -1
  10. package/dist/mcp/effectors.d.ts +1 -1
  11. package/dist/mcp/effectors.js.map +1 -1
  12. package/dist/{will-BDq-TMQr.d.ts → will-Bikuk4s2.d.ts} +48 -6
  13. package/package.json +1 -1
  14. package/src/channels/discord.ts +11 -11
  15. package/src/channels/roster.ts +1 -1
  16. package/src/channels/types.ts +1 -1
  17. package/src/channels/whatsapp.ts +25 -25
  18. package/src/cli.ts +20 -20
  19. package/src/cognition/acp.ts +28 -0
  20. package/src/cognition/agency/consequence.ts +174 -0
  21. package/src/cognition/agency/engines/action.selector.ts +301 -48
  22. package/src/cognition/agency/engines/affordance.synthesizer.ts +26 -16
  23. package/src/cognition/agency/engines/deliberation.engine.ts +28 -14
  24. package/src/cognition/agency/engines/motor.schema.executor.ts +86 -14
  25. package/src/cognition/agency/engines/reafference.engine.ts +122 -18
  26. package/src/cognition/agency/execution.primitives.ts +13 -13
  27. package/src/cognition/agency/proactive.communicator.ts +1 -1
  28. package/src/cognition/agency/reconcile.learning.ts +1 -1
  29. package/src/cognition/agency/revocation.ts +79 -0
  30. package/src/cognition/agency/schemas/repertoire.ts +2 -2
  31. package/src/cognition/agency/selection.scoring.ts +25 -9
  32. package/src/cognition/bus.ts +2 -2
  33. package/src/cognition/completion.inbox.ts +1 -1
  34. package/src/cognition/config.mirror.entities.ts +5 -5
  35. package/src/cognition/event.log.ts +2 -2
  36. package/src/cognition/event.schemas.ts +67 -67
  37. package/src/cognition/faculties/aesthetic.evaluator.ts +6 -6
  38. package/src/cognition/faculties/affective.blender.ts +36 -4
  39. package/src/cognition/faculties/attachment.evaluator.ts +6 -6
  40. package/src/cognition/faculties/attention.allocator.ts +63 -8
  41. package/src/cognition/faculties/autobiographical.narrator.ts +3 -3
  42. package/src/cognition/faculties/bias.detector.ts +7 -7
  43. package/src/cognition/faculties/circadian.oscillator.ts +3 -3
  44. package/src/cognition/faculties/confidence.calibrator.ts +7 -7
  45. package/src/cognition/faculties/dream.simulator.ts +5 -5
  46. package/src/cognition/faculties/empathy.simulator.ts +7 -7
  47. package/src/cognition/faculties/energy.regulator.ts +4 -4
  48. package/src/cognition/faculties/episodic.consolidator.ts +6 -6
  49. package/src/cognition/faculties/executive.engine/commands.ts +6 -6
  50. package/src/cognition/faculties/executive.engine/context.ts +42 -42
  51. package/src/cognition/faculties/executive.engine/deferred.effects.ts +2 -2
  52. package/src/cognition/faculties/executive.engine/engine.ts +25 -25
  53. package/src/cognition/faculties/executive.engine/facet.supervisor.ts +12 -12
  54. package/src/cognition/faculties/executive.engine/facet.ts +18 -18
  55. package/src/cognition/faculties/executive.engine/gating.ts +2 -2
  56. package/src/cognition/faculties/executive.engine/messages.ts +3 -3
  57. package/src/cognition/faculties/executive.engine/parser.ts +11 -11
  58. package/src/cognition/faculties/executive.engine/prompt.factory.ts +55 -55
  59. package/src/cognition/faculties/exteroception.ts +99 -5
  60. package/src/cognition/faculties/forgetting.curve.ts +3 -3
  61. package/src/cognition/faculties/frustration.evaluator.ts +6 -6
  62. package/src/cognition/faculties/goal.manager.ts +15 -15
  63. package/src/cognition/faculties/inhibition.controller.ts +3 -3
  64. package/src/cognition/faculties/interoception.ts +3 -3
  65. package/src/cognition/faculties/introspection.engine.ts +3 -3
  66. package/src/cognition/faculties/known.entity.tracker.ts +15 -15
  67. package/src/cognition/faculties/loss.evaluator.ts +2 -2
  68. package/src/cognition/faculties/moral.evaluator.ts +4 -4
  69. package/src/cognition/faculties/novelty.detector.ts +4 -4
  70. package/src/cognition/faculties/persona.consolidator.ts +12 -12
  71. package/src/cognition/faculties/planning.engine/engine.ts +47 -47
  72. package/src/cognition/faculties/planning.engine/plan.frontier.ts +5 -5
  73. package/src/cognition/faculties/planning.engine/plan.store.ts +1 -1
  74. package/src/cognition/faculties/planning.engine/plan.supervision.ts +20 -20
  75. package/src/cognition/faculties/reputation.tracker.ts +6 -6
  76. package/src/cognition/faculties/reward.evaluator.ts +4 -4
  77. package/src/cognition/faculties/self.model.updater.ts +8 -8
  78. package/src/cognition/faculties/semantic.engine/integrator.ts +15 -15
  79. package/src/cognition/faculties/sleep.pressure.regulator.ts +4 -4
  80. package/src/cognition/faculties/social.perception.ts +3 -3
  81. package/src/cognition/faculties/spaced.repetition.ts +2 -2
  82. package/src/cognition/faculties/stress.regulator.ts +27 -4
  83. package/src/cognition/faculties/task.switcher.ts +11 -6
  84. package/src/cognition/faculties/theory.of.mind.ts +6 -6
  85. package/src/cognition/faculties/threat.evaluator.ts +3 -3
  86. package/src/cognition/faculties/working.memory.ts +8 -8
  87. package/src/cognition/generative.model.ts +2 -2
  88. package/src/cognition/memory/vector.adapter.ts +5 -5
  89. package/src/cognition/memory/vector.content.ts +4 -4
  90. package/src/cognition/memory/vector.embedder.ts +9 -9
  91. package/src/cognition/persona.prior.ts +1 -1
  92. package/src/cognition/schema.registry.ts +2 -2
  93. package/src/cognition/senses/audition.engine/engine.ts +2 -2
  94. package/src/cognition/senses/base.sense.engine.ts +1 -1
  95. package/src/cognition/utilities/token.tracker.ts +5 -5
  96. package/src/core/abstracts.ts +1 -1
  97. package/src/core/completion.recorder.ts +2 -2
  98. package/src/core/serialization.ts +3 -3
  99. package/src/core/snapshot.manager.ts +1 -1
  100. package/src/core/state.manager.ts +1 -1
  101. package/src/core/utils.ts +1 -1
  102. package/src/host/boot.ts +30 -30
  103. package/src/host/utterances.ts +1 -1
  104. package/src/llm/index.ts +9 -9
  105. package/src/llm/summarizer.ts +4 -4
  106. package/src/llm/wire.contracts.ts +1 -1
  107. package/src/mcp/effectors.ts +10 -10
  108. package/src/mcp/server.ts +11 -11
  109. package/src/pma/eval.ts +1 -1
  110. package/src/pma/index.ts +21 -21
  111. package/src/runners/outreach.runner.ts +3 -3
  112. package/src/runners/social.runner.ts +1 -1
  113. package/src/runners/thin-shim.runner.ts +1 -1
  114. package/src/sdk/will.ts +5 -5
  115. package/src/serve/server.ts +12 -12
  116. package/src/stem/assembly.audit.ts +3 -3
  117. package/src/stem/guards/identity.coherence.ts +10 -10
  118. package/src/stem/guards/identity.guard.ts +22 -22
  119. package/src/stem/index.ts +11 -11
  120. package/src/stem/mind.ts +12 -12
  121. package/src/stem/tracts/biography.writer.ts +3 -3
  122. package/src/stem/tracts/effector.controller.ts +4 -4
  123. package/src/stem/tracts/health.reporter.ts +1 -1
  124. package/src/stem/tracts/outbox.controller.ts +4 -0
  125. package/src/stem/tracts/outbox.writer.ts +4 -4
  126. package/src/stem/tracts/pma.controller.ts +1 -1
  127. package/src/stem/tracts/replay.controller.ts +10 -10
  128. package/src/stem/tracts/sensory.controller.ts +2 -2
  129. package/src/stem/tracts/session.logger.ts +4 -4
  130. package/src/stem/tracts/transport/socketio.transport.ts +7 -7
  131. package/src/stem/tracts/transport/stream.transport.ts +2 -2
  132. package/src/stem/tracts/transport.controller.ts +15 -15
package/src/stem/mind.ts CHANGED
@@ -409,10 +409,10 @@ export function _resolveVectorMemory(
409
409
  const mockMode = process.env.WILL_VECTOR_MEMORY === 'mock'
410
410
  const rawModel = embeddingModel
411
411
  ?? process.env.WILL_EMBEDDING_MODEL
412
- ?? ( process.env.WILL_EMBEDDING_API_KEY ? 'text-embedding-3-small' : 'none' )
412
+ ?? ( process.env.WILL_EMBEDDING_API_KEY ? 'text-embedding-3-small' : 'none')
413
413
 
414
414
  // Explicitly disabled — the documented "none" sentinel or recall turned off.
415
- if( !mockMode && ( rawModel === 'none' || process.env.WILL_SEMANTIC_RECALL === 'false' ) )
415
+ if( !mockMode && ( rawModel === 'none' || process.env.WILL_SEMANTIC_RECALL === 'false') )
416
416
  return { embedder: null, vectorMemory: null }
417
417
 
418
418
  // testMode promises a deterministic, zero-key, offline mind — but a dev .env
@@ -581,9 +581,9 @@ export function assembleMind( willId: string, config: WillConfig ): MindAssembly
581
581
  profileContext: profile?.context,
582
582
  })
583
583
  if( !idGuard.ok )
584
- throw new Error( `Invalid Will identity for "${willId}": ${ idGuard.errors.join( '; ' ) }` )
584
+ throw new Error(`Invalid Will identity for "${willId}": ${ idGuard.errors.join('; ') }`)
585
585
  for( const w of idGuard.warnings )
586
- logger.warn( `[identity-guard] ${willId}: ${w}` )
586
+ logger.warn(`[identity-guard] ${willId}: ${w}`)
587
587
  config = { ...config, identity: idGuard.sanitized.identity }
588
588
 
589
589
  // ── Construct ────────────────────────────────────────────
@@ -602,8 +602,8 @@ export function assembleMind( willId: string, config: WillConfig ): MindAssembly
602
602
  // sessionLogger/grants); tests/unit/assembly.order.test.ts pins that set per
603
603
  // tier, so a NEW unwired attachment fails loudly in CI, not here.
604
604
  for( const rec of auditAssemblyWiring( simulation.orchestrator.engines ) )
605
- if( rec.status === 'unwired' )
606
- logger.debug( `[assembly] ${willId}: ${rec.engine}.${rec.method} unwired at assembly (anatomy=${anatomy})` )
605
+ if( rec.status === 'unwired')
606
+ logger.debug(`[assembly] ${willId}: ${rec.engine}.${rec.method} unwired at assembly (anatomy=${anatomy})`)
607
607
 
608
608
  // ── Seed readable simulation state ───────────────────────
609
609
  // Identity, optional initial goals, and the engine-config mirror.
@@ -772,7 +772,7 @@ function _constructCognition(
772
772
  // ── Planning Engine ──────────────────────────────────────
773
773
  const planningEngine = new PlanningEngine()
774
774
  planningEngine.attachGoalManager( goalManager )
775
- if( anatomy !== 'reflex' ) planningEngine.attachExecutiveEngine( executiveEngine )
775
+ if( anatomy !== 'reflex') planningEngine.attachExecutiveEngine( executiveEngine )
776
776
  executiveEngine.attachPlanningEngine( planningEngine )
777
777
 
778
778
  // ── Executive ────────────────────────────────────────────
@@ -791,7 +791,7 @@ function _constructCognition(
791
791
  autobiographicalNarrator.attachEpisodicConsolidator( episodicConsolidator )
792
792
  autobiographicalNarrator.attachSemanticIntegrator( semanticIntegrator )
793
793
  // Satellites harvest the executive's own output — attach wherever it runs.
794
- if( anatomy !== 'reflex' ){
794
+ if( anatomy !== 'reflex'){
795
795
  autobiographicalNarrator.attachExecutiveEngine( executiveEngine )
796
796
  introspectionEngine.attachExecutiveEngine( executiveEngine )
797
797
  }
@@ -807,7 +807,7 @@ function _constructCognition(
807
807
  empathySimulator.attachTheoryOfMind( theoryOfMind )
808
808
 
809
809
  // ── Context compaction components (mind anatomy only) ──
810
- if( anatomy !== 'reflex' ){
810
+ if( anatomy !== 'reflex'){
811
811
  const summarizer = new ExecutiveSummarizer({
812
812
  summaryInterval: parseInt( process.env.WILL_SUMMARY_INTERVAL ?? '10'),
813
813
  bufferSize: parseInt( process.env.WILL_SUMMARY_BUFFER_SIZE ?? '12'),
@@ -845,7 +845,7 @@ function _constructCognition(
845
845
  const olfactionEngine = new OlfactionEngine()
846
846
  const gustationEngine = new GustationEngine()
847
847
 
848
- if( anatomy !== 'reflex' )
848
+ if( anatomy !== 'reflex')
849
849
  auditionEngine.attachExecutiveEngine( executiveEngine )
850
850
 
851
851
  // §5.4 — cold-spawn digest hydration: on the first turn for an entity, seed an
@@ -906,7 +906,7 @@ function _constructCognition(
906
906
  // winner (graceful System-1 degradation).
907
907
  const deliberationEngine = new DeliberationEngine()
908
908
  deliberationEngine.setWillName( config.name )
909
- if( anatomy !== 'reflex' )
909
+ if( anatomy !== 'reflex')
910
910
  deliberationEngine.attachExecutive( executiveEngine )
911
911
 
912
912
  // ── Build Cognition ──────────────────────────────────────
@@ -1108,7 +1108,7 @@ function _seedIdentity(
1108
1108
  // to infer its identity from context. config.name is the canonical source of truth.
1109
1109
  const nameAlreadyInPrompt = personaText.toLowerCase().includes( config.name.toLowerCase() )
1110
1110
  const namePrefix = nameAlreadyInPrompt ? '' : `I am ${config.name}.`
1111
- const fullPersonaText = [ namePrefix, personaText ].filter( Boolean ).join( ' ' )
1111
+ const fullPersonaText = [ namePrefix, personaText ].filter( Boolean ).join(' ')
1112
1112
 
1113
1113
  const prompt = [
1114
1114
  WILL_CORE_PREAMBLE,
@@ -38,15 +38,15 @@ export class BiographyWriter {
38
38
  if( !fileLoggingEnabled() ) return
39
39
 
40
40
  const dataDir = process.env[ 'WILL_DATA_DIR' ] ?? './data'
41
- const dir = join( dataDir, 'wills', willId, 'profiles' )
41
+ const dir = join( dataDir, 'wills', willId, 'profiles')
42
42
  try {
43
43
  if( !this._ensuredDirs.has( dir ) ){
44
44
  mkdirSync( dir, { recursive: true } )
45
45
  this._ensuredDirs.add( dir )
46
46
  }
47
- appendFileSync( join( dir, file ), JSON.stringify( record ) + '\n', 'utf8' )
47
+ appendFileSync( join( dir, file ), JSON.stringify( record ) + '\n', 'utf8')
48
48
  } catch( err ){
49
- logger.error( `[biography] ${file} write failed:`, err )
49
+ logger.error(`[biography] ${file} write failed:`, err )
50
50
  }
51
51
  }
52
52
  /**
@@ -91,11 +91,11 @@ export class effectorController {
91
91
  const tick = instance.tickCount
92
92
 
93
93
  const intent = instance.simulation.stateManager.snapshot().entities.get( invocationId )
94
- if( !intent || intent.type !== 'agency.intent' ){
94
+ if( !intent || intent.type !== 'agency.intent'){
95
95
  // No awaiting intent for this id. Expected when the executor's 15-tick await
96
96
  // timeout already abandoned it (writing a failed outcome + advancing any plan)
97
97
  // before the host's late ack arrived, or the id is unknown. Drop the straggler.
98
- logger.warn( `[effector] confirmExecution: no awaiting agency.intent "${invocationId}" (timed out / already reconciled?) — ignored` )
98
+ logger.warn(`[effector] confirmExecution: no awaiting agency.intent "${invocationId}" (timed out / already reconciled?) — ignored`)
99
99
  return
100
100
  }
101
101
 
@@ -122,7 +122,7 @@ export class effectorController {
122
122
  if( typeof v === 'number' && Number.isFinite( v ) )
123
123
  instance.simulation.stateManager.setMetric( k, v )
124
124
  else
125
- logger.warn( `[effector] confirmExecution: dropped non-finite metric "${k}"=${String( v )} from host ack (${schema})` )
125
+ logger.warn(`[effector] confirmExecution: dropped non-finite metric "${k}"=${String( v )} from host ack (${schema})`)
126
126
  }
127
127
 
128
128
  instance.sessionLogger?.write({
@@ -135,7 +135,7 @@ export class effectorController {
135
135
  confirmedExternally: true,
136
136
  } as never)
137
137
 
138
- logger.info( `[effector] ✓ reconciled ${result.success ? 'success' : 'failure'}: intent "${invocationId}" (${schema})` )
138
+ logger.info(`[effector] ✓ reconciled ${result.success ? 'success' : 'failure'}: intent "${invocationId}" (${schema})`)
139
139
  }
140
140
  }
141
141
 
@@ -87,7 +87,7 @@ export class HealthReporter {
87
87
  for( const entity of instance.simulation.stateManager.getEntitiesByType('goal') ){
88
88
  totalGoals++
89
89
  const s = entity.metadata?.status
90
- if( s === 'active' || s === 'in_progress' ) activeGoals++
90
+ if( s === 'active' || s === 'in_progress') activeGoals++
91
91
  }
92
92
 
93
93
  const goalScore = totalGoals === 0
@@ -104,6 +104,10 @@ export class OutboxController {
104
104
  : `My message failed to reach the recipient.`,
105
105
  salience: delivered ? 0.35 : 0.6,
106
106
  changeType: delivered ? 'delivered' : 'failed',
107
+ // Reafference by construction — this percept describes our own action's
108
+ // outcome ("ear hears the word"). Tagged, not attenuated: it is the ack
109
+ // surface, not a content echo (EXAFFERENCE P2).
110
+ provenance: 'reafferent',
107
111
  messageId,
108
112
  },
109
113
  })
@@ -53,7 +53,7 @@ export class OutboxWriter {
53
53
  this._sessionLogger = logger
54
54
  }
55
55
 
56
- private _genId( suffix = '' ): string {
56
+ private _genId( suffix = ''): string {
57
57
  return `outbox-${ this._willId }-${ ++this._seq }${ suffix }`
58
58
  }
59
59
 
@@ -61,7 +61,7 @@ export class OutboxWriter {
61
61
  * Push one canonical outbox row and return its generated id. The single point
62
62
  * where the row shape is materialized — all producers funnel through here.
63
63
  */
64
- enqueue( row: OutboxRow, idSuffix = '' ): string {
64
+ enqueue( row: OutboxRow, idSuffix = ''): string {
65
65
  const id = this._genId( idSuffix )
66
66
  this._outbox.push({
67
67
  id,
@@ -105,7 +105,7 @@ export class OutboxWriter {
105
105
 
106
106
  const ids: string[] = []
107
107
  bubbles.forEach( ( bubble, i ) => {
108
- if( !pushToOutbox ){ ids.push( this._genId( `-${ i }` ) ); return }
108
+ if( !pushToOutbox ){ ids.push( this._genId(`-${ i }`) ); return }
109
109
  logger.info(`[outbox-writer] reply → ${ entityId } bubble[${ i }] "${ bubble.slice( 0, 80 ) }"`)
110
110
  ids.push( this.enqueue({
111
111
  targetEntityId: entityId,
@@ -113,7 +113,7 @@ export class OutboxWriter {
113
113
  content: bubble,
114
114
  effectorName: 'text',
115
115
  threadId,
116
- }, `-${ i }` ) )
116
+ }, `-${ i }`) )
117
117
  } )
118
118
 
119
119
  this._sessionLogger?.write({
@@ -29,7 +29,7 @@ export class PMAController {
29
29
  * with existing beliefs may cause unintended merges.
30
30
  */
31
31
  load( id: string, instance: WillInstance, pma: PMASnapshot ): void {
32
- if( instance.status === 'active' )
32
+ if( instance.status === 'active')
33
33
  throw new Error(`Cannot load PMA into an active Will (${id}). Pause first.`)
34
34
 
35
35
  // Re-validate the artifact's persona at the load boundary (Phase 2): a stored
@@ -44,7 +44,7 @@ export class ReplayController {
44
44
  // Pre-create the replay dir so flush() can persist segments incrementally
45
45
  // (stop() saves the consolidated file into the same dir).
46
46
  const dataDir = process.env[ 'WILL_DATA_DIR' ] ?? './data'
47
- const dir = join( dataDir, 'wills', id, 'replays' )
47
+ const dir = join( dataDir, 'wills', id, 'replays')
48
48
  mkdirSync( dir, { recursive: true } )
49
49
 
50
50
  const recorder = this._replayManager.createRecorder( id, runId, undefined, {
@@ -74,10 +74,10 @@ export class ReplayController {
74
74
  this._activeRecorders.delete( id )
75
75
 
76
76
  const dataDir = process.env[ 'WILL_DATA_DIR' ] ?? './data'
77
- const dir = join( dataDir, 'wills', id, 'replays' )
77
+ const dir = join( dataDir, 'wills', id, 'replays')
78
78
  mkdirSync( dir, { recursive: true } )
79
79
 
80
- const path = join( dir, `${active.runId}.json` )
80
+ const path = join( dir, `${active.runId}.json`)
81
81
  await active.recorder.save( path )
82
82
 
83
83
  const meta = active.recorder.getMetadata()
@@ -97,11 +97,11 @@ export class ReplayController {
97
97
  if( cached ) return cached
98
98
 
99
99
  const dataDir = process.env[ 'WILL_DATA_DIR' ] ?? './data'
100
- const path = join( dataDir, 'wills', id, 'replays', `${runId}.json` )
100
+ const path = join( dataDir, 'wills', id, 'replays', `${runId}.json`)
101
101
  if( !existsSync( path ) ) return null
102
102
 
103
103
  try {
104
- const meta = ( JSON.parse( readFileSync( path, 'utf8' ) ) as { metadata: ReplayMetadata } ).metadata
104
+ const meta = ( JSON.parse( readFileSync( path, 'utf8') ) as { metadata: ReplayMetadata } ).metadata
105
105
  this._completedReplays.set( key, meta )
106
106
  this._replayPaths.set( key, path )
107
107
  return meta
@@ -121,7 +121,7 @@ export class ReplayController {
121
121
  if( key.startsWith( prefix ) ) results.push( meta )
122
122
 
123
123
  const dataDir = process.env[ 'WILL_DATA_DIR' ] ?? './data'
124
- const dir = join( dataDir, 'wills', id, 'replays' )
124
+ const dir = join( dataDir, 'wills', id, 'replays')
125
125
 
126
126
  if( existsSync( dir ) ){
127
127
  const inMem = new Set(
@@ -137,7 +137,7 @@ export class ReplayController {
137
137
  if( inMem.has( runId ) ) continue
138
138
  try {
139
139
  const path = join( dir, file )
140
- const meta = ( JSON.parse( readFileSync( path, 'utf8' ) ) as { metadata: ReplayMetadata } ).metadata
140
+ const meta = ( JSON.parse( readFileSync( path, 'utf8') ) as { metadata: ReplayMetadata } ).metadata
141
141
  const key = `${id}:${runId}`
142
142
  this._completedReplays.set( key, meta )
143
143
  this._replayPaths.set( key, path )
@@ -164,14 +164,14 @@ export class ReplayController {
164
164
  * process (e.g. after a server restart).
165
165
  */
166
166
  private _resolvePath( id: string, runId: string ): string | undefined {
167
- const cached = this._replayPaths.get( `${id}:${runId}` )
167
+ const cached = this._replayPaths.get(`${id}:${runId}`)
168
168
  if( cached ) return cached
169
169
 
170
170
  const dataDir = process.env[ 'WILL_DATA_DIR' ] ?? './data'
171
- const path = join( dataDir, 'wills', id, 'replays', `${runId}.json` )
171
+ const path = join( dataDir, 'wills', id, 'replays', `${runId}.json`)
172
172
  if( !existsSync( path ) ) return undefined
173
173
 
174
- this._replayPaths.set( `${id}:${runId}`, path )
174
+ this._replayPaths.set(`${id}:${runId}`, path )
175
175
  return path
176
176
  }
177
177
  }
@@ -52,7 +52,7 @@ export class SensoryController {
52
52
  gustation: cog.gustationEngine,
53
53
  }
54
54
  const engine = engineMap[ domain ]
55
- if( !engine ) throw Object.assign( new Error( `Unknown sense domain: ${domain}` ), { code: 400 } )
55
+ if( !engine ) throw Object.assign( new Error(`Unknown sense domain: ${domain}`), { code: 400 } )
56
56
  await engine.ingest( input )
57
57
  }
58
58
 
@@ -135,7 +135,7 @@ export class SensoryController {
135
135
  private _ensureChunkFanout( instance: WillInstance ): void {
136
136
  if( this._chunkWired.has( instance ) ) return
137
137
  const audition = instance.cognition.auditionEngine
138
- if( typeof ( audition as { addChunkCallback?: unknown } ).addChunkCallback !== 'function' ) return
138
+ if( typeof ( audition as { addChunkCallback?: unknown } ).addChunkCallback !== 'function') return
139
139
 
140
140
  this._chunkWired.add( instance )
141
141
  audition.addChunkCallback( ( entityId: string, _threadId: string, chunk: string ) => {
@@ -97,7 +97,7 @@ export class SessionLogger {
97
97
  private _count = 0
98
98
 
99
99
  constructor( willId: string, dataDir: string = './data', opts: SessionLoggerOptions = {} ) {
100
- const ts = new Date().toISOString().replace( /[:.]/g, '-' ).slice( 0, 19 )
100
+ const ts = new Date().toISOString().replace( /[:.]/g, '-').slice( 0, 19 )
101
101
  const rnd = Math.random().toString( 36 ).slice( 2, 8 )
102
102
  this.sessionId = `${ts}-${rnd}`
103
103
 
@@ -105,9 +105,9 @@ export class SessionLogger {
105
105
 
106
106
  const fileLogging = opts.fileLogging ?? false
107
107
  if( fileLogging ){
108
- const dir = join( opts.dataDir ?? dataDir, 'wills', willId, 'sessions' )
108
+ const dir = join( opts.dataDir ?? dataDir, 'wills', willId, 'sessions')
109
109
  mkdirSync( dir, { recursive: true } )
110
- this.filePath = join( dir, `${this.sessionId}.jsonl` )
110
+ this.filePath = join( dir, `${this.sessionId}.jsonl`)
111
111
  this._stream = createWriteStream( this.filePath, { flags: 'a' } )
112
112
  } else {
113
113
  this.filePath = ''
@@ -133,7 +133,7 @@ export class SessionLogger {
133
133
 
134
134
  // File is a dev-only mirror.
135
135
  if( this._stream ){
136
- try { this._stream.write( JSON.stringify( record ) + '\n' ) }
136
+ try { this._stream.write( JSON.stringify( record ) + '\n') }
137
137
  catch { /* never block the tick loop on a log failure */ }
138
138
  }
139
139
 
@@ -91,7 +91,7 @@ export class SocketIoTransport implements ExternalTransport {
91
91
  const timer = setTimeout( () => done({ acked: false, via: 'timeout' }), timeoutMs )
92
92
 
93
93
  try {
94
- socket.emit( 'envelope', stamped, ( response: unknown ) => done({ acked: true, via: 'callback', payload: response }) )
94
+ socket.emit('envelope', stamped, ( response: unknown ) => done({ acked: true, via: 'callback', payload: response }) )
95
95
  }
96
96
  catch( err ){
97
97
  logger.warn(`[socketio-transport] emit failed: ${( err as Error ).message}`)
@@ -159,20 +159,20 @@ export class SocketIoTransport implements ExternalTransport {
159
159
 
160
160
  /** Attach socket.io event handlers that feed the inbound + status streams. */
161
161
  private _wire( socket: SocketLike ): void {
162
- socket.on( 'connect', () => this._notifyStatus( 'connected' ) )
163
- socket.on( 'disconnect', () => this._notifyStatus( 'disconnected' ) )
164
- socket.on( 'reconnect_attempt', () => this._notifyStatus( 'reconnecting' ) )
162
+ socket.on('connect', () => this._notifyStatus('connected') )
163
+ socket.on('disconnect', () => this._notifyStatus('disconnected') )
164
+ socket.on('reconnect_attempt', () => this._notifyStatus('reconnecting') )
165
165
 
166
166
  // Primary inbound channel — already-typed envelopes from the peer.
167
- socket.on( 'envelope', ( env: InboundEnvelope ) => this._emitInbound( env ) )
167
+ socket.on('envelope', ( env: InboundEnvelope ) => this._emitInbound( env ) )
168
168
 
169
169
  // Discrete ack events (Section 2): in case the peer emits acks independently
170
170
  // rather than via the emit() callback. Synthesized into ack envelopes; the
171
171
  // AckReconciler (Section 3) dedups against the callback path by correlationId.
172
- socket.on( 'message.delivered', ( m: { correlationId: string; delivered?: boolean } ) =>
172
+ socket.on('message.delivered', ( m: { correlationId: string; delivered?: boolean } ) =>
173
173
  this._emitInbound( this._deliveryAck( m.correlationId, m.delivered ?? true ) ) )
174
174
 
175
- socket.on( 'effector.invoked.ack', ( m: { correlationId: string; result: AckEnvelope['result'] } ) =>
175
+ socket.on('effector.invoked.ack', ( m: { correlationId: string; result: AckEnvelope['result'] } ) =>
176
176
  this._emitInbound( this._resultAck( m.correlationId, m.result ) ) )
177
177
  }
178
178
 
@@ -39,7 +39,7 @@ export class StreamTransport implements ExternalTransport {
39
39
  private readonly _inboundHandlers = new Set<( env: InboundEnvelope ) => void>()
40
40
  private readonly _statusHandlers = new Set<( s: TransportStatus ) => void>()
41
41
 
42
- constructor( willId: string = 'stream' ){
42
+ constructor( willId: string = 'stream'){
43
43
  this.willId = willId
44
44
  }
45
45
 
@@ -71,7 +71,7 @@ export class StreamTransport implements ExternalTransport {
71
71
  * `'reply'`) or `'*'` for all. Returns an unsubscribe function.
72
72
  */
73
73
  on( channel: StreamChannel, listener: OutboundListener ): () => void {
74
- if( channel === '*' ) return this.subscribe( listener )
74
+ if( channel === '*') return this.subscribe( listener )
75
75
  let set = this._outboundByCh.get( channel )
76
76
  if( !set ){ set = new Set(); this._outboundByCh.set( channel, set ) }
77
77
  set.add( listener )
@@ -88,12 +88,12 @@ export class TransportController {
88
88
  * the SAME path discrete ack events take — so applyInbound() reconciles both
89
89
  * idempotently. 'none' = fire-and-forget (chunks, replies: no outbox entry to mark).
90
90
  */
91
- private _emit( instance: WillInstance, env: OutboundEnvelope, reconcileAs: 'delivery' | 'result' | 'none' ): void {
91
+ private _emit( instance: WillInstance, env: OutboundEnvelope, reconcileAs: 'delivery' | 'result' | 'none'): void {
92
92
  const transport = instance.transport
93
93
  if( !transport ) return
94
94
 
95
95
  // Buffer state-affecting outbound until acked, so a reconnect can re-emit it.
96
- if( reconcileAs !== 'none' ){
96
+ if( reconcileAs !== 'none'){
97
97
  const pending = this._pendingFor( instance.config.id )
98
98
  pending.set( env.correlationId, env )
99
99
  // Bound the buffer — drop the oldest un-acked envelope past the cap (FIFO).
@@ -105,7 +105,7 @@ export class TransportController {
105
105
  }
106
106
 
107
107
  const pending = transport.emit( env )
108
- if( reconcileAs === 'none' ){ void pending; return }
108
+ if( reconcileAs === 'none'){ void pending; return }
109
109
 
110
110
  void pending.then( ack => {
111
111
  if( !ack.acked ) return
@@ -120,9 +120,9 @@ export class TransportController {
120
120
 
121
121
  /** Coerce an emit-callback ack payload into a confirmExecution result, or null. */
122
122
  private _asResult( payload: unknown ): { success: boolean; description: string; metrics?: Record<string, number> } | null {
123
- if( payload && typeof payload === 'object' && typeof ( payload as { success?: unknown } ).success === 'boolean' ){
123
+ if( payload && typeof payload === 'object' && typeof ( payload as { success?: unknown } ).success === 'boolean'){
124
124
  const p = payload as { success: boolean; description?: unknown; metrics?: Record<string, number> }
125
- return { success: p.success, description: String( p.description ?? '' ), ...( p.metrics ? { metrics: p.metrics } : {} ) }
125
+ return { success: p.success, description: String( p.description ?? ''), ...( p.metrics ? { metrics: p.metrics } : {} ) }
126
126
  }
127
127
  return null
128
128
  }
@@ -142,7 +142,7 @@ export class TransportController {
142
142
  seq,
143
143
  wallTime: wallClock(),
144
144
  entry,
145
- }, 'none' )
145
+ }, 'none')
146
146
  }
147
147
 
148
148
  /**
@@ -159,7 +159,7 @@ export class TransportController {
159
159
  seq,
160
160
  wallTime: wallClock(),
161
161
  report,
162
- }, 'none' )
162
+ }, 'none')
163
163
  }
164
164
 
165
165
  /**
@@ -185,7 +185,7 @@ export class TransportController {
185
185
  entityId,
186
186
  threadId,
187
187
  bubbles,
188
- }, 'none' )
188
+ }, 'none')
189
189
  } )
190
190
 
191
191
  // Outbound chunk fast-path (2.2): stream each filtered reply token off-tick.
@@ -200,13 +200,13 @@ export class TransportController {
200
200
  entityId,
201
201
  threadId,
202
202
  content,
203
- }, 'none' )
203
+ }, 'none')
204
204
  } )
205
205
  this._chunkUnsub.set( instance.config.id, chunkUnsub )
206
206
 
207
207
  // Outbound activity projection (2.5): forward all plan/activity events
208
208
  // ('*' wildcard = no entity filter). Observability only — fire-and-forget.
209
- const activityUnsub = instance.cognition.planningEngine.addActivityListener( '*', event => {
209
+ const activityUnsub = instance.cognition.planningEngine.addActivityListener('*', event => {
210
210
  this._emit( instance, {
211
211
  channel: 'activity',
212
212
  willId: instance.config.id,
@@ -216,13 +216,13 @@ export class TransportController {
216
216
  entityId: event.requestingEntityId ?? '',
217
217
  eventType: event.type,
218
218
  payload: { ...event },
219
- }, 'none' )
219
+ }, 'none')
220
220
  } )
221
221
  this._activityUnsub.set( instance.config.id, activityUnsub )
222
222
 
223
223
  // Reconnect: re-emit un-acked messages/invocations when the link returns.
224
224
  const statusUnsub = transport.onStatus( status => {
225
- if( status === 'connected' ) this._reemitPending( instance )
225
+ if( status === 'connected') this._reemitPending( instance )
226
226
  } )
227
227
  this._statusUnsub.set( instance.config.id, statusUnsub )
228
228
 
@@ -236,7 +236,7 @@ export class TransportController {
236
236
 
237
237
  logger.info(`[transport] reconnect — re-emitting ${pending.size} un-acked envelope(s) for ${instance.config.id}`)
238
238
  for( const env of [ ...pending.values() ] )
239
- this._emit( instance, env, env.channel === 'effector_invocation' ? 'result' : 'delivery' )
239
+ this._emit( instance, env, env.channel === 'effector_invocation' ? 'result' : 'delivery')
240
240
  }
241
241
 
242
242
  /**
@@ -258,7 +258,7 @@ export class TransportController {
258
258
  seq: this._nextSeq( instance.config.id ),
259
259
  wallTime: wallClock(),
260
260
  invocation,
261
- }, 'result' )
261
+ }, 'result')
262
262
  }
263
263
 
264
264
  /**
@@ -279,7 +279,7 @@ export class TransportController {
279
279
  seq: this._nextSeq( instance.config.id ),
280
280
  wallTime: wallClock(),
281
281
  message,
282
- }, 'delivery' )
282
+ }, 'delivery')
283
283
  }
284
284
 
285
285
  /** Tear down the transport and discard any un-applied inbound. */