@mindot/will 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -11
- package/dist/index.d.ts +188 -141
- package/dist/index.js +16660 -15206
- package/dist/index.js.map +1 -1
- package/dist/{channels → surface/channels}/discord.d.ts +50 -3
- package/dist/{channels → surface/channels}/discord.js +102 -7
- package/dist/surface/channels/discord.js.map +1 -0
- package/dist/{channels → surface/channels}/whatsapp.d.ts +2 -2
- package/dist/{channels → surface/channels}/whatsapp.js +7 -4
- package/dist/surface/channels/whatsapp.js.map +1 -0
- package/dist/{cli.js → surface/cli.js} +4406 -2904
- package/dist/surface/cli.js.map +1 -0
- package/dist/{mcp → surface/mcp}/effectors.d.ts +1 -1
- package/dist/{mcp → surface/mcp}/effectors.js +10 -4
- package/dist/surface/mcp/effectors.js.map +1 -0
- package/dist/{will-DbDj_TEH.d.ts → will-evj9_vrd.d.ts} +5699 -4854
- package/package.json +11 -12
- package/src/cognition/agency/consequence.ts +237 -3
- package/src/cognition/agency/conversation.aim.ts +32 -0
- package/src/cognition/agency/engines/action.selector.ts +59 -3
- package/src/cognition/agency/engines/affordance.synthesizer.ts +114 -10
- package/src/cognition/agency/engines/deliberation.engine.ts +76 -3
- package/src/cognition/agency/engines/motor.schema.executor.ts +362 -27
- package/src/cognition/agency/engines/reafference.engine.ts +43 -4
- package/src/cognition/agency/execution.primitives.ts +17 -4
- package/src/cognition/agency/reconcile.learning.ts +5 -4
- package/src/cognition/agency/schemas/innate.ts +96 -1
- package/src/cognition/agency/schemas/repertoire.ts +19 -1
- package/src/cognition/agency/selection.scoring.ts +16 -0
- package/src/cognition/agency/settlement.ts +203 -0
- package/src/cognition/agency/types.ts +38 -1
- package/src/cognition/config.mirror.entities.ts +0 -1
- package/src/cognition/event.schemas.ts +0 -8
- package/src/cognition/faculties/affective.blender.ts +21 -4
- package/src/cognition/faculties/circadian.oscillator.ts +36 -7
- package/src/cognition/faculties/executive.engine/action.record.ts +129 -0
- package/src/cognition/faculties/executive.engine/context.ts +41 -35
- package/src/cognition/faculties/executive.engine/engine.ts +270 -113
- package/src/cognition/faculties/executive.engine/escalation.buffer.ts +126 -59
- package/src/cognition/faculties/executive.engine/facet.supervisor.ts +10 -0
- package/src/cognition/faculties/executive.engine/parser.ts +100 -38
- package/src/cognition/faculties/executive.engine/prompt.factory.ts +168 -23
- package/src/cognition/faculties/executive.engine/types.ts +18 -15
- package/src/cognition/faculties/exteroception.ts +99 -98
- package/src/cognition/faculties/goal.manager.ts +50 -2
- package/src/cognition/faculties/known.entity.tracker.ts +22 -3
- package/src/cognition/faculties/planning.engine/engine.ts +4 -4
- package/src/cognition/faculties/planning.engine/plan.frontier.ts +1 -1
- package/src/cognition/faculties/semantic.engine/integrator.ts +1 -1
- package/src/cognition/faculties/working.memory.ts +6 -1
- package/src/cognition/instruction.handler.ts +1 -1
- package/src/cognition/memory/vector.embedder.ts +1 -3
- package/src/cognition/percept.entity.ts +122 -0
- package/src/cognition/sense.boundary.ts +176 -0
- package/src/cognition/senses/audition.engine/engine.ts +97 -16
- package/src/cognition/senses/base.sense.engine.ts +104 -6
- package/src/cognition/senses/index.ts +71 -13
- package/src/cognition/senses/provenance.ts +128 -0
- package/src/cognition/senses/somatosensation.engine.ts +117 -9
- package/src/cognition/social.identity.ts +23 -0
- package/src/cognition/utilities/token.tracker.ts +36 -5
- package/src/core/orchestrator.ts +13 -0
- package/src/index.ts +39 -5
- package/src/llm/gate.ts +48 -0
- package/src/llm/index.ts +102 -25
- package/src/llm/wire.contracts.ts +38 -0
- package/src/pma/index.ts +1 -1
- package/src/stem/index.ts +92 -21
- package/src/stem/mind.ts +26 -2
- package/src/stem/policy/arbiter.ts +10 -0
- package/src/stem/profiles/built-in.ts +7 -0
- package/src/{profiles → stem/profiles}/companion.ts +1 -1
- package/src/{profiles → stem/profiles}/company-brain.ts +1 -1
- package/src/{profiles → stem/profiles}/customer-service.ts +1 -1
- package/src/{profiles → stem/profiles}/game-npc.ts +1 -1
- package/src/{profiles → stem/profiles}/index.ts +1 -1
- package/src/{profiles → stem/profiles}/smart-home.ts +1 -1
- package/src/stem/tracts/effector/escalation.lifecycle.ts +239 -0
- package/src/stem/tracts/effector/policy.enforcement.ts +261 -0
- package/src/stem/tracts/effector/types.ts +110 -0
- package/src/stem/tracts/effector.controller.ts +112 -401
- package/src/stem/tracts/outbox.controller.ts +30 -17
- package/src/stem/tracts/sensory.controller.ts +6 -6
- package/src/stem/tracts/session.logger.ts +6 -1
- package/src/stem/tracts/transport/types.ts +20 -1
- package/src/stem/tracts/transport.controller.ts +33 -9
- package/src/{channels → surface/channels}/discord.ts +224 -7
- package/src/{channels → surface/channels}/roster.ts +1 -1
- package/src/{channels → surface/channels}/types.ts +1 -1
- package/src/{channels → surface/channels}/whatsapp.ts +9 -6
- package/src/{cli.ts → surface/cli.ts} +6 -6
- package/src/{host → surface/host}/boot.ts +3 -3
- package/src/{host → surface/host}/utterances.ts +2 -2
- package/src/{mcp → surface/mcp}/effectors.ts +19 -6
- package/src/{mcp → surface/mcp}/server.ts +19 -5
- package/src/{sdk → surface/sdk}/will.ts +156 -28
- package/src/{serve → surface/serve}/server.ts +11 -4
- package/src/types.ts +24 -3
- package/dist/channels/discord.js.map +0 -1
- package/dist/channels/whatsapp.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/mcp/effectors.js.map +0 -1
- package/src/extensions/livestream.ext.ts +0 -570
- package/src/extensions/time.ext.ts +0 -339
- package/src/profiles/built-in.ts +0 -7
- package/src/runners/coherence.runner.ts +0 -49
- package/src/runners/outreach.runner.ts +0 -155
- package/src/runners/social.runner.ts +0 -179
- package/src/runners/thin-shim.runner.ts +0 -205
- /package/dist/{cli.d.ts → surface/cli.d.ts} +0 -0
|
@@ -35,9 +35,12 @@ import type { CognitiveEventSchema } from '#cognition/schema.registry'
|
|
|
35
35
|
import type { Affordance, AffordanceSource, MotorSchema, LearnedSkill, SchemaPrecondition } from '#agency/types'
|
|
36
36
|
import type { SchemaRepertoire } from '#agency/schemas/repertoire'
|
|
37
37
|
import { INNATE_SCHEMAS } from '#agency/schemas/innate'
|
|
38
|
+
import { CURIOUS_RESOLVED } from '#faculties/known.entity.tracker'
|
|
38
39
|
import { collectGoalTargets } from '#agency/selection.scoring'
|
|
39
40
|
import { readEffectiveParams } from '#cognition/persona.prior'
|
|
40
|
-
import { liveConsequences, enactionFootprint, spokenAtByEntity, CONSEQUENCE_TTL_TICKS, type ConsequenceDescriptor } from '#agency/consequence'
|
|
41
|
+
import { liveConsequences, enactionFootprint, spokenAtByEntity, enactedAtBySchemaTarget, CONSEQUENCE_TTL_TICKS, type ConsequenceDescriptor } from '#agency/consequence'
|
|
42
|
+
import { readAliases, canonicalOf } from '#cognition/social.identity'
|
|
43
|
+
import { liveSettlements, settlementForce, type SettlementDescriptor } from '#agency/settlement'
|
|
41
44
|
|
|
42
45
|
/** Default field width for non-innate affordances when no attention metric exists. */
|
|
43
46
|
const DEFAULT_ATTENTION_CAP = 5
|
|
@@ -68,12 +71,31 @@ export class AffordanceSynthesizer implements CognitiveEngine {
|
|
|
68
71
|
* because `_build` runs per candidate and reading them is a full-entity scan.
|
|
69
72
|
*/
|
|
70
73
|
private _inFlight: readonly ConsequenceDescriptor[] = []
|
|
74
|
+
/** Durable "when did I last do this TO them" — the entity-bound peer of
|
|
75
|
+
* `_spokenAt`, collected once per tick for the same reason `_inFlight` is. */
|
|
76
|
+
private _enactedAt: ReadonlyMap<string, number> = new Map()
|
|
71
77
|
|
|
72
78
|
/** Ticks an act stays satiating (engine-config-action-selector.repeatWindowTicks). */
|
|
73
79
|
private _satiationWindow: number = CONSEQUENCE_TTL_TICKS
|
|
80
|
+
/** Verdicts System 2 has already reached and that have not yet aged out.
|
|
81
|
+
* Collected once per tick for the same reason `_inFlight` is — `_build` runs
|
|
82
|
+
* per candidate and this is a full-entity scan. */
|
|
83
|
+
private _settled: SettlementDescriptor[] = []
|
|
74
84
|
|
|
75
85
|
/** Tick of the last thing said to each entity — outlives the descriptor sweep. */
|
|
76
86
|
private _spokenAt: ReadonlyMap<string, number> = new Map()
|
|
87
|
+
private _spokeAnywhereAt: number | undefined = undefined
|
|
88
|
+
/**
|
|
89
|
+
* alias id → anchor id, read once per tick.
|
|
90
|
+
*
|
|
91
|
+
* Every surface below is keyed by WHO an act was aimed at, and the mind meets
|
|
92
|
+
* one person under more than one id: a reply is addressed to the transport id
|
|
93
|
+
* the percept arrived with (`discord:1019…`), a self-initiated message to the
|
|
94
|
+
* anchor the executive resolved (`ke:…`). `readSpokenTurns` resolved that for
|
|
95
|
+
* the PROMPT from the start; nothing resolved it for the WEIGHTS, so having
|
|
96
|
+
* just answered someone did not damp reaching out to them a cycle later.
|
|
97
|
+
*/
|
|
98
|
+
private _canon: ( id: string ) => string = id => id
|
|
77
99
|
private _bus: CognitiveBus | null = null
|
|
78
100
|
private _defaultCap: number
|
|
79
101
|
private _lastFieldSize = 0
|
|
@@ -131,7 +153,21 @@ export class AffordanceSynthesizer implements CognitiveEngine {
|
|
|
131
153
|
// `_build` runs for every candidate and this is a full-entity scan. Each
|
|
132
154
|
// candidate whose (schema, target) matches one of these carries a decaying
|
|
133
155
|
// `justEnacted`, so having just done a thing damps doing it again.
|
|
134
|
-
|
|
156
|
+
// One scan, then every target-keyed surface below shares its id space. They
|
|
157
|
+
// must agree with each other AND with the lookup at the call site: canonical
|
|
158
|
+
// keys read with a raw target damps nothing, and a raw key read with a
|
|
159
|
+
// canonical target breaks the damping that already worked.
|
|
160
|
+
const aliases = readAliases( state.entities )
|
|
161
|
+
this._canon = ( id: string ) => canonicalOf( aliases, id )
|
|
162
|
+
|
|
163
|
+
this._inFlight = liveConsequences( state.entities, tick, this._canon )
|
|
164
|
+
// Durable per-(schema, target) enaction. Descriptors alone expire at the ECHO
|
|
165
|
+
// window, so without this the back half of the satiation window damped
|
|
166
|
+
// nothing for any act with an object that is not speech.
|
|
167
|
+
this._enactedAt = enactedAtBySchemaTarget( state.entities, this._canon )
|
|
168
|
+
// What the mind has already decided. Read here so a verdict reaches the
|
|
169
|
+
// competition as a force in the field rather than a fact about one intent.
|
|
170
|
+
this._settled = liveSettlements( state.entities, tick, this._canon )
|
|
135
171
|
// How long this mind sits with something it has already done before doing it
|
|
136
172
|
// again — the tenant's, not the container's. Falls back to the echo TTL only
|
|
137
173
|
// when unseeded, so a bare harness behaves as before.
|
|
@@ -140,7 +176,12 @@ export class AffordanceSynthesizer implements CognitiveEngine {
|
|
|
140
176
|
// Durable "when did I last speak to them". Descriptors alone cannot carry
|
|
141
177
|
// satiation — the executor deletes them at their echo TTL, so any window
|
|
142
178
|
// longer than that was a no-op.
|
|
143
|
-
this._spokenAt = spokenAtByEntity( state.entities )
|
|
179
|
+
this._spokenAt = spokenAtByEntity( state.entities, this._canon )
|
|
180
|
+
// When this mind last spoke to ANYONE — the satiation arm that is not about
|
|
181
|
+
// the listener. Computed once per tick rather than per candidate.
|
|
182
|
+
let last = -Infinity
|
|
183
|
+
for( const t of this._spokenAt.values() ) if( t > last ) last = t
|
|
184
|
+
this._spokeAnywhereAt = last > -Infinity ? last : undefined
|
|
144
185
|
|
|
145
186
|
const set: EntityInput[] = []
|
|
146
187
|
const del: string[] = []
|
|
@@ -191,16 +232,18 @@ export class AffordanceSynthesizer implements CognitiveEngine {
|
|
|
191
232
|
const personSchemas = schemas.filter( s => s.binds === 'entity')
|
|
192
233
|
const objectSchemas = schemas.filter( s => s.binds === 'object')
|
|
193
234
|
|
|
194
|
-
|
|
195
|
-
|
|
235
|
+
// Not gated on there BEING a target-bound schema: `inspect` is offered from
|
|
236
|
+
// this same loop and belongs to the innate floor, so a mind with no `binds`
|
|
237
|
+
// schemas at all — which is every mind until a host declares one — must still
|
|
238
|
+
// reach it. Gating the loop skipped a room entirely, because the innate floor
|
|
239
|
+
// has no `binds: 'object'` schema for a thing to match.
|
|
240
|
+
for( const [ id, e ] of state.entities ){
|
|
196
241
|
if( e.type !== 'known-entity') continue
|
|
197
242
|
|
|
198
243
|
const m = e.metadata
|
|
199
244
|
const kind = str( m?.['kind'] )
|
|
200
245
|
const applicable = kind === 'sentient' ? personSchemas : kind === 'thing' ? objectSchemas : null
|
|
201
246
|
|
|
202
|
-
if( !applicable || applicable.length === 0 ) continue
|
|
203
|
-
|
|
204
247
|
const keid = str( m?.['keid'] ) ?? id
|
|
205
248
|
const fam = num( m?.['familiarity'], 0 )
|
|
206
249
|
const val = num( m?.['valence'], 0 )
|
|
@@ -208,7 +251,7 @@ export class AffordanceSynthesizer implements CognitiveEngine {
|
|
|
208
251
|
const salience = fam * 0.6 + Math.max( 0, val ) * 0.3 + res * 0.1 + ( goalTargets.get( keid ) ?? 0 )
|
|
209
252
|
const name = str( m?.['name'] ) ?? keid
|
|
210
253
|
|
|
211
|
-
for( const schema of applicable )
|
|
254
|
+
for( const schema of applicable ?? [] )
|
|
212
255
|
candidates.push({
|
|
213
256
|
salience,
|
|
214
257
|
affordance: this._build( schema, tick, state, valence, energyLow, skills, {
|
|
@@ -217,6 +260,38 @@ export class AffordanceSynthesizer implements CognitiveEngine {
|
|
|
217
260
|
parameters: { targetEntityName: name },
|
|
218
261
|
} ),
|
|
219
262
|
})
|
|
263
|
+
|
|
264
|
+
// ── looking at something I cannot place ──────────────────
|
|
265
|
+
//
|
|
266
|
+
// The wanting and the doing referenced different things. Curiosity is
|
|
267
|
+
// per-REFERENT — `drive.curiosity_resolve` rises with
|
|
268
|
+
// `familiarity × (1 − resolutionConfidence)`, and GoalManager turns it
|
|
269
|
+
// into a real goal that completes when that referent resolves. But the
|
|
270
|
+
// only `inspect` on offer bound to PERCEPTS, so a mind could want to know
|
|
271
|
+
// what a room was, hold a goal about it, and have no act that addressed
|
|
272
|
+
// it. The pull existed with nowhere to go.
|
|
273
|
+
//
|
|
274
|
+
// Offered here at the strength of the not-knowing itself, so the thing it
|
|
275
|
+
// most wants to place is the thing it is most drawn to look at — and the
|
|
276
|
+
// affordance appears BECAUSE something is unresolved rather than standing
|
|
277
|
+
// permanently on offer. A referent it can already place raises no
|
|
278
|
+
// candidate at all: there is nothing to find out.
|
|
279
|
+
//
|
|
280
|
+
// Alongside the percept-bound offering, not instead of it. Examining what
|
|
281
|
+
// is in front of you and looking up what you cannot place are both real,
|
|
282
|
+
// and they are not the same act.
|
|
283
|
+
if( perceptSchema && res < CURIOUS_RESOLVED ){
|
|
284
|
+
const wonder = fam * ( 1 - res )
|
|
285
|
+
if( wonder > 0 )
|
|
286
|
+
candidates.push({
|
|
287
|
+
salience: wonder + ( goalTargets.get( keid ) ?? 0 ),
|
|
288
|
+
affordance: this._build( perceptSchema, tick, state, valence, energyLow, skills, {
|
|
289
|
+
evokedBy: id,
|
|
290
|
+
targetEntityId: keid,
|
|
291
|
+
parameters: { focus: name, targetEntityName: name },
|
|
292
|
+
} ),
|
|
293
|
+
})
|
|
294
|
+
}
|
|
220
295
|
}
|
|
221
296
|
|
|
222
297
|
// ── ideomotor candidates: the executive's imagined actions, pre-activated ──
|
|
@@ -255,7 +330,7 @@ export class AffordanceSynthesizer implements CognitiveEngine {
|
|
|
255
330
|
// action its current frontier needs. The PlanningEngine writes one `plan.prior`
|
|
256
331
|
// per ready frontier step; each enters the field as a HIGH-salience candidate
|
|
257
332
|
// (the frontier is willed) carrying a `planBias` the scorer weighs and the
|
|
258
|
-
// planId/stepId
|
|
333
|
+
// planId/stepId link that flows through to action.outcome so the plan
|
|
259
334
|
// advances when the field actually enacts it. Like ideomotor, it never bypasses
|
|
260
335
|
// the selector — if a more pressing affordance wins, the plan simply re-projects
|
|
261
336
|
// next tick. The suggested schema must resolve in the repertoire; if it does not,
|
|
@@ -367,12 +442,31 @@ export class AffordanceSynthesizer implements CognitiveEngine {
|
|
|
367
442
|
// Satiation only applies to acts aimed at someone the mind SPEAKS to — the
|
|
368
443
|
// `conversation.sent` half is keyed by person, so it must not damp, say,
|
|
369
444
|
// inspecting them.
|
|
445
|
+
//
|
|
446
|
+
// For an act with NO OBJECT the footprint is the act itself: there is no
|
|
447
|
+
// target to key on, and "I have just done this" is the whole of the fact.
|
|
448
|
+
// The innate floor is entirely objectless, so without this it could not
|
|
449
|
+
// satiate at all and whichever stance won once won harder each tick after.
|
|
370
450
|
const speaks = schema.tags?.includes('communication') ?? false
|
|
451
|
+
// The lookup half. Only the QUESTION "have I just done this to them" is asked
|
|
452
|
+
// in canonical form — the affordance keeps the id it was built with, because
|
|
453
|
+
// that is the id the act will be delivered against.
|
|
454
|
+
const asked = ctx.targetEntityId ? this._canon( ctx.targetEntityId ) : undefined
|
|
371
455
|
const justEnacted = enactionFootprint(
|
|
372
|
-
this._inFlight, schema.id,
|
|
456
|
+
this._inFlight, schema.id, asked, tick, this._satiationWindow,
|
|
373
457
|
speaks ? this._spokenAt : undefined,
|
|
458
|
+
skill?.lastEnactedTick,
|
|
459
|
+
speaks ? this._spokeAnywhereAt : undefined,
|
|
460
|
+
// Not gated on `speaks`: this is exactly the arm speech does NOT need
|
|
461
|
+
// (it has `spokenAt`) and every other entity-bound act was missing.
|
|
462
|
+
this._enactedAt,
|
|
374
463
|
)
|
|
375
464
|
|
|
465
|
+
// The mirror of satiation: having thought this through holds the choice for
|
|
466
|
+
// a while, and fades. Keyed exactly as `justEnacted` is, so an objectless
|
|
467
|
+
// verdict cannot leak onto an act that has an object.
|
|
468
|
+
const settled = settlementForce( this._settled, schema.id, asked, tick )
|
|
469
|
+
|
|
376
470
|
const key = ctx.targetEntityId ?? ctx.evokedBy ?? schema.id
|
|
377
471
|
const source = ctx.source ?? schema.source
|
|
378
472
|
// A non-default-source candidate (ideomotor) gets a distinct id so it can coexist
|
|
@@ -396,6 +490,7 @@ export class AffordanceSynthesizer implements CognitiveEngine {
|
|
|
396
490
|
...( availability < 1 ? { availability } : {} ),
|
|
397
491
|
...( socialPrior !== 0 ? { socialPrior } : {} ),
|
|
398
492
|
...( justEnacted > 0 ? { justEnacted } : {} ),
|
|
493
|
+
...( settled > 0 ? { settled } : {} ),
|
|
399
494
|
planBias: ctx.planBias,
|
|
400
495
|
willBias: ctx.willBias,
|
|
401
496
|
planId: ctx.planId,
|
|
@@ -423,6 +518,15 @@ export class AffordanceSynthesizer implements CognitiveEngine {
|
|
|
423
518
|
description: a.description,
|
|
424
519
|
...( a.availability !== undefined ? { availability: a.availability } : {} ),
|
|
425
520
|
...( a.socialPrior !== undefined ? { socialPrior: a.socialPrior } : {} ),
|
|
521
|
+
// The act's own footprint. Omitted when 0 so a mind that has done nothing
|
|
522
|
+
// twice writes a byte-identical field — but WRITTEN when it is not, which
|
|
523
|
+
// it never was: this is the state hop between synthesis and the
|
|
524
|
+
// competition, and `justEnacted` did not cross it.
|
|
525
|
+
...( a.justEnacted !== undefined ? { justEnacted: a.justEnacted } : {} ),
|
|
526
|
+
// The verdict's standing weight — same hop, same rule. A field the
|
|
527
|
+
// synthesizer computes and the entity does not carry is a field the
|
|
528
|
+
// competition never sees, which is how `justEnacted` stayed dormant.
|
|
529
|
+
...( a.settled !== undefined ? { settled: a.settled } : {} ),
|
|
426
530
|
planBias: a.planBias,
|
|
427
531
|
willBias: a.willBias,
|
|
428
532
|
planId: a.planId,
|
|
@@ -31,6 +31,8 @@ import type { CognitiveBus } from '#cognition/bus'
|
|
|
31
31
|
import type { CognitiveEngine, EngineResult } from '#cognition/types'
|
|
32
32
|
import type { CognitiveEventSchema } from '#cognition/schema.registry'
|
|
33
33
|
import { revokedIntentIds, revocationId } from '#agency/revocation'
|
|
34
|
+
import { settlementEntity, expiredSettlementIds, SETTLEMENT_TTL_TICKS } from '#agency/settlement'
|
|
35
|
+
import { nameOf, isReferentId } from '#cognition/social.identity'
|
|
34
36
|
|
|
35
37
|
// ── Minimal structural view of the executive's facet machinery ───────────────
|
|
36
38
|
// Kept structural (not an import of the executive engine) so the agency module
|
|
@@ -98,7 +100,10 @@ export class DeliberationEngine implements CognitiveEngine {
|
|
|
98
100
|
// to let go of it — and the tombstone with it. We never deliberate a
|
|
99
101
|
// revoked intent.
|
|
100
102
|
const revoked = revokedIntentIds( state.entities, tick )
|
|
101
|
-
|
|
103
|
+
// Aged-out verdicts go with them. Nothing else owns settlements, and a
|
|
104
|
+
// question whose settlement has expired must be genuinely open again — not
|
|
105
|
+
// merely inert-but-present, which would leave the state growing forever.
|
|
106
|
+
const del: string[] = expiredSettlementIds( state.entities, tick )
|
|
102
107
|
|
|
103
108
|
// One deliberation per tick (the serial bottleneck).
|
|
104
109
|
let target: { id: string; meta: Record<string, unknown> } | null = null
|
|
@@ -136,7 +141,15 @@ export class DeliberationEngine implements CognitiveEngine {
|
|
|
136
141
|
|
|
137
142
|
return {
|
|
138
143
|
commands: {
|
|
139
|
-
set:
|
|
144
|
+
set: [
|
|
145
|
+
this._commit( id, meta, chosen, candidates, 'facet'),
|
|
146
|
+
// The verdict's trace in the field it was called in to resolve.
|
|
147
|
+
// Written ONLY here, on the path where System 2 actually thought —
|
|
148
|
+
// the no-executive path below confirms the substrate's winner without
|
|
149
|
+
// reaching a conclusion, and a mind should not be held to a verdict it
|
|
150
|
+
// never formed.
|
|
151
|
+
this._settle( chosen, candidates, tick ),
|
|
152
|
+
],
|
|
140
153
|
...( del.length > 0 ? { delete: del } : {} ),
|
|
141
154
|
metrics: [ [ 'agency.deliberation.count', 1 ] ],
|
|
142
155
|
},
|
|
@@ -186,6 +199,25 @@ export class DeliberationEngine implements CognitiveEngine {
|
|
|
186
199
|
}
|
|
187
200
|
}
|
|
188
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Record that this contest was weighed and settled.
|
|
204
|
+
*
|
|
205
|
+
* Keyed on what WON, not on the rival set, so a slightly differently-framed
|
|
206
|
+
* contest still meets a verdict the mind has already reached — the rivals ride
|
|
207
|
+
* along as the introspectable reason rather than as a matching key.
|
|
208
|
+
*/
|
|
209
|
+
private _settle( chosen: string, candidates: Candidate[], tick: Tick ): EntityInput {
|
|
210
|
+
const cand = candidates.find( c => c.schema === chosen )
|
|
211
|
+
const over = candidates.filter( c => c.schema !== chosen ).map( c => c.schema )
|
|
212
|
+
return settlementEntity({
|
|
213
|
+
schema: chosen,
|
|
214
|
+
targetEntityId: cand?.targetEntityId,
|
|
215
|
+
...( over.length > 0 ? { over } : {} ),
|
|
216
|
+
tick,
|
|
217
|
+
expiresAt: tick + SETTLEMENT_TTL_TICKS,
|
|
218
|
+
})
|
|
219
|
+
}
|
|
220
|
+
|
|
189
221
|
/** Write the deliberating intent back as 'selected' with the chosen action. */
|
|
190
222
|
private _commit(
|
|
191
223
|
id: string,
|
|
@@ -227,7 +259,35 @@ export class DeliberationEngine implements CognitiveEngine {
|
|
|
227
259
|
else
|
|
228
260
|
lines.push('My automatic action-selection was uncertain. Candidate actions:')
|
|
229
261
|
candidates.forEach( ( c, i ) => {
|
|
230
|
-
|
|
262
|
+
// What the target IS, never the id it is filed under.
|
|
263
|
+
//
|
|
264
|
+
// This printed `c.targetEntityId` raw, so a mind deliberating was offered
|
|
265
|
+
// "inspect toward agency-intent-30" and "inspect toward
|
|
266
|
+
// affordance-1-orient-orient" — engine bookkeeping ids, and by the time a
|
|
267
|
+
// facet reasons off-tick the affordance entities are already swept. Live,
|
|
268
|
+
// she said so herself: "the content of all three is opaque — I don't know
|
|
269
|
+
// what agency-intent-30 actually is", and chose at 0.3 confidence anyway
|
|
270
|
+
// because the instructions forbid inventing an action outside the list.
|
|
271
|
+
//
|
|
272
|
+
// The prompt factory already holds this line for "## People I Know"
|
|
273
|
+
// ("never leak the raw keid"); the deliberation focus is the one place that
|
|
274
|
+
// did not. Resolved through the same dossier lookup, so a `reach-out toward
|
|
275
|
+
// ke:1sqlkux` now reads as the person's name.
|
|
276
|
+
//
|
|
277
|
+
// Unresolvable ⇒ the clause is DROPPED rather than filled with an id. An
|
|
278
|
+
// option the mind cannot identify should look like what it is — a bare act
|
|
279
|
+
// — instead of borrowing authority from a number it cannot read.
|
|
280
|
+
const to = ( () => {
|
|
281
|
+
const id = c.targetEntityId
|
|
282
|
+
if( !id ) return ''
|
|
283
|
+
const named = nameOf( state.entities as never, id )
|
|
284
|
+
if( named ) return ` toward ${ named }`
|
|
285
|
+
// Unnamed: show it only if it means something to the MIND. A host-supplied
|
|
286
|
+
// target ("ada") does; an opaque anchor or a piece of engine bookkeeping
|
|
287
|
+
// does not, and printing those is what produced "inspect toward
|
|
288
|
+
// agency-intent-30" as a thing to choose.
|
|
289
|
+
return opaqueToTheMind( id ) ? '' : ` toward ${ id }`
|
|
290
|
+
} )()
|
|
231
291
|
// The ability's meaning, so the facet weighs what each option IS FOR rather
|
|
232
292
|
// than choosing among bare labels ("give" vs "attack" is a real difference).
|
|
233
293
|
const what = c.description ? ` — ${ c.description }` : ''
|
|
@@ -258,3 +318,16 @@ function extractChosen( decision: unknown, candidates: Candidate[] ): string | u
|
|
|
258
318
|
function str( v: unknown ): string | undefined {
|
|
259
319
|
return typeof v === 'string' ? v : undefined
|
|
260
320
|
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Ids the mind cannot read anything off.
|
|
324
|
+
*
|
|
325
|
+
* A `ke:` anchor is opaque BY DESIGN — 0.9.0 made identity deliberately
|
|
326
|
+
* meaningless as a string — and the rest are the engine's own bookkeeping
|
|
327
|
+
* entities, which exist for one tick and say nothing about the world. Neither
|
|
328
|
+
* belongs in a choice a mind has to make; a host-supplied target does.
|
|
329
|
+
*/
|
|
330
|
+
function opaqueToTheMind( id: string ): boolean {
|
|
331
|
+
return isReferentId( id )
|
|
332
|
+
|| /^(affordance|agency-intent|agency-outcome|ideomotor|facet|percept)[-:]/.test( id )
|
|
333
|
+
}
|