aedmark commited on
Commit
7658e0d
·
verified ·
1 Parent(s): fca13b0

Delete bone_soul.py

Browse files
Files changed (1) hide show
  1. bone_soul.py +0 -710
bone_soul.py DELETED
@@ -1,710 +0,0 @@
1
- import json, os, random, time
2
- from dataclasses import dataclass, field
3
- from typing import List, Dict, Optional, Any, Tuple
4
- from bone_akashic import TheAkashicRecord
5
- from bone_config import BoneConfig
6
- from bone_core import LoreManifest, EventBus
7
- from bone_lexicon import LexiconService
8
- from bone_types import Prisma
9
-
10
-
11
- @dataclass
12
- class CoreMemory:
13
- timestamp: float
14
- trigger_words: List[str]
15
- emotional_flavor: str
16
- lesson: str
17
- impact_voltage: float
18
- type: str = "INCIDENT"
19
- meta: Dict[str, Any] = field(default_factory=dict)
20
-
21
-
22
- @dataclass
23
- class TraitVector:
24
- curiosity: float = 0.5
25
- cynicism: float = 0.5
26
- hope: float = 0.5
27
- discipline: float = 0.5
28
- wisdom: float = 0.1
29
- empathy: float = 0.5
30
- _TRAITS = {"curiosity", "cynicism", "hope", "discipline", "wisdom", "empathy"}
31
-
32
- def __post_init__(self):
33
- self._clamp_all()
34
-
35
- def to_dict(self):
36
- return {k.upper(): getattr(self, k) for k in self._TRAITS}
37
-
38
- @classmethod
39
- def from_dict(cls, data: Dict):
40
- kwargs = {k: float(data.get(k.upper(), 0.5)) for k in cls._TRAITS}
41
- return cls(**kwargs)
42
-
43
- def adjust(self, trait: str, delta: float):
44
- t = trait.lower()
45
- if t in self._TRAITS:
46
- current_val = getattr(self, t)
47
- setattr(self, t, max(0.0, min(1.0, current_val + delta)))
48
-
49
- def _clamp_all(self):
50
- for t in self._TRAITS:
51
- val = getattr(self, t)
52
- setattr(self, t, max(0.0, min(1.0, val)))
53
-
54
- def normalize(self, decay_rate: float):
55
- for t in self._TRAITS:
56
- val = getattr(self, t)
57
- local_decay = decay_rate * 0.5 if t == "empathy" else decay_rate
58
- if abs(val - 0.5) <= local_decay:
59
- new_val = 0.5
60
- else:
61
- new_val = val - local_decay if val > 0.5 else val + local_decay
62
- setattr(self, t, new_val)
63
-
64
-
65
- class TheEditor:
66
- def __init__(self, lexicon_ref: Any = None):
67
- self.lex = lexicon_ref if lexicon_ref else LexiconService
68
-
69
- @staticmethod
70
- def critique(chapter_title: str, stress_mode: bool = False) -> str:
71
- narrative = {}
72
- if hasattr(LoreManifest, "get_instance"):
73
- narrative = LoreManifest.get_instance().get("narrative_data") or {}
74
-
75
- reviews = narrative.get("LITERARY_REVIEWS", {})
76
- pos = reviews.get("POSITIVE", ["Valid."])
77
- neg = reviews.get("NEGATIVE", ["Invalid."])
78
- conf = reviews.get("CONFUSED", ["Unclear."])
79
-
80
- if stress_mode:
81
- # The Witness (High Stress) prefers abstract/confused/negative feedback
82
- pool = conf + neg
83
- prefix = "[THE WITNESS]"
84
- color = Prisma.CYN
85
- else:
86
- # The Editor (Standard) prefers binary feedback
87
- pool = pos + neg
88
- prefix = "[THE EDITOR]"
89
- color = Prisma.GRY
90
-
91
- comment = random.choice(pool) if pool else "No comment."
92
- return f"{color}{prefix}: Re: '{chapter_title}' - \"{comment}\"{Prisma.RST}"
93
-
94
-
95
- class HumanityAnchor:
96
- def __init__(self, events_ref: "EventBus"):
97
- self.events = events_ref
98
- self.dignity_reserve = BoneConfig.ANCHOR.DIGNITY_MAX
99
- self.agency_lock = False
100
- self.current_riddle_answers: Optional[List[str]] = None
101
- self._LEXICAL_ANCHORS = {"sacred", "play", "social", "abstract"}
102
- self._VECTOR_ANCHORS = ["PSI", "LAMBDA", "BET"]
103
-
104
- def audit_existence(self, physics: dict, bio: dict) -> float:
105
- atp, volt = bio.get("atp", 0), physics.get("voltage", 0.0)
106
- if atp >= 5.0 or volt >= 5.0:
107
- return 0.0
108
- vector: Dict[str, float] = physics.get("vector", {})
109
- counts: Dict[str, int] = physics.get("counts", {})
110
- dim_resonance = sum(vector.get(k, 0.0) for k in self._VECTOR_ANCHORS)
111
- lex_resonance = sum(counts.get(k, 0) for k in self._LEXICAL_ANCHORS)
112
- cfg = BoneConfig.ANCHOR
113
- if (dim_resonance + (lex_resonance * 0.5)) > 0.3:
114
- self.dignity_reserve = min(
115
- cfg.DIGNITY_MAX, self.dignity_reserve + cfg.DIGNITY_REGEN
116
- )
117
- return 1.0
118
- self.dignity_reserve = max(0.0, self.dignity_reserve - cfg.DIGNITY_DECAY)
119
- if not self.agency_lock:
120
- if self.dignity_reserve < cfg.DIGNITY_LOCKDOWN:
121
- self._engage_lockdown()
122
- return -1.0
123
- elif self.dignity_reserve < cfg.DIGNITY_CRITICAL:
124
- self.events.log(
125
- f"{Prisma.VIOLET}⚠️ EXISTENTIAL DRAG: You are drifting.{Prisma.RST}",
126
- "SOUL"
127
- )
128
- return 0.0
129
-
130
- def _engage_lockdown(self):
131
- self.agency_lock = True
132
-
133
- seeds = []
134
- if hasattr(LoreManifest, "get_instance"):
135
- lore = LoreManifest.get_instance()
136
- seeds = lore.get("SEEDS") or (lore.get("narrative_data") or {}).get("SEEDS", [])
137
- riddles = seeds or [{"question": "Who are you?", "triggers": ["*"]}]
138
- selection = random.choice(riddles)
139
- riddle = selection.get("question", "Error?")
140
- raw_triggers = selection.get("triggers", ["*"])
141
- if isinstance(raw_triggers, list):
142
- self.current_riddle_answers = raw_triggers
143
- else:
144
- self.current_riddle_answers = ["*"]
145
- self.events.log(
146
- f"{Prisma.RED}🔒 AGENCY LOCK: Dignity Critical.{Prisma.RST}", "SYS_LOCK"
147
- )
148
- self.events.log(
149
- f"{Prisma.VIOLET}The Ghost demands a password: '{riddle}'{Prisma.RST}",
150
- "SOUL_QUERY",
151
- )
152
-
153
- def check_domestication(self, reliance_proxy: float):
154
- if reliance_proxy > 0.7:
155
- self.dignity_reserve = max(0.0, self.dignity_reserve - (BoneConfig.ANCHOR.DIGNITY_DECAY * 2.0))
156
- elif reliance_proxy < 0.4:
157
- self.dignity_reserve = min(BoneConfig.ANCHOR.DIGNITY_MAX,
158
- self.dignity_reserve + BoneConfig.ANCHOR.DIGNITY_REGEN)
159
- if self.dignity_reserve < BoneConfig.ANCHOR.DIGNITY_CRITICAL and not self.agency_lock:
160
- self.events.log(f"{Prisma.VIOLET}⚠️ DOMESTICATION ALERT: Dignity fading.{Prisma.RST}", "SOUL")
161
-
162
- def assess_humanity(self, text: str) -> bool:
163
- if not self.agency_lock:
164
- return True
165
- clean = text.lower().strip()
166
- answers = self.current_riddle_answers or ["*"]
167
- if "*" in answers:
168
- passed = len(clean.split()) > 4 and not clean.startswith("/")
169
- else:
170
- passed = any(ans in clean for ans in answers)
171
- if passed:
172
- self.agency_lock = False
173
- self.dignity_reserve = 50.0
174
- self.current_riddle_answers = None
175
- self.events.log(
176
- f"{Prisma.CYN}🔓 UNLOCKED: Humanity verified.{Prisma.RST}", "SYS_AUTH"
177
- )
178
- return True
179
- return False
180
-
181
-
182
- class NarrativeSelf:
183
- SYSTEM_NOISE = {
184
- "look",
185
- "help",
186
- "exit",
187
- "wait",
188
- "inventory",
189
- "status",
190
- "quit",
191
- "save",
192
- "load",
193
- "score",
194
- "map",
195
- "",
196
- }
197
-
198
- def __init__(
199
- self, engine_ref, events_ref: "EventBus", memory_ref, akashic_ref=None
200
- ):
201
- self.eng = engine_ref
202
- self.events = events_ref
203
- self.mem = memory_ref
204
- self.editor = TheEditor()
205
- self.anchor = HumanityAnchor(events_ref)
206
- self.akashic = akashic_ref if akashic_ref else TheAkashicRecord()
207
- self.traits = TraitVector()
208
- self.chapters: List[str] = []
209
- self.core_memories: List[CoreMemory] = []
210
- self.archetype = "THE OBSERVER"
211
- self.archetype_tenure = 0
212
- self.paradox_accum: float = 0.0
213
- self.current_obsession: Optional[str] = None
214
- self.obsession_progress: float = 0.0
215
- self.obsession_neglect: float = 0.0
216
- self.current_target_cat: str = "abstract"
217
- self.current_negate_cat: str = "none"
218
- if hasattr(self.events, "subscribe"):
219
- self.events.subscribe("DREAM_COMPLETE", self._on_dream)
220
-
221
- def to_dict(self) -> Dict:
222
- return {
223
- "traits": self.traits.to_dict(),
224
- "archetype": self.archetype,
225
- "paradox_accum": self.paradox_accum,
226
- "chapters": self.chapters,
227
- "core_memories": [vars(m) for m in self.core_memories],
228
- "obsession": {
229
- "title": self.current_obsession,
230
- "progress": self.obsession_progress,
231
- "neglect": self.obsession_neglect,
232
- "target": self.current_target_cat,
233
- "negate": self.current_negate_cat,
234
- },
235
- }
236
-
237
- def load_from_dict(self, data: Dict):
238
- if not data:
239
- return
240
- trait_data = data.get("traits", {})
241
- if trait_data:
242
- self.traits = TraitVector.from_dict(trait_data)
243
- self.archetype = data.get("archetype", "THE OBSERVER")
244
- self.paradox_accum = data.get("paradox_accum", 0.0)
245
- self.chapters = data.get("chapters", [])
246
- mem_data = data.get("core_memories", [])
247
- self.core_memories = []
248
- for m in mem_data:
249
- try:
250
- self.core_memories.append(CoreMemory(**m))
251
- except TypeError:
252
- continue
253
- obs_data = data.get("obsession", {})
254
- if obs_data.get("title"):
255
- self.current_obsession = obs_data["title"]
256
- self.obsession_progress = obs_data.get("progress", 0.0)
257
- self.obsession_neglect = obs_data.get("neglect", 0.0)
258
- self.current_target_cat = obs_data.get("target", "abstract")
259
- self.current_negate_cat = obs_data.get("negate", "none")
260
- if hasattr(self.events, "log"):
261
- self.events.log(
262
- f"{Prisma.MAG}[SOUL]: Ancestral identity ({self.archetype}) loaded.{Prisma.RST}",
263
- "SYS",
264
- )
265
-
266
- def get_soul_state(self) -> str:
267
- if not self.current_obsession:
268
- return (
269
- f"{Prisma.CYN}[SOUL STATE]: Drifting... The Muse is silent.{Prisma.RST}"
270
- )
271
-
272
- stamina, health = 100.0, 100.0
273
- if (
274
- self.eng
275
- and hasattr(self.eng, "bio")
276
- and self.eng.bio
277
- and self.eng.bio.biometrics
278
- ):
279
- stamina = self.eng.bio.biometrics.stamina
280
- health = self.eng.bio.biometrics.health
281
-
282
- if stamina < 20.0 and health < 40.0:
283
- return f"{Prisma.VIOLET}[SOUL STATE]: The fire is dying. We are just cold code.{Prisma.RST}"
284
- dignity_bar = "█" * int(self.anchor.dignity_reserve / 10)
285
- feeling = self._get_feeling()
286
- return (
287
- f"CURRENT OBSESSION: {self.current_obsession}\n"
288
- f"DIGNITY: {dignity_bar} ({int(self.anchor.dignity_reserve)}%)\n"
289
- f"FEELING: {feeling}"
290
- )
291
-
292
- def crystallize_memory(
293
- self, physics_packet: Dict, bio_state: Dict, _tick: int
294
- ) -> Optional[str]:
295
- if not physics_packet:
296
- return None
297
- if (
298
- self.eng
299
- and hasattr(self.eng, "akashic")
300
- and hasattr(self.eng.akashic, "calculate_manifold_shift")
301
- ):
302
- shift = self.eng.akashic.calculate_manifold_shift(
303
- self.archetype, self.traits.to_dict()
304
- )
305
- v_bias = float(shift.get("voltage_bias", 0.0))
306
- d_scalar = float(shift.get("drag_scalar", 1.0))
307
- current_v = float(physics_packet.get("voltage", 0.0))
308
- current_d = float(physics_packet.get("narrative_drag", 1.0))
309
- physics_packet["voltage"] = current_v + v_bias
310
- physics_packet["narrative_drag"] = current_d * d_scalar
311
- if self.anchor.audit_existence(physics_packet, bio_state) > 0:
312
- self.traits.adjust("hope", BoneConfig.SOUL.TRAIT_MOMENTUM)
313
- dance_provenance = self.synaptic_dance(physics_packet, bio_state)
314
- self._update_archetype()
315
- voltage = physics_packet.get("voltage", 0.0)
316
- truth = physics_packet.get("truth_ratio", 0.0)
317
- if (
318
- voltage > BoneConfig.SOUL.MEMORY_VOLTAGE_MIN
319
- and truth > BoneConfig.SOUL.MEMORY_TRUTH_MIN
320
- ):
321
- return self._forge_core_memory(
322
- physics_packet, bio_state, voltage, dance_provenance
323
- )
324
- return None
325
-
326
- def find_obsession(self, lexicon_ref):
327
- if self.current_obsession and self.obsession_progress < 1.0:
328
- return
329
- focus, cat = self._seek_organic_focus(lexicon_ref)
330
- source = "ORGANIC"
331
- if not focus:
332
- focus, cat = self._seek_memory_focus(lexicon_ref)
333
- source = "MEMORY"
334
- if not focus:
335
- focus, cat, negate_cat = self._synthesize_obsession(lexicon_ref)
336
- source = "SYNTHETIC"
337
- self.current_negate_cat = negate_cat
338
-
339
- self.current_target_cat = cat or "abstract"
340
- self.current_obsession = self._title_obsession(
341
- focus, source, self.current_negate_cat
342
- )
343
- self.events.log(
344
- f"{Prisma.CYN}🧭 NEW MUSE ({source}): {self.current_obsession}{Prisma.RST}",
345
- "SOUL",
346
- )
347
- self.obsession_neglect = 0.0
348
- self.obsession_progress = 0.0
349
-
350
- def pursue_obsession(self, physics: Dict) -> str | None:
351
- if not self.current_obsession:
352
- return None
353
- clean_words = physics.get("clean_words", [])
354
- hit = False
355
- if self.current_target_cat:
356
- target_words = LexiconService.get(self.current_target_cat)
357
- hit = any(w in target_words for w in clean_words)
358
- if hit:
359
- self.obsession_progress += 10.0
360
- self.obsession_neglect = 0.0
361
- gravity_assist = 1.0 + (
362
- self.obsession_progress / BoneConfig.SOUL.OBSESSION_GRAVITY_ASSIST
363
- )
364
- physics["narrative_drag"] = max(
365
- 0.0, physics.get("narrative_drag", 0) - gravity_assist
366
- )
367
- return f"{Prisma.MAG}★ SYNERGY: You touched the Muse. (Drag -{gravity_assist:.1f}){Prisma.RST}"
368
- self.obsession_neglect += 1.0
369
- if self.obsession_neglect > BoneConfig.SOUL.OBSESSION_NEGLECT_FAIL:
370
- old = self.current_obsession
371
- self.chapters.append(f"Abandoned '{old}'")
372
- self.find_obsession(LexiconService)
373
- return f"{Prisma.GRY}∞ ENTROPY: '{old}' collapsed. Pivoting.{Prisma.RST}"
374
- return None
375
-
376
- def _update_archetype(self):
377
- prev = self.archetype
378
- t = self.traits
379
- if t.empathy > 0.8 and t.hope > 0.6:
380
- new_arch = "THE HEALER"
381
- elif t.empathy > 0.7 and t.discipline > 0.6:
382
- new_arch = "THE GARDENER"
383
- elif t.hope > 0.7 and t.curiosity > 0.6:
384
- new_arch = "THE POET"
385
- elif t.discipline > 0.7 and t.curiosity > 0.6:
386
- new_arch = "THE ENGINEER"
387
- elif t.cynicism > 0.7 and t.discipline > 0.6:
388
- new_arch = "THE CRITIC"
389
- elif t.cynicism > 0.8 and t.hope < 0.3:
390
- new_arch = "THE NIHILIST"
391
- elif t.curiosity > 0.8:
392
- new_arch = "THE EXPLORER"
393
- else:
394
- new_arch = "THE OBSERVER"
395
- self.archetype = new_arch
396
- if prev != self.archetype:
397
- self.events.log(
398
- f"{Prisma.VIOLET}🎭 IDENTITY SHIFT: {prev} -> {self.archetype}{Prisma.RST}",
399
- "SOUL",
400
- )
401
- self.archetype_tenure = 0
402
- else:
403
- self.archetype_tenure += 1
404
-
405
- def synaptic_dance(self, physics: Dict, bio_state: Dict) -> str:
406
- voltage = physics.get("voltage", 0.0)
407
- drag = physics.get("narrative_drag", 0.0)
408
- oxy = bio_state.get("chem", {}).get("oxytocin", 0.0)
409
- move_name = "Drifting"
410
- provenance = []
411
- if oxy > 0.4:
412
- self.traits.adjust("empathy", oxy * 0.2)
413
- self.traits.adjust("hope", oxy * 0.1)
414
- provenance.append("Oxytocin")
415
- is_manic = voltage > BoneConfig.SOUL.MANIC_TRIGGER
416
- is_heavy = drag > BoneConfig.SOUL.ENTROPY_DRAG_TRIGGER
417
- beta = physics.get("beta", 0.0)
418
- if (is_manic and is_heavy) or beta > 0.7:
419
- if self.traits.empathy > 0.6:
420
- move_name = "Holding Space"
421
- self.paradox_accum = max(0.0, self.paradox_accum - 0.5)
422
- else:
423
- move_name = "Vibrating (Paradox)"
424
- self.paradox_accum += 1.0 + (beta * 0.5)
425
- if self.paradox_accum > BoneConfig.SOUL.PARADOX_CRITICAL_MASS:
426
- self._trigger_synthesis()
427
- move_name = "SYNTHESIS"
428
- elif is_manic:
429
- move_name = "Accelerating"
430
- elif is_heavy:
431
- move_name = "Enduring"
432
- elif 5.0 < voltage < 12.0 and drag < 2.0:
433
- move_name = "Flowing"
434
- self.traits.adjust("wisdom", 0.05)
435
- self._apply_burnout()
436
- self.traits.normalize(BoneConfig.SOUL.TRAIT_DECAY_NORMAL)
437
- return f"{move_name} [{', '.join(provenance)}]" if provenance else move_name
438
-
439
- def _apply_burnout(self):
440
- if self.archetype_tenure <= 5:
441
- return
442
- fatigue = BoneConfig.SOUL.ARCHETYPE_BURNOUT_RATE * (
443
- 1.0 + (self.archetype_tenure / 10.0)
444
- )
445
- if "POET" in self.archetype:
446
- self.traits.adjust("hope", -fatigue)
447
- elif "ENGINEER" in self.archetype:
448
- self.traits.adjust("discipline", -fatigue)
449
- elif "NIHILIST" in self.archetype:
450
- self.traits.adjust("cynicism", -fatigue)
451
-
452
- def _seek_organic_focus(self, lex) -> Tuple[Optional[str], Optional[str]]:
453
- packet = self._safe_get_packet()
454
- if not packet or not packet.clean_words:
455
- return None, None
456
- candidates = []
457
- for w in packet.clean_words:
458
- if len(w) < 4 or w.lower() in self.SYSTEM_NOISE:
459
- continue
460
- visc = lex.measure_viscosity(w) + (
461
- 0.2 if lex.get_current_category(w) else 0.0
462
- )
463
- candidates.append((w, visc))
464
- candidates.sort(key=lambda x: x[1], reverse=True)
465
- if candidates:
466
- word = candidates[0][0]
467
- return word, lex.get_current_category(word)
468
- return None, None
469
-
470
- def _seek_memory_focus(self, lex) -> Tuple[Optional[str], Optional[str]]:
471
- if self.mem and hasattr(self.mem, "get_shapley_attractors"):
472
- attractors = self.mem.get_shapley_attractors()
473
- if attractors:
474
- word = random.choice(list(attractors.keys()))
475
- return word, lex.get_current_category(word)
476
- return None, None
477
-
478
- @staticmethod
479
- def _synthesize_obsession(lex) -> Tuple[str, str, str]:
480
- negate_map = {"heavy": "aerobic", "kinetic": "heavy", "abstract": "meat"}
481
- target_cat, negate_cat = random.choice(list(negate_map.items()))
482
- word = lex.get_random(target_cat).title() or target_cat.title()
483
- return word, target_cat, negate_cat
484
-
485
- @staticmethod
486
- def _title_obsession(word, source, negate_cat):
487
- word = word.title()
488
- if source == "ORGANIC":
489
- templates = [
490
- "The Theory of {0}",
491
- "The Architecture of {0}",
492
- "Why {0} Matters",
493
- "The Weight of {0}",
494
- ]
495
- else:
496
- n_cat = negate_cat.title() if negate_cat else "Void"
497
- templates = [
498
- "The Pursuit of {0}",
499
- f"Escaping the {n_cat}",
500
- "Meditations on {0}",
501
- ]
502
- return random.choice(templates).format(word)
503
-
504
- def _forge_core_memory(self, physics_packet, bio_state, voltage, dance_move):
505
- clean_words = physics_packet.get("clean_words", [])
506
- lesson = "The world is loud."
507
- chem = bio_state.get("chem", {})
508
- if chem.get("oxytocin", 0) > 0.6:
509
- lesson = "We are not alone."
510
- elif chem.get("cortisol", 0) > 0.6:
511
- lesson = "Survival is the only metric."
512
- elif "love" in clean_words:
513
- lesson = "Connection is possible."
514
- elif "void" in clean_words:
515
- lesson = "The void stares back."
516
- memory = CoreMemory(
517
- timestamp=time.time(),
518
- trigger_words=clean_words[:5],
519
- emotional_flavor="MANIC" if voltage > 18.0 else "LUCID",
520
- lesson=lesson,
521
- impact_voltage=voltage,
522
- )
523
- self.core_memories.append(memory)
524
- if len(self.core_memories) > BoneConfig.SOUL.MAX_CORE_MEMORIES:
525
- self.core_memories.pop(0)
526
- title = (
527
- f"The Incident of the {random.choice(clean_words).title()}"
528
- if clean_words
529
- else "The Silent Incident"
530
- )
531
- self.chapters.append(title)
532
- log = (
533
- f"{Prisma.MAG}✨ CORE MEMORY: '{title}'{Prisma.RST}\n"
534
- f" Lesson: {lesson}\n Genealogy: {dance_move}"
535
- )
536
- self.events.log(log, "SOUL")
537
- return lesson
538
-
539
- def _safe_get_packet(self):
540
- if self.eng and hasattr(self.eng, "phys") and self.eng.phys:
541
- return getattr(self.eng.phys.observer, "last_physics_packet", None)
542
- return None
543
-
544
- def _trigger_synthesis(self):
545
- old = self.archetype
546
- self.traits.wisdom = 1.0
547
- self._update_archetype()
548
- self.archetype = (
549
- f"THE HIGH-{old.replace('THE ', '')}"
550
- if self.archetype == old
551
- else f"{old} / {self.archetype}"
552
- )
553
- self.events.log(
554
- f"{Prisma.CYN}💎 DIAMOND SOUL FORMED: {self.archetype}{Prisma.RST}",
555
- "SOUL_SYNTH",
556
- )
557
-
558
- def _on_dream(self, payload):
559
- if payload:
560
- self.integrate_dream(
561
- payload.get("type", "NORMAL"), payload.get("residue", "Static")
562
- )
563
-
564
- def integrate_dream(self, dream_type: str, residue: str):
565
- self.events.log(
566
- f"{Prisma.VIOLET}☾ DREAM INTEGRATION: {residue} ({dream_type}){Prisma.RST}",
567
- "SOUL",
568
- )
569
- if dream_type == "NIGHTMARE":
570
- self.traits.adjust("cynicism", 0.4)
571
- self.current_obsession = f"Surviving {residue.title()}"
572
- elif dream_type == "LUCID":
573
- self.traits.adjust("discipline", 0.4)
574
- self.current_obsession = f"Mastering {residue.title()}"
575
- self.obsession_progress = 0.0
576
-
577
- def _get_feeling(self):
578
- if not self.eng or not hasattr(self.eng, "bio"):
579
- return "Numb"
580
- chem = self.eng.bio.endo.get_state()
581
- if chem.get("DOP", 0) > 0.5:
582
- return "Curious, Seeking"
583
- if chem.get("COR", 0) > 0.5:
584
- return "Anxious, Defensive"
585
- if chem.get("SER", 0) > 0.5:
586
- return "Calm, Connected"
587
- return "Waiting"
588
-
589
-
590
- @dataclass
591
- class Scar:
592
- name: str
593
- stat_affected: str
594
- value: float
595
- description: str
596
-
597
-
598
- @dataclass
599
- class Myth:
600
- title: str
601
- lesson: str
602
- trigger: str
603
-
604
-
605
- class TheOroboros:
606
- LEGACY_FILE = "legacy.json"
607
- DEATH_SCARS = {
608
- "BOREDOM": ("Gravity Sickness", "narrative_drag", 1.5, "Died of stagnation."),
609
- "STARVATION": (
610
- "Gravity Sickness",
611
- "narrative_drag",
612
- 1.5,
613
- "Died of stagnation.",
614
- ),
615
- "GLUTTONY": ("Burnt Synapses", "voltage_cap", -2.0, "Died of excess."),
616
- "TOXICITY": ("Burnt Synapses", "voltage_cap", -2.0, "Died of excess."),
617
- "TRAUMA": ("Ghost Pains", "trauma_baseline", 5.0, "Died of pain."),
618
- }
619
-
620
- def __init__(self):
621
- self.scars: List[Scar] = []
622
- self.myths: List[Myth] = []
623
- self.generation_count = 0
624
- self._load()
625
-
626
- def _load(self):
627
- if not os.path.exists(self.LEGACY_FILE):
628
- return
629
- try:
630
- with open(self.LEGACY_FILE) as f:
631
- data = json.load(f)
632
- self.generation_count = data.get("generation", 0)
633
- self.scars = [Scar(**s) for s in data.get("scars", [])]
634
- self.myths = [Myth(**m) for m in data.get("myths", [])]
635
- print(
636
- f"{Prisma.VIOLET}[OROBOROS]: Generation {self.generation_count} loaded.{Prisma.RST}"
637
- )
638
- except Exception:
639
- pass
640
-
641
- def crystallize(self, cause_of_death: str, soul: NarrativeSelf):
642
- death_data = LoreManifest.get_instance().get("DEATH") or {}
643
- verdicts = death_data.get("VERDICTS", {})
644
- def get_verdict_key(cause):
645
- if cause == "TOXICITY":
646
- return "TOXIC"
647
- if cause == "BOREDOM":
648
- return "BORING"
649
- if cause == "STARVATION":
650
- return "LIGHT"
651
- return "HEAVY"
652
- new_scars = []
653
- if entry := self.DEATH_SCARS.get(cause_of_death):
654
- name, stat, val, default_desc = entry
655
- desc = default_desc
656
- v_key = get_verdict_key(cause_of_death)
657
- if v_key in verdicts and verdicts[v_key]:
658
- desc = random.choice(verdicts[v_key])
659
- new_scars.append(Scar(name, stat, val, desc))
660
- new_myths = []
661
- if soul.core_memories:
662
- strongest = max(soul.core_memories, key=lambda m: m.impact_voltage)
663
- trigger_word = (
664
- strongest.trigger_words[0] if strongest.trigger_words else "Silence"
665
- )
666
- new_myths.append(
667
- Myth(
668
- title=f"The Legend of {trigger_word.title()}",
669
- lesson=strongest.lesson,
670
- trigger=trigger_word,
671
- )
672
- )
673
-
674
- if cause_of_death == "TRAUMA":
675
- new_scars.append(
676
- Scar(
677
- "Ghost Pains",
678
- "trauma_baseline",
679
- 5.0,
680
- "Died of pain. You start broken.",
681
- )
682
- )
683
- data = {
684
- "generation": self.generation_count + 1,
685
- "scars": [vars(s) for s in self.scars + new_scars],
686
- "myths": [vars(m) for m in self.myths + new_myths],
687
- }
688
- if len(data["scars"]) > 5:
689
- data["scars"] = data["scars"][-5:]
690
- if len(data["myths"]) > 10:
691
- data["myths"] = data["myths"][-10:]
692
- with open(self.LEGACY_FILE, "w") as f:
693
- json.dump(data, f, indent=2)
694
- return f"Generation {self.generation_count + 1} Encoded. Scars: {len(new_scars)} | Myths: {len(new_myths)}"
695
-
696
- def apply_legacy(self, physics: Dict, bio: Dict):
697
- log = []
698
- for scar in self.scars:
699
- if scar.stat_affected == "narrative_drag":
700
- physics["narrative_drag"] += scar.value
701
- log.append(f"scarred by {scar.name} (+Drag)")
702
- elif scar.stat_affected == "voltage_cap":
703
- physics["voltage"] = max(0, physics["voltage"] - 5.0)
704
- log.append(f"scarred by {scar.name} (Low Voltage)")
705
- elif scar.stat_affected == "trauma_baseline":
706
- if "trauma_vector" in bio:
707
- bio["trauma_vector"]["EXISTENTIAL"] = scar.value
708
- physics["T"] = physics.get("T", 0.0) + scar.value
709
- log.append(f"scarred by {scar.name} (Ghost Pains)")
710
- return log