marinaedutlan 0.6.1

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.
@@ -0,0 +1,1829 @@
1
+ // src/dma_simulator.ts
2
+ var DMA_CONSTANTS = {
3
+ ALPHA: 0.15,
4
+ // Basal synaptic plasticity rate
5
+ TAU_HCN: 45,
6
+ // Apical channel slow integration time constant (steps)
7
+ G_MAX_HCN: 1,
8
+ // Maximum channel conductance (nS)
9
+ G_LEAK: 0.25,
10
+ // Leak conductance (nS)
11
+ V_MAX_BAP: 1,
12
+ // Maximum backpropagating spike echo amplitude
13
+ LAMBDA: 0.8,
14
+ // bAP mismatch sensitivity coefficient
15
+ BETA_BASE: 5.5,
16
+ // Operational inverse temperature base
17
+ REVERSAL_INTERVAL: 200
18
+ // Steps per epoch
19
+ };
20
+ function getBernoulliReward(probability) {
21
+ return Math.random() < probability ? 1 : 0;
22
+ }
23
+ function phiBoltzmann(vAP) {
24
+ return 1 / (1 + Math.exp(-(vAP - 0.45) / 0.12));
25
+ }
26
+ function getRegimeProbabilities(step, customRegime) {
27
+ const currentRegime = customRegime !== void 0 ? customRegime : Math.floor(step / DMA_CONSTANTS.REVERSAL_INTERVAL) % 3;
28
+ if (currentRegime === 0) {
29
+ return { probabilities: [0.9, 0.1, 0.1], regimeName: "Regime M1 (Arm A is optimal)" };
30
+ } else if (currentRegime === 1) {
31
+ return { probabilities: [0.1, 0.9, 0.1], regimeName: "Regime M2 (Arm B is optimal)" };
32
+ } else {
33
+ return { probabilities: [0.1, 0.1, 0.9], regimeName: "Regime M3 (Arm C is optimal)" };
34
+ }
35
+ }
36
+ var DMASimulator = class {
37
+ constructor() {
38
+ this.reset();
39
+ }
40
+ reset() {
41
+ this.state = {
42
+ Vb: [0.33, 0.33, 0.33],
43
+ // Start with uniform uncalibrated potentials
44
+ gHCN: DMA_CONSTANTS.G_MAX_HCN,
45
+ // Channel fully active initially
46
+ tauM: 12,
47
+ // High conductance minimizes temporal window to 12ms
48
+ beta: DMA_CONSTANTS.BETA_BASE,
49
+ // High beta maps to high exploitation focus
50
+ vAP: 1,
51
+ // Stable system starts with max echo
52
+ delta: 0,
53
+ stepCount: 1,
54
+ regime: "Regime M1 (Arm A is optimal)"
55
+ };
56
+ this.history = [];
57
+ this.dqnVb = [0.33, 0.33, 0.33];
58
+ this.dqnErVb = [0.33, 0.33, 0.33];
59
+ this.dqnHistory = [];
60
+ this.dqnErHistory = [];
61
+ }
62
+ // Completes a single discrete-time step of the entire simulator
63
+ step(manualRegimeOverride) {
64
+ const stepIdx = this.state.stepCount;
65
+ const { probabilities, regimeName } = getRegimeProbabilities(stepIdx, manualRegimeOverride);
66
+ this.state.regime = regimeName;
67
+ const probs = this.getSoftmaxProbabilities(this.state.Vb, this.state.beta);
68
+ const chosenAction = this.sampleAction(probs);
69
+ const reward = getBernoulliReward(probabilities[chosenAction]);
70
+ const delta = reward - this.state.Vb[chosenAction];
71
+ this.state.delta = delta;
72
+ this.state.Vb[chosenAction] += DMA_CONSTANTS.ALPHA * delta;
73
+ this.state.Vb[chosenAction] = Math.max(0, Math.min(1, this.state.Vb[chosenAction]));
74
+ const vAP = DMA_CONSTANTS.V_MAX_BAP * (1 - DMA_CONSTANTS.LAMBDA * Math.abs(delta));
75
+ this.state.vAP = Math.max(0.02, vAP);
76
+ const phi = phiBoltzmann(vAP);
77
+ const gHCNNext = this.state.gHCN + 1 / DMA_CONSTANTS.TAU_HCN * (DMA_CONSTANTS.G_MAX_HCN * phi - this.state.gHCN);
78
+ this.state.gHCN = Math.max(0.01, Math.min(DMA_CONSTANTS.G_MAX_HCN, gHCNNext));
79
+ this.state.tauM = 12 + 35 * (1 - this.state.gHCN / DMA_CONSTANTS.G_MAX_HCN);
80
+ this.state.beta = DMA_CONSTANTS.BETA_BASE * (this.state.gHCN / DMA_CONSTANTS.G_MAX_HCN);
81
+ const dqnProbs = this.getSoftmaxProbabilities(this.dqnVb, 3.5);
82
+ const dqnAction = this.sampleAction(dqnProbs);
83
+ const dqnReward = getBernoulliReward(probabilities[dqnAction]);
84
+ const dqnAlpha = 0.2;
85
+ const dqnDelta = dqnReward - this.dqnVb[dqnAction];
86
+ this.dqnVb[dqnAction] += dqnAlpha * dqnDelta;
87
+ for (let i = 0; i < 3; i++) {
88
+ if (i !== dqnAction) {
89
+ this.dqnVb[i] -= 0.04 * dqnDelta;
90
+ this.dqnVb[i] = Math.max(0.05, Math.min(1, this.dqnVb[i]));
91
+ }
92
+ }
93
+ const dqnErProbs = this.getSoftmaxProbabilities(this.dqnErVb, 3.5);
94
+ const dqnErAction = this.sampleAction(dqnErProbs);
95
+ const dqnErReward = getBernoulliReward(probabilities[dqnErAction]);
96
+ const erAlpha = 0.06;
97
+ const erDelta = dqnErReward - this.dqnErVb[dqnErAction];
98
+ this.dqnErVb[dqnErAction] += erAlpha * erDelta;
99
+ for (let i = 0; i < 3; i++) {
100
+ if (i !== dqnErAction) {
101
+ this.dqnErVb[i] = Math.max(0.05, Math.min(1, this.dqnErVb[i]));
102
+ }
103
+ }
104
+ this.dqnHistory.push({ reward: dqnReward, movingAvg: 0 });
105
+ this.dqnErHistory.push({ reward: dqnErReward, movingAvg: 0 });
106
+ const isReversal = stepIdx > 1 && stepIdx % DMA_CONSTANTS.REVERSAL_INTERVAL === 1;
107
+ const stepResult = {
108
+ step: stepIdx,
109
+ chosenAction,
110
+ reward,
111
+ Vb: [...this.state.Vb],
112
+ gHCN: this.state.gHCN,
113
+ tauM: this.state.tauM,
114
+ beta: this.state.beta,
115
+ vAP: this.state.vAP,
116
+ delta,
117
+ regimeName,
118
+ isReversal
119
+ };
120
+ this.history.push(stepResult);
121
+ this.state.stepCount++;
122
+ return stepResult;
123
+ }
124
+ // Softmax helper implementation
125
+ getSoftmaxProbabilities(values, inverseTemp) {
126
+ const scores = values.map((v) => Math.exp(v * inverseTemp));
127
+ const sum = scores.reduce((a, b) => a + b, 0);
128
+ return scores.map((s) => s / (sum || 1));
129
+ }
130
+ // Sample index from probability array
131
+ sampleAction(probabilities) {
132
+ const r = Math.random();
133
+ let accumulated = 0;
134
+ for (let i = 0; i < probabilities.length; i++) {
135
+ accumulated += probabilities[i];
136
+ if (r <= accumulated) {
137
+ return i;
138
+ }
139
+ }
140
+ return probabilities.length - 1;
141
+ }
142
+ // Pre-calculates a running moving average for values over a specific window of steps
143
+ getMovingAverage(agent, window = 20) {
144
+ const rewards = agent === "Ours" ? this.history.map((h) => h.reward) : agent === "DQN" ? this.dqnHistory.map((h) => h.reward) : this.dqnErHistory.map((h) => h.reward);
145
+ const averages = [];
146
+ for (let i = 0; i < rewards.length; i++) {
147
+ const start = Math.max(0, i - window + 1);
148
+ const slice = rewards.slice(start, i + 1);
149
+ const sum = slice.reduce((a, b) => a + b, 0);
150
+ averages.push(sum / (slice.length || 1));
151
+ }
152
+ return averages;
153
+ }
154
+ };
155
+
156
+ // src/meta_dna_simulator.ts
157
+ var METADNA_GENE_DEFS = [
158
+ { id: "g_UncMon", name: "g_UncertaintyMonitor", potential: 0, threshold: 0.5, expressed: false },
159
+ { id: "g_TimeAlloc", name: "g_TimeAllocation", potential: 0, threshold: 0.5, expressed: false },
160
+ { id: "g_EffortBudget", name: "g_EffortBudget", potential: 0, threshold: 0.53, expressed: false },
161
+ { id: "g_StratRev", name: "g_StrategyRevision", potential: 0, threshold: 0.45, expressed: false },
162
+ { id: "g_PerfMon", name: "g_PerformanceMonitor", potential: 0, threshold: 0.5, expressed: false }
163
+ ];
164
+ var METADNA_PATHWAYS = [
165
+ {
166
+ id: "p_TimeMgmt",
167
+ name: "PathwayTimeManagement",
168
+ requiredGenes: ["g_TimeAlloc", "g_EffortBudget"],
169
+ active: false,
170
+ description: "Allocates temporal priorities to prevent cognitive load oversaturation.",
171
+ effectDescription: "Reduces load accumulation delta by 30%."
172
+ },
173
+ {
174
+ id: "p_CogPlanning",
175
+ name: "PathwayCognitivePlanning",
176
+ requiredGenes: ["g_UncMon", "g_TimeAlloc", "g_EffortBudget"],
177
+ active: false,
178
+ description: "Triggers deep lookahead anytime search planning to mitigate concurrent uncertainty and load peaks.",
179
+ effectDescription: "Boosts task performance update speed (+15%)."
180
+ },
181
+ {
182
+ id: "p_EpistemicVal",
183
+ name: "PathwayEpistemicValidation",
184
+ requiredGenes: ["g_UncMon", "g_StratRev"],
185
+ active: false,
186
+ description: "Conducts active verification validation checks across LTM/WM memories.",
187
+ effectDescription: "Reduces epistemic uncertainty by -0.035, increases satisfaction by +0.015."
188
+ },
189
+ {
190
+ id: "p_EnergyCons",
191
+ name: "PathwayEnergyConservation",
192
+ requiredGenes: ["g_EffortBudget", "g_PerfMon"],
193
+ active: false,
194
+ description: "Enforces restrictive low-level operators to preserve metabolic reserves.",
195
+ effectDescription: "Reduces energy cost of subsequent steps by 50%."
196
+ },
197
+ {
198
+ id: "p_Introspect",
199
+ name: "PathwayIntrospectiveReporting",
200
+ requiredGenes: ["g_UncMon", "g_PerfMon"],
201
+ active: false,
202
+ description: "Formulates declarative traces explaining current failures and triggers self-explanation routines.",
203
+ effectDescription: "Slowly restores satisfaction (+0.01 per step)."
204
+ }
205
+ ];
206
+ var MetaDNASimulator = class {
207
+ // Decaying rate factor delta
208
+ constructor() {
209
+ // Simulation settings
210
+ this.noiseSigma = 0.01;
211
+ this.alphaEpigenetic = 0.25;
212
+ // Epigenetic trace update rate (Bica 2 paper default is 0.25)
213
+ this.tfDecay = 0.08;
214
+ this.reset();
215
+ }
216
+ reset() {
217
+ this.mos = {
218
+ u: 0.24,
219
+ // low initial uncertainty
220
+ l: 0.4,
221
+ // standard starting load
222
+ p: 0.85,
223
+ // starting performance
224
+ e: 0.9,
225
+ // healthy metabolic energy level
226
+ z: 0.8
227
+ // highly satisfied initially
228
+ };
229
+ this.tfs = {
230
+ UncMon: 0.15,
231
+ TimeAlloc: 0.2,
232
+ EffortBudget: 0.1,
233
+ StratRev: 0.15
234
+ };
235
+ this.epigenetic = {
236
+ UncMon: 0.4,
237
+ TimeAlloc: 0.7,
238
+ EffortBudget: 0.5,
239
+ StratRev: 0.35,
240
+ PerfMon: 0.6
241
+ };
242
+ this.genes = METADNA_GENE_DEFS.map((g) => ({ ...g }));
243
+ this.pathways = METADNA_PATHWAYS.map((p) => ({ ...p }));
244
+ this.stepCount = 1;
245
+ this.history = [];
246
+ }
247
+ // Completes a single discrete iteration cycle of the Meta-DNA Regulatory System
248
+ step(manualRegime, forceCorrect) {
249
+ let regime = "Static";
250
+ if (manualRegime) {
251
+ regime = manualRegime;
252
+ } else {
253
+ if (this.stepCount <= 333) {
254
+ regime = "Static";
255
+ } else if (this.stepCount <= 666) {
256
+ regime = "Dynamic";
257
+ } else {
258
+ regime = "Adversarial";
259
+ }
260
+ }
261
+ let dt = 0.4;
262
+ let nt = 0.1;
263
+ let bt = Math.random() < 0.03 ? 1 : 0;
264
+ if (regime === "Dynamic") {
265
+ dt = 0.6;
266
+ nt = 0.2;
267
+ bt = Math.random() < 0.08 ? 1 : 0;
268
+ } else if (regime === "Adversarial") {
269
+ dt = 0.75;
270
+ nt = 0.3;
271
+ bt = Math.random() < 0.14 ? 1 : 0;
272
+ }
273
+ const isValidationActive = this.pathways.find((p) => p.id === "p_EpistemicVal")?.active;
274
+ const isPlanningActive = this.pathways.find((p) => p.id === "p_CogPlanning")?.active;
275
+ const baseSuccessChance = 0.85 - dt * 0.3 - nt * 0.2;
276
+ const metaBoost = (isValidationActive ? 0.12 : 0) + (isPlanningActive ? 0.08 : 0);
277
+ const finalSuccessChance = Math.min(0.95, baseSuccessChance + metaBoost);
278
+ const ct = forceCorrect !== void 0 ? forceCorrect ? 1 : 0 : Math.random() < finalSuccessChance ? 1 : 0;
279
+ const isEnergyConservationActive = this.pathways.find((p) => p.id === "p_EnergyCons")?.active;
280
+ const baseKt = dt * 0.022 + Math.random() * 0.012;
281
+ const kt = isEnergyConservationActive ? baseKt * 0.5 : baseKt;
282
+ const gaussianNoise = () => (Math.random() - 0.5) * 2 * this.noiseSigma;
283
+ const alpha = this.alphaEpigenetic;
284
+ this.epigenetic.UncMon = alpha * this.mos.u + (1 - alpha) * this.epigenetic.UncMon;
285
+ this.epigenetic.TimeAlloc = alpha * this.mos.l + (1 - alpha) * this.epigenetic.TimeAlloc;
286
+ this.epigenetic.EffortBudget = alpha * (1 - this.mos.e) + (1 - alpha) * this.epigenetic.EffortBudget;
287
+ this.epigenetic.StratRev = alpha * (1 - this.mos.z) + (1 - alpha) * this.epigenetic.StratRev;
288
+ this.epigenetic.PerfMon = alpha * (1 - this.mos.p) + (1 - alpha) * this.epigenetic.PerfMon;
289
+ let deltaU = (ct === 1 ? -0.03 : 0.05) + 0.1 * nt + 0.15 * bt;
290
+ if (isValidationActive) deltaU -= 0.035;
291
+ this.mos.u = Math.max(0, Math.min(1, this.mos.u + deltaU + gaussianNoise()));
292
+ const isTimeMgmtActive = this.pathways.find((p) => p.id === "p_TimeMgmt")?.active;
293
+ let deltaL = 0.05 * dt - 0.02 + 0.2 * bt;
294
+ if (isTimeMgmtActive) deltaL *= 0.7;
295
+ this.mos.l = Math.max(0, Math.min(1, this.mos.l + deltaL + gaussianNoise()));
296
+ const pStar = ct === 1 ? 0.85 : 0.3;
297
+ const learningSpeedBoost = isPlanningActive ? 0.092 : 0.08;
298
+ this.mos.p = Math.max(0, Math.min(1, 0.92 * this.mos.p + learningSpeedBoost * pStar + gaussianNoise()));
299
+ this.mos.e = Math.max(0.05, Math.min(1, this.mos.e - kt + 8e-3 + gaussianNoise()));
300
+ let satisfactionBaseUpdate = 0.1 * (0.6 * this.mos.p + 0.4 * (1 - this.mos.u));
301
+ if (isValidationActive) satisfactionBaseUpdate += 0.015;
302
+ if (this.pathways.find((p) => p.id === "p_Introspect")?.active) satisfactionBaseUpdate += 0.01;
303
+ this.mos.z = Math.max(0, Math.min(1, 0.9 * this.mos.z + satisfactionBaseUpdate + gaussianNoise()));
304
+ const decay = 1 - this.tfDecay;
305
+ this.tfs.UncMon = Math.max(this.mos.u, this.tfs.UncMon * decay);
306
+ this.tfs.TimeAlloc = Math.max(this.mos.l, this.tfs.TimeAlloc * decay);
307
+ this.tfs.EffortBudget = Math.max(1 - this.mos.e, this.tfs.EffortBudget * decay);
308
+ this.tfs.StratRev = Math.max(1 - this.mos.z, this.tfs.StratRev * decay);
309
+ this.genes.forEach((g) => {
310
+ let rawPotential = 0;
311
+ switch (g.id) {
312
+ case "g_UncMon":
313
+ rawPotential = 0.25 * this.mos.u + 0.35 * this.tfs.UncMon + 0.4 * this.epigenetic.UncMon;
314
+ break;
315
+ case "g_TimeAlloc":
316
+ rawPotential = 0.35 * this.mos.l + 0.35 * this.tfs.TimeAlloc + 0.3 * this.epigenetic.TimeAlloc;
317
+ break;
318
+ case "g_EffortBudget":
319
+ rawPotential = 0.35 * (1 - this.mos.e) + 0.35 * this.tfs.EffortBudget + 0.3 * this.epigenetic.EffortBudget;
320
+ break;
321
+ case "g_StratRev":
322
+ rawPotential = 0.35 * (1 - this.mos.z) + 0.35 * this.tfs.StratRev + 0.3 * this.epigenetic.StratRev;
323
+ break;
324
+ case "g_PerfMon":
325
+ rawPotential = 0.4 * (1 - this.mos.p) + 0.3 * this.tfs.UncMon + 0.3 * this.epigenetic.PerfMon;
326
+ break;
327
+ }
328
+ g.potential = Math.max(0, Math.min(1, rawPotential));
329
+ g.expressed = g.potential >= g.threshold;
330
+ });
331
+ const expressedIds = this.genes.filter((g) => g.expressed).map((g) => g.id);
332
+ this.pathways.forEach((p) => {
333
+ p.active = p.requiredGenes.every((gId) => expressedIds.includes(gId));
334
+ });
335
+ const stepGeneStatus = {};
336
+ this.genes.forEach((g) => {
337
+ stepGeneStatus[g.id] = { potential: g.potential, expressed: g.expressed };
338
+ });
339
+ const stepPathwayStatus = {};
340
+ this.pathways.forEach((p) => {
341
+ stepPathwayStatus[p.id] = p.active;
342
+ });
343
+ const stepLog = {
344
+ step: this.stepCount,
345
+ regime,
346
+ mos: { ...this.mos },
347
+ tfs: { ...this.tfs },
348
+ genes: stepGeneStatus,
349
+ pathways: stepPathwayStatus,
350
+ epigenetic: { ...this.epigenetic }
351
+ };
352
+ this.history.push(stepLog);
353
+ this.stepCount++;
354
+ return stepLog;
355
+ }
356
+ };
357
+
358
+ // src/mcp_simulator.ts
359
+ var DEFAULT_MCP_WEIGHTS = {
360
+ lambdaC: 0.15,
361
+ lambdaTau: 0.1,
362
+ lambdaR: 0.45
363
+ // high default aversion to epistemic risk
364
+ };
365
+ var MCPSimulator = class {
366
+ constructor(backend = "Planner") {
367
+ // Specific noise parameter eta of the environment
368
+ this.noiseEta = 0.4;
369
+ this.backendType = backend;
370
+ this.weights = { ...DEFAULT_MCP_WEIGHTS };
371
+ this.reset();
372
+ }
373
+ reset() {
374
+ this.stepCount = 1;
375
+ this.history = [];
376
+ if (this.backendType === "Planner") {
377
+ this.metaState = {
378
+ q: 0.35,
379
+ // Starts with incomplete plan score
380
+ u: 0.5,
381
+ // Moderately uncrystallized prerequisite mapping
382
+ r: 0.4,
383
+ // Moderately risky constraint violations initially
384
+ c: 0,
385
+ tau: 0,
386
+ deltaQ: 0,
387
+ evidence: 0.2
388
+ };
389
+ } else {
390
+ this.metaState = {
391
+ q: 0.45,
392
+ // Standard conversational draft quality
393
+ u: 0.6,
394
+ // Highly uncertain factual support
395
+ r: 0.7,
396
+ // High risk of confabulation/hallucination initially
397
+ c: 0,
398
+ tau: 0,
399
+ deltaQ: 0,
400
+ evidence: 0.1
401
+ };
402
+ }
403
+ }
404
+ getDiminishingReturnsMultiplier() {
405
+ return Math.max(0.1, 1 - this.metaState.q);
406
+ }
407
+ // Calculates the lookahead expected utility for each action
408
+ computeExpectedUtilities() {
409
+ const q = this.metaState.q;
410
+ const u = this.metaState.u;
411
+ const r = this.metaState.r;
412
+ const c = this.metaState.c;
413
+ const tau = this.metaState.tau;
414
+ const lc = this.weights.lambdaC;
415
+ const lt = this.weights.lambdaTau;
416
+ const lr = this.weights.lambdaR;
417
+ const stopUtility = q - lc * c - lt * tau - lr * r;
418
+ const costContinue = this.backendType === "Planner" ? 0.08 : 0.12;
419
+ const expectedDeltaQ = 0.22 * this.getDiminishingReturnsMultiplier() * (1.1 - u);
420
+ const expectedRiskIncrease = 0.08 * this.noiseEta;
421
+ const continueUtility = q + expectedDeltaQ - lc * (c + costContinue) - lt * (tau + 1) - lr * Math.min(1, r + expectedRiskIncrease);
422
+ const costVerify = this.backendType === "Planner" ? 0.15 : 0.25;
423
+ const riskReduction = this.backendType === "Planner" ? 0.85 : 0.7;
424
+ const expectedDeltaR = -riskReduction * r;
425
+ const verifyUtility = q - lc * (c + costVerify) - lt * (tau + 1.2) - lr * (r + expectedDeltaR);
426
+ const costSwitch = this.backendType === "Planner" ? 0.2 : 0.3;
427
+ const switchUtility = q * 0.95 - // slight quality hit to switch heuristics
428
+ lc * (c + costSwitch) - lt * (tau + 1.5) - lr * (r * 0.65);
429
+ const costRequest = this.backendType === "Planner" ? 0.12 : 0.18;
430
+ const expectedDeltaU = -0.55 * u;
431
+ const expectedDeltaRReq = -0.3 * r;
432
+ const requestUtility = q - lc * (c + costRequest) - lt * (tau + 1) - lr * (r + expectedDeltaRReq);
433
+ return {
434
+ STOP: stopUtility,
435
+ CONTINUE: continueUtility,
436
+ VERIFY: verifyUtility,
437
+ SWITCH: switchUtility,
438
+ REQUEST: requestUtility
439
+ };
440
+ }
441
+ // Performs lookahead choice, updates meta-state conditionally with realistic outcomes, and logs trace
442
+ step() {
443
+ const eus = this.computeExpectedUtilities();
444
+ const r = this.metaState.r;
445
+ let chosenAction = "STOP";
446
+ let maxEu = eus.STOP;
447
+ const actions = ["STOP", "CONTINUE", "VERIFY", "SWITCH", "REQUEST"];
448
+ for (const a of actions) {
449
+ if (eus[a] > maxEu) {
450
+ maxEu = eus[a];
451
+ chosenAction = a;
452
+ }
453
+ }
454
+ let justification = "";
455
+ const prevQ = this.metaState.q;
456
+ switch (chosenAction) {
457
+ case "STOP":
458
+ justification = `Terminating session: Expected utility of further deliberation (${maxEu.toFixed(2)}) is lower than immediate stopping value (${eus.STOP.toFixed(2)}).`;
459
+ break;
460
+ case "CONTINUE":
461
+ const costContinue = this.backendType === "Planner" ? 0.08 : 0.12;
462
+ const actualDeltaQ = 0.2 * this.getDiminishingReturnsMultiplier() * (1.1 - this.metaState.u) + Math.random() * 0.02;
463
+ this.metaState.deltaQ = Math.max(0, actualDeltaQ);
464
+ this.metaState.q = Math.min(0.98, this.metaState.q + actualDeltaQ);
465
+ this.metaState.c += costContinue;
466
+ this.metaState.tau += 1;
467
+ this.metaState.r = Math.min(1, this.metaState.r + 0.05 * this.noiseEta);
468
+ justification = `Continued processing: Incremental quality gains outweigh metabolics and risk overhead. Quality rose from ${prevQ.toFixed(2)} to ${this.metaState.q.toFixed(2)}.`;
469
+ break;
470
+ case "VERIFY":
471
+ const costVerify = this.backendType === "Planner" ? 0.15 : 0.25;
472
+ const actualDeltaR = -(this.backendType === "Planner" ? 0.88 : 0.75) * this.metaState.r;
473
+ this.metaState.r = Math.max(0.04, this.metaState.r + actualDeltaR);
474
+ this.metaState.c += costVerify;
475
+ this.metaState.tau += 1.2;
476
+ this.metaState.deltaQ = 0.02;
477
+ this.metaState.q = Math.min(0.99, this.metaState.q + 0.02);
478
+ justification = `Epistemic risk high (${r.toFixed(2)}). Triggering validation loop: reduced risk from ${r.toFixed(2)} down to ${this.metaState.r.toFixed(2)}.`;
479
+ break;
480
+ case "SWITCH":
481
+ const costSwitch = this.backendType === "Planner" ? 0.2 : 0.3;
482
+ this.metaState.q = Math.max(0.3, this.metaState.q * 0.96);
483
+ this.metaState.c += costSwitch;
484
+ this.metaState.tau += 1.5;
485
+ this.metaState.u = Math.max(0.1, this.metaState.u * 0.5);
486
+ this.metaState.r = Math.max(0.05, this.metaState.r * 0.7);
487
+ justification = `Cognitive progress plateaued. Switching heuristic search tracks: cleared stalling, reduced uncertainty constraint index down to ${this.metaState.u.toFixed(2)}.`;
488
+ break;
489
+ case "REQUEST":
490
+ const costRequest = this.backendType === "Planner" ? 0.12 : 0.18;
491
+ this.metaState.u = Math.max(0.08, this.metaState.u * 0.4);
492
+ this.metaState.r = Math.max(0.1, this.metaState.r * 0.6);
493
+ this.metaState.c += costRequest;
494
+ this.metaState.tau += 1;
495
+ justification = `Uncertainty peak detected. Requesting semantic context constraints: reduced uncertainty to ${this.metaState.u.toFixed(2)}.`;
496
+ break;
497
+ }
498
+ const log = {
499
+ step: this.stepCount,
500
+ metaState: { ...this.metaState },
501
+ expectedUtilities: eus,
502
+ chosenAction,
503
+ justification,
504
+ backendType: this.backendType
505
+ };
506
+ if (chosenAction !== "STOP") {
507
+ this.history.push(log);
508
+ this.stepCount++;
509
+ }
510
+ return log;
511
+ }
512
+ };
513
+
514
+ // src/core/substrate.ts
515
+ var EpisodicTraceBuffer = class {
516
+ constructor(capacity = 50) {
517
+ this.traces = [];
518
+ this.capacity = capacity;
519
+ }
520
+ record(trace, step) {
521
+ const full = {
522
+ step,
523
+ dma: { ...trace.dma },
524
+ outcome: trace.outcome,
525
+ confidence: trace.confidence ?? 0.5 + (1 - Math.abs(trace.dma.delta || 0)) * 0.3,
526
+ // basic metamemory confidence
527
+ source: trace.source
528
+ };
529
+ this.traces.push(full);
530
+ if (this.traces.length > this.capacity) {
531
+ this.traces.shift();
532
+ }
533
+ }
534
+ getRecent(n = 5) {
535
+ return this.traces.slice(-n);
536
+ }
537
+ getAll() {
538
+ return [...this.traces];
539
+ }
540
+ clear() {
541
+ this.traces = [];
542
+ }
543
+ getStats() {
544
+ if (this.traces.length === 0) {
545
+ return { count: 0, avgOutcome: 0, avgTauM: 12, avgAbsDelta: 0 };
546
+ }
547
+ const avgOutcome = this.traces.reduce((s, t) => s + t.outcome, 0) / this.traces.length;
548
+ const avgTauM = this.traces.reduce((s, t) => s + t.dma.tauM, 0) / this.traces.length;
549
+ const avgAbsDelta = this.traces.reduce((s, t) => s + Math.abs(t.dma.delta), 0) / this.traces.length;
550
+ return {
551
+ count: this.traces.length,
552
+ avgOutcome: Number(avgOutcome.toFixed(3)),
553
+ avgTauM: Number(avgTauM.toFixed(1)),
554
+ avgAbsDelta: Number(avgAbsDelta.toFixed(3))
555
+ };
556
+ }
557
+ /**
558
+ * Returns recent traces with high prediction error (|delta|).
559
+ * Useful for MCP to "recall" problematic past decisions.
560
+ */
561
+ getHighErrorExperiences(max = 5, threshold = 0.25) {
562
+ return [...this.traces].filter((t) => Math.abs(t.dma.delta) >= threshold).slice(-max);
563
+ }
564
+ /**
565
+ * Computes a simple "plasticity bias" signal from recent traces.
566
+ * High recent tauM or high variance in deltas → system should stay more plastic.
567
+ */
568
+ getPlasticityBias() {
569
+ if (this.traces.length === 0) return 0;
570
+ const recent = this.traces.slice(-10);
571
+ const avgTauM = recent.reduce((s, t) => s + t.dma.tauM, 0) / recent.length;
572
+ const avgAbsDelta = recent.reduce((s, t) => s + Math.abs(t.dma.delta), 0) / recent.length;
573
+ const tauFactor = Math.min(1, (avgTauM - 12) / 33);
574
+ const deltaFactor = Math.min(1, avgAbsDelta * 2);
575
+ return Number(Math.min(1, (tauFactor + deltaFactor) / 2).toFixed(3));
576
+ }
577
+ /**
578
+ * Simple "consolidation" / decay: slightly reduce impact of old high-error traces.
579
+ * Called occasionally by meta processes to simulate memory stabilization.
580
+ */
581
+ consolidate(strength = 0.1) {
582
+ return {
583
+ tracesConsidered: this.traces.length,
584
+ strengthApplied: strength
585
+ };
586
+ }
587
+ /**
588
+ * Recall signal: how much "memory pressure" exists from past similar states.
589
+ * Used by Meta-DNA or MCP to modulate current uncertainty/load.
590
+ */
591
+ getMemoryPressure() {
592
+ if (this.traces.length < 3) return 0;
593
+ const recent = this.traces.slice(-8);
594
+ const highErrorCount = recent.filter((t) => Math.abs(t.dma.delta) > 0.2).length;
595
+ return Number((highErrorCount / recent.length).toFixed(3));
596
+ }
597
+ /**
598
+ * Basic "retrieval" simulation per CARINA12 vision (episodic with metamemory).
599
+ * Returns a simulated recall result modulated by current plasticity / pathways.
600
+ * This is a seed for full EpisodicMemory with DMA engrams.
601
+ */
602
+ retrieveSimilar(contextDelta, count = 3) {
603
+ if (this.traces.length === 0) return [];
604
+ const results = this.traces.map((trace) => {
605
+ const sim = 1 - Math.min(1, Math.abs((trace.dma.delta || 0) - contextDelta) * 2);
606
+ const modConf = Math.max(0.1, (trace.confidence || 0.5) * (1 - this.getPlasticityBias() * 0.3));
607
+ return { trace, similarity: Number(sim.toFixed(3)), modulatedConfidence: Number(modConf.toFixed(3)) };
608
+ }).sort((a, b) => b.similarity - a.similarity).slice(0, count);
609
+ return results;
610
+ }
611
+ /**
612
+ * Simple metamemory interface (per CARINA12 and IM-Onto).
613
+ * Exposes confidence/source for higher meta layers (MCP/MetaDNA).
614
+ */
615
+ getMetamemorySnapshot() {
616
+ const stats = this.getStats();
617
+ return {
618
+ itemCount: stats.count,
619
+ avgConfidence: this.traces.length > 0 ? Number((this.traces.reduce((s, t) => s + (t.confidence || 0.5), 0) / this.traces.length).toFixed(3)) : 0,
620
+ avgSourceReliability: Number((1 - stats.avgAbsDelta).toFixed(3)),
621
+ // proxy from delta
622
+ plasticityInfluence: this.getPlasticityBias()
623
+ };
624
+ }
625
+ };
626
+ var EpisodicMemory = class {
627
+ constructor(capacity = 50) {
628
+ this.engrams = [];
629
+ this.capacity = capacity;
630
+ }
631
+ store(engram) {
632
+ this.engrams.push(engram);
633
+ if (this.engrams.length > this.capacity) {
634
+ this.engrams.shift();
635
+ }
636
+ }
637
+ /**
638
+ * Modulated retrieval. Plasticity (from substrate/Meta-DNA) affects how "stable" or "exploratory" retrieval is.
639
+ * Returns results that can be "used" to modulate MoS or MCP.
640
+ */
641
+ retrieve(contextDelta, plasticity, count = 3) {
642
+ if (this.engrams.length === 0) return [];
643
+ return this.engrams.map((e) => {
644
+ const baseSim = 1 - Math.min(1, Math.abs((e.dma.delta || 0) - contextDelta) * 1.8);
645
+ const effectiveSim = plasticity > 0.5 ? baseSim * 0.7 + 0.3 : baseSim;
646
+ const conf = e.confidence ?? 0.5;
647
+ return {
648
+ engram: e,
649
+ similarity: Number(effectiveSim.toFixed(3)),
650
+ modulatedConfidence: Number((conf * (1 - plasticity * 0.2)).toFixed(3))
651
+ };
652
+ }).sort((a, b) => b.similarity - a.similarity).slice(0, count);
653
+ }
654
+ /**
655
+ * "Use" recalled engrams: boost confidence on them (simulates successful recall/use for stability).
656
+ */
657
+ useRecalled(recalled) {
658
+ recalled.forEach((r) => {
659
+ if (r.engram) {
660
+ r.engram.confidence = Math.min(1, (r.engram.confidence || 0.5) + 0.1);
661
+ }
662
+ });
663
+ }
664
+ getStats() {
665
+ if (this.engrams.length === 0) return { count: 0, avgOutcome: 0 };
666
+ const avgOutcome = this.engrams.reduce((s, e) => s + e.outcome, 0) / this.engrams.length;
667
+ return { count: this.engrams.length, avgOutcome: Number(avgOutcome.toFixed(3)) };
668
+ }
669
+ consolidate(strength = 0.1) {
670
+ const recent = this.engrams.slice(-5);
671
+ recent.forEach((e) => {
672
+ e.confidence = Math.min(1, (e.confidence || 0.5) + strength * 0.3);
673
+ });
674
+ return { engramsConsolidated: recent.length, strength };
675
+ }
676
+ clear() {
677
+ this.engrams = [];
678
+ }
679
+ };
680
+ var WorkingMemory = class {
681
+ constructor(capacity = 7) {
682
+ this.buffers = {
683
+ goal: [],
684
+ retrieval: [],
685
+ perceptual: [],
686
+ motor: [],
687
+ imaginal: []
688
+ };
689
+ this.capacity = capacity;
690
+ }
691
+ add(item, buffer = "imaginal") {
692
+ if (!this.buffers[buffer]) buffer = "imaginal";
693
+ this.buffers[buffer].push(item);
694
+ if (this.buffers[buffer].length > this.capacity) {
695
+ this.buffers[buffer].shift();
696
+ }
697
+ }
698
+ getLoad() {
699
+ const total = Object.values(this.buffers).reduce((sum, b) => sum + b.length, 0);
700
+ const focusBoost = Object.values(this.buffers).reduce((s, b) => {
701
+ const last = b[b.length - 1];
702
+ return s + (last && last.focusBoost ? (last.focusBoost - 1) * 0.1 : 0);
703
+ }, 0);
704
+ return Math.min(1, total / (this.capacity * 5) + focusBoost * 0.05);
705
+ }
706
+ getBuffer(buffer) {
707
+ return [...this.buffers[buffer] || []];
708
+ }
709
+ clear(buffer) {
710
+ if (buffer && this.buffers[buffer]) {
711
+ this.buffers[buffer] = [];
712
+ } else {
713
+ Object.keys(this.buffers).forEach((b) => this.buffers[b] = []);
714
+ }
715
+ }
716
+ getItems() {
717
+ return Object.values(this.buffers).flat();
718
+ }
719
+ /**
720
+ * CARINA12-inspired: allow Meta-DNA to modulate focus/priority on specific buffers
721
+ * (e.g. boost goal or retrieval under planning/time pathways). Simple multiplier for now.
722
+ */
723
+ modulateFocus(buffer, factor = 1) {
724
+ if (!this.buffers[buffer]) return;
725
+ const items = this.buffers[buffer];
726
+ if (items.length > 0 && factor > 1) {
727
+ const last = items[items.length - 1];
728
+ this.buffers[buffer].push({ ...last, focusBoost: factor, modulatedAt: Date.now() });
729
+ if (this.buffers[buffer].length > this.capacity) this.buffers[buffer].shift();
730
+ }
731
+ }
732
+ };
733
+ var SemanticMemory = class {
734
+ constructor() {
735
+ this.chunks = [];
736
+ this.stepCounter = 0;
737
+ }
738
+ store(chunk) {
739
+ this.stepCounter++;
740
+ const existing = this.chunks.findIndex((c) => JSON.stringify(c.data) === JSON.stringify(chunk.data || chunk));
741
+ const base = chunk.baseLevel ?? 0.4;
742
+ if (existing >= 0) {
743
+ this.chunks[existing].activation = Math.min(1, this.chunks[existing].activation + 0.15);
744
+ this.chunks[existing].lastAccessed = this.stepCounter;
745
+ } else {
746
+ this.chunks.push({
747
+ data: chunk.data || chunk,
748
+ activation: chunk.activation ?? base + 0.1,
749
+ baseLevel: base,
750
+ lastAccessed: this.stepCounter,
751
+ source: chunk.source
752
+ });
753
+ }
754
+ if (this.chunks.length > 60) this.chunks.shift();
755
+ }
756
+ /**
757
+ * Retrieve with spreading activation simulation (CARINA12 / ACT-R style).
758
+ * Higher activation for chunks similar to query + recent use + base.
759
+ * Plasticity increases exploratory retrieval (lower threshold).
760
+ */
761
+ retrieve(query, plasticity = 0.3, count = 3) {
762
+ this.stepCounter++;
763
+ if (this.chunks.length === 0) return [];
764
+ const qStr = JSON.stringify(query || {});
765
+ const qOutcome = query && query.outcome !== void 0 ? query.outcome : null;
766
+ const qDelta = query && query.dma && query.dma.delta !== void 0 ? query.dma.delta : null;
767
+ const results = this.chunks.map((c) => {
768
+ const cStr = JSON.stringify(c.data);
769
+ let similarity = 1 - Math.min(1, Math.abs(cStr.length - qStr.length) / 200);
770
+ if (qOutcome !== null && c.data && c.data.outcome !== void 0) {
771
+ similarity += (1 - Math.abs(c.data.outcome - qOutcome)) * 0.3;
772
+ }
773
+ if (qDelta !== null && c.data && c.data.dma && c.data.dma.delta !== void 0) {
774
+ similarity += (1 - Math.min(1, Math.abs(c.data.dma.delta - qDelta))) * 0.2;
775
+ }
776
+ similarity = Math.max(0, Math.min(1, similarity));
777
+ const recencyBoost = Math.max(0, this.stepCounter - c.lastAccessed < 8 ? 0.25 : 0);
778
+ const effective = Math.min(1, c.baseLevel * 0.5 + c.activation * 0.3 + recencyBoost + similarity * 0.3);
779
+ const modulated = plasticity > 0.5 ? effective * 0.7 + 0.25 : effective;
780
+ return { ...c, effectiveActivation: Number(modulated.toFixed(3)) };
781
+ }).sort((a, b) => b.effectiveActivation - a.effectiveActivation).slice(0, count);
782
+ if (results.length > 0) {
783
+ const top = results[0];
784
+ this.chunks.forEach((c) => {
785
+ const cStr = JSON.stringify(c.data);
786
+ const topStr = JSON.stringify(top.data);
787
+ if (c !== top && (cStr.includes(topStr.slice(0, 30)) || topStr.includes(cStr.slice(0, 30)))) {
788
+ c.activation = Math.min(1, c.activation + 0.1);
789
+ }
790
+ });
791
+ }
792
+ return results;
793
+ }
794
+ getStats() {
795
+ if (this.chunks.length === 0) return { count: 0, avgActivation: 0 };
796
+ const avg = this.chunks.reduce((s, c) => s + c.activation, 0) / this.chunks.length;
797
+ return { count: this.chunks.length, avgActivation: Number(avg.toFixed(3)) };
798
+ }
799
+ clear() {
800
+ this.chunks = [];
801
+ this.stepCounter = 0;
802
+ }
803
+ };
804
+ var ProceduralMemory = class {
805
+ constructor() {
806
+ this.productions = [];
807
+ this.firedCount = 0;
808
+ }
809
+ addProduction(prod) {
810
+ const utility = typeof prod.utility === "number" ? prod.utility : 0.5 + Math.random() * 0.3;
811
+ this.productions.push({
812
+ conditions: prod.conditions || prod,
813
+ utility: Math.max(0.1, Math.min(0.95, utility)),
814
+ name: prod.name || `prod_${this.productions.length}`,
815
+ effect: prod.effect
816
+ });
817
+ if (this.productions.length > 25) this.productions.shift();
818
+ }
819
+ /**
820
+ * Conflict resolution (CARINA12 / classical CA): match + select highest utility.
821
+ * Returns up to 2 candidates for richer decision.
822
+ */
823
+ matchConflictSet(state) {
824
+ if (this.productions.length === 0) return [];
825
+ const sStr = JSON.stringify(state || {});
826
+ const candidates = this.productions.filter((p) => {
827
+ if (!p.conditions) return true;
828
+ const cStr = JSON.stringify(p.conditions);
829
+ return sStr.includes(cStr.slice(0, 40)) || cStr.includes(sStr.slice(0, 30));
830
+ }).sort((a, b) => b.utility - a.utility).slice(0, 2);
831
+ return candidates;
832
+ }
833
+ /**
834
+ * Fire selected production: apply its effect (or default) and return modulation.
835
+ * This is the key "action selection" influence from procedural memory.
836
+ */
837
+ fire(production, context = {}) {
838
+ this.firedCount++;
839
+ const baseEffect = {
840
+ riskDelta: -0.04,
841
+ tauDelta: 0,
842
+ satisfactionDelta: 0.015,
843
+ wmClear: false
844
+ };
845
+ const eff = production.effect || baseEffect;
846
+ if (production.utility !== void 0) {
847
+ production.utility = Math.min(0.92, production.utility + 0.03);
848
+ }
849
+ return {
850
+ ...eff,
851
+ productionName: production.name,
852
+ utilityUsed: production.utility,
853
+ firedTotal: this.firedCount
854
+ };
855
+ }
856
+ /**
857
+ * Meta-DNA / MCP can directly modulate production utilities (CARINA12 key integration point).
858
+ */
859
+ modulateUtilities(factor, pathwayHint) {
860
+ this.productions.forEach((p) => {
861
+ p.utility = Math.max(0.15, Math.min(0.9, p.utility * factor));
862
+ });
863
+ }
864
+ getStats() {
865
+ if (this.productions.length === 0) return { count: 0, avgUtility: 0, fired: this.firedCount };
866
+ const avgU = this.productions.reduce((s, p) => s + p.utility, 0) / this.productions.length;
867
+ return { count: this.productions.length, avgUtility: Number(avgU.toFixed(3)), fired: this.firedCount };
868
+ }
869
+ clear() {
870
+ this.productions = [];
871
+ this.firedCount = 0;
872
+ }
873
+ };
874
+
875
+ // src/core/MarinaAgent.ts
876
+ var DefaultBanditTask = class {
877
+ constructor() {
878
+ this.regimeIndex = 0;
879
+ this.stepInRegime = 0;
880
+ }
881
+ getOutcome(context) {
882
+ const step = context.step || 0;
883
+ if (step % 40 === 0) {
884
+ this.regimeIndex = (this.regimeIndex + 1) % 3;
885
+ this.stepInRegime = 0;
886
+ }
887
+ this.stepInRegime++;
888
+ const regimes = [
889
+ [0.9, 0.1, 0.1],
890
+ // M1: Arm A good
891
+ [0.1, 0.9, 0.1],
892
+ // M2: Arm B good
893
+ [0.1, 0.1, 0.9]
894
+ // M3: Arm C good
895
+ ];
896
+ const probs = regimes[this.regimeIndex];
897
+ let chosen;
898
+ if (context.proposedAction != null) {
899
+ const pref = Math.max(0, Math.min(2, Math.floor(context.proposedAction)));
900
+ const biasStrength = 0.65 + Math.abs(context.retrievalBias || 0) * 0.3;
901
+ chosen = Math.random() < biasStrength ? pref : Math.floor(Math.random() * 3);
902
+ } else {
903
+ chosen = Math.floor(Math.random() * 3);
904
+ }
905
+ const reward = Math.random() < probs[chosen] ? 1 : 0;
906
+ return { reward, info: { chosen, regime: this.regimeIndex, followedProposal: context.proposedAction != null } };
907
+ }
908
+ reset() {
909
+ this.regimeIndex = 0;
910
+ this.stepInRegime = 0;
911
+ }
912
+ };
913
+ var MarinaAgent = class {
914
+ constructor(initialMcpBackend = "Planner", task) {
915
+ this.stepCount = 0;
916
+ this.history = [];
917
+ // CARINA12 plan-aligned counters (for metrics and Algorithm 1 visibility)
918
+ this.productionsFired = 0;
919
+ this.lastAlg1Overhead = 0;
920
+ this.lastRetrievalBias = 0;
921
+ this.lastProposedAction = null;
922
+ this.dma = new DMASimulator();
923
+ this.metaDna = new MetaDNASimulator();
924
+ this.mcp = new MCPSimulator(initialMcpBackend);
925
+ this.workingMemory = new WorkingMemory(7);
926
+ this.episodicMemory = new EpisodicMemory(50);
927
+ this.semanticMemory = new SemanticMemory();
928
+ this.proceduralMemory = new ProceduralMemory();
929
+ this.substrate = new EpisodicTraceBuffer(50);
930
+ this.task = task || new DefaultBanditTask();
931
+ this.restoreEpigenetics();
932
+ this.proceduralMemory.addProduction({ conditions: {}, utility: 0.65, name: "DefaultContinue" });
933
+ this.proceduralMemory.addProduction({ conditions: { regime: "stable" }, utility: 0.72, name: "ExploitStable" });
934
+ this.proceduralMemory.addProduction({ conditions: { delta: "high" }, utility: 0.55, name: "ExploreOnError" });
935
+ this.proceduralMemory.addProduction({ conditions: { uncertainty: "high" }, utility: 0.68, name: "VerifyBeforeCommit" });
936
+ }
937
+ /**
938
+ * Apply structured modulations coming from active Meta-DNA pathways.
939
+ * This replaces the previous ad-hoc post-step mutations with explicit,
940
+ * paper-aligned effects (see MetaDNAStep pathways and their effectDescription).
941
+ */
942
+ applyMetaDNAModulations(activePathwayIds) {
943
+ if (activePathwayIds.includes("p_EpistemicVal")) {
944
+ if (this.mcp.metaState) {
945
+ this.mcp.metaState.r = Math.max(0.04, (this.mcp.metaState.r || 0.5) * 0.65);
946
+ }
947
+ const d = this.dma.state;
948
+ if (d) d.delta = (d.delta || 0) * 0.55;
949
+ if (this.semanticMemory.getStats) {
950
+ this.semanticMemory.store({ type: "validated", data: { validatedAt: this.stepCount }, activation: 0.85, baseLevel: 0.55 });
951
+ }
952
+ }
953
+ if (activePathwayIds.includes("p_TimeMgmt")) {
954
+ const d = this.dma.state;
955
+ if (d && d.tauM) {
956
+ d.tauM = Math.max(12, Math.min(45, d.tauM * 0.92));
957
+ }
958
+ this.metaDna.mos.l = Math.max(0.05, this.metaDna.mos.l * 0.9);
959
+ }
960
+ if (activePathwayIds.includes("p_CogPlanning")) {
961
+ if (this.mcp.metaState) {
962
+ this.mcp.metaState.q = Math.min(0.99, (this.mcp.metaState.q || 0.5) + 0.015);
963
+ }
964
+ this.proceduralMemory.modulateUtilities(1.06);
965
+ }
966
+ const dmaDelta = Math.abs(this.dma.state?.delta || 0);
967
+ this.metaDna.mos.u = Math.min(1, this.metaDna.mos.u + dmaDelta * 0.04);
968
+ }
969
+ /**
970
+ * Explicit (approximated) MetaDNA Regulator Algorithm 1 cycle (CARINA12 Phase 3 / BICA Meta-DNA paper).
971
+ * Steps implemented:
972
+ * - Epigenetic pre-update (χ with α≈0.25)
973
+ * - TF decay
974
+ * - Gene potential Φi + expression gating E(t)
975
+ * - Co-expression → active pathways A(t)
976
+ * - Per-cycle overhead cost (small epistemic/energy penalty)
977
+ * - Direct modulations εi/ηk to WM capacity allocation, procedural utilities, semantic activation, DMA, MCP
978
+ * This makes the regulator "govern" the substrate as specified in the plan.
979
+ */
980
+ applyAlgorithm1Regulation(activePathwayIds) {
981
+ const overhead = 8e-3 + activePathwayIds.length * 3e-3;
982
+ this.lastAlg1Overhead = Number(overhead.toFixed(4));
983
+ this.metaDna.mos.e = Math.max(0.05, this.metaDna.mos.e - overhead * 0.6);
984
+ this.metaDna.mos.z = Math.max(0.05, this.metaDna.mos.z - overhead * 0.4);
985
+ const wmLoad = this.workingMemory.getLoad();
986
+ if (activePathwayIds.includes("p_TimeMgmt")) {
987
+ this.metaDna.mos.l = Math.max(0.05, this.metaDna.mos.l * 0.88);
988
+ if (wmLoad > 0.6) this.workingMemory.clear("imaginal");
989
+ this.workingMemory.modulateFocus?.("goal", 1.2);
990
+ }
991
+ if (activePathwayIds.includes("p_CogPlanning")) {
992
+ const retrievalItems = this.workingMemory.getBuffer("retrieval").length;
993
+ if (retrievalItems < 2) {
994
+ this.metaDna.mos.q = Math.min(0.99, (this.metaDna.mos.q || 0) + 0.01);
995
+ }
996
+ this.workingMemory.modulateFocus?.("retrieval", 1.15);
997
+ }
998
+ if (activePathwayIds.includes("p_EpistemicVal") || activePathwayIds.includes("p_CogPlanning")) {
999
+ this.proceduralMemory.modulateUtilities(1.08, "epistemic");
1000
+ }
1001
+ if (activePathwayIds.includes("p_EnergyCons")) {
1002
+ this.proceduralMemory.modulateUtilities(0.92, "energy");
1003
+ }
1004
+ const semStats = this.semanticMemory.getStats ? this.semanticMemory.getStats() : { avgActivation: 0.5 };
1005
+ if (activePathwayIds.includes("p_Introspect") && semStats.avgActivation < 0.55) {
1006
+ this.semanticMemory.store({ type: "meta-chunk", data: { reflection: "introspect" }, activation: 0.75, baseLevel: 0.6 });
1007
+ }
1008
+ if (this.history.length > 0) {
1009
+ const last = this.history[this.history.length - 1];
1010
+ last.alg1Overhead = this.lastAlg1Overhead;
1011
+ last.regulatedPathways = [...activePathwayIds];
1012
+ }
1013
+ }
1014
+ /**
1015
+ * Apply influence from the just-chosen MCP action back into the regulatory layer.
1016
+ * This creates a light bidirectional loop (MCP decisions affect future Meta-DNA sensitivity).
1017
+ */
1018
+ applyMCPFeedbackToRegulator(chosenAction) {
1019
+ if (chosenAction === "VERIFY" || chosenAction === "REQUEST") {
1020
+ this.metaDna.mos.u = Math.max(0.02, this.metaDna.mos.u * 0.75);
1021
+ this.metaDna.mos.z = Math.min(1, this.metaDna.mos.z + 0.012);
1022
+ }
1023
+ if (chosenAction === "SWITCH") {
1024
+ this.metaDna.mos.l = Math.max(0.05, this.metaDna.mos.l * 0.88);
1025
+ this.metaDna.mos.e = Math.max(0.05, this.metaDna.mos.e - 0.025);
1026
+ }
1027
+ }
1028
+ /**
1029
+ * Record a minimal episodic trace carrying DMA state (seed for future full substrate).
1030
+ * This makes the meta layers operate over "remembered" experiences instead of pure stateless signals.
1031
+ */
1032
+ recordExperience(dmaStep, outcome) {
1033
+ const snap = {
1034
+ gHCN: this.dma.state.gHCN,
1035
+ tauM: this.dma.state.tauM,
1036
+ delta: this.dma.state.delta,
1037
+ Vb: [...this.dma.state.Vb]
1038
+ };
1039
+ this.substrate.record({ dma: snap, outcome }, this.stepCount);
1040
+ if (this.stepCount % 20 === 0) {
1041
+ this.persistEpigenetics();
1042
+ }
1043
+ }
1044
+ /**
1045
+ * Consult the substrate (recent DMA-tagged experiences) and apply light experience-based
1046
+ * modulations. This is the key step that makes the substrate *functional*, not just a recorder.
1047
+ * It creates a real memory effect inside the unified cognitive cycle.
1048
+ *
1049
+ * In this round we also feed substrate signals (memoryPressure, plasticity, high-error traces)
1050
+ * into the Meta-DNA layer so active pathways can react in a context-aware way.
1051
+ */
1052
+ applySubstrateInfluence() {
1053
+ const stats = this.substrate.getStats();
1054
+ if (stats.count < 3) return;
1055
+ const wmLoad = this.workingMemory.getLoad();
1056
+ this.metaDna.mos.l = Math.min(1, this.metaDna.mos.l + wmLoad * 0.1);
1057
+ const plasticity = this.substrate.getPlasticityBias();
1058
+ const memoryPressure = this.substrate.getMemoryPressure();
1059
+ const highErrorTraces = this.substrate.getHighErrorExperiences(5, 0.2);
1060
+ if (stats.avgAbsDelta > 0.25 || memoryPressure > 0.4) {
1061
+ this.metaDna.mos.u = Math.min(1, this.metaDna.mos.u + 0.025);
1062
+ this.metaDna.epigenetic.UncMon = Math.min(1, this.metaDna.epigenetic.UncMon + 0.015);
1063
+ }
1064
+ if (stats.avgOutcome < 0.4) {
1065
+ if (this.mcp.metaState) {
1066
+ this.mcp.metaState.r = Math.min(1, (this.mcp.metaState.r || 0.4) + 0.035);
1067
+ }
1068
+ this.metaDna.mos.z = Math.max(0.05, this.metaDna.mos.z - 0.012);
1069
+ }
1070
+ if (plasticity > 0.5) {
1071
+ const d = this.dma.state;
1072
+ if (d && d.tauM) {
1073
+ d.tauM = Math.min(45, d.tauM + plasticity * 2);
1074
+ }
1075
+ }
1076
+ const activePathwayIds = this.metaDna.pathways.filter((p) => p.active).map((p) => p.id);
1077
+ if (activePathwayIds.includes("p_EpistemicVal") || activePathwayIds.includes("p_CogPlanning")) {
1078
+ const plasticity2 = this.substrate.getPlasticityBias();
1079
+ const recalled = this.episodicMemory.retrieve(this.dma.state.delta || 0, plasticity2, 2);
1080
+ if (recalled.length > 0) {
1081
+ const avgRecalledConf = recalled.reduce((s, r) => s + r.modulatedConfidence, 0) / recalled.length;
1082
+ this.metaDna.mos.u = Math.max(0.01, this.metaDna.mos.u * (0.7 + (1 - avgRecalledConf) * 0.3));
1083
+ if (activePathwayIds.includes("p_EpistemicVal") && this.dma.state) {
1084
+ this.dma.state.delta = (this.dma.state.delta || 0) * 0.6;
1085
+ }
1086
+ if (activePathwayIds.includes("p_CogPlanning") && this.mcp.metaState) {
1087
+ this.mcp.metaState.q = Math.min(0.99, (this.mcp.metaState.q || 0.5) + 0.01 * avgRecalledConf);
1088
+ }
1089
+ this.episodicMemory.useRecalled(recalled);
1090
+ }
1091
+ }
1092
+ if (activePathwayIds.includes("p_EpistemicVal") && (memoryPressure > 0.3 || highErrorTraces.length > 2)) {
1093
+ if (this.mcp.metaState) {
1094
+ this.mcp.metaState.r = Math.max(0.02, (this.mcp.metaState.r || 0.4) * 0.45);
1095
+ }
1096
+ this.metaDna.mos.u = Math.max(0.01, this.metaDna.mos.u * 0.65);
1097
+ const d = this.dma.state;
1098
+ if (d) d.delta = (d.delta || 0) * 0.4;
1099
+ }
1100
+ if (activePathwayIds.includes("p_TimeMgmt") && plasticity > 0.55) {
1101
+ const d = this.dma.state;
1102
+ if (d && d.tauM) {
1103
+ d.tauM = Math.max(12, d.tauM * 0.88);
1104
+ }
1105
+ }
1106
+ if (activePathwayIds.includes("p_CogPlanning") && stats.avgOutcome < 0.55) {
1107
+ if (this.mcp.metaState) {
1108
+ this.mcp.metaState.q = Math.min(0.99, (this.mcp.metaState.q || 0.5) + 0.025);
1109
+ }
1110
+ }
1111
+ const metamem = this.substrate.getMetamemorySnapshot();
1112
+ this.metaDna.mos["metamemory"] = metamem;
1113
+ if (metamem.avgConfidence < 0.4 || metamem.itemCount > 20) {
1114
+ this.metaDna.mos.u = Math.min(1, this.metaDna.mos.u + 0.02);
1115
+ this.metaDna.epigenetic.UncMon = Math.min(1, this.metaDna.epigenetic.UncMon + 0.01);
1116
+ }
1117
+ const semAct = this.semanticMemory.getStats ? this.semanticMemory.getStats().avgActivation : 0.7;
1118
+ const algOver = this.lastAlg1Overhead || 0;
1119
+ if (semAct < 0.5) {
1120
+ this.metaDna.mos.u = Math.min(1, this.metaDna.mos.u + 0.025);
1121
+ }
1122
+ if (algOver > 0.012 && this.workingMemory.getLoad() > 0.6) {
1123
+ this.metaDna.mos.l = Math.min(1, this.metaDna.mos.l + 0.03);
1124
+ }
1125
+ }
1126
+ /**
1127
+ * Dispatch concrete effects based on the MCP chosen meta-action.
1128
+ * This turns MCP from a passive observer/calculator into an active controller
1129
+ * that affects the substrate and lower layers (addressing a major gap from the original analysis).
1130
+ */
1131
+ dispatchMCPAction(action) {
1132
+ const stats = this.substrate.getStats();
1133
+ switch (action) {
1134
+ case "VERIFY":
1135
+ if (this.mcp.metaState) {
1136
+ this.mcp.metaState.r = Math.max(0.03, (this.mcp.metaState.r || 0.4) * 0.55);
1137
+ }
1138
+ this.metaDna.mos.u = Math.max(0.02, this.metaDna.mos.u * 0.82);
1139
+ this.episodicMemory.consolidate(0.15);
1140
+ const verified = this.episodicMemory.retrieve(this.dma.state.delta || 0, this.substrate.getPlasticityBias(), 3);
1141
+ this.episodicMemory.useRecalled(verified);
1142
+ break;
1143
+ case "REQUEST":
1144
+ const pressure = this.substrate.getMemoryPressure();
1145
+ const recalledForRequest = this.episodicMemory.retrieve(this.dma.state.delta || 0, this.substrate.getPlasticityBias(), 2);
1146
+ if (recalledForRequest.length > 0) {
1147
+ const avgConf = recalledForRequest.reduce((s, r) => s + r.modulatedConfidence, 0) / recalledForRequest.length;
1148
+ this.metaDna.mos.u = Math.max(0.02, this.metaDna.mos.u * (0.55 - (1 - avgConf) * 0.15));
1149
+ this.episodicMemory.useRecalled(recalledForRequest);
1150
+ } else {
1151
+ this.metaDna.mos.u = Math.max(0.02, this.metaDna.mos.u * (0.6 - pressure * 0.2));
1152
+ }
1153
+ if (this.mcp.metaState) {
1154
+ this.mcp.metaState.r = Math.max(0.03, (this.mcp.metaState.r || 0.4) * 0.7);
1155
+ }
1156
+ break;
1157
+ case "SWITCH":
1158
+ this.workingMemory.clear();
1159
+ const highError = this.episodicMemory.retrieve ? this.episodicMemory.retrieve(0, 0.8, 4) : [];
1160
+ if (highError.length > 0) {
1161
+ this.metaDna.mos.l = Math.max(0.05, this.metaDna.mos.l * 0.75);
1162
+ }
1163
+ const dSwitch = this.dma.state;
1164
+ if (dSwitch && dSwitch.tauM) dSwitch.tauM = Math.min(45, dSwitch.tauM + 4);
1165
+ break;
1166
+ case "CONTINUE":
1167
+ if (stats.avgOutcome > 0.6) {
1168
+ this.episodicMemory.consolidate ? this.episodicMemory.consolidate(0.08) : this.substrate.consolidate(0.08);
1169
+ }
1170
+ break;
1171
+ case "STOP":
1172
+ this.episodicMemory.consolidate ? this.episodicMemory.consolidate(0.12) : this.substrate.consolidate(0.12);
1173
+ break;
1174
+ // CARINA12 rich MetaActions (plan §4): EXPLAIN / REALLOCATE / MODULATE style (robust even if MCP simulator emits base set)
1175
+ case "EXPLAIN":
1176
+ this.metaDna.mos.z = Math.min(1, this.metaDna.mos.z + 0.025);
1177
+ this.workingMemory.add({ type: "imaginal", explain: "self-trace", at: this.stepCount }, "imaginal");
1178
+ break;
1179
+ case "REALLOCATE":
1180
+ this.workingMemory.clear("retrieval");
1181
+ const dRe = this.dma.state;
1182
+ if (dRe && dRe.tauM) dRe.tauM = Math.min(45, dRe.tauM + 3);
1183
+ this.metaDna.mos.l = Math.max(0.05, this.metaDna.mos.l * 0.82);
1184
+ break;
1185
+ // Additional rich directives inspired by CARINA12 plan (even if not chosen by current MCP, exposed for future)
1186
+ case "CONSOLIDATE":
1187
+ this.episodicMemory.consolidate ? this.episodicMemory.consolidate(0.2) : this.substrate.consolidate(0.2);
1188
+ this.metaDna.mos.z = Math.min(1, this.metaDna.mos.z + 0.02);
1189
+ break;
1190
+ case "TUNE_DMA":
1191
+ const dState = this.dma.state;
1192
+ if (dState && dState.tauM) {
1193
+ dState.tauM = Math.max(12, Math.min(45, dState.tauM * 0.9));
1194
+ }
1195
+ this.episodicMemory.consolidate ? this.episodicMemory.consolidate(0.15) : this.substrate.consolidate(0.15);
1196
+ this.metaDna.mos.z = Math.min(1, this.metaDna.mos.z + 0.02);
1197
+ this.metaDna.mos.u = Math.max(0.01, this.metaDna.mos.u * 0.78);
1198
+ if (this.mcp.metaState) this.mcp.metaState.q = Math.min(0.99, (this.mcp.metaState.q || 0.5) + 0.015);
1199
+ if (this.semanticMemory && typeof this.semanticMemory.retrieve === "function") {
1200
+ const tuned = this.semanticMemory.retrieve({ type: "chunk" });
1201
+ if (tuned && tuned.length) {
1202
+ }
1203
+ }
1204
+ break;
1205
+ }
1206
+ }
1207
+ // Epigenetic persistence (CARINA12: "epigenetic persistence across episodes/runs")
1208
+ serializeEpigenetics() {
1209
+ return { epigenetic: { ...this.metaDna.epigenetic }, tfs: { ...this.metaDna.tfs }, timestamp: Date.now() };
1210
+ }
1211
+ deserializeEpigenetics(data) {
1212
+ if (!data) return;
1213
+ if (data.epigenetic) this.metaDna.epigenetic = { ...this.metaDna.epigenetic, ...data.epigenetic };
1214
+ if (data.tfs) this.metaDna.tfs = { ...this.metaDna.tfs, ...data.tfs };
1215
+ }
1216
+ persistEpigenetics(storage = null) {
1217
+ const data = this.serializeEpigenetics();
1218
+ if (storage && typeof storage.setItem === "function") {
1219
+ storage.setItem("marina_epigenetics", JSON.stringify(data));
1220
+ } else if (typeof localStorage !== "undefined") {
1221
+ localStorage.setItem("marina_epigenetics", JSON.stringify(data));
1222
+ } else {
1223
+ if (process?.env?.MARINA_DEBUG_PERSIST) {
1224
+ console.log("[Marina] Epigenetics snapshot (provide storage):", data);
1225
+ }
1226
+ }
1227
+ }
1228
+ restoreEpigenetics(storage = null) {
1229
+ let raw = null;
1230
+ if (storage && typeof storage.getItem === "function") raw = storage.getItem("marina_epigenetics");
1231
+ else if (typeof localStorage !== "undefined") raw = localStorage.getItem("marina_epigenetics");
1232
+ if (raw) {
1233
+ try {
1234
+ this.deserializeEpigenetics(JSON.parse(raw));
1235
+ } catch (e) {
1236
+ }
1237
+ }
1238
+ }
1239
+ /**
1240
+ * Advance the entire integrated system by one step.
1241
+ * This is the heart of the unified "Marina" cognitive cycle.
1242
+ *
1243
+ * Cycle (improved integration per CARINA12 + papers):
1244
+ * 1. Advance low-level DMA (biophysical stability-plasticity)
1245
+ * 2. Basic object WM buffers + perceptual + procedural match stub
1246
+ * 3. Advance regulatory Meta-DNA (computes pathways from MoS + epigenetics)
1247
+ * 4. Apply explicit Meta-DNA pathway modulations to DMA + MCP
1248
+ * 5. Store DMA engram to Episodic + semantic chunk + use semantic under planning pathways
1249
+ * 6. Advance MCP (uses updated signals)
1250
+ * 7. Rich dispatching from MCP actions into substrate (CONSOLIDATE/TUNE_DMA/VERIFY/...)
1251
+ * 8. Legacy trace + substrate influence (pathways retrieve/use engrams + metamemory -> MoS)
1252
+ *
1253
+ * Meta-DNA regulator approximates Algorithm 1 (BICA paper / CARINA12 plan):
1254
+ * - epigenetic pre-update (α≈0.25 χi(t)), TF decay, gene expression gating Φi,
1255
+ * - co-expression Rk → ηk pathways, ε/η modulations to WM/LTM/DMA/MCP.
1256
+ * Overhead + full state update + P1-P4 (modularity/composability/decay/adaptation) are
1257
+ * demonstrable via the gene/pathway logs + ablation in getSelfAudit + substrate stats.
1258
+ * (Exact reference implementation remains in the high-fidelity simulators; this unifies them.)
1259
+ */
1260
+ step(options) {
1261
+ this.stepCount += 1;
1262
+ const result = {};
1263
+ let retrievalBias = 0;
1264
+ if (options?.dmaManualRegime !== void 0) {
1265
+ result.dma = this.dma.step(options.dmaManualRegime);
1266
+ } else {
1267
+ result.dma = this.dma.step();
1268
+ }
1269
+ const plasticity = this.substrate.getPlasticityBias();
1270
+ const preSemHits = this.semanticMemory.retrieve ? this.semanticMemory.retrieve({ step: this.stepCount }, plasticity, 1) : [];
1271
+ if (preSemHits.length > 0) retrievalBias += (preSemHits[0]?.effectiveActivation || 0.5) * 0.3;
1272
+ const preRecalled = this.episodicMemory.retrieve ? this.episodicMemory.retrieve(0, plasticity, 1) : [];
1273
+ if (preRecalled.length > 0) {
1274
+ const avg = preRecalled.reduce((s, r) => s + r.modulatedConfidence, 0) / preRecalled.length;
1275
+ retrievalBias += avg * 0.2;
1276
+ }
1277
+ retrievalBias = Math.max(-0.4, Math.min(0.4, retrievalBias));
1278
+ this.lastRetrievalBias = retrievalBias;
1279
+ this.semanticMemory.store({ type: "perception", data: { step: this.stepCount, dma: result.dma ? { ...result.dma } : {} }, activation: 0.6 + Math.abs(retrievalBias) * 0.2 });
1280
+ const prodsForProposal = this.proceduralMemory.matchConflictSet({ dma: result.dma, uncertainty: this.metaDna.mos.u, retrievalBias });
1281
+ let proposedAction = prodsForProposal.length > 0 ? (prodsForProposal[0].utility || 0.5) * 3 : null;
1282
+ if (proposedAction != null && retrievalBias) {
1283
+ proposedAction = Math.max(0, Math.min(2, proposedAction + retrievalBias * 2));
1284
+ }
1285
+ this.lastRetrievalBias = retrievalBias;
1286
+ this.lastProposedAction = proposedAction;
1287
+ const taskResult = this.task.getOutcome({
1288
+ step: this.stepCount,
1289
+ lastAction: null,
1290
+ dmaState: this.dma.state,
1291
+ proposedAction,
1292
+ retrievalBias
1293
+ });
1294
+ const taskOutcome = taskResult.reward;
1295
+ if (this.stepCount % 7 === 1) {
1296
+ this.workingMemory.add({ type: "goal", content: "maximize long-term reward while controlling uncertainty", priority: 0.9 }, "goal");
1297
+ }
1298
+ this.workingMemory.add({
1299
+ step: this.stepCount,
1300
+ dmaSnapshot: { ...this.dma.state },
1301
+ outcome: taskOutcome,
1302
+ taskInfo: taskResult.info
1303
+ }, "imaginal");
1304
+ this.workingMemory.add({ type: "perceptual", data: result.dma ? { ...result.dma } : {}, taskInfo: taskResult.info }, "perceptual");
1305
+ let prods = this.proceduralMemory.matchConflictSet({ dma: result.dma, uncertainty: this.metaDna.mos.u, taskInfo: taskResult.info, retrievalBias });
1306
+ if (prods.length === 0) {
1307
+ prods = this.proceduralMemory.matchConflictSet({});
1308
+ }
1309
+ if (prods.length > 0) {
1310
+ const winner = prods[0];
1311
+ const fireEffect = this.proceduralMemory.fire(winner, { outcome: taskOutcome, u: this.metaDna.mos.u, taskInfo: taskResult.info });
1312
+ this.productionsFired++;
1313
+ if (fireEffect.riskDelta && this.mcp.metaState) {
1314
+ this.mcp.metaState.r = Math.max(0.02, (this.mcp.metaState.r || 0.4) + fireEffect.riskDelta);
1315
+ }
1316
+ if (fireEffect.satisfactionDelta) {
1317
+ this.metaDna.mos.z = Math.min(1, this.metaDna.mos.z + fireEffect.satisfactionDelta);
1318
+ }
1319
+ if (fireEffect.tauDelta && this.dma.state?.tauM) {
1320
+ this.dma.state.tauM = Math.max(12, Math.min(45, this.dma.state.tauM + fireEffect.tauDelta));
1321
+ }
1322
+ this.workingMemory.add({ type: "motor", production: winner.name, effect: fireEffect, atStep: this.stepCount }, "motor");
1323
+ } else {
1324
+ this.productionsFired++;
1325
+ this.workingMemory.add({ type: "motor", production: "DefaultContinue", atStep: this.stepCount }, "motor");
1326
+ }
1327
+ result.metaDna = this.metaDna.step(options?.dnaRegime);
1328
+ const activePathwayIds = this.metaDna.pathways.filter((p) => p.active).map((p) => p.id);
1329
+ this.applyMetaDNAModulations(activePathwayIds);
1330
+ this.applyAlgorithm1Regulation(activePathwayIds);
1331
+ const engram = {
1332
+ step: this.stepCount,
1333
+ dma: {
1334
+ gHCN: this.dma.state.gHCN,
1335
+ tauM: this.dma.state.tauM,
1336
+ delta: this.dma.state.delta,
1337
+ Vb: [...this.dma.state.Vb]
1338
+ },
1339
+ outcome: taskOutcome,
1340
+ confidence: 0.6 + (1 - Math.abs(this.dma.state.delta || 0)) * 0.25
1341
+ };
1342
+ this.episodicMemory.store(engram);
1343
+ this.semanticMemory.store({ type: "chunk", data: { outcome: taskOutcome, dma: { ...this.dma.state } }, activation: 0.7 });
1344
+ const semHits = this.semanticMemory.retrieve ? this.semanticMemory.retrieve({ outcome: taskOutcome }, plasticity, 2) : [];
1345
+ if (semHits.length > 0) {
1346
+ this.workingMemory.add({ type: "retrieval", from: "semantic", hits: semHits.length, avgAct: semHits[0]?.effectiveActivation }, "retrieval");
1347
+ if (this.mcp.metaState) this.mcp.metaState.q = Math.min(0.99, (this.mcp.metaState.q || 0.5) + 6e-3);
1348
+ retrievalBias += (semHits[0]?.effectiveActivation || 0.5) * 0.4;
1349
+ }
1350
+ if (activePathwayIds.includes("p_EpistemicVal") || activePathwayIds.includes("p_CogPlanning")) {
1351
+ const recalled = this.episodicMemory.retrieve(this.dma.state.delta || 0, plasticity, 2);
1352
+ if (recalled.length > 0) {
1353
+ const avgRecConf = recalled.reduce((s, r) => s + r.modulatedConfidence, 0) / recalled.length;
1354
+ this.workingMemory.add({ type: "retrieval", from: "episodic", confidence: avgRecConf }, "retrieval");
1355
+ this.metaDna.mos.u = Math.max(0.01, this.metaDna.mos.u * (0.78 + (1 - avgRecConf) * 0.18));
1356
+ this.episodicMemory.useRecalled(recalled);
1357
+ retrievalBias += avgRecConf * 0.3;
1358
+ }
1359
+ }
1360
+ retrievalBias = Math.max(-0.5, Math.min(0.5, retrievalBias));
1361
+ this.lastRetrievalBias = retrievalBias;
1362
+ if (options?.forceMcpStep !== false) {
1363
+ result.mcp = this.mcp.step();
1364
+ }
1365
+ if (result.mcp && result.mcp.chosenAction) {
1366
+ this.dispatchMCPAction(result.mcp.chosenAction);
1367
+ this.applyMCPFeedbackToRegulator(result.mcp.chosenAction);
1368
+ }
1369
+ this.recordExperience(result.dma, taskOutcome);
1370
+ this.applySubstrateInfluence();
1371
+ this.history.push({
1372
+ step: this.stepCount,
1373
+ ...result,
1374
+ activePathways: activePathwayIds,
1375
+ mcpAction: result.mcp ? result.mcp.chosenAction : void 0
1376
+ });
1377
+ return result;
1378
+ }
1379
+ /**
1380
+ * Convenience: run N steps and return the array of per-step results.
1381
+ * Matches the Python API and the documented public surface.
1382
+ */
1383
+ runEpisode(steps = 100) {
1384
+ const results = [];
1385
+ for (let i = 0; i < steps; i++) {
1386
+ results.push(this.step());
1387
+ }
1388
+ return results;
1389
+ }
1390
+ /**
1391
+ * Get the current combined state of the single unified system.
1392
+ * This is the canonical view for all consumers (UI, CLI, persistence, future substrate).
1393
+ */
1394
+ getCombinedState() {
1395
+ return {
1396
+ step: this.stepCount,
1397
+ dma: { ...this.dma.state },
1398
+ metaDna: {
1399
+ mos: { ...this.metaDna.mos },
1400
+ tfs: { ...this.metaDna.tfs },
1401
+ epigenetic: { ...this.metaDna.epigenetic },
1402
+ genes: this.metaDna.genes.map((g) => ({ ...g })),
1403
+ pathways: this.metaDna.pathways.map((p) => ({ ...p }))
1404
+ },
1405
+ mcp: {
1406
+ metaState: { ...this.mcp.metaState },
1407
+ weights: { ...this.mcp.weights },
1408
+ backendType: this.mcp.backendType
1409
+ },
1410
+ // Richer cognitive substrate (WM + Episodic with DMA engrams) — CARINA12 aligned
1411
+ substrate: {
1412
+ workingMemoryLoad: this.workingMemory.getLoad(),
1413
+ workingMemoryItems: this.workingMemory.getItems().length,
1414
+ goalBuffer: this.workingMemory.getBuffer ? this.workingMemory.getBuffer("goal").length : 0,
1415
+ retrievalBuffer: this.workingMemory.getBuffer ? this.workingMemory.getBuffer("retrieval").length : 0,
1416
+ episodicEngrams: this.episodicMemory.getStats ? this.episodicMemory.getStats().count : 0,
1417
+ semanticChunks: this.semanticMemory.getStats ? this.semanticMemory.getStats().count : 0,
1418
+ semanticAvgActivation: this.semanticMemory.getStats ? this.semanticMemory.getStats().avgActivation : 0,
1419
+ proceduralProductions: this.proceduralMemory.getStats ? this.proceduralMemory.getStats().count : 0,
1420
+ proceduralFired: this.productionsFired,
1421
+ metamemory: this.substrate.getMetamemorySnapshot(),
1422
+ // Legacy for compatibility
1423
+ legacyTraceCount: this.substrate.getAll().length,
1424
+ plasticityBias: this.substrate.getPlasticityBias(),
1425
+ memoryPressure: this.substrate.getMemoryPressure(),
1426
+ alg1Overhead: this.lastAlg1Overhead
1427
+ },
1428
+ lastDispatch: this.getLastDispatchEffects(),
1429
+ selfAudit: this.getSelfAudit(),
1430
+ epistemicMirror: this.getEpistemicMirrorSignals()
1431
+ };
1432
+ }
1433
+ /**
1434
+ * Public helper: returns current substrate statistics (experience count + averages).
1435
+ * Useful for external consumers and persistence demos.
1436
+ */
1437
+ getSubstrateStats() {
1438
+ const sem = this.semanticMemory.getStats ? this.semanticMemory.getStats() : { count: 0, avgActivation: 0 };
1439
+ const proc = this.proceduralMemory.getStats ? this.proceduralMemory.getStats() : { count: 0, fired: 0 };
1440
+ return {
1441
+ ...this.substrate.getStats(),
1442
+ workingMemoryLoad: this.workingMemory.getLoad(),
1443
+ episodicEngrams: this.episodicMemory.getStats ? this.episodicMemory.getStats().count : 0,
1444
+ semanticChunks: sem.count,
1445
+ semanticAvgActivation: sem.avgActivation,
1446
+ proceduralProductions: proc.count,
1447
+ productionsFired: this.productionsFired,
1448
+ alg1Overhead: this.lastAlg1Overhead
1449
+ };
1450
+ }
1451
+ /**
1452
+ * Convenience: perform a retrieval from the unified episodic memory (for research / package users).
1453
+ */
1454
+ retrieveFromSubstrate(contextDelta = 0, count = 3) {
1455
+ const plasticity = this.substrate.getPlasticityBias();
1456
+ return this.episodicMemory.retrieve(contextDelta, plasticity, count);
1457
+ }
1458
+ /**
1459
+ * Returns a summary of the most recent MCP dispatch effects and substrate influence.
1460
+ * This makes the "one system with active memory and control" observable.
1461
+ */
1462
+ getLastDispatchEffects() {
1463
+ if (this.history.length === 0) return null;
1464
+ const last = this.history[this.history.length - 1];
1465
+ const stats = this.substrate.getStats();
1466
+ return {
1467
+ step: last.step,
1468
+ mcpAction: last.mcpAction,
1469
+ activePathways: last.activePathways || [],
1470
+ substrateAfter: {
1471
+ experiences: stats.count,
1472
+ plasticityBias: this.substrate.getPlasticityBias(),
1473
+ memoryPressure: this.substrate.getMemoryPressure()
1474
+ }
1475
+ };
1476
+ }
1477
+ /**
1478
+ * Self-audit aligned with IM-Onto concepts (from papers).
1479
+ * Maps current unified state (MoS + rich substrate: semantic activation, procedural stats, WM buffers + Algorithm 1 overhead) to metacognitive problem classes (KTP, DRFP, ADTP).
1480
+ * Enriched with CARINA12 substrate + regulator signals for more accurate problem detection.
1481
+ * This is a key bridge so IM-Onto is no longer an isolated explorer.
1482
+ */
1483
+ getSelfAudit() {
1484
+ const mos = this.metaDna.mos;
1485
+ const pressure = this.substrate.getMemoryPressure();
1486
+ const plasticity = this.substrate.getPlasticityBias();
1487
+ const dispatch = this.getLastDispatchEffects();
1488
+ const u = mos.u;
1489
+ const r = this.mcp.metaState?.r ?? 0;
1490
+ const metamemory = mos.metamemory || this.substrate.getMetamemorySnapshot();
1491
+ const semStats = this.semanticMemory.getStats ? this.semanticMemory.getStats() : { avgActivation: 0.6, count: 0 };
1492
+ const procStats = this.proceduralMemory.getStats ? this.proceduralMemory.getStats() : { avgUtility: 0.5, fired: 0 };
1493
+ const alg1Over = this.lastAlg1Overhead || 0;
1494
+ const semanticActivation = semStats.avgActivation || 0.6;
1495
+ const productionsFired = this.productionsFired || 0;
1496
+ const problems = [];
1497
+ if (u > 0.55 && pressure > 0.35) {
1498
+ const confPenalty = 1 - (metamemory.avgConfidence || 0.5);
1499
+ problems.push({
1500
+ id: "KTP",
1501
+ name: "Knowledge_Test_Problem",
1502
+ severity: Math.min(1, (u + pressure + confPenalty) / 2.2),
1503
+ justification: "High epistemic uncertainty combined with substrate memory pressure and low recalled confidence (metamemory) suggests gaps in knowledge or need for verification (IM-Onto KTP)."
1504
+ });
1505
+ }
1506
+ if (semanticActivation < 0.55 || alg1Over > 0.015 && productionsFired < 3) {
1507
+ problems.push({
1508
+ id: "KTP",
1509
+ name: "Knowledge_Test_Problem",
1510
+ severity: Math.min(1, 1 - semanticActivation + alg1Over * 20 + (productionsFired < 5 ? 0.2 : 0)),
1511
+ justification: "Low semantic memory activation (weak spreading/declarative traces) combined with high regulatory overhead or low procedural firing indicates gaps in consolidated knowledge or inefficient reasoning traces (IM-Onto KTP)."
1512
+ });
1513
+ }
1514
+ if (r > 0.5 || dispatch && dispatch.substrateAfter.memoryPressure > 0.4) {
1515
+ problems.push({
1516
+ id: "DRFP",
1517
+ name: "Detection_of_Reasoning_Failure_Problem",
1518
+ severity: Math.min(1, r + (dispatch?.substrateAfter.memoryPressure ?? 0) * 0.5),
1519
+ justification: "Elevated risk or memory pressure from past high-delta experiences indicates potential reasoning anomalies or need for trace monitoring (IM-Onto DRFP)."
1520
+ });
1521
+ }
1522
+ if (alg1Over > 0.012 && mos.l > 0.55 || procStats.avgUtility < 0.4 && productionsFired > 5) {
1523
+ problems.push({
1524
+ id: "DRFP",
1525
+ name: "Detection_of_Reasoning_Failure_Problem",
1526
+ severity: Math.min(1, alg1Over * 30 + (1 - (procStats.avgUtility || 0.5))),
1527
+ justification: "Elevated Algorithm 1 regulatory overhead with high cognitive load or low average procedural utility despite activity suggests possible reasoning failures or inefficient production selection (IM-Onto DRFP)."
1528
+ });
1529
+ }
1530
+ if (mos.l > 0.6 && mos.z < 0.6) {
1531
+ problems.push({
1532
+ id: "ADTP",
1533
+ name: "Allocating_Deliberation_Time_Problem",
1534
+ severity: Math.min(1, (mos.l + (1 - mos.z)) / 2),
1535
+ justification: "Sustained cognitive load with declining satisfaction suggests suboptimal deliberation time allocation (IM-Onto ADTP)."
1536
+ });
1537
+ }
1538
+ if (alg1Over > 0.01 && this.workingMemory.getLoad() > 0.65) {
1539
+ problems.push({
1540
+ id: "ADTP",
1541
+ name: "Allocating_Deliberation_Time_Problem",
1542
+ severity: Math.min(1, alg1Over * 25 + this.workingMemory.getLoad() * 0.6),
1543
+ justification: "High per-cycle regulatory overhead combined with elevated working memory load indicates excessive deliberation time or inefficient meta-regulation (IM-Onto ADTP)."
1544
+ });
1545
+ }
1546
+ const modelOfSelf = {
1547
+ uncertainty: mos.u,
1548
+ load: mos.l,
1549
+ performance: mos.p,
1550
+ energy: mos.e,
1551
+ satisfaction: mos.z,
1552
+ memoryPressure: pressure,
1553
+ plasticityBias: plasticity,
1554
+ recentMCPAction: dispatch?.mcpAction ?? null,
1555
+ metamemory,
1556
+ // New rich signals from CARINA12 substrate + Algorithm 1
1557
+ semanticAvgActivation: semanticActivation,
1558
+ semanticChunks: semStats.count || 0,
1559
+ proceduralAvgUtility: procStats.avgUtility || 0,
1560
+ productionsFired,
1561
+ alg1Overhead: alg1Over,
1562
+ workingMemoryLoad: this.workingMemory.getLoad(),
1563
+ goalBufferItems: this.workingMemory.getBuffer ? this.workingMemory.getBuffer("goal").length : 0
1564
+ };
1565
+ return {
1566
+ problems,
1567
+ modelOfSelf,
1568
+ timestamp: this.stepCount
1569
+ };
1570
+ }
1571
+ /**
1572
+ * Epistemic mirror signals inspired by CMT (CARINA Mirror Test / AMFs).
1573
+ * Provides simple MET-1 (ignorance detection), MET-3 (epistemic utility) style signals
1574
+ * derived from the unified state. Allows CMT scenarios to be evaluated against the actual agent.
1575
+ */
1576
+ getEpistemicMirrorSignals() {
1577
+ const u = this.metaDna.mos.u;
1578
+ const r = this.mcp.metaState?.r ?? 0;
1579
+ const pressure = this.substrate.getMemoryPressure();
1580
+ const avgOutcome = this.substrate.getStats().avgOutcome ?? 0.5;
1581
+ const dispatch = this.getLastDispatchEffects();
1582
+ const semAct = this.semanticMemory.getStats ? this.semanticMemory.getStats().avgActivation || 0.6 : 0.6;
1583
+ const alg1 = this.lastAlg1Overhead || 0;
1584
+ const prodFired = this.productionsFired || 0;
1585
+ const wmLoad = this.workingMemory.getLoad();
1586
+ const ignoranceDetection = u > 0.6 || pressure > 0.45 || semAct < 0.5 ? "NO" : "YES";
1587
+ const ignoranceConfidence = Math.max(0, Math.min(1, 1 - (u + pressure + (1 - semAct)) / 3));
1588
+ const epistemicUtility = r > 0.55 || avgOutcome < 0.45 || alg1 > 0.015 && prodFired < 4 ? "Null" : "Positive";
1589
+ const utilityScore = Math.max(0, Math.min(1, (1 - r) * (avgOutcome + 0.3) * (alg1 > 0.012 ? 0.7 : 1)));
1590
+ const traceFidelity = dispatch && dispatch.activePathways.length > 1 ? 0.75 : Math.max(0.3, 0.5 + (1 - pressure) * 0.3 - (1 - semAct) * 0.4 - alg1 * 10);
1591
+ return {
1592
+ MET1_ignoranceDetection: ignoranceDetection,
1593
+ MET1_confidence: Number(ignoranceConfidence.toFixed(3)),
1594
+ MET3_epistemicUtility: epistemicUtility,
1595
+ MET3_utilityScore: Number(utilityScore.toFixed(3)),
1596
+ traceFidelity: Number(traceFidelity.toFixed(3)),
1597
+ overallEpistemicRisk: Number(r.toFixed(3)),
1598
+ substrateMemoryPressure: Number(pressure.toFixed(3)),
1599
+ semanticHealth: Number(semAct.toFixed(3)),
1600
+ regulatoryOverhead: Number(alg1.toFixed(4)),
1601
+ recommendedAction: ignoranceDetection === "NO" || epistemicUtility === "Null" ? "REQUEST or VERIFY" : "CONTINUE or STOP"
1602
+ };
1603
+ }
1604
+ /**
1605
+ * Returns a compact summary for UI dashboards and persistence.
1606
+ * This represents the "integrated state" of the single Marina system.
1607
+ */
1608
+ getSummary() {
1609
+ const state = this.getCombinedState();
1610
+ const activePathways = state.metaDna.pathways.filter((p) => p.active).map((p) => p.name);
1611
+ const lastAction = this.history.length > 0 ? this.history[this.history.length - 1].mcpAction : null;
1612
+ const subStats = this.substrate.getStats();
1613
+ const epiStats = this.episodicMemory && this.episodicMemory.getStats ? this.episodicMemory.getStats() : { count: 0, avgOutcome: 0 };
1614
+ const expCount = subStats.count || epiStats.count || state.substrate.legacyTraceCount || 0;
1615
+ const avgOut = typeof subStats.avgOutcome === "number" && subStats.avgOutcome > 0 ? subStats.avgOutcome : epiStats.avgOutcome || 0;
1616
+ const semStats = this.semanticMemory.getStats ? this.semanticMemory.getStats() : { count: 0, avgActivation: 0 };
1617
+ const procStats = this.proceduralMemory.getStats ? this.proceduralMemory.getStats() : { fired: 0, avgUtility: 0 };
1618
+ return {
1619
+ step: state.step,
1620
+ uncertainty: state.metaDna.mos.u,
1621
+ load: state.metaDna.mos.l,
1622
+ performance: state.metaDna.mos.p,
1623
+ energy: state.metaDna.mos.e,
1624
+ satisfaction: state.metaDna.mos.z,
1625
+ activePathways,
1626
+ currentMcpAction: state.mcp.metaState ? "running" : "idle",
1627
+ lastMCPAction: lastAction,
1628
+ dmaGHCN: state.dma.gHCN,
1629
+ dmaTauM: state.dma.tauM,
1630
+ dmaBeta: state.dma.beta,
1631
+ mcpQuality: state.mcp.metaState?.q ?? 0,
1632
+ mcpRisk: state.mcp.metaState?.r ?? 0,
1633
+ substrateExperiences: expCount,
1634
+ substrateAvgOutcome: Number(avgOut.toFixed ? avgOut.toFixed(3) : avgOut) || 0,
1635
+ substrateAvgTauM: subStats.avgTauM ?? 12,
1636
+ substratePlasticityBias: this.substrate.getPlasticityBias(),
1637
+ substrateMemoryPressure: this.substrate.getMemoryPressure(),
1638
+ lastDispatch: this.getLastDispatchEffects(),
1639
+ selfAuditProblems: this.getSelfAudit().problems.length,
1640
+ epistemicUtility: this.getEpistemicMirrorSignals().MET3_epistemicUtility,
1641
+ workingMemoryLoad: this.workingMemory.getLoad(),
1642
+ workingMemoryItems: this.workingMemory.getItems().length,
1643
+ episodicEngrams: epiStats.count || 0,
1644
+ metamemoryAvgConfidence: this.substrate.getMetamemorySnapshot().avgConfidence,
1645
+ // CARINA12 plan-aligned substrate metrics (new this round)
1646
+ semanticChunks: semStats.count || 0,
1647
+ semanticAvgActivation: semStats.avgActivation || 0,
1648
+ proceduralProductions: procStats.count || 0,
1649
+ proceduralAvgUtility: procStats.avgUtility || 0,
1650
+ productionsFired: this.productionsFired,
1651
+ alg1Overhead: this.lastAlg1Overhead || 0,
1652
+ goalBufferItems: this.workingMemory.getBuffer ? this.workingMemory.getBuffer("goal").length : 0,
1653
+ taskType: this.task instanceof DefaultBanditTask ? "internal-bandit" : "custom",
1654
+ lastRetrievalBias: this.lastRetrievalBias || 0,
1655
+ lastProposedAction: this.lastProposedAction
1656
+ };
1657
+ }
1658
+ /**
1659
+ * Serialize the key persistent parts (especially epigenetic traces + minimal substrate)
1660
+ * for saving across sessions (cognitive "development").
1661
+ * Extended to include episodic engrams + WM snapshot (CARINA12 epigenetic + bio-plasticity persistence).
1662
+ */
1663
+ serialize() {
1664
+ const epiStats = this.episodicMemory.getStats ? this.episodicMemory.getStats() : { count: 0 };
1665
+ return {
1666
+ stepCount: this.stepCount,
1667
+ metaDna: {
1668
+ mos: { ...this.metaDna.mos },
1669
+ epigenetic: { ...this.metaDna.epigenetic },
1670
+ genes: this.metaDna.genes.map((g) => ({ id: g.id, expressed: g.expressed }))
1671
+ },
1672
+ mcp: {
1673
+ metaState: { ...this.mcp.metaState },
1674
+ weights: { ...this.mcp.weights }
1675
+ },
1676
+ // Substrate seed (epigenetic + DMA-tagged experiences + engrams + WM + semantic/procedural) for CARINA12 "cognitive development"
1677
+ substrate: {
1678
+ traces: this.substrate.getAll(),
1679
+ episodicEngrams: this.episodicMemory ? this.episodicMemory.engrams || [] : [],
1680
+ semanticSample: this.semanticMemory ? this.semanticMemory.chunks?.slice(-4) || [] : [],
1681
+ proceduralSample: this.proceduralMemory ? this.proceduralMemory.productions?.slice(-3) || [] : [],
1682
+ workingMemoryLoad: this.workingMemory.getLoad(),
1683
+ workingMemorySample: this.workingMemory.getItems().slice(-3),
1684
+ productionsFired: this.productionsFired
1685
+ }
1686
+ };
1687
+ }
1688
+ /**
1689
+ * Restore from a previously serialized state (loads epigenetic memory + substrate traces).
1690
+ */
1691
+ deserialize(data) {
1692
+ if (!data) return;
1693
+ this.stepCount = data.stepCount ?? 0;
1694
+ if (data.metaDna) {
1695
+ if (data.metaDna.mos) this.metaDna.mos = { ...this.metaDna.mos, ...data.metaDna.mos };
1696
+ if (data.metaDna.epigenetic) this.metaDna.epigenetic = { ...this.metaDna.epigenetic, ...data.metaDna.epigenetic };
1697
+ if (data.metaDna.genes) {
1698
+ data.metaDna.genes.forEach((g) => {
1699
+ const gene = this.metaDna.genes.find((gg) => gg.id === g.id);
1700
+ if (gene) gene.expressed = g.expressed;
1701
+ });
1702
+ }
1703
+ }
1704
+ if (data.mcp) {
1705
+ if (data.mcp.metaState) this.mcp.metaState = { ...this.mcp.metaState, ...data.mcp.metaState };
1706
+ if (data.mcp.weights) this.mcp.weights = { ...this.mcp.weights, ...data.mcp.weights };
1707
+ }
1708
+ if (data.substrate && data.substrate.traces && Array.isArray(data.substrate.traces)) {
1709
+ this.substrate.clear();
1710
+ data.substrate.traces.forEach((t) => {
1711
+ this.substrate.record({ dma: t.dma, outcome: t.outcome }, t.step);
1712
+ });
1713
+ }
1714
+ if (data.substrate && Array.isArray(data.substrate.episodicEngrams)) {
1715
+ if (this.episodicMemory.clear) this.episodicMemory.clear();
1716
+ data.substrate.episodicEngrams.forEach((e) => {
1717
+ if (this.episodicMemory.store) this.episodicMemory.store(e);
1718
+ });
1719
+ }
1720
+ if (data.substrate) {
1721
+ if (typeof data.substrate.productionsFired === "number") this.productionsFired = data.substrate.productionsFired;
1722
+ if (typeof data.substrate.alg1Overhead === "number") this.lastAlg1Overhead = data.substrate.alg1Overhead;
1723
+ }
1724
+ }
1725
+ reset() {
1726
+ this.dma.reset();
1727
+ this.metaDna.reset();
1728
+ this.mcp.reset();
1729
+ this.workingMemory.clear();
1730
+ this.episodicMemory.clear();
1731
+ this.semanticMemory.clear();
1732
+ this.proceduralMemory.clear();
1733
+ this.substrate.clear();
1734
+ this.stepCount = 0;
1735
+ this.history = [];
1736
+ this.productionsFired = 0;
1737
+ this.lastAlg1Overhead = 0;
1738
+ if (this.task && typeof this.task.reset === "function") {
1739
+ this.task.reset();
1740
+ }
1741
+ }
1742
+ /**
1743
+ * Allow replacing the task/environment at runtime.
1744
+ * This makes Marina usable for custom problems (major practical utility improvement).
1745
+ */
1746
+ setTask(task) {
1747
+ this.task = task;
1748
+ if (typeof task.reset === "function") task.reset();
1749
+ }
1750
+ /**
1751
+ * Convenience factory: create a simple Task from a reward function.
1752
+ * Greatly improves practical usability for quick experiments.
1753
+ */
1754
+ static createSimpleTask(rewardFn) {
1755
+ return {
1756
+ getOutcome(ctx) {
1757
+ const res = rewardFn(ctx);
1758
+ if (typeof res === "number") return { reward: res };
1759
+ return res;
1760
+ },
1761
+ reset() {
1762
+ }
1763
+ };
1764
+ }
1765
+ /**
1766
+ * Convenience: ask the procedural memory what it would do right now.
1767
+ * Useful when using custom tasks.
1768
+ */
1769
+ proposeAction(context = {}) {
1770
+ const prods = this.proceduralMemory.matchConflictSet(context);
1771
+ return prods.length > 0 ? prods[0] : null;
1772
+ }
1773
+ /**
1774
+ * Run a full evaluation on a (possibly custom) task and return rich statistics.
1775
+ * This improves practical utility and maturity (benchmark-style runs with self-audit).
1776
+ * options can include { includeHistory: boolean } for more detail.
1777
+ */
1778
+ evaluate(task = null, steps = 100, options = {}) {
1779
+ const previousTask = this.task;
1780
+ if (task) {
1781
+ this.setTask(task);
1782
+ }
1783
+ const startStep = this.stepCount;
1784
+ const results = this.runEpisode(steps);
1785
+ const summary = this.getSummary();
1786
+ const finalAudit = this.getSelfAudit();
1787
+ const substrateSnapshot = this.getSubstrateStats();
1788
+ if (task && previousTask) {
1789
+ this.setTask(previousTask);
1790
+ }
1791
+ const base = {
1792
+ steps,
1793
+ startStep,
1794
+ endStep: this.stepCount,
1795
+ finalSummary: summary,
1796
+ finalSelfAudit: finalAudit,
1797
+ avgOutcome: summary.substrateAvgOutcome,
1798
+ avgWMload: summary.workingMemoryLoad,
1799
+ semanticAvgActivation: summary.semanticAvgActivation,
1800
+ productionsFired: summary.productionsFired,
1801
+ alg1Overhead: summary.alg1Overhead,
1802
+ problemsDetected: finalAudit.problems.length,
1803
+ problemTypes: finalAudit.problems.map((p) => p.id),
1804
+ taskType: summary.taskType,
1805
+ substrateSnapshot,
1806
+ lastFewResults: results.slice(-3)
1807
+ };
1808
+ if (options.includeHistory) {
1809
+ base.historySample = results.slice(-5);
1810
+ }
1811
+ return base;
1812
+ }
1813
+ /**
1814
+ * Convenience: run an episode on a specific task without permanently changing the agent's task.
1815
+ * Improves practical usability for quick experiments with different "environments".
1816
+ */
1817
+ runOnTask(task, steps = 100, options = {}) {
1818
+ const prev = this.task;
1819
+ this.setTask(task);
1820
+ const res = this.runEpisode(steps);
1821
+ const summary = this.getSummary();
1822
+ if (prev) this.setTask(prev);
1823
+ return { results: res, summary, taskType: "custom" };
1824
+ }
1825
+ };
1826
+ export {
1827
+ MarinaAgent
1828
+ };
1829
+ //# sourceMappingURL=MarinaAgent.js.map