@mindot/will 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/dist/channels/discord.d.ts +1 -1
  2. package/dist/channels/discord.js.map +1 -1
  3. package/dist/channels/whatsapp.d.ts +1 -1
  4. package/dist/channels/whatsapp.js.map +1 -1
  5. package/dist/cli.js +567 -51
  6. package/dist/cli.js.map +1 -1
  7. package/dist/index.d.ts +2 -2
  8. package/dist/index.js +567 -51
  9. package/dist/index.js.map +1 -1
  10. package/dist/mcp/effectors.d.ts +1 -1
  11. package/dist/mcp/effectors.js.map +1 -1
  12. package/dist/{will-BDq-TMQr.d.ts → will-Bikuk4s2.d.ts} +48 -6
  13. package/package.json +1 -1
  14. package/src/channels/discord.ts +11 -11
  15. package/src/channels/roster.ts +1 -1
  16. package/src/channels/types.ts +1 -1
  17. package/src/channels/whatsapp.ts +25 -25
  18. package/src/cli.ts +20 -20
  19. package/src/cognition/acp.ts +28 -0
  20. package/src/cognition/agency/consequence.ts +174 -0
  21. package/src/cognition/agency/engines/action.selector.ts +301 -48
  22. package/src/cognition/agency/engines/affordance.synthesizer.ts +26 -16
  23. package/src/cognition/agency/engines/deliberation.engine.ts +28 -14
  24. package/src/cognition/agency/engines/motor.schema.executor.ts +86 -14
  25. package/src/cognition/agency/engines/reafference.engine.ts +122 -18
  26. package/src/cognition/agency/execution.primitives.ts +13 -13
  27. package/src/cognition/agency/proactive.communicator.ts +1 -1
  28. package/src/cognition/agency/reconcile.learning.ts +1 -1
  29. package/src/cognition/agency/revocation.ts +79 -0
  30. package/src/cognition/agency/schemas/repertoire.ts +2 -2
  31. package/src/cognition/agency/selection.scoring.ts +25 -9
  32. package/src/cognition/bus.ts +2 -2
  33. package/src/cognition/completion.inbox.ts +1 -1
  34. package/src/cognition/config.mirror.entities.ts +5 -5
  35. package/src/cognition/event.log.ts +2 -2
  36. package/src/cognition/event.schemas.ts +67 -67
  37. package/src/cognition/faculties/aesthetic.evaluator.ts +6 -6
  38. package/src/cognition/faculties/affective.blender.ts +36 -4
  39. package/src/cognition/faculties/attachment.evaluator.ts +6 -6
  40. package/src/cognition/faculties/attention.allocator.ts +63 -8
  41. package/src/cognition/faculties/autobiographical.narrator.ts +3 -3
  42. package/src/cognition/faculties/bias.detector.ts +7 -7
  43. package/src/cognition/faculties/circadian.oscillator.ts +3 -3
  44. package/src/cognition/faculties/confidence.calibrator.ts +7 -7
  45. package/src/cognition/faculties/dream.simulator.ts +5 -5
  46. package/src/cognition/faculties/empathy.simulator.ts +7 -7
  47. package/src/cognition/faculties/energy.regulator.ts +4 -4
  48. package/src/cognition/faculties/episodic.consolidator.ts +6 -6
  49. package/src/cognition/faculties/executive.engine/commands.ts +6 -6
  50. package/src/cognition/faculties/executive.engine/context.ts +42 -42
  51. package/src/cognition/faculties/executive.engine/deferred.effects.ts +2 -2
  52. package/src/cognition/faculties/executive.engine/engine.ts +25 -25
  53. package/src/cognition/faculties/executive.engine/facet.supervisor.ts +12 -12
  54. package/src/cognition/faculties/executive.engine/facet.ts +18 -18
  55. package/src/cognition/faculties/executive.engine/gating.ts +2 -2
  56. package/src/cognition/faculties/executive.engine/messages.ts +3 -3
  57. package/src/cognition/faculties/executive.engine/parser.ts +11 -11
  58. package/src/cognition/faculties/executive.engine/prompt.factory.ts +55 -55
  59. package/src/cognition/faculties/exteroception.ts +99 -5
  60. package/src/cognition/faculties/forgetting.curve.ts +3 -3
  61. package/src/cognition/faculties/frustration.evaluator.ts +6 -6
  62. package/src/cognition/faculties/goal.manager.ts +15 -15
  63. package/src/cognition/faculties/inhibition.controller.ts +3 -3
  64. package/src/cognition/faculties/interoception.ts +3 -3
  65. package/src/cognition/faculties/introspection.engine.ts +3 -3
  66. package/src/cognition/faculties/known.entity.tracker.ts +15 -15
  67. package/src/cognition/faculties/loss.evaluator.ts +2 -2
  68. package/src/cognition/faculties/moral.evaluator.ts +4 -4
  69. package/src/cognition/faculties/novelty.detector.ts +4 -4
  70. package/src/cognition/faculties/persona.consolidator.ts +12 -12
  71. package/src/cognition/faculties/planning.engine/engine.ts +47 -47
  72. package/src/cognition/faculties/planning.engine/plan.frontier.ts +5 -5
  73. package/src/cognition/faculties/planning.engine/plan.store.ts +1 -1
  74. package/src/cognition/faculties/planning.engine/plan.supervision.ts +20 -20
  75. package/src/cognition/faculties/reputation.tracker.ts +6 -6
  76. package/src/cognition/faculties/reward.evaluator.ts +4 -4
  77. package/src/cognition/faculties/self.model.updater.ts +8 -8
  78. package/src/cognition/faculties/semantic.engine/integrator.ts +15 -15
  79. package/src/cognition/faculties/sleep.pressure.regulator.ts +4 -4
  80. package/src/cognition/faculties/social.perception.ts +3 -3
  81. package/src/cognition/faculties/spaced.repetition.ts +2 -2
  82. package/src/cognition/faculties/stress.regulator.ts +27 -4
  83. package/src/cognition/faculties/task.switcher.ts +11 -6
  84. package/src/cognition/faculties/theory.of.mind.ts +6 -6
  85. package/src/cognition/faculties/threat.evaluator.ts +3 -3
  86. package/src/cognition/faculties/working.memory.ts +8 -8
  87. package/src/cognition/generative.model.ts +2 -2
  88. package/src/cognition/memory/vector.adapter.ts +5 -5
  89. package/src/cognition/memory/vector.content.ts +4 -4
  90. package/src/cognition/memory/vector.embedder.ts +9 -9
  91. package/src/cognition/persona.prior.ts +1 -1
  92. package/src/cognition/schema.registry.ts +2 -2
  93. package/src/cognition/senses/audition.engine/engine.ts +2 -2
  94. package/src/cognition/senses/base.sense.engine.ts +1 -1
  95. package/src/cognition/utilities/token.tracker.ts +5 -5
  96. package/src/core/abstracts.ts +1 -1
  97. package/src/core/completion.recorder.ts +2 -2
  98. package/src/core/serialization.ts +3 -3
  99. package/src/core/snapshot.manager.ts +1 -1
  100. package/src/core/state.manager.ts +1 -1
  101. package/src/core/utils.ts +1 -1
  102. package/src/host/boot.ts +30 -30
  103. package/src/host/utterances.ts +1 -1
  104. package/src/llm/index.ts +9 -9
  105. package/src/llm/summarizer.ts +4 -4
  106. package/src/llm/wire.contracts.ts +1 -1
  107. package/src/mcp/effectors.ts +10 -10
  108. package/src/mcp/server.ts +11 -11
  109. package/src/pma/eval.ts +1 -1
  110. package/src/pma/index.ts +21 -21
  111. package/src/runners/outreach.runner.ts +3 -3
  112. package/src/runners/social.runner.ts +1 -1
  113. package/src/runners/thin-shim.runner.ts +1 -1
  114. package/src/sdk/will.ts +5 -5
  115. package/src/serve/server.ts +12 -12
  116. package/src/stem/assembly.audit.ts +3 -3
  117. package/src/stem/guards/identity.coherence.ts +10 -10
  118. package/src/stem/guards/identity.guard.ts +22 -22
  119. package/src/stem/index.ts +11 -11
  120. package/src/stem/mind.ts +12 -12
  121. package/src/stem/tracts/biography.writer.ts +3 -3
  122. package/src/stem/tracts/effector.controller.ts +4 -4
  123. package/src/stem/tracts/health.reporter.ts +1 -1
  124. package/src/stem/tracts/outbox.controller.ts +4 -0
  125. package/src/stem/tracts/outbox.writer.ts +4 -4
  126. package/src/stem/tracts/pma.controller.ts +1 -1
  127. package/src/stem/tracts/replay.controller.ts +10 -10
  128. package/src/stem/tracts/sensory.controller.ts +2 -2
  129. package/src/stem/tracts/session.logger.ts +4 -4
  130. package/src/stem/tracts/transport/socketio.transport.ts +7 -7
  131. package/src/stem/tracts/transport/stream.transport.ts +2 -2
  132. package/src/stem/tracts/transport.controller.ts +15 -15
package/dist/cli.js CHANGED
@@ -4655,6 +4655,9 @@ var SleepPressureRegulator = class {
4655
4655
  }
4656
4656
  };
4657
4657
 
4658
+ // src/cognition/acp.ts
4659
+ var ACP_SELF_PRECISION = 0.35;
4660
+
4658
4661
  // src/cognition/persona.prior.ts
4659
4662
  var PERSONA_PRIOR_ID = "persona-prior";
4660
4663
  var PERSONA_PRIOR_TYPE = "persona.prior";
@@ -4763,6 +4766,8 @@ function consolidatePrior(current, adjustments, tick, opts = {}) {
4763
4766
  }
4764
4767
 
4765
4768
  // src/cognition/faculties/attention.allocator.ts
4769
+ var ACP_USAGE_UPLIFT = 0.15;
4770
+ var ACP_CONFIDENCE = 0.4;
4766
4771
  var EFFORT_BASELINE2 = 0.7;
4767
4772
  var EFFORT_MIN = 0.4;
4768
4773
  var EFFORT_MAX = 1;
@@ -4784,6 +4789,8 @@ var AttentionAllocator = class {
4784
4789
  _effort = EFFORT_BASELINE2;
4785
4790
  /** A one-shot focus/rest request from the executive, applied next react(). */
4786
4791
  _effortRequest = null;
4792
+ /** ACP-P2: a self-caused precision attenuation is armed; react() restores after one observe. */
4793
+ _acpOneShot = false;
4787
4794
  _bus = null;
4788
4795
  _model = new GenerativeModel();
4789
4796
  constructor(config = {}) {
@@ -4804,8 +4811,12 @@ var AttentionAllocator = class {
4804
4811
  "executive.prediction.formed",
4805
4812
  "attention.regulate",
4806
4813
  // voluntary focus/rest from the executive (Option C)
4807
- "senses.*"
4814
+ "senses.*",
4808
4815
  // all sense percepts — salience feeds attention allocation
4816
+ // ACP-P2: our own enactions — anticipate the attention swing they cause
4817
+ "agency.enacted",
4818
+ "agency.communicate",
4819
+ "agency.invocation"
4809
4820
  ];
4810
4821
  }
4811
4822
  publishes() {
@@ -4832,6 +4843,18 @@ var AttentionAllocator = class {
4832
4843
  this._model.setPrecision("attention.usage", 1 + p.confidence * 0.5);
4833
4844
  break;
4834
4845
  }
4846
+ case "agency.enacted":
4847
+ case "agency.communicate":
4848
+ case "agency.invocation": {
4849
+ const usage = this._model.predict("attention.usage");
4850
+ const free = this._model.predict("attention.free_fraction");
4851
+ this._model.anticipate("attention.usage", Math.min(1, usage + ACP_USAGE_UPLIFT), ACP_CONFIDENCE);
4852
+ this._model.anticipate("attention.free_fraction", Math.max(0, free - ACP_USAGE_UPLIFT), ACP_CONFIDENCE);
4853
+ this._model.setPrecision("attention.usage", ACP_SELF_PRECISION);
4854
+ this._model.setPrecision("attention.free_fraction", ACP_SELF_PRECISION);
4855
+ this._acpOneShot = true;
4856
+ break;
4857
+ }
4835
4858
  default:
4836
4859
  if (e.type.startsWith("senses.")) {
4837
4860
  const percept = e.payload;
@@ -4915,6 +4938,11 @@ var AttentionAllocator = class {
4915
4938
  if (_bus) {
4916
4939
  const usageErr = this._model.observe("attention.usage", attentionUsage);
4917
4940
  const freeErr = this._model.observe("attention.free_fraction", freeFraction);
4941
+ if (this._acpOneShot) {
4942
+ this._model.setPrecision("attention.usage", 1);
4943
+ this._model.setPrecision("attention.free_fraction", 1);
4944
+ this._acpOneShot = false;
4945
+ }
4918
4946
  if (!usageErr.gated || !freeErr.gated)
4919
4947
  _bus.publish({ type: "attention.state.changed", version: 1, sourceEngine: this.name, salience: Math.max(usageErr.salience, freeErr.salience), payload: { usage: attentionUsage, focusCount, capacity: effectiveCapacity, freeFraction } });
4920
4948
  }
@@ -5034,7 +5062,18 @@ var StressRegulator = class {
5034
5062
  }
5035
5063
  // ── Engine interface ─────────────────────────────────────
5036
5064
  subscribes() {
5037
- return ["energy.state.changed", "sleep.state.changed", "novelty.state.changed", "goal.state.changed", "metacognition.state.changed", "executive.prediction.formed"];
5065
+ return [
5066
+ "energy.state.changed",
5067
+ "sleep.state.changed",
5068
+ "novelty.state.changed",
5069
+ "goal.state.changed",
5070
+ "metacognition.state.changed",
5071
+ "executive.prediction.formed",
5072
+ // ACP-P2: our own enactions — the stress swing they cause is expected
5073
+ "agency.enacted",
5074
+ "agency.communicate",
5075
+ "agency.invocation"
5076
+ ];
5038
5077
  }
5039
5078
  publishes() {
5040
5079
  return [];
@@ -5063,8 +5102,17 @@ var StressRegulator = class {
5063
5102
  this._model.setPrecision("stress.load", 1 + p.confidence * 0.5);
5064
5103
  break;
5065
5104
  }
5105
+ case "agency.enacted":
5106
+ case "agency.communicate":
5107
+ case "agency.invocation": {
5108
+ this._model.setPrecision("stress.load", ACP_SELF_PRECISION);
5109
+ this._acpOneShot = true;
5110
+ break;
5111
+ }
5066
5112
  }
5067
5113
  }
5114
+ /** ACP-P2: self-caused stress attenuation armed; react() restores after one observe. */
5115
+ _acpOneShot = false;
5068
5116
  snapshot() {
5069
5117
  return {
5070
5118
  energyLevel: this._energyLevel,
@@ -5157,6 +5205,10 @@ var StressRegulator = class {
5157
5205
  if (_bus) {
5158
5206
  const zoneCode = zone === "low" ? 0 : zone === "optimal" ? 1 : zone === "distress" ? 2 : 3;
5159
5207
  const predErr = this._model.observe("stress.load", newLoad);
5208
+ if (this._acpOneShot) {
5209
+ this._model.setPrecision("stress.load", 1);
5210
+ this._acpOneShot = false;
5211
+ }
5160
5212
  if (!predErr.gated || zone !== previousZone) {
5161
5213
  _bus.publish({ type: "stress.state.changed", version: 1, sourceEngine: this.name, salience: predErr.salience, payload: { load: newLoad, zoneCode, deadlineUrgency: state.metrics.get("deadline.urgency") ?? 0, cognitiveLoad: state.metrics.get("cognitive.load") ?? state.metrics.get("attention.usage") ?? 0 } });
5162
5214
  }
@@ -5379,6 +5431,116 @@ var CircadianOscillator = class {
5379
5431
  }
5380
5432
  };
5381
5433
 
5434
+ // src/cognition/agency/consequence.ts
5435
+ var CONSEQUENCE_TYPE = "agency.consequence";
5436
+ var ATTENUATION = 0.25;
5437
+ var MIN_TEXT_MATCH_LEN = 12;
5438
+ var CONSEQUENCE_TTL_TICKS = 30;
5439
+ function fnv1a(text) {
5440
+ let h = 2166136261;
5441
+ for (let i = 0; i < text.length; i++) {
5442
+ h ^= text.charCodeAt(i);
5443
+ h = Math.imul(h, 16777619) >>> 0;
5444
+ }
5445
+ return h >>> 0;
5446
+ }
5447
+ function paramsKey(value) {
5448
+ if (value === null || typeof value !== "object")
5449
+ return typeof value === "string" ? JSON.stringify(value) : String(value);
5450
+ if (Array.isArray(value))
5451
+ return `[${value.map(paramsKey).join(",")}]`;
5452
+ const obj = value;
5453
+ const keys = Object.keys(obj).sort();
5454
+ return `{${keys.map((k) => `${k}:${paramsKey(obj[k])}`).join(",")}}`;
5455
+ }
5456
+ function consequenceEntity(d) {
5457
+ return {
5458
+ id: `agency-consequence-${d.intentId}`,
5459
+ type: CONSEQUENCE_TYPE,
5460
+ metadata: { ...d }
5461
+ };
5462
+ }
5463
+ function readConsequence(m) {
5464
+ const meta = m ?? {};
5465
+ const intentId = typeof meta["intentId"] === "string" ? meta["intentId"] : void 0;
5466
+ const schema = typeof meta["schema"] === "string" ? meta["schema"] : void 0;
5467
+ const mode = meta["mode"] === "communicate" || meta["mode"] === "external" ? meta["mode"] : void 0;
5468
+ if (!intentId || !schema || !mode) return null;
5469
+ return {
5470
+ intentId,
5471
+ schema,
5472
+ mode,
5473
+ effector: typeof meta["effector"] === "string" ? meta["effector"] : void 0,
5474
+ targetEntityId: typeof meta["targetEntityId"] === "string" ? meta["targetEntityId"] : void 0,
5475
+ textHash: typeof meta["textHash"] === "number" ? meta["textHash"] : void 0,
5476
+ text: typeof meta["text"] === "string" ? meta["text"] : void 0,
5477
+ paramsHash: typeof meta["paramsHash"] === "number" ? meta["paramsHash"] : void 0,
5478
+ expiresAt: typeof meta["expiresAt"] === "number" ? meta["expiresAt"] : 0,
5479
+ tick: typeof meta["tick"] === "number" ? meta["tick"] : 0
5480
+ };
5481
+ }
5482
+ function liveConsequences(entities, tick) {
5483
+ const out = [];
5484
+ for (const [, e] of entities) {
5485
+ if (e.type !== CONSEQUENCE_TYPE) continue;
5486
+ const d = readConsequence(e.metadata);
5487
+ if (d && tick < d.expiresAt) out.push(d);
5488
+ }
5489
+ return out.sort((a, b) => a.intentId < b.intentId ? -1 : a.intentId > b.intentId ? 1 : 0);
5490
+ }
5491
+ function matchConsequenceText(descriptors, candidate) {
5492
+ if (candidate.length === 0) return null;
5493
+ const candidateHash = fnv1a(candidate);
5494
+ for (const d of descriptors) {
5495
+ if (d.textHash !== void 0 && d.textHash === candidateHash) return d;
5496
+ if (d.text !== void 0 && d.text.length >= MIN_TEXT_MATCH_LEN && candidate.includes(d.text)) return d;
5497
+ }
5498
+ return null;
5499
+ }
5500
+ var CORRESPONDENCE_ATTENUATION = 0.5;
5501
+ function matchConsequenceEntity(descriptors, entityId, changeType) {
5502
+ if (changeType !== "modified" || entityId.length === 0) return null;
5503
+ for (const d of descriptors)
5504
+ if (d.mode === "external" && d.targetEntityId === entityId) return d;
5505
+ return null;
5506
+ }
5507
+
5508
+ // src/cognition/agency/revocation.ts
5509
+ var REVOCATION_TYPE = "agency.revocation";
5510
+ var RUPTURE_REVOKE_GATE = 0.7;
5511
+ var REVOCATION_TTL_TICKS = 5;
5512
+ function revocationId(intentId) {
5513
+ return `agency-revocation-${intentId}`;
5514
+ }
5515
+ function revocationEntity(intentId, schema, rupture, tick) {
5516
+ return {
5517
+ id: revocationId(intentId),
5518
+ type: REVOCATION_TYPE,
5519
+ metadata: { intentId, schema, rupture, tick, expiresAt: tick + REVOCATION_TTL_TICKS }
5520
+ };
5521
+ }
5522
+ function revokedIntentIds(entities, tick) {
5523
+ const out = /* @__PURE__ */ new Set();
5524
+ for (const [, e] of entities) {
5525
+ if (e.type !== REVOCATION_TYPE) continue;
5526
+ const m = e.metadata ?? {};
5527
+ const intentId = typeof m["intentId"] === "string" ? m["intentId"] : void 0;
5528
+ const expiresAt = typeof m["expiresAt"] === "number" ? m["expiresAt"] : 0;
5529
+ if (intentId && tick < expiresAt) out.add(intentId);
5530
+ }
5531
+ return out;
5532
+ }
5533
+ function staleRevocationIds(entities, tick) {
5534
+ const stale = [];
5535
+ for (const [id, e] of entities) {
5536
+ if (e.type !== REVOCATION_TYPE) continue;
5537
+ const m = e.metadata ?? {};
5538
+ const expiresAt = typeof m["expiresAt"] === "number" ? m["expiresAt"] : 0;
5539
+ if (tick >= expiresAt) stale.push(id);
5540
+ }
5541
+ return stale;
5542
+ }
5543
+
5382
5544
  // src/cognition/faculties/exteroception.ts
5383
5545
  var internalTypes = /* @__PURE__ */ new Set([
5384
5546
  "percept",
@@ -5404,7 +5566,12 @@ var internalTypes = /* @__PURE__ */ new Set([
5404
5566
  "episodic_memory",
5405
5567
  // Internal state entities written by our own engines — not external events
5406
5568
  "affect.blends",
5407
- "executive.summary"
5569
+ "executive.summary",
5570
+ // The agency's own forward-model records (EXAFFERENCE P1/P2): perceiving our
5571
+ // expected-consequence descriptors would be a self-noise loop.
5572
+ CONSEQUENCE_TYPE,
5573
+ // The agency's own revocation tombstones (EXAFFERENCE P4) — internal bookkeeping.
5574
+ REVOCATION_TYPE
5408
5575
  ]);
5409
5576
  var Exteroception = class {
5410
5577
  name = "exteroception";
@@ -5454,17 +5621,26 @@ var Exteroception = class {
5454
5621
  const events = [], commands = { set: [], delete: [], metrics: [] };
5455
5622
  const rawPercepts = this._scanWorld(state);
5456
5623
  const capped = rawPercepts.slice(0, this._maxPerceptsPerTick);
5624
+ const consequences = liveConsequences(state.entities, tick);
5457
5625
  for (let i = 0; i < capped.length; i++) {
5458
5626
  const rp = capped[i];
5627
+ const textHit = consequences.length > 0 && rp.matchText ? matchConsequenceText(consequences, rp.matchText) : null;
5628
+ const entityHit = !textHit && consequences.length > 0 ? matchConsequenceEntity(consequences, rp.entityId, rp.changeType) : null;
5629
+ const hit = textHit ?? entityHit;
5630
+ const salience = textHit ? rp.salience * ATTENUATION : entityHit ? rp.salience * CORRESPONDENCE_ATTENUATION : rp.salience;
5459
5631
  const perceptEntity = {
5460
5632
  id: `percept-${tick}-${i}`,
5461
5633
  type: "percept",
5462
5634
  metadata: {
5463
5635
  entityId: rp.entityId,
5464
5636
  changeType: rp.changeType,
5465
- salience: rp.salience,
5637
+ salience,
5466
5638
  category: rp.category,
5467
5639
  summary: rp.summary,
5640
+ provenance: hit ? "reafferent" : "exafferent",
5641
+ ...hit ? { sourceIntentId: hit.intentId } : {},
5642
+ // affect→percept seam (registry #5): what this percept FEELS like
5643
+ ...rp.valence !== void 0 ? { valence: rp.valence, valenceSource: rp.valenceSource } : {},
5468
5644
  tick
5469
5645
  }
5470
5646
  };
@@ -5475,7 +5651,7 @@ var Exteroception = class {
5475
5651
  source: this.name,
5476
5652
  payload: {
5477
5653
  entityId: rp.entityId,
5478
- salience: rp.salience,
5654
+ salience,
5479
5655
  category: rp.category,
5480
5656
  summary: rp.summary
5481
5657
  }
@@ -5523,7 +5699,9 @@ var Exteroception = class {
5523
5699
  changeType: "appeared",
5524
5700
  salience: this._computeSalience(entity, "appeared", state.time),
5525
5701
  category: entity.type,
5526
- summary: this._summarizeEntity(entity, "appeared")
5702
+ summary: this._summarizeEntity(entity, "appeared"),
5703
+ matchText: this._matchText(entity),
5704
+ ...this._valenceOf(id, state)
5527
5705
  });
5528
5706
  } else if (entity.updatedAt > previousVersion) {
5529
5707
  percepts.push({
@@ -5531,7 +5709,9 @@ var Exteroception = class {
5531
5709
  changeType: "modified",
5532
5710
  salience: this._computeSalience(entity, "modified", state.time),
5533
5711
  category: entity.type,
5534
- summary: this._summarizeEntity(entity, "modified")
5712
+ summary: this._summarizeEntity(entity, "modified"),
5713
+ matchText: this._matchText(entity),
5714
+ ...this._valenceOf(id, state)
5535
5715
  });
5536
5716
  }
5537
5717
  this._previousEntityVersions.set(id, entity.updatedAt);
@@ -5557,6 +5737,46 @@ var Exteroception = class {
5557
5737
  * Generate a meaningful summary for an entity.
5558
5738
  * Instead of "New percept: percept-54-0", produce something useful.
5559
5739
  */
5740
+ /**
5741
+ * The text the corollary-discharge matcher inspects for this entity — its
5742
+ * content (a message body) over its description over its summary. Where our
5743
+ * own delivered words would surface if the world echoes them back.
5744
+ */
5745
+ /**
5746
+ * The affect→percept valence seam (registry #5). A percept carries how the
5747
+ * mind *feels* about what it is a percept OF, resolved most-specific-first:
5748
+ *
5749
+ * 1. the KnownEntityTracker's dossier for this entity (`ke-<id>.valence`) —
5750
+ * a real per-entity felt valence, the honest signal;
5751
+ * 2. otherwise the ambient `affect.valence` — the felt tone at perception
5752
+ * time. Weaker evidence, so it is tagged `'ambient'` and consumers
5753
+ * weight it down (mood is context, not appraisal of this thing).
5754
+ *
5755
+ * Absent both, no valence is stamped and every consumer keeps its
5756
+ * pre-seam behaviour.
5757
+ */
5758
+ /** Spread-friendly form of `_valenceFor` for percept construction. */
5759
+ _valenceOf(entityId, state) {
5760
+ const v = this._valenceFor(entityId, state);
5761
+ return v ? { valence: v.valence, valenceSource: v.source } : {};
5762
+ }
5763
+ _valenceFor(entityId, state) {
5764
+ const dossier = state.entities.get(`ke-${entityId}`);
5765
+ const felt = dossier?.metadata?.["valence"];
5766
+ if (typeof felt === "number" && Number.isFinite(felt))
5767
+ return { valence: felt, source: "entity" };
5768
+ const ambient = state.metrics.get("affect.valence");
5769
+ if (typeof ambient === "number" && Number.isFinite(ambient))
5770
+ return { valence: ambient, source: "ambient" };
5771
+ return void 0;
5772
+ }
5773
+ _matchText(entity) {
5774
+ const m = entity.metadata;
5775
+ const content = typeof m?.["content"] === "string" ? m["content"] : void 0;
5776
+ const description = typeof m?.["description"] === "string" ? m["description"] : void 0;
5777
+ const summary = typeof m?.["summary"] === "string" ? m["summary"] : void 0;
5778
+ return content ?? description ?? summary;
5779
+ }
5560
5780
  _summarizeEntity(entity, changeType) {
5561
5781
  const name = entity.metadata?.name;
5562
5782
  const description = entity.metadata?.description;
@@ -7541,6 +7761,8 @@ var MoralEvaluator = class {
7541
7761
  };
7542
7762
 
7543
7763
  // src/cognition/faculties/affective.blender.ts
7764
+ var ACP_AROUSAL_UPLIFT = 0.1;
7765
+ var ACP_CONFIDENCE2 = 0.4;
7544
7766
  var DOMINANT_EMOTION_CODES = {
7545
7767
  "neutral": 0,
7546
7768
  "fear": 1,
@@ -7641,6 +7863,8 @@ var AffectiveBlender = class {
7641
7863
  _previousPAD = { valence: 0, arousal: 0.3, dominance: 0.5 };
7642
7864
  _emotionHistory = /* @__PURE__ */ new Map();
7643
7865
  _moodBaseline = 0.5;
7866
+ /** ACP-P2: self-caused arousal attenuation armed; react() restores after one observe. */
7867
+ _acpOneShot = false;
7644
7868
  _energyLevel = 100;
7645
7869
  _comfort = 0.5;
7646
7870
  _sleepPressure = 0;
@@ -7674,8 +7898,12 @@ var AffectiveBlender = class {
7674
7898
  "sleep.state.changed",
7675
7899
  "stress.state.changed",
7676
7900
  "executive.prediction.formed",
7677
- "interaction.occurred"
7901
+ "interaction.occurred",
7678
7902
  // 2.1: social stimuli drive immediate arousal/valence shifts
7903
+ // ACP-P2: our own enactions — the arousal they cause is expected, not surprising
7904
+ "agency.enacted",
7905
+ "agency.communicate",
7906
+ "agency.invocation"
7679
7907
  ];
7680
7908
  }
7681
7909
  publishes() {
@@ -7684,6 +7912,15 @@ var AffectiveBlender = class {
7684
7912
  onCognitiveEvent(e) {
7685
7913
  this._model.observe(e.type, e.salience);
7686
7914
  switch (e.type) {
7915
+ case "agency.enacted":
7916
+ case "agency.communicate":
7917
+ case "agency.invocation": {
7918
+ const arousal = this._model.predict("affect.arousal");
7919
+ this._model.anticipate("affect.arousal", Math.min(1, arousal + ACP_AROUSAL_UPLIFT), ACP_CONFIDENCE2);
7920
+ this._model.setPrecision("affect.arousal", ACP_SELF_PRECISION);
7921
+ this._acpOneShot = true;
7922
+ break;
7923
+ }
7687
7924
  case "circadian.state.changed":
7688
7925
  this._moodBaseline = e.payload["moodBaseline"] ?? this._moodBaseline;
7689
7926
  break;
@@ -7787,8 +8024,14 @@ var AffectiveBlender = class {
7787
8024
  const _bus = this._bus;
7788
8025
  if (_bus)
7789
8026
  _bus.publish({ type: "affect.state.shifted", version: 1, sourceEngine: this.name, salience: Math.min(1, Math.abs(modulatedPAD.valence) + modulatedPAD.arousal * 0.5), payload: { valence: modulatedPAD.valence, arousal: modulatedPAD.arousal, dominantEmotion: dominant } });
7790
- if (_bus)
7791
- _bus.publish({ type: "affect.state.changed", version: 1, sourceEngine: this.name, salience: this._model.observe("affect.arousal", modulatedPAD.arousal).salience, payload: { valence: modulatedPAD.valence, arousal: modulatedPAD.arousal, dominance: modulatedPAD.dominance } });
8027
+ if (_bus) {
8028
+ const arousalErr = this._model.observe("affect.arousal", modulatedPAD.arousal);
8029
+ if (this._acpOneShot) {
8030
+ this._model.setPrecision("affect.arousal", 1);
8031
+ this._acpOneShot = false;
8032
+ }
8033
+ _bus.publish({ type: "affect.state.changed", version: 1, sourceEngine: this.name, salience: arousalErr.salience, payload: { valence: modulatedPAD.valence, arousal: modulatedPAD.arousal, dominance: modulatedPAD.dominance } });
8034
+ }
7792
8035
  return { events: events.length > 0 ? events : void 0, commands };
7793
8036
  }
7794
8037
  // ── PAD computation ──────────────────────────────────────
@@ -16206,7 +16449,8 @@ var TaskSwitcher = class {
16206
16449
  const currentGoal = activeGoals.find((g) => g.id === this._currentFocus.goalId);
16207
16450
  const currentPriority = currentGoal?.priority ?? 0;
16208
16451
  const switchAdvantage = topGoal.priority - currentPriority;
16209
- const switchCost = this._baseSwitchCost * (1 + this._currentFocus.focusTicks * 0.01);
16452
+ const stability = state.metrics.get("situation.stability") ?? 1;
16453
+ const switchCost = this._baseSwitchCost * (1 + this._currentFocus.focusTicks * 0.01 * stability);
16210
16454
  const netBenefit = switchAdvantage - switchCost;
16211
16455
  if (netBenefit > this._switchThreshold && this._currentFocus.focusTicks >= this._minFocusTicks) {
16212
16456
  this._currentFocus = {
@@ -19896,9 +20140,7 @@ var AffordanceSynthesizer = class {
19896
20140
  if (e.type === "affordance") del.push(id);
19897
20141
  const floor = schemas.filter((s) => s.binds === "none");
19898
20142
  for (const schema of floor)
19899
- set.push(this._toEntity(
19900
- this._build(schema, tick, state, valence, energyLow, skills, {})
19901
- ));
20143
+ set.push(this._toEntity(this._build(schema, tick, state, valence, energyLow, skills, {})));
19902
20144
  const candidates = [];
19903
20145
  const goalTargets = collectGoalTargets(state);
19904
20146
  const perceptSchema = schemas.find((s) => s.binds === "percept");
@@ -20112,11 +20354,24 @@ var BASE_SWITCH_COST = 0.15;
20112
20354
  var FOCUS_GAIN = 0.01;
20113
20355
  var AWAIT_STALE_TICKS = 15;
20114
20356
  var STALE_DECAY = 0.5;
20357
+ var RUPTURE_SALIENCE_GATE = 0.4;
20358
+ var RUPTURE_WINDOW_TICKS = 2;
20359
+ var STABILITY_RECOVERY = 0.05;
20360
+ var STABILITY_EPSILON = 1e-4;
20361
+ var REVOKE_HINT_WINDOW = 8;
20115
20362
  var ActionSelector = class {
20116
20363
  name = "action-selector";
20117
20364
  _bus = null;
20118
20365
  _lastEntropy = 0;
20119
20366
  _lastDeliberate = false;
20367
+ // EXAFFERENCE P4 follow-up (Channel B): the schema we most recently revoked
20368
+ // under rupture, so the *next* deliberation formed in its wake can own the
20369
+ // interruption in-character ("something changed — I dropped what I was
20370
+ // weighing"). Telemetry-grade instance state, mirroring _lastEntropy.
20371
+ _lastRevoked = null;
20372
+ // ACP §2b: sense-channel percepts buffered off the bus for the next react's
20373
+ // rupture computation (they never become entities). Cross-tick ⇒ FN9.
20374
+ _senseBuffer = [];
20120
20375
  attachBus(bus) {
20121
20376
  this._bus = bus;
20122
20377
  }
@@ -20124,16 +20379,60 @@ var ActionSelector = class {
20124
20379
  return [
20125
20380
  { type: "agency.selection.made", version: 1, validate: () => null },
20126
20381
  { type: "agency.selection.ambiguous", version: 1, validate: () => null },
20127
- { type: "agency.action.preempted", version: 1, validate: () => null }
20382
+ { type: "agency.action.preempted", version: 1, validate: () => null },
20383
+ { type: "agency.situation.rupture", version: 1, validate: () => null },
20384
+ { type: "agency.commitment.revoked", version: 1, validate: () => null }
20128
20385
  ];
20129
20386
  }
20130
20387
  subscribes() {
20131
- return [];
20388
+ return [
20389
+ "senses.*",
20390
+ // Registry #6 (ACP-P3): the model-error term — each carries its
20391
+ // engine's prediction-error salience, ALREADY precision-attenuated for
20392
+ // self-caused swings by the ACP-P2 consumers, so the echo guard
20393
+ // composes by construction: our own action's interoceptive wake
20394
+ // arrives below the rupture gate.
20395
+ "attention.state.changed",
20396
+ "affect.state.changed",
20397
+ "stress.state.changed"
20398
+ ];
20132
20399
  }
20133
- onCognitiveEvent() {
20400
+ /**
20401
+ * Mostly pull-model — but two afferent classes never become entities and
20402
+ * would leave rupture blind: sense-channel percepts
20403
+ * (ACTION_CONDITIONED_PREDICTION §2b) and the model-error state-change
20404
+ * events (registry #6). Buffer both (cross-tick: bus flush at T, consumed
20405
+ * by react at T+1 — FN9-snapshotted); the echo guard is applied at read
20406
+ * time for texts, and at the SOURCE for model errors (ACP-P2 precision).
20407
+ */
20408
+ onCognitiveEvent(e) {
20409
+ const isSense = e.type.startsWith("senses.") && e.type.endsWith(".percept");
20410
+ const isModelError = e.type === "attention.state.changed" || e.type === "affect.state.changed" || e.type === "stress.state.changed";
20411
+ if (!isSense && !isModelError) return;
20412
+ const p = e.payload;
20413
+ this._senseBuffer.push({
20414
+ salience: e.salience,
20415
+ ...isSense && typeof p?.content === "string" ? { text: p.content } : {}
20416
+ });
20134
20417
  }
20135
20418
  snapshot() {
20136
- return { lastEntropy: this._lastEntropy, lastDeliberate: this._lastDeliberate };
20419
+ return {
20420
+ lastEntropy: this._lastEntropy,
20421
+ lastDeliberate: this._lastDeliberate,
20422
+ lastRevoked: this._lastRevoked,
20423
+ senseBuffer: this._senseBuffer
20424
+ };
20425
+ }
20426
+ /** FN9: `_lastRevoked` has behavioral effect (the Channel-B `revokedBy` stamp),
20427
+ * so a restored mind must carry it — a rupture-driven letting-go survives a
20428
+ * snapshot boundary instead of silently losing its narrative thread. */
20429
+ restore(s) {
20430
+ if (typeof s["lastEntropy"] === "number") this._lastEntropy = s["lastEntropy"];
20431
+ if (typeof s["lastDeliberate"] === "boolean") this._lastDeliberate = s["lastDeliberate"];
20432
+ const lr = s["lastRevoked"];
20433
+ this._lastRevoked = lr && typeof lr === "object" && typeof lr.schema === "string" && typeof lr.tick === "number" ? { schema: lr.schema, tick: lr.tick } : null;
20434
+ const sb = s["senseBuffer"];
20435
+ this._senseBuffer = Array.isArray(sb) ? sb.filter((it) => it && typeof it.salience === "number").map((it) => ({ salience: it.salience, ...typeof it.text === "string" ? { text: it.text } : {} })) : [];
20137
20436
  }
20138
20437
  async react(_delta, tick, state, _context) {
20139
20438
  const eligible = [];
@@ -20162,54 +20461,121 @@ var ActionSelector = class {
20162
20461
  let blocking = false;
20163
20462
  let awaiting = null;
20164
20463
  let composite = null;
20464
+ let deliberating = null;
20165
20465
  for (const it of intents) {
20166
- if (it.st === "deliberating") blocking = true;
20167
- else if (it.st === "expanding") composite = { id: it.id, activation: it.activation, schema: it.schema };
20466
+ if (it.st === "deliberating") {
20467
+ blocking = true;
20468
+ deliberating = { id: it.id, schema: it.schema };
20469
+ } else if (it.st === "expanding") composite = { id: it.id, activation: it.activation, schema: it.schema };
20168
20470
  else if (it.st === "awaiting") awaiting = { id: it.id, activation: it.activation, schema: it.schema, target: it.target, dispatchedAt: it.dispatchedAt };
20169
20471
  else if (it.st === "selected") {
20170
20472
  const activeMacroSub = it.parentIntentId !== void 0 && expandingParents.has(it.parentIntentId);
20171
20473
  if (!activeMacroSub) blocking = true;
20172
20474
  }
20173
20475
  }
20174
- const busy = (n) => ({ commands: { metrics: [
20175
- ["agency.field.eligible", n],
20176
- ["agency.selection.busy", 1]
20177
- ] } });
20476
+ const senseEvents = this._senseBuffer;
20477
+ this._senseBuffer = [];
20478
+ const rupture = computeRupture(state, tick, senseEvents);
20479
+ const prevStab = metric2(state, "situation.stability", 1);
20480
+ const nextStabRaw = clamp018(prevStab + STABILITY_RECOVERY * (1 - prevStab) - rupture);
20481
+ const nextStab = 1 - nextStabRaw < STABILITY_EPSILON ? 1 : nextStabRaw;
20482
+ const stabMetrics = rupture > 0 || prevStab < 1 ? [["situation.stability", nextStab]] : [];
20483
+ if (rupture > 0 && this._bus) {
20484
+ try {
20485
+ this._bus.publish({
20486
+ type: "agency.situation.rupture",
20487
+ version: 1,
20488
+ sourceEngine: this.name,
20489
+ salience: rupture,
20490
+ payload: { rupture, stability: nextStab, tick }
20491
+ });
20492
+ } catch (err) {
20493
+ logger.warn(`[selector] rupture publish failed: ${err instanceof Error ? err.message : String(err)}`);
20494
+ }
20495
+ }
20496
+ const busy = (n) => ({
20497
+ commands: {
20498
+ metrics: [
20499
+ ["agency.field.eligible", n],
20500
+ ["agency.selection.busy", 1],
20501
+ ...stabMetrics
20502
+ ]
20503
+ }
20504
+ });
20505
+ if (deliberating && rupture >= RUPTURE_REVOKE_GATE) {
20506
+ if (this._bus) {
20507
+ try {
20508
+ this._bus.publish({
20509
+ type: "agency.commitment.revoked",
20510
+ version: 1,
20511
+ sourceEngine: this.name,
20512
+ salience: 0.85,
20513
+ payload: { from: deliberating.schema, reason: "exafferent-rupture", rupture, tick }
20514
+ });
20515
+ } catch (err) {
20516
+ logger.warn(`[selector] revoked publish failed: ${err instanceof Error ? err.message : String(err)}`);
20517
+ }
20518
+ }
20519
+ this._lastRevoked = { schema: deliberating.schema, tick };
20520
+ return {
20521
+ commands: {
20522
+ set: [revocationEntity(deliberating.id, deliberating.schema, rupture, tick)],
20523
+ metrics: [
20524
+ ["agency.field.eligible", eligible.length],
20525
+ ["agency.selection.busy", 1],
20526
+ ["agency.commitment.revoked", 1],
20527
+ ...stabMetrics
20528
+ ]
20529
+ }
20530
+ };
20531
+ }
20178
20532
  if (blocking) return busy(eligible.length);
20179
20533
  if (eligible.length === 0)
20180
- return { commands: { metrics: [["agency.field.eligible", 0], ["agency.selection.busy", awaiting || composite ? 1 : 0]] } };
20534
+ return {
20535
+ commands: {
20536
+ metrics: [
20537
+ ["agency.field.eligible", 0],
20538
+ ["agency.selection.busy", awaiting || composite ? 1 : 0],
20539
+ ...stabMetrics
20540
+ ]
20541
+ }
20542
+ };
20181
20543
  const bias = buildBias(state);
20182
- const effSwitchCost = effectiveSwitchCost(state);
20544
+ const effSwitchCost = effectiveSwitchCost(state) * (1 - rupture);
20183
20545
  const weights = effectiveWeights(state);
20184
20546
  const scored = eligible.map((a) => ({ affordance: a, activation: scoreAffordance(a, bias, weights) })).sort((x, y) => y.activation - x.activation);
20185
20547
  const winner = scored[0];
20186
20548
  if (!winner) return busy(eligible.length);
20549
+ let compositeTombstone;
20550
+ let compositeFrom;
20187
20551
  if (composite) {
20188
20552
  const different = winner.affordance.schema !== composite.schema;
20189
20553
  const switchCost = effSwitchCost * (1 - stakes(winner.affordance, bias));
20190
- if (different && winner.activation > composite.activation + switchCost) {
20191
- if (this._bus) try {
20554
+ if (!different || winner.activation <= composite.activation + switchCost)
20555
+ return busy(eligible.length);
20556
+ if (this._bus)
20557
+ try {
20192
20558
  this._bus.publish({
20193
20559
  type: "agency.action.preempted",
20194
20560
  version: 1,
20195
20561
  sourceEngine: this.name,
20196
20562
  salience: 0.8,
20197
- payload: { from: composite.schema, to: winner.affordance.schema, activation: winner.activation, tick }
20563
+ payload: {
20564
+ from: composite.schema,
20565
+ to: winner.affordance.schema,
20566
+ activation: winner.activation,
20567
+ tick
20568
+ }
20198
20569
  });
20199
20570
  } catch (err) {
20200
20571
  logger.warn(`[selector] preempt publish failed: ${err instanceof Error ? err.message : String(err)}`);
20201
20572
  }
20202
- return { commands: { delete: [composite.id], metrics: [
20203
- ["agency.field.eligible", eligible.length],
20204
- ["agency.selection.busy", 1],
20205
- ["agency.selection.preempted", 1]
20206
- ] } };
20207
- }
20208
- return busy(eligible.length);
20573
+ compositeTombstone = composite.id;
20574
+ compositeFrom = composite.schema;
20209
20575
  }
20210
20576
  let preemptDelete;
20211
- let preemptedFrom;
20212
- if (awaiting) {
20577
+ let preemptedFrom = compositeFrom;
20578
+ if (awaiting && !compositeTombstone) {
20213
20579
  const sameAction = winner.affordance.schema === awaiting.schema && (winner.affordance.targetEntityId ?? "") === awaiting.target;
20214
20580
  if (sameAction) return busy(eligible.length);
20215
20581
  const staleness = Math.min(1, (tick - awaiting.dispatchedAt) / AWAIT_STALE_TICKS);
@@ -20232,6 +20598,13 @@ var ActionSelector = class {
20232
20598
  const deliberate = margin < marginGate || stk > stakesGate;
20233
20599
  this._lastEntropy = entropy;
20234
20600
  this._lastDeliberate = deliberate;
20601
+ let revokedBy;
20602
+ if (this._lastRevoked) {
20603
+ if (deliberate && tick - this._lastRevoked.tick <= REVOKE_HINT_WINDOW)
20604
+ revokedBy = this._lastRevoked.schema;
20605
+ if (revokedBy || tick - this._lastRevoked.tick > REVOKE_HINT_WINDOW)
20606
+ this._lastRevoked = null;
20607
+ }
20235
20608
  const intent = {
20236
20609
  id: `agency-intent-${tick}`,
20237
20610
  type: "agency.intent",
@@ -20274,6 +20647,9 @@ var ActionSelector = class {
20274
20647
  // interrupted, so the deliberation facet can own the interruption in-character
20275
20648
  // ("I was about to X, but this pulled me away"). Only meaningful while deliberating.
20276
20649
  ...preemptedFrom ? { preemptedFrom } : {},
20650
+ // Channel B: this deliberation forms in the wake of a rupture-driven
20651
+ // revocation — the facet can own "something changed, I let go of X".
20652
+ ...revokedBy ? { revokedBy } : {},
20277
20653
  tick
20278
20654
  }
20279
20655
  };
@@ -20312,7 +20688,9 @@ var ActionSelector = class {
20312
20688
  }
20313
20689
  }
20314
20690
  const commands = {
20315
- set: [intent],
20691
+ // A composite preemption rides along as a tombstone (never a delete — the
20692
+ // executor's in-tick macro-advance would resurrect the parent).
20693
+ set: compositeTombstone ? [intent, revocationEntity(compositeTombstone, compositeFrom ?? "", rupture, tick)] : [intent],
20316
20694
  ...preemptDelete ? { delete: [preemptDelete] } : {},
20317
20695
  metrics: [
20318
20696
  ["agency.field.eligible", eligible.length],
@@ -20321,7 +20699,8 @@ var ActionSelector = class {
20321
20699
  ["agency.selection.margin", margin],
20322
20700
  ["agency.selection.deliberate", deliberate ? 1 : 0],
20323
20701
  ["agency.selection.preempted", preemptedFrom ? 1 : 0],
20324
- ["agency.selection.activation", winner.activation]
20702
+ ["agency.selection.activation", winner.activation],
20703
+ ...stabMetrics
20325
20704
  ]
20326
20705
  };
20327
20706
  return { commands };
@@ -20331,7 +20710,29 @@ function effectiveSwitchCost(state) {
20331
20710
  const params = readEffectiveParams(state, "engine-config-action-selector");
20332
20711
  const base = num2(params["switchCost"], BASE_SWITCH_COST);
20333
20712
  const focusTicks = metric2(state, "task_switch.current_focus_ticks", 0);
20334
- return base * (1 + focusTicks * FOCUS_GAIN);
20713
+ const stability = metric2(state, "situation.stability", 1);
20714
+ return base * (1 + focusTicks * FOCUS_GAIN * stability);
20715
+ }
20716
+ function computeRupture(state, tick, senseEvents = []) {
20717
+ let maxSalience = 0;
20718
+ for (const e of state.entities.values()) {
20719
+ if (e.type !== "percept") continue;
20720
+ const m = e.metadata;
20721
+ if (str2(m?.["provenance"]) !== "exafferent") continue;
20722
+ const pTick = num2(m?.["tick"], -1);
20723
+ if (pTick < 0 || tick - pTick > RUPTURE_WINDOW_TICKS) continue;
20724
+ const s = num2(m?.["salience"], 0);
20725
+ if (s > maxSalience) maxSalience = s;
20726
+ }
20727
+ if (senseEvents.length > 0) {
20728
+ const live = liveConsequences(state.entities, tick);
20729
+ for (const ev of senseEvents) {
20730
+ if (ev.text !== void 0 && live.length > 0 && matchConsequenceText(live, ev.text)) continue;
20731
+ if (ev.salience > maxSalience) maxSalience = ev.salience;
20732
+ }
20733
+ }
20734
+ if (maxSalience <= RUPTURE_SALIENCE_GATE) return 0;
20735
+ return clamp018((maxSalience - RUPTURE_SALIENCE_GATE) / (1 - RUPTURE_SALIENCE_GATE));
20335
20736
  }
20336
20737
  function effectiveWeights(state) {
20337
20738
  const p = readEffectiveParams(state, "engine-config-action-selector");
@@ -20432,19 +20833,28 @@ var DeliberationEngine = class {
20432
20833
  return { deliberations: this._deliberations };
20433
20834
  }
20434
20835
  async react(_delta, tick, state, _context) {
20836
+ const revoked = revokedIntentIds(state.entities, tick);
20837
+ const del = [];
20435
20838
  let target = null;
20436
20839
  for (const [id2, e] of state.entities) {
20437
20840
  if (e.type !== "agency.intent") continue;
20438
20841
  if (str3(e.metadata?.["status"]) !== "deliberating") continue;
20842
+ if (revoked.has(id2)) {
20843
+ del.push(id2, revocationId(id2));
20844
+ continue;
20845
+ }
20439
20846
  const meta2 = e.metadata ?? {};
20440
20847
  if (!target || id2 < target.id) target = { id: id2, meta: meta2 };
20441
20848
  }
20442
- if (!target) return { commands: {} };
20849
+ if (!target) return del.length > 0 ? { commands: { delete: del } } : { commands: {} };
20443
20850
  const { id, meta } = target;
20444
20851
  const provisional = str3(meta["schema"]) ?? "wait";
20445
20852
  const candidates = Array.isArray(meta["candidates"]) ? meta["candidates"] : [];
20446
20853
  if (!this._provider)
20447
- return { commands: { set: [this._commit(id, meta, provisional, candidates, "no-executive")] } };
20854
+ return { commands: {
20855
+ set: [this._commit(id, meta, provisional, candidates, "no-executive")],
20856
+ ...del.length > 0 ? { delete: del } : {}
20857
+ } };
20448
20858
  const chosen = await this._deliberate(state, candidates, provisional, meta);
20449
20859
  this._deliberations++;
20450
20860
  if (this._bus) {
@@ -20462,6 +20872,7 @@ var DeliberationEngine = class {
20462
20872
  return {
20463
20873
  commands: {
20464
20874
  set: [this._commit(id, meta, chosen, candidates, "facet")],
20875
+ ...del.length > 0 ? { delete: del } : {},
20465
20876
  metrics: [["agency.deliberation.count", 1]]
20466
20877
  }
20467
20878
  };
@@ -20519,7 +20930,10 @@ var DeliberationEngine = class {
20519
20930
  _buildFocusContent(state, candidates, meta) {
20520
20931
  const lines = [];
20521
20932
  const preemptedFrom = str3(meta["preemptedFrom"]);
20522
- if (preemptedFrom)
20933
+ const revokedBy = str3(meta["revokedBy"]);
20934
+ if (revokedBy)
20935
+ lines.push(`Something in my situation just shifted and I let go of what I was weighing ("${revokedBy}"). Decide afresh what to do now:`);
20936
+ else if (preemptedFrom)
20523
20937
  lines.push(`I just broke off a pending action ("${preemptedFrom}") because something more pressing pulled at me. Decide what to do now:`);
20524
20938
  else
20525
20939
  lines.push("My automatic action-selection was uncertain. Candidate actions:");
@@ -20692,6 +21106,19 @@ var MotorSchemaExecutor = class {
20692
21106
  const metrics = [];
20693
21107
  const energy = state.metrics.get("energy.level") ?? 100;
20694
21108
  const stress = state.metrics.get("stress.load") ?? 0;
21109
+ for (const [id, e] of state.entities) {
21110
+ if (e.type !== CONSEQUENCE_TYPE) continue;
21111
+ if (tick >= num3(e.metadata?.["expiresAt"], 0)) del.push(id);
21112
+ }
21113
+ del.push(...staleRevocationIds(state.entities, tick));
21114
+ const revoked = revokedIntentIds(state.entities, tick);
21115
+ if (revoked.size > 0)
21116
+ for (const [id, e] of state.entities) {
21117
+ if (e.type !== "agency.intent") continue;
21118
+ const parentId = str5(e.metadata?.["parentIntentId"]);
21119
+ if (revoked.has(id)) del.push(id, revocationId(id));
21120
+ else if (parentId && revoked.has(parentId)) del.push(id);
21121
+ }
20695
21122
  for (const [id, e] of state.entities) {
20696
21123
  if (e.type !== "agency.intent" || str5(e.metadata?.["status"]) !== "awaiting") continue;
20697
21124
  const dispatchedAt = num3(e.metadata?.["dispatchedAt"], tick);
@@ -20718,6 +21145,9 @@ var MotorSchemaExecutor = class {
20718
21145
  const selected = [...state.entities.entries()].filter(([, e]) => e.type === "agency.intent" && str5(e.metadata?.["status"]) === "selected").sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
20719
21146
  let enactedCount = 0;
20720
21147
  for (const [id, e] of selected) {
21148
+ if (revoked.has(id)) continue;
21149
+ const parentOf = str5(e.metadata?.["parentIntentId"]);
21150
+ if (parentOf && revoked.has(parentOf)) continue;
20721
21151
  const intent = readIntent(id, e.metadata);
20722
21152
  const schema = this._resolve(intent.schema);
20723
21153
  if (schema?.kind === "composite" && schema.composedOf && schema.composedOf.length > 0) {
@@ -20766,6 +21196,18 @@ var MotorSchemaExecutor = class {
20766
21196
  predictedValence: predicted.expectedValence
20767
21197
  }
20768
21198
  });
21199
+ const awaitingText = enaction.mode === "communicate" ? str5(intent.parameters["content"]) ?? firstMessage(intent.parameters["messages"]) : void 0;
21200
+ set.push(consequenceEntity({
21201
+ intentId: id,
21202
+ schema: intent.schema,
21203
+ mode: enaction.mode === "communicate" ? "communicate" : "external",
21204
+ ...enaction.mode === "communicate" ? { effector: COMM_SCHEMA_TO_EFFECTOR[intent.schema] ?? intent.schema } : {},
21205
+ ...intent.targetEntityId ? { targetEntityId: intent.targetEntityId } : {},
21206
+ ...awaitingText ? { text: awaitingText, textHash: fnv1a(awaitingText) } : {},
21207
+ paramsHash: fnv1a(paramsKey(intent.parameters)),
21208
+ expiresAt: tick + CONSEQUENCE_TTL_TICKS,
21209
+ tick
21210
+ }));
20769
21211
  this._emitDispatch(intent, enaction.mode, tick);
20770
21212
  metrics.push([enaction.mode === "communicate" ? "agency.communicate.dispatched" : "agency.invocation.dispatched", 1]);
20771
21213
  }
@@ -20932,6 +21374,18 @@ var MotorSchemaExecutor = class {
20932
21374
  };
20933
21375
  set.push(outcomeEntity(tick, intent, out, predicted));
20934
21376
  del.push(id);
21377
+ if (result.success)
21378
+ set.push(consequenceEntity({
21379
+ intentId: id,
21380
+ schema: intent.schema,
21381
+ mode: "communicate",
21382
+ effector,
21383
+ ...intent.targetEntityId ? { targetEntityId: intent.targetEntityId } : {},
21384
+ textHash: fnv1a(bubbles.join("\n")),
21385
+ text: bubbles.join("\n"),
21386
+ expiresAt: tick + CONSEQUENCE_TTL_TICKS,
21387
+ tick
21388
+ }));
20935
21389
  this._emitEnacted(intent, out, predicted, tick);
20936
21390
  this._emitActionOutcome(
20937
21391
  intent,
@@ -21070,6 +21524,10 @@ function errMsg(err) {
21070
21524
 
21071
21525
  // src/cognition/agency/engines/reafference.engine.ts
21072
21526
  var PROC_THRESHOLD2 = 0.6;
21527
+ var SENSORY_SOFT_QUALITY = 0.6;
21528
+ var SENSORY_VALENCE_SPAN_ENTITY = 0.25;
21529
+ var SENSORY_VALENCE_SPAN_AMBIENT = 0.1;
21530
+ var SENSORY_SUCCESS_FLOOR = 0.5;
21073
21531
  var ReafferenceEngine = class {
21074
21532
  name = "reafference";
21075
21533
  _repertoire;
@@ -21119,14 +21577,64 @@ var ReafferenceEngine = class {
21119
21577
  const set = [];
21120
21578
  const del = [];
21121
21579
  const metrics = [];
21122
- let updates = 0;
21123
- let discovered = 0;
21580
+ const outcomes = [];
21581
+ const gradedIntentIds = /* @__PURE__ */ new Set();
21124
21582
  for (const [id, e] of state.entities) {
21125
21583
  if (e.type !== "agency.outcome") continue;
21126
21584
  const m = e.metadata ?? {};
21585
+ outcomes.push({ id, meta: m, fromState: true });
21586
+ const iid = str6(m["intentId"]);
21587
+ if (iid) gradedIntentIds.add(iid);
21588
+ }
21589
+ const awaiting = /* @__PURE__ */ new Map();
21590
+ for (const [id, e] of state.entities) {
21591
+ if (e.type !== "agency.intent" || str6(e.metadata?.["status"]) !== "awaiting") continue;
21592
+ const m = e.metadata ?? {};
21593
+ if (tick - num4(m["dispatchedAt"], tick) >= AWAIT_TIMEOUT) continue;
21594
+ awaiting.set(id, {
21595
+ schema: str6(m["schema"]) ?? "",
21596
+ predictedReward: num4(m["predictedReward"], 0.5),
21597
+ predictedValence: num4(m["predictedValence"], 0)
21598
+ });
21599
+ }
21600
+ let sensory = 0;
21601
+ const sensedIntentIds = /* @__PURE__ */ new Set();
21602
+ for (const [, e] of state.entities) {
21603
+ if (e.type !== "percept") continue;
21604
+ const m = e.metadata ?? {};
21605
+ if (str6(m["provenance"]) !== "reafferent") continue;
21606
+ const iid = str6(m["sourceIntentId"]);
21607
+ if (!iid || gradedIntentIds.has(iid) || sensedIntentIds.has(iid)) continue;
21608
+ const aw = awaiting.get(iid);
21609
+ if (!aw || !aw.schema) continue;
21610
+ sensedIntentIds.add(iid);
21611
+ sensory++;
21612
+ const feltRaw = m["valence"];
21613
+ const felt = typeof feltRaw === "number" && Number.isFinite(feltRaw) ? feltRaw : void 0;
21614
+ const span = str6(m["valenceSource"]) === "entity" ? SENSORY_VALENCE_SPAN_ENTITY : SENSORY_VALENCE_SPAN_AMBIENT;
21615
+ const quality = felt === void 0 ? SENSORY_SOFT_QUALITY : clamp0111(SENSORY_SOFT_QUALITY + Math.max(-1, Math.min(1, felt)) * span);
21616
+ outcomes.push({ id: `agency-outcome-${tick}-${iid}-sensory`, fromState: false, meta: {
21617
+ schema: aw.schema,
21618
+ intentId: iid,
21619
+ success: quality >= SENSORY_SUCCESS_FLOOR,
21620
+ outcomeQuality: quality,
21621
+ valence: felt ?? aw.predictedValence,
21622
+ predictedReward: aw.predictedReward,
21623
+ predictedValence: aw.predictedValence,
21624
+ surprise: clamp0111(Math.abs(aw.predictedReward - quality)),
21625
+ mode: "external",
21626
+ reconciled: true,
21627
+ sensory: true,
21628
+ ...felt !== void 0 ? { sensoryValence: felt, valenceSource: str6(m["valenceSource"]) } : {},
21629
+ tick
21630
+ } });
21631
+ }
21632
+ let updates = 0;
21633
+ let discovered = 0;
21634
+ for (const { id, meta: m, fromState } of outcomes) {
21127
21635
  const schema = str6(m["schema"]);
21128
21636
  if (!schema) {
21129
- del.push(id);
21637
+ if (fromState) del.push(id);
21130
21638
  continue;
21131
21639
  }
21132
21640
  const { skill, proceduralized } = this._repertoire.recordOutcome({
@@ -21138,7 +21646,7 @@ var ReafferenceEngine = class {
21138
21646
  tick
21139
21647
  });
21140
21648
  set.push(skillEntity(skill));
21141
- del.push(id);
21649
+ if (fromState) del.push(id);
21142
21650
  const intentId = str6(m["intentId"]);
21143
21651
  if (intentId) del.push(intentId);
21144
21652
  updates++;
@@ -21166,7 +21674,8 @@ var ReafferenceEngine = class {
21166
21674
  ["agency.learning.updates", updates],
21167
21675
  ["agency.discovered.count", discovered],
21168
21676
  ["agency.skill.count", skills.size],
21169
- ["agency.habitual.count", habitual]
21677
+ ["agency.habitual.count", habitual],
21678
+ ["agency.sensory.confirmed", sensory]
21170
21679
  );
21171
21680
  return { commands: { set, delete: del, metrics } };
21172
21681
  }
@@ -21250,6 +21759,9 @@ function str6(v) {
21250
21759
  function num4(v, fallback) {
21251
21760
  return typeof v === "number" && Number.isFinite(v) ? v : fallback;
21252
21761
  }
21762
+ function clamp0111(n) {
21763
+ return n < 0 ? 0 : n > 1 ? 1 : n;
21764
+ }
21253
21765
 
21254
21766
  // src/cognition/config.mirror.entities.ts
21255
21767
  function buildEngineConfigEntities(config, executiveInterval) {
@@ -23981,6 +24493,10 @@ var OutboxController = class {
23981
24493
  summary: delivered ? `My message was delivered successfully.` : `My message failed to reach the recipient.`,
23982
24494
  salience: delivered ? 0.35 : 0.6,
23983
24495
  changeType: delivered ? "delivered" : "failed",
24496
+ // Reafference by construction — this percept describes our own action's
24497
+ // outcome ("ear hears the word"). Tagged, not attenuated: it is the ack
24498
+ // surface, not a content echo (EXAFFERENCE P2).
24499
+ provenance: "reafferent",
23984
24500
  messageId
23985
24501
  }
23986
24502
  });
@@ -24382,7 +24898,7 @@ var InboundQueue = class {
24382
24898
  function reconcileInvocation(intentId, schema, result, tick, predicted = { reward: 0.5, valence: 0 }, provenance = {}) {
24383
24899
  const outcomeQuality = result.outcomeQuality ?? (result.success ? 0.8 : 0.1);
24384
24900
  const valence = result.valence ?? (result.success ? 0.2 : -0.2);
24385
- const surprise = clamp0111(Math.abs(predicted.reward - outcomeQuality));
24901
+ const surprise = clamp0112(Math.abs(predicted.reward - outcomeQuality));
24386
24902
  return {
24387
24903
  id: `agency-outcome-${tick}-${intentId}`,
24388
24904
  type: "agency.outcome",
@@ -24404,7 +24920,7 @@ function reconcileInvocation(intentId, schema, result, tick, predicted = { rewar
24404
24920
  }
24405
24921
  };
24406
24922
  }
24407
- function clamp0111(n) {
24923
+ function clamp0112(n) {
24408
24924
  return n < 0 ? 0 : n > 1 ? 1 : n;
24409
24925
  }
24410
24926