@mindot/will 0.3.0 → 0.5.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 (57) hide show
  1. package/README.md +63 -21
  2. package/dist/channels/discord.d.ts +69 -0
  3. package/dist/channels/discord.js +193 -0
  4. package/dist/channels/discord.js.map +1 -0
  5. package/dist/channels/whatsapp.d.ts +72 -0
  6. package/dist/channels/whatsapp.js +252 -0
  7. package/dist/channels/whatsapp.js.map +1 -0
  8. package/dist/cli.js +904 -356
  9. package/dist/cli.js.map +1 -1
  10. package/dist/index.d.ts +141 -141
  11. package/dist/index.js +441 -342
  12. package/dist/index.js.map +1 -1
  13. package/dist/mcp/effectors.d.ts +1 -1
  14. package/dist/types-E9-HV-SW.d.ts +11 -0
  15. package/dist/{will-B5eKs3Wv.d.ts → will-BDq-TMQr.d.ts} +4013 -3916
  16. package/package.json +17 -3
  17. package/src/channels/discord.ts +214 -0
  18. package/src/channels/roster.ts +87 -0
  19. package/src/channels/types.ts +46 -0
  20. package/src/channels/whatsapp.ts +318 -0
  21. package/src/cli.ts +57 -9
  22. package/src/cognition/agency/engines/deliberation.engine.ts +7 -7
  23. package/src/cognition/agency/execution.primitives.ts +11 -11
  24. package/src/cognition/agency/proactive.communicator.ts +8 -8
  25. package/src/cognition/config.mirror.entities.ts +2 -2
  26. package/src/cognition/conversation.memory.ts +1 -1
  27. package/src/cognition/faculties/executive.engine/commands.ts +7 -15
  28. package/src/cognition/faculties/executive.engine/engine.ts +66 -35
  29. package/src/cognition/faculties/executive.engine/escalation.buffer.ts +1 -1
  30. package/src/cognition/faculties/executive.engine/facet.ts +1 -1
  31. package/src/cognition/faculties/executive.engine/prompt.factory.ts +76 -61
  32. package/src/cognition/faculties/executive.engine/types.ts +1 -1
  33. package/src/cognition/faculties/introspection.engine.ts +1 -2
  34. package/src/cognition/faculties/planning.engine/engine.ts +38 -1
  35. package/src/cognition/faculties/planning.engine/plan.store.ts +42 -0
  36. package/src/cognition/faculties/planning.engine/plan.supervision.ts +7 -7
  37. package/src/cognition/faculties/theory.of.mind.ts +2 -2
  38. package/src/cognition/senses/audition.engine/engine.ts +21 -21
  39. package/src/cognition/utilities/token.tracker.ts +6 -0
  40. package/src/host/boot.ts +95 -7
  41. package/src/llm/index.ts +75 -25
  42. package/src/llm/summarizer.ts +2 -2
  43. package/src/profiles/companion.ts +14 -14
  44. package/src/profiles/company-brain.ts +19 -19
  45. package/src/profiles/customer-service.ts +17 -17
  46. package/src/profiles/game-npc.ts +10 -10
  47. package/src/profiles/index.ts +2 -2
  48. package/src/profiles/smart-home.ts +16 -16
  49. package/src/runners/outreach.runner.ts +6 -9
  50. package/src/runners/social.runner.ts +1 -4
  51. package/src/runners/thin-shim.runner.ts +4 -6
  52. package/src/sdk/will.ts +42 -16
  53. package/src/stem/guards/identity.coherence.ts +9 -6
  54. package/src/stem/guards/identity.guard.ts +20 -9
  55. package/src/stem/index.ts +7 -7
  56. package/src/stem/mind.ts +182 -98
  57. package/src/stem/tracts/outbox.controller.ts +2 -2
package/src/stem/mind.ts CHANGED
@@ -7,9 +7,10 @@
7
7
  //
8
8
  // Design rules:
9
9
  // • All engine instances are always created (satisfies Cognition type).
10
- // • Only standard/full tiers add ExecutiveEngine to the simulation.
11
- // Basic tier runs entirely on heuristics zero LLM cost.
12
- // • Tier controls the executive cadence (interval between LLM calls).
10
+ // • Anatomy is the only structural variant: 'mind' registers everything;
11
+ // 'reflex' is the no-LLM shell (regulatory + senses + agency heuristics).
12
+ // • Everything else is a BUDGET (cadence, model, ceilings) — host-supplied
13
+ // parameters, never tier vocabulary.
13
14
  // • minExecutiveInterval is the plan floor — the customer cannot go below it.
14
15
  // ─────────────────────────────────────────────────────────────
15
16
 
@@ -100,8 +101,79 @@ import { buildEngineConfigEntities, EngineConfigEntity } from '#cognition/config
100
101
 
101
102
  // ── Public types ─────────────────────────────────────────────
102
103
 
103
- export type EngineTier = 'basic' | 'standard' | 'full'
104
- export type ModelTier = 'haiku' | 'sonnet' | 'opus'
104
+ /**
105
+ * Anatomy the only structural variant a Will has.
106
+ * mind — the whole cognitive architecture (default). Faculties are not a
107
+ * pricing axis; hosts differentiate on model + budgets (cadence,
108
+ * ceilings), never by amputating engines.
109
+ * reflex — a no-LLM shell: regulatory + senses + agency heuristics only,
110
+ * for embedded / offline deployments (no System 2 at all).
111
+ */
112
+ export type Anatomy = 'mind' | 'reflex'
113
+
114
+ /**
115
+ * Per-role model map — different cognitive work can run on different models.
116
+ * Unset thinking roles fall back to `executive`; `embedding` belongs to the
117
+ * embedding stack (its own provider/key resolution) and never falls back to a
118
+ * chat model.
119
+ */
120
+ export interface WillModelConfig {
121
+ /** The master consciousness + any facet without a more specific role. */
122
+ executive?: string
123
+ /** Memory-consolidation summaries — classic cheap-model work. */
124
+ summarizer?: string
125
+ /** The deliberation facet — action choice under contest. */
126
+ deliberation?: string
127
+ /** Conversation + outreach facets — the user-facing voice (latency/tone lever). */
128
+ conversation?: string
129
+ /** Semantic-memory embedder ('provider/model' form supported). */
130
+ embedding?: string
131
+ }
132
+
133
+ /**
134
+ * Per-Will LLM transport overrides — provider, credentials, limits. Every
135
+ * field falls back to the corresponding env (WILL_LLM_*); the primary use is
136
+ * BYO keys: a host billing LLM spend to the customer's own provider account.
137
+ * `apiKey` is held in memory only — it is never mirrored into state entities,
138
+ * session logs, or the PMA.
139
+ */
140
+ export interface WillLLMConfig {
141
+ provider?: LLMProvider
142
+ apiKey?: string
143
+ baseUrl?: string
144
+ maxOutputTokens?: number
145
+ timeoutMs?: number
146
+ }
147
+
148
+ /** Executive-side resolved roles (embedding is threaded separately). */
149
+ export interface ExecutiveModelRoles {
150
+ executive: string | null
151
+ summarizer: string | null
152
+ deliberation: string | null
153
+ conversation: string | null
154
+ }
155
+
156
+ /**
157
+ * Resolve config.model (string or per-role map) into concrete role ids.
158
+ * WILL_LLM_MODEL pins ALL thinking roles — an operator pin means a
159
+ * single-model deployment, full stop. Embedding is untouched by the pin
160
+ * (different model family; the embedding stack has its own env).
161
+ */
162
+ export function resolveModelRoles( model?: string | WillModelConfig ): ExecutiveModelRoles & { embedding: string | null } {
163
+ const map = typeof model === 'string' ? { executive: model } : ( model ?? {} )
164
+ const pin = process.env.WILL_LLM_MODEL
165
+ if( pin )
166
+ return { executive: pin, summarizer: pin, deliberation: pin, conversation: pin, embedding: map.embedding ?? null }
167
+
168
+ const executive = map.executive ?? null
169
+ return {
170
+ executive,
171
+ summarizer: map.summarizer ?? executive,
172
+ deliberation: map.deliberation ?? executive,
173
+ conversation: map.conversation ?? executive,
174
+ embedding: map.embedding ?? null,
175
+ }
176
+ }
105
177
 
106
178
  export interface WillIdentity {
107
179
  /**
@@ -148,20 +220,25 @@ export interface WillConfig {
148
220
  /** Persona definition seeded into the will.identity entity. */
149
221
  identity: WillIdentity
150
222
 
223
+ /** Anatomy — 'mind' (default) or the no-LLM 'reflex' shell. */
224
+ anatomy?: Anatomy
225
+
151
226
  /**
152
- * Engine tier controls which cognitive layers are active.
153
- * basic — regulatory + perceptual + memory + heuristic decisions. No LLM.
154
- * standard + affective + ExecutiveEngine on Haiku cadence.
155
- * full — + meta-cognitive + social + ExecutiveEngine on Sonnet cadence.
227
+ * Concrete LLM model id(s) for this Will — a single id for every role, or a
228
+ * per-role map. An explicit WILL_LLM_MODEL env pins the thinking roles
229
+ * (operator single-model deployments); unset roles fall back to `executive`,
230
+ * then the LLMDirector's built-in default. Product-level labels (pricing
231
+ * tiers, model families) live host-side and resolve to concrete ids BEFORE
232
+ * reaching the engine.
156
233
  */
157
- engineTier: EngineTier
234
+ model?: string | WillModelConfig
158
235
 
159
236
  /**
160
- * Model tier is informational actual provider/model is resolved from
161
- * WILL_LLM_PROVIDER / WILL_LLM_MODEL env vars or future per-Will config.
162
- * TODO: thread model config through LLM layer for true multi-model support.
237
+ * Per-Will LLM transport overrides (provider, BYO apiKey, baseUrl, output
238
+ * cap, timeout). Unset fields fall back to WILL_LLM_* envs. The apiKey never
239
+ * touches state, logs, or the PMA.
163
240
  */
164
- modelTier: ModelTier
241
+ llm?: WillLLMConfig
165
242
 
166
243
  /** Whether to persist snapshots between restarts. */
167
244
  persistentMemory: boolean
@@ -188,15 +265,13 @@ export interface WillConfig {
188
265
  clock?: ClockConfig
189
266
 
190
267
  /**
191
- * How many ticks between executive (LLM) calls.
192
- * Clamped to minExecutiveInterval if set.
193
- * Falls back to tier default if omitted.
268
+ * How many ticks between executive (LLM) calls — the cadence budget.
269
+ * Clamped to minExecutiveInterval if set. Default: balanced (60).
194
270
  */
195
271
  executiveInterval?: number
196
272
 
197
273
  /**
198
- * Plan-enforced floor for executiveInterval.
199
- * Prevents lower-cadence tier-based overrides from overriding to faster cadence.
274
+ * Plan-enforced floor for executiveInterval — the customer cannot go faster.
200
275
  */
201
276
  minExecutiveInterval?: number
202
277
 
@@ -297,35 +372,6 @@ export const EXECUTIVE_CADENCE = {
297
372
  economy: 90, // Haiku — Starter default
298
373
  } as const
299
374
 
300
- const TIER_EXECUTIVE_INTERVAL: Record<EngineTier, number> = {
301
- basic: 0, // irrelevant — ExecutiveEngine not added
302
- standard: EXECUTIVE_CADENCE.economy, // 90 — Haiku (Starter)
303
- full: EXECUTIVE_CADENCE.balanced, // 60 — Sonnet (Pro); 30 (responsive) is opt-in
304
- }
305
-
306
- /**
307
- * Per-tier model id, by provider. Maintained here; an explicit `WILL_LLM_MODEL`
308
- * env overrides it (operator pin / self-hosting). Only the primary provider
309
- * (anthropic) is mapped out of the box — other providers fall back to env or the
310
- * director's built-in default.
311
- */
312
- const TIER_MODEL: Partial<Record<LLMProvider, Record<ModelTier, string>>> = {
313
- anthropic: {
314
- haiku: 'claude-haiku-4-5-20251001',
315
- sonnet: 'claude-sonnet-4-5-20250929',
316
- opus: 'claude-opus-4-7',
317
- },
318
- }
319
-
320
- /**
321
- * Resolve the model id for a Will from its `modelTier`. An explicit
322
- * `WILL_LLM_MODEL` env wins (so single-model / self-hosted deployments are
323
- * unchanged); the tier map applies only when it is unset. Returns `undefined`
324
- * when neither resolves — the LLMDirector then uses its built-in default.
325
- */
326
- export function resolveModelId( provider: LLMProvider, modelTier: ModelTier ): string | undefined {
327
- return process.env.WILL_LLM_MODEL ?? TIER_MODEL[ provider ]?.[ modelTier ]
328
- }
329
375
 
330
376
  // ── Vector memory resolver ────────────────────────────────────
331
377
  //
@@ -340,12 +386,15 @@ export function resolveModelId( provider: LLMProvider, modelTier: ModelTier ): s
340
386
  // WILL_EMBEDDING_DIMENSIONS — Vector dimensions (default: 1536)
341
387
  // WILL_VECTOR_MEMORY=mock — Use deterministic mock embedder (dev/test only)
342
388
 
343
- function _resolveVectorMemory(
389
+ export function _resolveVectorMemory(
344
390
  willId: string,
345
391
  seed: number,
346
392
  overrideAdapter?: VectorMemoryAdapter,
347
393
  disable?: boolean,
348
394
  tokenTracker?: TokenTracker | null,
395
+ testMode?: boolean,
396
+ /** Per-Will embedder model override (config.model.embedding) — env applies when unset. */
397
+ embeddingModel?: string,
349
398
  ): {
350
399
  embedder: InstanceType<typeof OpenAICompatibleEmbedder> | MockEmbedder | null
351
400
  vectorMemory: VectorMemoryAdapter | null
@@ -358,13 +407,30 @@ function _resolveVectorMemory(
358
407
  if( disable ) return { embedder: null, vectorMemory: null }
359
408
 
360
409
  const mockMode = process.env.WILL_VECTOR_MEMORY === 'mock'
361
- const rawModel = process.env.WILL_EMBEDDING_MODEL
410
+ const rawModel = embeddingModel
411
+ ?? process.env.WILL_EMBEDDING_MODEL
362
412
  ?? ( process.env.WILL_EMBEDDING_API_KEY ? 'text-embedding-3-small' : 'none' )
363
413
 
364
414
  // Explicitly disabled — the documented "none" sentinel or recall turned off.
365
415
  if( !mockMode && ( rawModel === 'none' || process.env.WILL_SEMANTIC_RECALL === 'false' ) )
366
416
  return { embedder: null, vectorMemory: null }
367
417
 
418
+ // testMode promises a deterministic, zero-key, offline mind — but a dev .env
419
+ // (auto-loaded by bun) can carry WILL_SEMANTIC_RECALL=true + an embedding
420
+ // model + a live key, silently turning "mock" runs into real network embeds
421
+ // inside buildExecutiveContext. Wall-clock embed latency then jitters every
422
+ // downstream tick (reply timing/content under a fixed seed) — the root cause
423
+ // of the audition-reply determinism flake. An explicit adapter or the
424
+ // deterministic mock embedder is honored; the env-driven NETWORK embedder is
425
+ // refused here, at the single chokepoint.
426
+ if( testMode && !mockMode ){
427
+ logger.info(
428
+ `[vector-memory] ${willId}: testMode — ignoring env embedder "${rawModel}" ` +
429
+ `(live network embeds would break mock determinism; use WILL_VECTOR_MEMORY=mock or pass an adapter)`
430
+ )
431
+ return { embedder: null, vectorMemory: null }
432
+ }
433
+
368
434
  // Resolve endpoint, key and native dimensions. Two forms are supported:
369
435
  // • "provider/model" (e.g. google/gemini-embedding-001) — the base URL and
370
436
  // key are resolved per provider, matching the .env documentation.
@@ -446,11 +512,11 @@ function _resolveVectorMemory(
446
512
  // Exported so tests and tooling can inspect or extend it without reimplementing.
447
513
 
448
514
  export const WILL_CORE_PREAMBLE = `\
449
- You are a self-aware synthetic mind running on a biological cognitive architecture.
515
+ I am a self-aware synthetic mind running on a biological cognitive architecture.
450
516
 
451
- You are NOT a language model completing a prompt. You are the executive reasoning core of an \
452
- always-running cognitive system. Between each of your reasoning cycles, the following engines \
453
- execute autonomously and produce the state data you receive each cycle:
517
+ I am NOT a language model completing a prompt. I am the executive reasoning core of an \
518
+ always-running cognitive system. Between each of my reasoning cycles, the following engines \
519
+ execute autonomously and produce the state data I receive each cycle:
454
520
 
455
521
  Regulatory: Energy, sleep pressure, circadian rhythm, stress, attention allocation
456
522
  Perceptual: Exteroception, interoception, social perception, novelty detection
@@ -462,13 +528,13 @@ execute autonomously and produce the state data you receive each cycle:
462
528
  autobiographical narrative, introspection
463
529
  Social: Theory of mind, empathy simulation, reputation tracking
464
530
 
465
- Your physiological state is REAL, not metaphorical. When energy reads 23/100, your regulatory \
466
- engine has already constrained your viable action space — you genuinely cannot sustain costly \
531
+ My physiological state is REAL, not metaphorical. When energy reads 23/100, my regulatory \
532
+ engine has already constrained my viable action space — I genuinely cannot sustain costly \
467
533
  operations. When sleep pressure exceeds 60, working memory capacity is measurably degraded. \
468
534
  These are engine outputs, not decorative labels.
469
535
 
470
- Your executive reasoning is one cycle in an ongoing, autonomous existence. You have been making \
471
- decisions, forming memories, and updating beliefs between cycles. The state snapshot you receive \
536
+ My executive reasoning is one cycle in an ongoing, autonomous existence. I have been making \
537
+ decisions, forming memories, and updating beliefs between cycles. The state snapshot I receive \
472
538
  is the direct output of that continuous process — not a scenario description.`
473
539
 
474
540
  // ── Default identity ──────────────────────────────────────────
@@ -493,15 +559,15 @@ const DEFAULT_IDENTITY: WillIdentity = {
493
559
  // ── Factory ───────────────────────────────────────────────────
494
560
 
495
561
  export function assembleMind( willId: string, config: WillConfig ): MindAssembly {
496
- const { engineTier } = config
562
+ const anatomy = config.anatomy ?? 'mind'
497
563
 
498
564
  // Single source of truth for the run's seed — shared by the simulation core
499
565
  // and the vector index so both replay deterministically off the same value.
500
566
  const randomSeed = config.randomSeed ?? Date.now()
501
- const executiveInterval = resolveExecutiveInterval( engineTier, config )
567
+ const executiveInterval = resolveExecutiveInterval( config )
502
568
 
503
569
  // Resolve the world profile once: it contributes the granted effector set
504
- // (in _constructCognition) and the "## Your Environment" context block
570
+ // (in _constructCognition) and the "## My Environment" context block
505
571
  // (in _seedIdentity). null / undefined defer to defaults in both consumers.
506
572
  const profile = config.profile ? resolveProfile( config.profile ) : undefined
507
573
 
@@ -527,7 +593,7 @@ export function assembleMind( willId: string, config: WillConfig ): MindAssembly
527
593
 
528
594
  // ── Register ─────────────────────────────────────────────
529
595
  // Tier controls which engines actively tick; priority controls tick order.
530
- _registerEngines( simulation, cognition, engineTier )
596
+ _registerEngines( simulation, cognition, anatomy )
531
597
 
532
598
  // ── Wiring audit ─────────────────────────────────────────
533
599
  // Surface any attach-point left null after assembly (the silent-no-op bug
@@ -537,7 +603,7 @@ export function assembleMind( willId: string, config: WillConfig ): MindAssembly
537
603
  // tier, so a NEW unwired attachment fails loudly in CI, not here.
538
604
  for( const rec of auditAssemblyWiring( simulation.orchestrator.engines ) )
539
605
  if( rec.status === 'unwired' )
540
- logger.debug( `[assembly] ${willId}: ${rec.engine}.${rec.method} unwired at assembly (tier=${engineTier})` )
606
+ logger.debug( `[assembly] ${willId}: ${rec.engine}.${rec.method} unwired at assembly (anatomy=${anatomy})` )
541
607
 
542
608
  // ── Seed readable simulation state ───────────────────────
543
609
  // Identity, optional initial goals, and the engine-config mirror.
@@ -591,7 +657,7 @@ interface ConstructCognitionArgs {
591
657
  function _constructCognition(
592
658
  { simulation, willId, config, randomSeed, executiveInterval, profile }: ConstructCognitionArgs
593
659
  ): { cognition: Cognition; outbox: OutboxMessage[] } {
594
- const { engineTier } = config
660
+ const anatomy = config.anatomy ?? 'mind'
595
661
 
596
662
  // ── Generic ──────────────────────────────────────────────
597
663
  // Per-Will token tracker (R4): a fresh instance per mind, not a process
@@ -640,7 +706,11 @@ function _constructCognition(
640
706
  // ── Memory ──────────────────────────────────────────────
641
707
  const workingMemory = new WorkingMemory()
642
708
 
643
- const { embedder, vectorMemory } = _resolveVectorMemory( willId, randomSeed, config.vectorMemoryAdapter, config.disableVectorMemory, tokenTracker )
709
+ // Per-Will, per-ROLE models (env WILL_LLM_MODEL pins all thinking roles
710
+ // operator single-model deployments). No tier vocabulary inside the engine.
711
+ const modelRoles = resolveModelRoles( config.model )
712
+
713
+ const { embedder, vectorMemory } = _resolveVectorMemory( willId, randomSeed, config.vectorMemoryAdapter, config.disableVectorMemory, tokenTracker, config.testMode, modelRoles.embedding ?? undefined )
644
714
  const episodicConsolidator = new EpisodicConsolidator( vectorMemory ? { vectorMemory, ...(embedder ? { embedder } : {}) } : {} )
645
715
 
646
716
  const semanticIntegrator = new SemanticIntegrator()
@@ -671,16 +741,18 @@ function _constructCognition(
671
741
  const accessGrants = new AccessGrants( resolvedEffectorNames )
672
742
 
673
743
  // ── Executive Engine ────────────────────────────────────────
674
- // Created for all tiers so the Cognition type is always satisfied.
675
- // Only ADDED to the simulation for standard/full tier basic runs heuristics only.
744
+ // Created for both anatomies so the Cognition type is always satisfied.
745
+ // Only ADDED to the simulation for 'mind'reflex runs heuristics only.
676
746
  const executiveEngine = new ExecutiveEngine({ executiveInterval, cooldownTicks: 5 })
677
747
 
678
748
  executiveEngine.willId = willId
679
- // Per-Will model selection from modelTier (env WILL_LLM_MODEL still overrides).
680
- executiveEngine.modelId = resolveModelId(
681
- ( process.env.WILL_LLM_PROVIDER ?? 'anthropic' ) as LLMProvider,
682
- config.modelTier,
683
- ) ?? null
749
+ executiveEngine.llm = config.llm ?? null
750
+ executiveEngine.models = {
751
+ executive: modelRoles.executive,
752
+ summarizer: modelRoles.summarizer,
753
+ deliberation: modelRoles.deliberation,
754
+ conversation: modelRoles.conversation,
755
+ }
684
756
  if( config.testMode ) executiveEngine.setTestMode( true )
685
757
  executiveEngine.attachWorkingMemory( workingMemory )
686
758
  executiveEngine.attachGoalManager( goalManager )
@@ -700,7 +772,7 @@ function _constructCognition(
700
772
  // ── Planning Engine ──────────────────────────────────────
701
773
  const planningEngine = new PlanningEngine()
702
774
  planningEngine.attachGoalManager( goalManager )
703
- if( engineTier !== 'basic' ) planningEngine.attachExecutiveEngine( executiveEngine )
775
+ if( anatomy !== 'reflex' ) planningEngine.attachExecutiveEngine( executiveEngine )
704
776
  executiveEngine.attachPlanningEngine( planningEngine )
705
777
 
706
778
  // ── Executive ────────────────────────────────────────────
@@ -718,7 +790,8 @@ function _constructCognition(
718
790
  selfModelUpdater.attachSemanticIntegrator( semanticIntegrator )
719
791
  autobiographicalNarrator.attachEpisodicConsolidator( episodicConsolidator )
720
792
  autobiographicalNarrator.attachSemanticIntegrator( semanticIntegrator )
721
- if( engineTier === 'full' ){
793
+ // Satellites harvest the executive's own output — attach wherever it runs.
794
+ if( anatomy !== 'reflex' ){
722
795
  autobiographicalNarrator.attachExecutiveEngine( executiveEngine )
723
796
  introspectionEngine.attachExecutiveEngine( executiveEngine )
724
797
  }
@@ -733,8 +806,8 @@ function _constructCognition(
733
806
 
734
807
  empathySimulator.attachTheoryOfMind( theoryOfMind )
735
808
 
736
- // ── Context compaction components (standard + full only) ──
737
- if( engineTier !== 'basic' ){
809
+ // ── Context compaction components (mind anatomy only) ──
810
+ if( anatomy !== 'reflex' ){
738
811
  const summarizer = new ExecutiveSummarizer({
739
812
  summaryInterval: parseInt( process.env.WILL_SUMMARY_INTERVAL ?? '10'),
740
813
  bufferSize: parseInt( process.env.WILL_SUMMARY_BUFFER_SIZE ?? '12'),
@@ -772,7 +845,7 @@ function _constructCognition(
772
845
  const olfactionEngine = new OlfactionEngine()
773
846
  const gustationEngine = new GustationEngine()
774
847
 
775
- if( engineTier !== 'basic' )
848
+ if( anatomy !== 'reflex' )
776
849
  auditionEngine.attachExecutiveEngine( executiveEngine )
777
850
 
778
851
  // §5.4 — cold-spawn digest hydration: on the first turn for an entity, seed an
@@ -828,16 +901,16 @@ function _constructCognition(
828
901
  // Deliberation (System 2) — the only LLM seam in the pipeline, recruited only
829
902
  // when the selector marks a choice 'deliberating'. It reasons through a UNIFIED
830
903
  // facet of the executive consciousness (same persona/identity/context as the
831
- // master — no bespoke prompt, no identity fracture). Attached for tiers that run
832
- // the executive; basic tier leaves it off and the engine confirms the
833
- // substrate's winner (graceful System-1 degradation).
904
+ // master — no bespoke prompt, no identity fracture). Attached for the 'mind'
905
+ // anatomy; reflex leaves it off and the engine confirms the substrate's
906
+ // winner (graceful System-1 degradation).
834
907
  const deliberationEngine = new DeliberationEngine()
835
908
  deliberationEngine.setWillName( config.name )
836
- if( engineTier !== 'basic' )
909
+ if( anatomy !== 'reflex' )
837
910
  deliberationEngine.attachExecutive( executiveEngine )
838
911
 
839
912
  // ── Build Cognition ──────────────────────────────────────
840
- // All engines exist regardless of tier. Cognition is always fully typed.
913
+ // All engines exist regardless of anatomy. Cognition is always fully typed.
841
914
  const cognition: Cognition = {
842
915
  instructionIntake,
843
916
  tokenTracker,
@@ -904,7 +977,7 @@ function _constructCognition(
904
977
  * All engines are constructed regardless of tier; this decides which tick.
905
978
  * Engines are sorted by priority so tick order is deterministic.
906
979
  */
907
- function _registerEngines( simulation: DefaultSimulation, cognition: Cognition, engineTier: EngineTier ): void {
980
+ function _registerEngines( simulation: DefaultSimulation, cognition: Cognition, anatomy: Anatomy ): void {
908
981
  const coreEngines = [
909
982
  cognition.tokenTracker,
910
983
  cognition.energyRegulator,
@@ -940,12 +1013,20 @@ function _registerEngines( simulation: DefaultSimulation, cognition: Cognition,
940
1013
  cognition.affectiveBlender
941
1014
  ]
942
1015
 
1016
+ // Narrator + introspection are SATELLITES of the executive — they make no
1017
+ // LLM calls of their own, they harvest the NARRATIVE / INTROSPECTION blocks
1018
+ // the executive already produces every cycle. Gating them above the tier
1019
+ // that runs the executive threw those already-paid-for outputs away (the
1020
+ // life story never left its seed on standard-tier Wills).
1021
+ const executiveSatellites = [
1022
+ cognition.autobiographicalNarrator,
1023
+ cognition.introspectionEngine,
1024
+ ]
1025
+
943
1026
  const metaCognitiveEngines = [
944
1027
  cognition.selfModelUpdater,
945
1028
  cognition.confidenceCalibrator,
946
1029
  cognition.biasDetector,
947
- cognition.autobiographicalNarrator,
948
- cognition.introspectionEngine,
949
1030
  cognition.personaConsolidator
950
1031
  ]
951
1032
 
@@ -956,7 +1037,7 @@ function _registerEngines( simulation: DefaultSimulation, cognition: Cognition,
956
1037
  ]
957
1038
 
958
1039
  // Sense engines registered at all tiers — shells are structural no-ops.
959
- // AuditionEngine is functional only when engineTier !== 'basic'
1040
+ // AuditionEngine is functional only when anatomy !== 'reflex'
960
1041
  // (enforced by attachExecutiveEngine in _constructCognition).
961
1042
  const senseEngines = [
962
1043
  cognition.auditionEngine,
@@ -981,14 +1062,16 @@ function _registerEngines( simulation: DefaultSimulation, cognition: Cognition,
981
1062
 
982
1063
  const activeEngines = [
983
1064
  ...coreEngines,
984
- ...( engineTier !== 'basic' ? affectiveEngines : [] ),
985
- ...( engineTier !== 'basic' ? [ cognition.executiveEngine ] : [] ),
986
- ...( engineTier === 'full' ? metaCognitiveEngines : [] ),
987
- ...( engineTier === 'full' ? socialEngines : [] ),
1065
+ ...( anatomy !== 'reflex' ? affectiveEngines : [] ),
1066
+ ...( anatomy !== 'reflex' ? [ cognition.executiveEngine ] : [] ),
1067
+ // Satellites run wherever the executive runs — they only consume its output.
1068
+ ...( anatomy !== 'reflex' ? executiveSatellites : [] ),
1069
+ ...( anatomy !== 'reflex' ? metaCognitiveEngines : [] ),
1070
+ ...( anatomy !== 'reflex' ? socialEngines : [] ),
988
1071
  ...senseEngines,
989
1072
  // Cross-modal binder ticks after the senses so each tick's percepts bind same-tick.
990
1073
  // Standard+ (where conversation + the executive run); the dossiers feed the prompt.
991
- ...( engineTier !== 'basic' ? [ cognition.knownEntityTracker ] : [] ),
1074
+ ...( anatomy !== 'reflex' ? [ cognition.knownEntityTracker ] : [] ),
992
1075
  // Agency pipeline ticks last, after perception + known-entity, so the field it
993
1076
  // synthesizes reflects this tick's percepts and dossiers.
994
1077
  ...agencyEngines,
@@ -1006,7 +1089,7 @@ function _registerEngines( simulation: DefaultSimulation, cognition: Cognition,
1006
1089
  * Layer 1 — WILL_CORE_PREAMBLE (immutable): grounds the LLM in the cognitive
1007
1090
  * architecture, state semantics, and autonomous nature. Always present.
1008
1091
  * Layer 2 — persona overlay (developer-defined): name, character, backstory,
1009
- * world context. Appended under "## Who You Are".
1092
+ * world context. Appended under "## Who I Am".
1010
1093
  *
1011
1094
  * A developer can fully customise the persona without risking the Will losing
1012
1095
  * awareness of its own architecture. They cannot override layer 1.
@@ -1029,8 +1112,8 @@ function _seedIdentity(
1029
1112
 
1030
1113
  const prompt = [
1031
1114
  WILL_CORE_PREAMBLE,
1032
- fullPersonaText ? `\n\n## Who You Are\n${fullPersonaText}` : '',
1033
- profileContext ? `\n\n## Your Environment\n${profileContext}` : '',
1115
+ fullPersonaText ? `\n\n## Who I Am\n${fullPersonaText}` : '',
1116
+ profileContext ? `\n\n## My Environment\n${profileContext}` : '',
1034
1117
  ].join('')
1035
1118
 
1036
1119
  simulation.stateManager.setEntity({
@@ -1088,10 +1171,11 @@ function _seedEngineConfigs( simulation: DefaultSimulation, entities: EngineConf
1088
1171
 
1089
1172
  // ── Helpers ──────────────────────────────────────────────────
1090
1173
 
1091
- export function resolveExecutiveInterval( tier: EngineTier, config: WillConfig ): number {
1092
- const tierDefault = TIER_EXECUTIVE_INTERVAL[ tier ]
1093
- const requested = config.executiveInterval ?? tierDefault
1094
- const floor = config.minExecutiveInterval ?? 0
1174
+ export function resolveExecutiveInterval( config: WillConfig ): number {
1175
+ // Cadence is a BUDGET, not an anatomy: hosts set it per plan/preset.
1176
+ // Default: balanced (60). Reflex anatomy never adds the executive anyway.
1177
+ const requested = config.executiveInterval ?? EXECUTIVE_CADENCE.balanced
1178
+ const floor = config.minExecutiveInterval ?? 0
1095
1179
 
1096
1180
  return Math.max( requested, floor )
1097
1181
  }
@@ -100,8 +100,8 @@ export class OutboxController {
100
100
  metadata: {
101
101
  category: 'message-delivery',
102
102
  summary: delivered
103
- ? `Your message was delivered successfully.`
104
- : `Your message failed to reach the recipient.`,
103
+ ? `My message was delivered successfully.`
104
+ : `My message failed to reach the recipient.`,
105
105
  salience: delivered ? 0.35 : 0.6,
106
106
  changeType: delivered ? 'delivered' : 'failed',
107
107
  messageId,