@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.
- package/LICENSE +202 -0
- package/README.md +777 -0
- package/dist/index.d.ts +8144 -0
- package/dist/index.js +26231 -0
- package/dist/index.js.map +1 -0
- package/package.json +73 -0
- package/src/cognition/agency/access.grants.ts +59 -0
- package/src/cognition/agency/competence.codec.ts +89 -0
- package/src/cognition/agency/engines/action.selector.ts +462 -0
- package/src/cognition/agency/engines/affordance.synthesizer.ts +384 -0
- package/src/cognition/agency/engines/deliberation.engine.ts +241 -0
- package/src/cognition/agency/engines/instruction.intake.ts +54 -0
- package/src/cognition/agency/engines/motor.schema.executor.ts +532 -0
- package/src/cognition/agency/engines/reafference.engine.ts +241 -0
- package/src/cognition/agency/execution.primitives.ts +118 -0
- package/src/cognition/agency/index.ts +58 -0
- package/src/cognition/agency/proactive.communicator.ts +274 -0
- package/src/cognition/agency/reconcile.learning.ts +82 -0
- package/src/cognition/agency/schemas/external.ts +59 -0
- package/src/cognition/agency/schemas/innate.ts +111 -0
- package/src/cognition/agency/schemas/repertoire.ts +246 -0
- package/src/cognition/agency/selection.scoring.ts +191 -0
- package/src/cognition/agency/types.ts +165 -0
- package/src/cognition/bus.ts +391 -0
- package/src/cognition/completion.inbox.ts +86 -0
- package/src/cognition/config.mirror.entities.ts +475 -0
- package/src/cognition/conversation.memory.ts +81 -0
- package/src/cognition/event.log.ts +116 -0
- package/src/cognition/event.schemas.ts +568 -0
- package/src/cognition/faculties/aesthetic.evaluator.ts +313 -0
- package/src/cognition/faculties/affective.blender.ts +562 -0
- package/src/cognition/faculties/attachment.evaluator.ts +432 -0
- package/src/cognition/faculties/attention.allocator.ts +422 -0
- package/src/cognition/faculties/autobiographical.narrator.ts +300 -0
- package/src/cognition/faculties/bias.detector.ts +363 -0
- package/src/cognition/faculties/circadian.oscillator.ts +294 -0
- package/src/cognition/faculties/confidence.calibrator.ts +324 -0
- package/src/cognition/faculties/dream.simulator.ts +251 -0
- package/src/cognition/faculties/empathy.simulator.ts +253 -0
- package/src/cognition/faculties/energy.regulator.ts +320 -0
- package/src/cognition/faculties/episodic.consolidator.ts +728 -0
- package/src/cognition/faculties/executive.engine/commands.ts +459 -0
- package/src/cognition/faculties/executive.engine/config.ts +46 -0
- package/src/cognition/faculties/executive.engine/context.ts +605 -0
- package/src/cognition/faculties/executive.engine/deferred.effects.ts +104 -0
- package/src/cognition/faculties/executive.engine/deliberate.reasoning.ts +60 -0
- package/src/cognition/faculties/executive.engine/effort.gate.ts +114 -0
- package/src/cognition/faculties/executive.engine/engine.ts +1028 -0
- package/src/cognition/faculties/executive.engine/escalation.buffer.ts +90 -0
- package/src/cognition/faculties/executive.engine/facet.supervisor.ts +271 -0
- package/src/cognition/faculties/executive.engine/facet.ts +628 -0
- package/src/cognition/faculties/executive.engine/gating.ts +222 -0
- package/src/cognition/faculties/executive.engine/index.ts +6 -0
- package/src/cognition/faculties/executive.engine/messages.ts +102 -0
- package/src/cognition/faculties/executive.engine/parser.ts +380 -0
- package/src/cognition/faculties/executive.engine/prompt.factory.ts +1053 -0
- package/src/cognition/faculties/executive.engine/types.ts +323 -0
- package/src/cognition/faculties/exteroception.ts +338 -0
- package/src/cognition/faculties/forgetting.curve.ts +202 -0
- package/src/cognition/faculties/frustration.evaluator.ts +280 -0
- package/src/cognition/faculties/goal.manager.ts +1008 -0
- package/src/cognition/faculties/inhibition.controller.ts +351 -0
- package/src/cognition/faculties/interoception.ts +417 -0
- package/src/cognition/faculties/introspection.engine.ts +246 -0
- package/src/cognition/faculties/known.entity.tracker.ts +439 -0
- package/src/cognition/faculties/loss.evaluator.ts +224 -0
- package/src/cognition/faculties/moral.evaluator.ts +437 -0
- package/src/cognition/faculties/novelty.detector.ts +254 -0
- package/src/cognition/faculties/persona.consolidator.ts +845 -0
- package/src/cognition/faculties/planning.engine/engine.ts +859 -0
- package/src/cognition/faculties/planning.engine/plan.frontier.ts +83 -0
- package/src/cognition/faculties/planning.engine/plan.store.ts +174 -0
- package/src/cognition/faculties/planning.engine/plan.supervision.ts +494 -0
- package/src/cognition/faculties/planning.engine/types.ts +143 -0
- package/src/cognition/faculties/reputation.tracker.ts +294 -0
- package/src/cognition/faculties/reward.evaluator.ts +304 -0
- package/src/cognition/faculties/self.model.updater.ts +677 -0
- package/src/cognition/faculties/semantic.engine/clustering.ts +673 -0
- package/src/cognition/faculties/semantic.engine/index.ts +6 -0
- package/src/cognition/faculties/semantic.engine/integrator.ts +750 -0
- package/src/cognition/faculties/semantic.engine/types.ts +53 -0
- package/src/cognition/faculties/sleep.pressure.regulator.ts +262 -0
- package/src/cognition/faculties/social.perception.ts +333 -0
- package/src/cognition/faculties/spaced.repetition.ts +605 -0
- package/src/cognition/faculties/stress.regulator.ts +375 -0
- package/src/cognition/faculties/task.switcher.ts +239 -0
- package/src/cognition/faculties/theory.of.mind.ts +333 -0
- package/src/cognition/faculties/threat.evaluator.ts +312 -0
- package/src/cognition/faculties/working.memory.ts +406 -0
- package/src/cognition/generative.model.ts +344 -0
- package/src/cognition/heartbeat.ts +70 -0
- package/src/cognition/index.ts +291 -0
- package/src/cognition/instruction.handler.ts +146 -0
- package/src/cognition/memory/index.ts +35 -0
- package/src/cognition/memory/vector.adapter.ts +316 -0
- package/src/cognition/memory/vector.content.ts +47 -0
- package/src/cognition/memory/vector.embedder.ts +212 -0
- package/src/cognition/memory/vector.index.ts +459 -0
- package/src/cognition/memory/vector.types.ts +65 -0
- package/src/cognition/orchestrator.ts +142 -0
- package/src/cognition/persona.prior.ts +265 -0
- package/src/cognition/schema.registry.ts +145 -0
- package/src/cognition/senses/audition.engine/engine.ts +976 -0
- package/src/cognition/senses/audition.engine/salience.ts +59 -0
- package/src/cognition/senses/base.sense.engine.ts +117 -0
- package/src/cognition/senses/gustation.engine.ts +24 -0
- package/src/cognition/senses/index.ts +172 -0
- package/src/cognition/senses/olfaction.engine.ts +24 -0
- package/src/cognition/senses/somatosensation.engine.ts +23 -0
- package/src/cognition/senses/vision.engine.ts +23 -0
- package/src/cognition/types.ts +63 -0
- package/src/cognition/utilities/token.tracker.ts +492 -0
- package/src/core/abstracts.ts +60 -0
- package/src/core/async.engine.ts +539 -0
- package/src/core/clock.ts +196 -0
- package/src/core/completion.recorder.ts +122 -0
- package/src/core/conflict.detector.ts +140 -0
- package/src/core/distributed.ts +626 -0
- package/src/core/event.bus.ts +292 -0
- package/src/core/inbound.recorder.ts +100 -0
- package/src/core/index.ts +167 -0
- package/src/core/logger.ts +85 -0
- package/src/core/metrics.ts +107 -0
- package/src/core/orchestrator.ts +625 -0
- package/src/core/replay.ts +589 -0
- package/src/core/scenario.ts +120 -0
- package/src/core/serialization.ts +448 -0
- package/src/core/simulation.ts +197 -0
- package/src/core/snapshot.manager.ts +293 -0
- package/src/core/state.manager.ts +283 -0
- package/src/core/types.ts +274 -0
- package/src/core/utils.ts +82 -0
- package/src/core/wall.clock.ts +23 -0
- package/src/extensions/livestream.ext.ts +570 -0
- package/src/extensions/time.ext.ts +339 -0
- package/src/index.ts +91 -0
- package/src/llm/gate.ts +140 -0
- package/src/llm/index.ts +716 -0
- package/src/llm/summarizer.ts +170 -0
- package/src/llm/wire.contracts.ts +67 -0
- package/src/pma/eval.ts +651 -0
- package/src/pma/index.ts +1082 -0
- package/src/profiles/built-in.ts +7 -0
- package/src/profiles/companion.ts +28 -0
- package/src/profiles/company-brain.ts +54 -0
- package/src/profiles/customer-service.ts +30 -0
- package/src/profiles/game-npc.ts +20 -0
- package/src/profiles/index.ts +42 -0
- package/src/profiles/smart-home.ts +34 -0
- package/src/runners/coherence.runner.ts +49 -0
- package/src/runners/outreach.runner.ts +158 -0
- package/src/runners/social.runner.ts +182 -0
- package/src/runners/thin-shim.runner.ts +195 -0
- package/src/sdk/will.ts +334 -0
- package/src/stem/assembly.audit.ts +88 -0
- package/src/stem/distribution.ts +203 -0
- package/src/stem/guards/identity.coherence.ts +152 -0
- package/src/stem/guards/identity.guard.ts +227 -0
- package/src/stem/index.ts +1145 -0
- package/src/stem/mind.ts +1090 -0
- package/src/stem/tracts/ack.reconciler.ts +55 -0
- package/src/stem/tracts/biography.writer.ts +190 -0
- package/src/stem/tracts/effector.controller.ts +143 -0
- package/src/stem/tracts/health.reporter.ts +113 -0
- package/src/stem/tracts/inbound.queue.ts +54 -0
- package/src/stem/tracts/outbox.controller.ts +167 -0
- package/src/stem/tracts/outbox.writer.ts +133 -0
- package/src/stem/tracts/pma.controller.ts +109 -0
- package/src/stem/tracts/replay.controller.ts +177 -0
- package/src/stem/tracts/sensory.controller.ts +168 -0
- package/src/stem/tracts/session.logger.ts +157 -0
- package/src/stem/tracts/transport/index.ts +38 -0
- package/src/stem/tracts/transport/loopback.transport.ts +86 -0
- package/src/stem/tracts/transport/socketio.transport.ts +200 -0
- package/src/stem/tracts/transport/stream.transport.ts +152 -0
- package/src/stem/tracts/transport/types.ts +193 -0
- package/src/stem/tracts/transport.controller.ts +380 -0
- package/src/types.ts +116 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────────────────────
|
|
2
|
+
// src/cognition/faculties/planning.engine/plan.frontier.ts — the ready frontier
|
|
3
|
+
// ─────────────────────────────────────────────────────────────
|
|
4
|
+
//
|
|
5
|
+
// Planning-as-prior's mechanical heart: resolve the prerequisite DAG to find the
|
|
6
|
+
// ready frontier, and project active steps as transient `plan.prior` entities the
|
|
7
|
+
// AffordanceSynthesizer turns into competing affordances. A prior BIASES the one
|
|
8
|
+
// action competition — it never dispatches (see the engine header).
|
|
9
|
+
//
|
|
10
|
+
// Pure functions over (plan, state) — no engine state, no bus. Extracted
|
|
11
|
+
// verbatim from planning.engine.ts; behavior identical.
|
|
12
|
+
// ─────────────────────────────────────────────────────────────
|
|
13
|
+
|
|
14
|
+
import type { Tick, ReadonlySimulationState, StateCommands } from '#core/types'
|
|
15
|
+
import { clamp01, type Plan, type PlanStep } from '#faculties/planning.engine/types'
|
|
16
|
+
|
|
17
|
+
/** Steps whose prerequisites are all completed/skipped — ready to activate. */
|
|
18
|
+
export function computeReadySet( plan: Plan ): PlanStep[] {
|
|
19
|
+
const ready: PlanStep[] = []
|
|
20
|
+
|
|
21
|
+
for( const step of plan.steps ){
|
|
22
|
+
if( step.status !== 'pending' ) continue
|
|
23
|
+
|
|
24
|
+
const allPrereqsSatisfied = step.prerequisites.every( prereqId => {
|
|
25
|
+
const prereqStep = plan.steps.find( s => s.id === prereqId )
|
|
26
|
+
return prereqStep && ( prereqStep.status === 'completed' || prereqStep.status === 'skipped' )
|
|
27
|
+
} )
|
|
28
|
+
|
|
29
|
+
allPrereqsSatisfied && ready.push( step )
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return ready
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Project every executing plan's active frontier as transient `plan.prior`
|
|
37
|
+
* entities — the top-down bias the AffordanceSynthesizer reads. Rebuilt each tick
|
|
38
|
+
* (cleared then re-emitted, like the affordance field), so a frontier that
|
|
39
|
+
* advances or a plan that ends stops biasing automatically. The prior carries the
|
|
40
|
+
* planId/stepId provenance that flows affordance → intent → action.outcome, and a
|
|
41
|
+
* `planBias` strength from the goal's importance ⊕ the plan's confidence. It never
|
|
42
|
+
* forces an action — if a more pressing affordance wins, the plan re-projects next
|
|
43
|
+
* tick (no orphaning).
|
|
44
|
+
*/
|
|
45
|
+
export function projectFrontier(
|
|
46
|
+
plans: Iterable<Plan>,
|
|
47
|
+
commands: StateCommands,
|
|
48
|
+
tick: Tick,
|
|
49
|
+
state: ReadonlySimulationState,
|
|
50
|
+
goalPriority: ( goalId: string ) => number,
|
|
51
|
+
biasGain: number,
|
|
52
|
+
): void {
|
|
53
|
+
// Clear the previous tick's priors — they are transient.
|
|
54
|
+
for( const [ id, e ] of state.entities )
|
|
55
|
+
if( e.type === 'plan.prior' ) commands.delete!.push( id )
|
|
56
|
+
|
|
57
|
+
for( const plan of plans ){
|
|
58
|
+
if( plan.status !== 'executing' ) continue
|
|
59
|
+
|
|
60
|
+
// Channel A: conscientiousness develops `planBiasGain` UP, so a conscientious
|
|
61
|
+
// Will pushes its plan's frontier harder against competing impulses.
|
|
62
|
+
const strength = clamp01( ( 0.5 * goalPriority( plan.goalId ) + 0.5 * plan.confidence ) * biasGain )
|
|
63
|
+
|
|
64
|
+
for( const step of plan.steps ){
|
|
65
|
+
if( step.status !== 'active' ) continue
|
|
66
|
+
commands.set!.push({
|
|
67
|
+
// tick in the id (like the affordance field) so this tick's fresh prior
|
|
68
|
+
// never collides with last tick's cleared one in the same command batch.
|
|
69
|
+
id: `plan-prior-${ tick }-${ plan.id }-${ step.id }`,
|
|
70
|
+
type: 'plan.prior',
|
|
71
|
+
metadata: {
|
|
72
|
+
schema: step.action, // advisory suggested schema (not dispatched)
|
|
73
|
+
planId: plan.id,
|
|
74
|
+
stepId: step.id,
|
|
75
|
+
planBias: strength,
|
|
76
|
+
targetEntityId: step.targetEntityId,
|
|
77
|
+
parameters: {},
|
|
78
|
+
tick,
|
|
79
|
+
},
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────────────────────
|
|
2
|
+
// src/cognition/faculties/planning.engine/plan.store.ts — canonical plan state
|
|
3
|
+
// ─────────────────────────────────────────────────────────────
|
|
4
|
+
//
|
|
5
|
+
// Owns every map the engine used to hold: the canonical plan store, the
|
|
6
|
+
// goal-scoped index (P4: multiple plans per goal), terminal bookkeeping
|
|
7
|
+
// (persist-once + retention GC — P5), and the id counter. Pure state +
|
|
8
|
+
// deterministic bookkeeping; no bus, no facets, no LLM.
|
|
9
|
+
//
|
|
10
|
+
// Extracted verbatim from planning.engine.ts — behavior identical.
|
|
11
|
+
// ─────────────────────────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
import type { Tick, StateCommands } from '#core/types'
|
|
14
|
+
import { TERMINAL_STATUSES, type Plan } from '#faculties/planning.engine/types'
|
|
15
|
+
|
|
16
|
+
export class PlanStore {
|
|
17
|
+
/**
|
|
18
|
+
* Canonical plan store, keyed by plan.id ("plan-N") — the id the execution,
|
|
19
|
+
* outcome (`action.outcome.planId`) and facet paths all use.
|
|
20
|
+
*/
|
|
21
|
+
private _plans = new Map<string, Plan>()
|
|
22
|
+
/**
|
|
23
|
+
* Secondary index goalId → ordered plan.ids (creation order). Multiple plans
|
|
24
|
+
* per goal supported (P4); terminal plans stay in the list as history and are
|
|
25
|
+
* filtered out by activePlanForGoal. Goal-scoped reads route through the
|
|
26
|
+
* helpers below.
|
|
27
|
+
*/
|
|
28
|
+
private _planByGoal = new Map<string, string[]>()
|
|
29
|
+
/**
|
|
30
|
+
* Plan ids already persisted in a terminal state. Terminal plans never change
|
|
31
|
+
* again, so they are persisted once and then skipped by persist() — avoids
|
|
32
|
+
* unbounded state-write amplification as completed/failed plans accumulate. (P5)
|
|
33
|
+
*/
|
|
34
|
+
private _persistedTerminal = new Set<string>()
|
|
35
|
+
/** planId → sim tick it became terminal; drives retention GC (gcTerminal). */
|
|
36
|
+
private _terminalAt = new Map<string, number>()
|
|
37
|
+
private _planCounter = 0
|
|
38
|
+
|
|
39
|
+
// ── Reads ──────────────────────────────────────────────────
|
|
40
|
+
|
|
41
|
+
get size(): number { return this._plans.size }
|
|
42
|
+
|
|
43
|
+
get( planId: string ): Plan | undefined { return this._plans.get( planId ) }
|
|
44
|
+
has( planId: string ): boolean { return this._plans.has( planId ) }
|
|
45
|
+
all(): IterableIterator<Plan> { return this._plans.values() }
|
|
46
|
+
|
|
47
|
+
isTerminal( plan: Plan ): boolean { return TERMINAL_STATUSES.includes( plan.status ) }
|
|
48
|
+
|
|
49
|
+
/** All plans for a goal, in creation order (any status). */
|
|
50
|
+
plansForGoal( goalId: string ): Plan[] {
|
|
51
|
+
const ids = this._planByGoal.get( goalId )
|
|
52
|
+
if( !ids ) return []
|
|
53
|
+
const out: Plan[] = []
|
|
54
|
+
for( const id of ids ){
|
|
55
|
+
const p = this._plans.get( id )
|
|
56
|
+
if( p ) out.push( p )
|
|
57
|
+
}
|
|
58
|
+
return out
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** The most-recently-created non-terminal plan for a goal, if any. */
|
|
62
|
+
activePlanForGoal( goalId: string ): Plan | undefined {
|
|
63
|
+
const all = this.plansForGoal( goalId )
|
|
64
|
+
for( let i = all.length - 1; i >= 0; i-- )
|
|
65
|
+
if( !TERMINAL_STATUSES.includes( all[ i ]!.status ) ) return all[ i ]
|
|
66
|
+
return undefined
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Resolve which plan an executive plan-op targets. Prefers an explicit
|
|
71
|
+
* `planId` (must belong to the same goal); otherwise falls back to the goal's
|
|
72
|
+
* active plan. Returns undefined when neither resolves (caller may create one).
|
|
73
|
+
*/
|
|
74
|
+
resolveIngestTarget( goalId: string, planId?: string ): Plan | undefined {
|
|
75
|
+
if( planId ){
|
|
76
|
+
const p = this._plans.get( planId )
|
|
77
|
+
if( p && p.goalId === goalId ) return p
|
|
78
|
+
}
|
|
79
|
+
return this.activePlanForGoal( goalId )
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ── Writes ─────────────────────────────────────────────────
|
|
83
|
+
|
|
84
|
+
/** Next sequential plan id ("plan-N") — deterministic, never PRNG. */
|
|
85
|
+
nextId(): string {
|
|
86
|
+
this._planCounter++
|
|
87
|
+
return `plan-${this._planCounter}`
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Register a plan in both the canonical store and the goal index. */
|
|
91
|
+
index( plan: Plan ): void {
|
|
92
|
+
this._plans.set( plan.id, plan )
|
|
93
|
+
const ids = this._planByGoal.get( plan.goalId ) ?? []
|
|
94
|
+
ids.push( plan.id )
|
|
95
|
+
this._planByGoal.set( plan.goalId, ids )
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Record the tick a plan entered a terminal status (drives retention GC). */
|
|
99
|
+
markTerminal( planId: string, tick: number ): void {
|
|
100
|
+
this._terminalAt.set( planId, tick )
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ── Retention GC ───────────────────────────────────────────
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Evict terminal plans (and delete their state entity) once they've been
|
|
107
|
+
* terminal longer than the retention window. Terminal plans never change, so
|
|
108
|
+
* retaining them forever accretes memory + state entities on a long-lived mind.
|
|
109
|
+
* Deterministic: the window is compared against sim ticks (R2-safe).
|
|
110
|
+
* `onEvict` lets the engine tear down any facet still keyed to the plan.
|
|
111
|
+
*/
|
|
112
|
+
gcTerminal( tick: Tick, commands: StateCommands, retentionTicks: number, onEvict: ( planId: string ) => void ): void {
|
|
113
|
+
const now = tick as unknown as number
|
|
114
|
+
let evicted = 0
|
|
115
|
+
|
|
116
|
+
for( const [ id, plan ] of this._plans ){
|
|
117
|
+
if( !TERMINAL_STATUSES.includes( plan.status ) ) continue
|
|
118
|
+
const since = this._terminalAt.get( id ) ?? now
|
|
119
|
+
if( now - since <= retentionTicks ) continue
|
|
120
|
+
|
|
121
|
+
this._plans.delete( id )
|
|
122
|
+
this._persistedTerminal.delete( id )
|
|
123
|
+
this._terminalAt.delete( id )
|
|
124
|
+
onEvict( id ) // safety — a terminal plan shouldn't still hold a facet
|
|
125
|
+
|
|
126
|
+
const ids = this._planByGoal.get( plan.goalId )
|
|
127
|
+
if( ids ){
|
|
128
|
+
const next = ids.filter( x => x !== id )
|
|
129
|
+
if( next.length ) this._planByGoal.set( plan.goalId, next )
|
|
130
|
+
else this._planByGoal.delete( plan.goalId )
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
commands.delete!.push( id )
|
|
134
|
+
evicted++
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if( evicted > 0 )
|
|
138
|
+
commands.metrics!.push( [ 'planning.plans_evicted', evicted ] )
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// ── Persistence ────────────────────────────────────────────
|
|
142
|
+
|
|
143
|
+
persist( commands: StateCommands, tick: Tick ): void {
|
|
144
|
+
for( const plan of this._plans.values() ){
|
|
145
|
+
// Terminal plans never change again — persist once (in their terminal state)
|
|
146
|
+
// then skip, so completed/failed/rejected plans don't re-serialize every
|
|
147
|
+
// tick forever (unbounded write amplification on long sessions). (P5)
|
|
148
|
+
const terminal = TERMINAL_STATUSES.includes( plan.status )
|
|
149
|
+
if( terminal && this._persistedTerminal.has( plan.id ) ) continue
|
|
150
|
+
|
|
151
|
+
commands.set!.push( {
|
|
152
|
+
id: plan.id, type: 'plan',
|
|
153
|
+
createdAt: plan.createdAt, updatedAt: tick,
|
|
154
|
+
metadata: {
|
|
155
|
+
goalId: plan.goalId,
|
|
156
|
+
steps: plan.steps.map( s => ( {
|
|
157
|
+
id: s.id, order: s.order, action: s.action,
|
|
158
|
+
description: s.description, expectedOutcome: s.expectedOutcome,
|
|
159
|
+
prerequisites: s.prerequisites, estimatedDuration: s.estimatedDuration,
|
|
160
|
+
status: s.status, outcome: s.outcome,
|
|
161
|
+
} ) ),
|
|
162
|
+
estimatedCost: plan.estimatedCost, confidence: plan.confidence,
|
|
163
|
+
status: plan.status, executionTier: plan.executionTier,
|
|
164
|
+
expectedOutcome: plan.expectedOutcome,
|
|
165
|
+
requestingEntityId: plan.requestingEntityId,
|
|
166
|
+
requestingThreadId: plan.requestingThreadId,
|
|
167
|
+
source: 'planning-engine'
|
|
168
|
+
}
|
|
169
|
+
} )
|
|
170
|
+
|
|
171
|
+
if( terminal ) this._persistedTerminal.add( plan.id )
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|