@mindot/will 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +777 -0
  3. package/dist/index.d.ts +8144 -0
  4. package/dist/index.js +26231 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +73 -0
  7. package/src/cognition/agency/access.grants.ts +59 -0
  8. package/src/cognition/agency/competence.codec.ts +89 -0
  9. package/src/cognition/agency/engines/action.selector.ts +462 -0
  10. package/src/cognition/agency/engines/affordance.synthesizer.ts +384 -0
  11. package/src/cognition/agency/engines/deliberation.engine.ts +241 -0
  12. package/src/cognition/agency/engines/instruction.intake.ts +54 -0
  13. package/src/cognition/agency/engines/motor.schema.executor.ts +532 -0
  14. package/src/cognition/agency/engines/reafference.engine.ts +241 -0
  15. package/src/cognition/agency/execution.primitives.ts +118 -0
  16. package/src/cognition/agency/index.ts +58 -0
  17. package/src/cognition/agency/proactive.communicator.ts +274 -0
  18. package/src/cognition/agency/reconcile.learning.ts +82 -0
  19. package/src/cognition/agency/schemas/external.ts +59 -0
  20. package/src/cognition/agency/schemas/innate.ts +111 -0
  21. package/src/cognition/agency/schemas/repertoire.ts +246 -0
  22. package/src/cognition/agency/selection.scoring.ts +191 -0
  23. package/src/cognition/agency/types.ts +165 -0
  24. package/src/cognition/bus.ts +391 -0
  25. package/src/cognition/completion.inbox.ts +86 -0
  26. package/src/cognition/config.mirror.entities.ts +475 -0
  27. package/src/cognition/conversation.memory.ts +81 -0
  28. package/src/cognition/event.log.ts +116 -0
  29. package/src/cognition/event.schemas.ts +568 -0
  30. package/src/cognition/faculties/aesthetic.evaluator.ts +313 -0
  31. package/src/cognition/faculties/affective.blender.ts +562 -0
  32. package/src/cognition/faculties/attachment.evaluator.ts +432 -0
  33. package/src/cognition/faculties/attention.allocator.ts +422 -0
  34. package/src/cognition/faculties/autobiographical.narrator.ts +300 -0
  35. package/src/cognition/faculties/bias.detector.ts +363 -0
  36. package/src/cognition/faculties/circadian.oscillator.ts +294 -0
  37. package/src/cognition/faculties/confidence.calibrator.ts +324 -0
  38. package/src/cognition/faculties/dream.simulator.ts +251 -0
  39. package/src/cognition/faculties/empathy.simulator.ts +253 -0
  40. package/src/cognition/faculties/energy.regulator.ts +320 -0
  41. package/src/cognition/faculties/episodic.consolidator.ts +728 -0
  42. package/src/cognition/faculties/executive.engine/commands.ts +459 -0
  43. package/src/cognition/faculties/executive.engine/config.ts +46 -0
  44. package/src/cognition/faculties/executive.engine/context.ts +605 -0
  45. package/src/cognition/faculties/executive.engine/deferred.effects.ts +104 -0
  46. package/src/cognition/faculties/executive.engine/deliberate.reasoning.ts +60 -0
  47. package/src/cognition/faculties/executive.engine/effort.gate.ts +114 -0
  48. package/src/cognition/faculties/executive.engine/engine.ts +1028 -0
  49. package/src/cognition/faculties/executive.engine/escalation.buffer.ts +90 -0
  50. package/src/cognition/faculties/executive.engine/facet.supervisor.ts +271 -0
  51. package/src/cognition/faculties/executive.engine/facet.ts +628 -0
  52. package/src/cognition/faculties/executive.engine/gating.ts +222 -0
  53. package/src/cognition/faculties/executive.engine/index.ts +6 -0
  54. package/src/cognition/faculties/executive.engine/messages.ts +102 -0
  55. package/src/cognition/faculties/executive.engine/parser.ts +380 -0
  56. package/src/cognition/faculties/executive.engine/prompt.factory.ts +1053 -0
  57. package/src/cognition/faculties/executive.engine/types.ts +323 -0
  58. package/src/cognition/faculties/exteroception.ts +338 -0
  59. package/src/cognition/faculties/forgetting.curve.ts +202 -0
  60. package/src/cognition/faculties/frustration.evaluator.ts +280 -0
  61. package/src/cognition/faculties/goal.manager.ts +1008 -0
  62. package/src/cognition/faculties/inhibition.controller.ts +351 -0
  63. package/src/cognition/faculties/interoception.ts +417 -0
  64. package/src/cognition/faculties/introspection.engine.ts +246 -0
  65. package/src/cognition/faculties/known.entity.tracker.ts +439 -0
  66. package/src/cognition/faculties/loss.evaluator.ts +224 -0
  67. package/src/cognition/faculties/moral.evaluator.ts +437 -0
  68. package/src/cognition/faculties/novelty.detector.ts +254 -0
  69. package/src/cognition/faculties/persona.consolidator.ts +845 -0
  70. package/src/cognition/faculties/planning.engine/engine.ts +859 -0
  71. package/src/cognition/faculties/planning.engine/plan.frontier.ts +83 -0
  72. package/src/cognition/faculties/planning.engine/plan.store.ts +174 -0
  73. package/src/cognition/faculties/planning.engine/plan.supervision.ts +494 -0
  74. package/src/cognition/faculties/planning.engine/types.ts +143 -0
  75. package/src/cognition/faculties/reputation.tracker.ts +294 -0
  76. package/src/cognition/faculties/reward.evaluator.ts +304 -0
  77. package/src/cognition/faculties/self.model.updater.ts +677 -0
  78. package/src/cognition/faculties/semantic.engine/clustering.ts +673 -0
  79. package/src/cognition/faculties/semantic.engine/index.ts +6 -0
  80. package/src/cognition/faculties/semantic.engine/integrator.ts +750 -0
  81. package/src/cognition/faculties/semantic.engine/types.ts +53 -0
  82. package/src/cognition/faculties/sleep.pressure.regulator.ts +262 -0
  83. package/src/cognition/faculties/social.perception.ts +333 -0
  84. package/src/cognition/faculties/spaced.repetition.ts +605 -0
  85. package/src/cognition/faculties/stress.regulator.ts +375 -0
  86. package/src/cognition/faculties/task.switcher.ts +239 -0
  87. package/src/cognition/faculties/theory.of.mind.ts +333 -0
  88. package/src/cognition/faculties/threat.evaluator.ts +312 -0
  89. package/src/cognition/faculties/working.memory.ts +406 -0
  90. package/src/cognition/generative.model.ts +344 -0
  91. package/src/cognition/heartbeat.ts +70 -0
  92. package/src/cognition/index.ts +291 -0
  93. package/src/cognition/instruction.handler.ts +146 -0
  94. package/src/cognition/memory/index.ts +35 -0
  95. package/src/cognition/memory/vector.adapter.ts +316 -0
  96. package/src/cognition/memory/vector.content.ts +47 -0
  97. package/src/cognition/memory/vector.embedder.ts +212 -0
  98. package/src/cognition/memory/vector.index.ts +459 -0
  99. package/src/cognition/memory/vector.types.ts +65 -0
  100. package/src/cognition/orchestrator.ts +142 -0
  101. package/src/cognition/persona.prior.ts +265 -0
  102. package/src/cognition/schema.registry.ts +145 -0
  103. package/src/cognition/senses/audition.engine/engine.ts +976 -0
  104. package/src/cognition/senses/audition.engine/salience.ts +59 -0
  105. package/src/cognition/senses/base.sense.engine.ts +117 -0
  106. package/src/cognition/senses/gustation.engine.ts +24 -0
  107. package/src/cognition/senses/index.ts +172 -0
  108. package/src/cognition/senses/olfaction.engine.ts +24 -0
  109. package/src/cognition/senses/somatosensation.engine.ts +23 -0
  110. package/src/cognition/senses/vision.engine.ts +23 -0
  111. package/src/cognition/types.ts +63 -0
  112. package/src/cognition/utilities/token.tracker.ts +492 -0
  113. package/src/core/abstracts.ts +60 -0
  114. package/src/core/async.engine.ts +539 -0
  115. package/src/core/clock.ts +196 -0
  116. package/src/core/completion.recorder.ts +122 -0
  117. package/src/core/conflict.detector.ts +140 -0
  118. package/src/core/distributed.ts +626 -0
  119. package/src/core/event.bus.ts +292 -0
  120. package/src/core/inbound.recorder.ts +100 -0
  121. package/src/core/index.ts +167 -0
  122. package/src/core/logger.ts +85 -0
  123. package/src/core/metrics.ts +107 -0
  124. package/src/core/orchestrator.ts +625 -0
  125. package/src/core/replay.ts +589 -0
  126. package/src/core/scenario.ts +120 -0
  127. package/src/core/serialization.ts +448 -0
  128. package/src/core/simulation.ts +197 -0
  129. package/src/core/snapshot.manager.ts +293 -0
  130. package/src/core/state.manager.ts +283 -0
  131. package/src/core/types.ts +274 -0
  132. package/src/core/utils.ts +82 -0
  133. package/src/core/wall.clock.ts +23 -0
  134. package/src/extensions/livestream.ext.ts +570 -0
  135. package/src/extensions/time.ext.ts +339 -0
  136. package/src/index.ts +91 -0
  137. package/src/llm/gate.ts +140 -0
  138. package/src/llm/index.ts +716 -0
  139. package/src/llm/summarizer.ts +170 -0
  140. package/src/llm/wire.contracts.ts +67 -0
  141. package/src/pma/eval.ts +651 -0
  142. package/src/pma/index.ts +1082 -0
  143. package/src/profiles/built-in.ts +7 -0
  144. package/src/profiles/companion.ts +28 -0
  145. package/src/profiles/company-brain.ts +54 -0
  146. package/src/profiles/customer-service.ts +30 -0
  147. package/src/profiles/game-npc.ts +20 -0
  148. package/src/profiles/index.ts +42 -0
  149. package/src/profiles/smart-home.ts +34 -0
  150. package/src/runners/coherence.runner.ts +49 -0
  151. package/src/runners/outreach.runner.ts +158 -0
  152. package/src/runners/social.runner.ts +182 -0
  153. package/src/runners/thin-shim.runner.ts +195 -0
  154. package/src/sdk/will.ts +334 -0
  155. package/src/stem/assembly.audit.ts +88 -0
  156. package/src/stem/distribution.ts +203 -0
  157. package/src/stem/guards/identity.coherence.ts +152 -0
  158. package/src/stem/guards/identity.guard.ts +227 -0
  159. package/src/stem/index.ts +1145 -0
  160. package/src/stem/mind.ts +1090 -0
  161. package/src/stem/tracts/ack.reconciler.ts +55 -0
  162. package/src/stem/tracts/biography.writer.ts +190 -0
  163. package/src/stem/tracts/effector.controller.ts +143 -0
  164. package/src/stem/tracts/health.reporter.ts +113 -0
  165. package/src/stem/tracts/inbound.queue.ts +54 -0
  166. package/src/stem/tracts/outbox.controller.ts +167 -0
  167. package/src/stem/tracts/outbox.writer.ts +133 -0
  168. package/src/stem/tracts/pma.controller.ts +109 -0
  169. package/src/stem/tracts/replay.controller.ts +177 -0
  170. package/src/stem/tracts/sensory.controller.ts +168 -0
  171. package/src/stem/tracts/session.logger.ts +157 -0
  172. package/src/stem/tracts/transport/index.ts +38 -0
  173. package/src/stem/tracts/transport/loopback.transport.ts +86 -0
  174. package/src/stem/tracts/transport/socketio.transport.ts +200 -0
  175. package/src/stem/tracts/transport/stream.transport.ts +152 -0
  176. package/src/stem/tracts/transport/types.ts +193 -0
  177. package/src/stem/tracts/transport.controller.ts +380 -0
  178. package/src/types.ts +116 -0
@@ -0,0 +1,104 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // src/cognition/faculties/executive.engine/deferred.effects.ts
3
+ // ─────────────────────────────────────────────────────────────
4
+ //
5
+ // DeferredEffectQueue — commit-gated manager-write queue (FN11).
6
+ //
7
+ // buildStateCommands is pure: it returns entity/metric commands plus the
8
+ // mirroring manager writes (summarizer / goals / beliefs / effectors + the
9
+ // action-diversity ring buffer) as deferred thunks. Those thunks must run
10
+ // ONLY after the orchestrator confirms the tick committed — a pre-commit
11
+ // validator (e.g. the inhibition veto) can abort a tick and discard the
12
+ // commands, and we must not let the manager writes land for a tick whose
13
+ // entities were dropped.
14
+ //
15
+ // Commit is detected on the next react() via the committed
16
+ // `executive.last_tick` metric (set by buildStateCommands) matching the
17
+ // entry's observed tick.
18
+ //
19
+ // Extracted verbatim from ExecutiveEngine (R5-g-1) as a pure collaborator.
20
+ // ─────────────────────────────────────────────────────────────
21
+
22
+ import { logger } from '#core/logger'
23
+ import type { ReadonlySimulationState } from '#core/types'
24
+ import type { DeferredEffect } from '#faculties/executive.engine/commands'
25
+
26
+ interface DeferredEntry {
27
+ /** footprint.tickObserved — equals the committed `executive.last_tick`. */
28
+ observedTick: number
29
+ /** react() tick when the commands were returned (decision is made after this). */
30
+ queuedAtTick: number
31
+ effects: DeferredEffect[]
32
+ }
33
+
34
+ export class DeferredEffectQueue {
35
+ private _entries: DeferredEntry[] = []
36
+
37
+ /** The tick of the most recent react() call — the commit tick for queued effects. */
38
+ private _lastReactTick = -1
39
+
40
+ /**
41
+ * Record the current react() tick. Effects queued after this call are
42
+ * stamped with it as their `queuedAtTick`, so flush() knows to wait one
43
+ * more tick before deciding whether the tick committed.
44
+ */
45
+ markReactTick( tick: number ): void {
46
+ this._lastReactTick = tick
47
+ }
48
+
49
+ /**
50
+ * Queue commit-gated manager writes for `observedTick`. No-op when there
51
+ * are no effects to run.
52
+ */
53
+ enqueue( observedTick: number, effects: DeferredEffect[] ): void {
54
+ if( effects.length === 0 ) return
55
+ this._entries.push({
56
+ observedTick,
57
+ queuedAtTick: this._lastReactTick,
58
+ effects,
59
+ })
60
+ }
61
+
62
+ /**
63
+ * Run deferred manager writes for committed ticks; drop them for aborted ticks.
64
+ *
65
+ * An entry queued during react() at tick C is resolved on the *next* react:
66
+ * • committed `executive.last_tick === observedTick` → the commands landed,
67
+ * so run the mirroring manager writes.
68
+ * • the queuing tick has passed without that match → the tick was aborted
69
+ * (e.g. inhibition veto), so drop the writes — no compensation needed
70
+ * because the entity commands were discarded too.
71
+ */
72
+ flush( state: ReadonlySimulationState, currentTick: number ): void {
73
+ if( this._entries.length === 0 ) return
74
+
75
+ const committedTick = state.metrics.get( 'executive.last_tick' )
76
+ const keep: DeferredEntry[] = []
77
+
78
+ for( const entry of this._entries ){
79
+ // Not yet resolved — commands were returned this same tick; wait one tick
80
+ // for the orchestrator to commit (or abort) before deciding.
81
+ if( currentTick <= entry.queuedAtTick ){
82
+ keep.push( entry )
83
+ continue
84
+ }
85
+
86
+ if( committedTick === entry.observedTick ){
87
+ for( const effect of entry.effects ){
88
+ try { effect() }
89
+ catch( err ){
90
+ logger.error( `[executive] deferred effect failed (tick ${entry.observedTick}):`, err )
91
+ }
92
+ }
93
+ }
94
+ else {
95
+ logger.warn(
96
+ `[executive] dropping deferred manager writes for aborted tick ${entry.observedTick} ` +
97
+ `(committed executive tick: ${committedTick ?? 'none'})`
98
+ )
99
+ }
100
+ }
101
+
102
+ this._entries = keep
103
+ }
104
+ }
@@ -0,0 +1,60 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // src/cognition/faculties/executive.engine/deliberate.reasoning.ts
3
+ // ─────────────────────────────────────────────────────────────
4
+
5
+ /**
6
+ * Shared System 2 machinery for the master AND its facets.
7
+ *
8
+ * Facets are "the master over their focus" — they reason with the same PromptFactory +
9
+ * parser and make their own deliberate decision (e.g. a planning facet: replan / continue
10
+ * / abandon). So they deliberate the same way: an a-priori effort gate (`selectProcess`)
11
+ * picks fast vs deliberate, and on the deliberate path a *propose* pass generates a
12
+ * divergent candidate set that the *decision* pass weighs before committing.
13
+ *
14
+ * This module owns the one genuinely shared, new piece — the propose (ideation) pass —
15
+ * so master and facet share it rather than duplicating. Each caller keeps its own
16
+ * prompt-building, decision call (with its own streaming/logging), and parsing.
17
+ */
18
+
19
+ import type { LLMDirector, LLMCallMeta } from '#llm/index'
20
+ import type { IdeationCandidate } from '#faculties/executive.engine/types'
21
+ import { parseIdeation } from '#faculties/executive.engine/parser'
22
+
23
+ export interface ProposeParams {
24
+ director: LLMDirector
25
+ /** Same system prompt the decision pass uses — shares the prompt cache. */
26
+ systemPrompt: string
27
+ /** User message carrying the ideation output-format override (full context, asks for options). */
28
+ ideationUserMessage: string
29
+ tick: number
30
+ /** Elevated sampling temperature (creativity-driven) — diverge when proposing. */
31
+ proposeTemperature: number
32
+ /**
33
+ * Cost-attribution for the propose (ideation) pass. The caller passes its own
34
+ * attribution (master vs facet, with its scope) so the System-2 overhead is
35
+ * billed to the right bucket under `function: 'ideation'`. Defaults to the
36
+ * master executive when unset.
37
+ */
38
+ meta?: LLMCallMeta
39
+ }
40
+
41
+ /**
42
+ * Run the propose (ideation) pass: one non-streaming LLM call at elevated temperature,
43
+ * returning the parsed candidate set. The call is internal scratch (nothing streams to a
44
+ * user). A failure or empty parse degrades gracefully to `undefined`, so the caller then
45
+ * proceeds exactly as System 1 (no candidates injected). R2-safe: the distinct ideation
46
+ * prompt gets its own replay entry at this tick.
47
+ */
48
+ export async function proposeCandidates( params: ProposeParams ): Promise<IdeationCandidate[] | undefined> {
49
+ try {
50
+ const result = await params.director.call(
51
+ params.systemPrompt, params.ideationUserMessage, params.tick, params.proposeTemperature,
52
+ params.meta ?? { category: 'executive', attribute: 'master', function: 'ideation' }
53
+ )
54
+ const candidates = parseIdeation( result.text ).candidates
55
+ return candidates.length > 0 ? candidates : undefined
56
+ }
57
+ catch {
58
+ return undefined // degrade to System 1 — never let a flaky propose pass break a tick
59
+ }
60
+ }
@@ -0,0 +1,114 @@
1
+ // ─────────────────────────────────────────────────────────────
2
+ // src/cognition/faculties/executive.engine/effort.gate.ts
3
+ // ─────────────────────────────────────────────────────────────
4
+
5
+ /**
6
+ * Dual-process control for the master executive.
7
+ *
8
+ * The master reasons in one of two processes per tick:
9
+ * - **System 1 (`fast`)** — the single-shot call. Quick, habitual, low-effort; the
10
+ * default for routine ticks.
11
+ * - **System 2 (`deliberate`)** — an effortful propose→evaluate pass, engaged only
12
+ * when the situation demands the effort.
13
+ *
14
+ * `selectProcess` is the *a-priori* gate: it chooses BEFORE any LLM call, from signals
15
+ * already computed this tick, so there is no wasted work and (unlike post-hoc
16
+ * escalation) no risk of streaming an intuition we then override. It is a pure,
17
+ * deterministic function of those signals (R2): no wall-clock, no RNG.
18
+ *
19
+ * This is deliberately the one seat where effort allocation lives. Two things grow
20
+ * here later, on this same seam:
21
+ * - the `DELIBERATE_THRESHOLD` becomes a persona-prior-developable disposition (an
22
+ * analytical / conscientious Will lowers it ⇒ deliberates more readily; an impulsive
23
+ * one raises it), unifying dual-process with the trait system; and
24
+ * - a System-1→System-2 *escalation* hook (System 1 runs, then raises its hand when
25
+ * unsure) — which is why the deliberate path reports its own confidence.
26
+ */
27
+
28
+ /** Which cognitive process the master runs this tick. */
29
+ export type CognitiveProcess = 'fast' | 'deliberate'
30
+
31
+ /** A-priori signals (all available before the master's LLM call) driving the choice. */
32
+ export interface EffortSignals {
33
+ /** Epistemic uncertainty for this tick (0..1). Higher ⇒ deliberate. */
34
+ epistemicUncertainty: number
35
+ /** Confidence on the master's *previous* decision (0..1). Lower ⇒ deliberate. */
36
+ priorConfidence: number
37
+ /** Perceptual novelty (0..1). Higher ⇒ deliberate. */
38
+ novelty: number
39
+ /** Stress load (0..100). High load flags a situation that matters ⇒ deliberate. */
40
+ stressLoad: number
41
+ /** A human message is awaiting a reply this tick. A social, stakes-bearing moment. */
42
+ hasPendingMessage: boolean
43
+ }
44
+
45
+ export interface ProcessSelection {
46
+ process: CognitiveProcess
47
+ /** Aggregate effort demand (0..1) that drove the choice — telemetry + future tuning. */
48
+ effortScore: number
49
+ /** The dominant contributor (auditability), e.g. `deliberate:uncertainty`. */
50
+ reason: string
51
+ }
52
+
53
+ // Contribution weights sum to 1, so effortScore ∈ [0,1]. Tunable; see the module note
54
+ // on making the threshold persona-prior-developable.
55
+ const W_UNCERTAINTY = 0.30
56
+ const W_LOW_CONFIDENCE = 0.25
57
+ const W_NOVELTY = 0.20
58
+ const W_PENDING = 0.15
59
+ const W_STRESS = 0.10
60
+
61
+ /** Effort demand at/above which the master engages System 2 (deliberate). */
62
+ export const DELIBERATE_THRESHOLD = 0.5
63
+
64
+ const clamp01 = ( x: number ): number => Math.max( 0, Math.min( 1, x ) )
65
+
66
+ /**
67
+ * Choose the master's cognitive process for this tick. Pure + deterministic.
68
+ * System 1 (`fast`) is the default; System 2 (`deliberate`) is engaged when the
69
+ * weighted effort demand crosses `threshold`.
70
+ *
71
+ * `threshold` defaults to `DELIBERATE_THRESHOLD` but is passed in by the engine as the
72
+ * *effective* threshold (base ⊕ persona-prior): an analytical Will develops a lower
73
+ * threshold and so deliberates more readily — effort allocation as a developing trait.
74
+ */
75
+ export function selectProcess(
76
+ signals: EffortSignals,
77
+ threshold: number = DELIBERATE_THRESHOLD,
78
+ ): ProcessSelection {
79
+ const contributions: Array<[ string, number ]> = [
80
+ [ 'uncertainty', W_UNCERTAINTY * clamp01( signals.epistemicUncertainty ) ],
81
+ [ 'low_confidence', W_LOW_CONFIDENCE * ( 1 - clamp01( signals.priorConfidence ) ) ],
82
+ [ 'novelty', W_NOVELTY * clamp01( signals.novelty ) ],
83
+ [ 'pending_reply', W_PENDING * ( signals.hasPendingMessage ? 1 : 0 ) ],
84
+ [ 'load', W_STRESS * clamp01( signals.stressLoad / 100 ) ],
85
+ ]
86
+
87
+ const effortScore = contributions.reduce( ( sum, [ , v ] ) => sum + v, 0 )
88
+ const dominant = contributions.reduce( ( a, b ) => ( b[ 1 ] > a[ 1 ] ? b : a ) )[ 0 ]
89
+ const deliberate = effortScore >= threshold
90
+
91
+ return {
92
+ process: deliberate ? 'deliberate' : 'fast',
93
+ effortScore,
94
+ reason: deliberate ? `deliberate:${dominant}` : 'fast',
95
+ }
96
+ }
97
+
98
+ // ── Ideation temperature (closes TODO edge #4) ────────────────
99
+
100
+ /** Safe sampling-temperature band for the ideation (propose) pass. */
101
+ export const IDEATION_TEMP_MIN = 0.6
102
+ export const IDEATION_TEMP_MAX = 1.0
103
+
104
+ /**
105
+ * Map the `creativity` self-model trait (0..1) to the ideation pass's sampling
106
+ * temperature. A more creative Will diverges harder when proposing options. Bounded to
107
+ * [IDEATION_TEMP_MIN, IDEATION_TEMP_MAX] so the *decision* pass (provider default) is
108
+ * never destabilised. This closes TODO edge #4 — and cleanly, because temperature now
109
+ * lives only on the isolated ideation call, not the fused decision call. As the
110
+ * creativity trait develops in the self-model, this rises with it for free.
111
+ */
112
+ export function ideationTemperature( creativity: number ): number {
113
+ return IDEATION_TEMP_MIN + clamp01( creativity ) * ( IDEATION_TEMP_MAX - IDEATION_TEMP_MIN )
114
+ }