Ctrl K
ComunidadGuías…

docs/novaberg-ei-plutchik.md

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Novaberg — EI: Plutchik-Emotionsmodell

**Projekt:** Novaberg — The Nova Anima Resonance System
**Dokument:** Technik Plutchik-Emotionsmodell (Oktagon, sektorabhängige Normalisierung, Arousal-Radius)
**Stand:** 23. August 2026 (**die zweite `NEGATIVE_EMOTIONEN` ist fort** — der Zustelldienst importiert die abgeleitete Menge; §11 nachgezogen). Davor: 16. August 2026 (gegen den Code geprüft), 17. April 2026, Chat 52 (Code-Alignment)
**Pfad:** novaberg/docs/novaberg-ei-plutchik.md
**Quellen:** nova-04-t-a.md
**Dateien:** `config.py` (Sektor-Map, Distanzmatrix, Exponenten), `graph/nodes/enricher.py` (Normalisierung), Perzeption-Prompt (16+1 Emotionen), `client/ui/emotionen_tab.py` (Oktagon-Radar)

---

## 1. Das Prinzip

Robert Plutchik beschrieb 1980 acht Primäremotionen, kreisförmig angeordnet mit diametralen Gegenpaaren. Jede Emotion hat drei Intensitätsstufen — von mild (Außenring) über moderat (Mittelring) bis intensiv (Innenring). Benachbarte Emotionen auf dem Rad sind psychologisch verwandt, gegenüberliegende sind Antagonisten.

Nova adaptiert dieses Modell als **Oktagon**: Acht Sektoren mit je zwei kanonischen Emotionen (intensiv und moderat), Arousal als Radius, und eine sektorabhängige Normalisierung im Enricher, die benachbarte Emotionen schützt und gegenüberliegende verdrängt.

### Warum Plutchik?

Das bisherige Modell teilte Emotionen in drei Gruppen: positiv, negativ, neutral. Die Normalisierung war uniform — alle Emotionen wurden durch denselben Maximalwert geteilt, unabhängig von ihrer Beziehung zueinander. Das führte zu zwei Problemen:

1. **Kannibalisierung innerhalb der Gruppe:** Akkumulierte Zufriedenheit (3 Turns) erdrückte einmalige Begeisterung durch die uniforme Division — obwohl beide positiv sind und sich gegenseitig stützen sollten.

2. **Fehlende Antagonismus-Wirkung:** Frustration und Freude wurden gleich behandelt wie Frustration und Ärger — obwohl die erste Beziehung antagonistisch ist und die zweite verstärkend.

Plutchiks Rad liefert die fehlende Topologie: Eine wissenschaftlich fundierte Anordnung, die definiert, welche Emotionen sich stützen (benachbart), neutral zueinander stehen (diagonal) oder einander verdrängen (gegenüber).

---

## 2. Das Oktagon

### 2.1 Acht Sektoren

Anordnung im Uhrzeigersinn, strikt nach Plutchik. Positive und negative Emotionen sind interleaved — nicht auf Hälften getrennt:

```
              1 Freude
       8 Neugier        2 Zuversicht
     7 Ärger                3 Angst
       6 Enttäuschung   4 Überraschung
              5 Trauer
```

### 2.2 Gegenpaare

Jedes Paar bildet einen psychologisch fundierten Antagonismus (Plutchik 1:1):

| Gegenpaar | Plutchik-Original | Begründung |
|-----------|-------------------|------------|
| 1 Freude ↔ 5 Trauer | Joy ↔ Sadness | Grundlegende Valenz-Achse |
| 2 Zuversicht ↔ 6 Enttäuschung | Trust ↔ Disgust | Vertrauen erfüllt ↔ Vertrauen gebrochen |
| 3 Angst ↔ 7 Ärger | Fear ↔ Anger | Flight ↔ Fight |
| 4 Überraschung ↔ 8 Neugier | Surprise ↔ Anticipation | Unerwartetes ↔ Erwartetes |

### 2.3 Nachbarschaften

Die Übergänge zwischen benachbarten Sektoren bilden natürliche emotionale Verläufe. Plutchiks Kombinations-Emotionen bestätigen die Nachbarschaft:

| Nachbarn | Plutchik-Kombination | Beispiel |
|----------|---------------------|---------|
| 1–2 Freude–Zuversicht | Liebe (love) | „Ich bin glücklich und vertraue dir" |
| 2–3 Zuversicht–Angst | Unterwerfung (submission) | „Ich vertraue, aber habe Angst enttäuscht zu werden" |
| 3–4 Angst–Überraschung | Ehrfurcht (awe) | „Das macht mir Angst und fasziniert mich zugleich" |
| 4–5 Überraschung–Trauer | Missbilligung (disapproval) | „Das hätte ich nicht erwartet — das tut weh" |
| 5–6 Trauer–Enttäuschung | Reue (remorse) | „Ich bin traurig und enttäuscht von mir selbst" |
| 6–7 Enttäuschung–Ärger | Verachtung (contempt) | „Das ist widerlich und macht mich wütend" |
| 7–8 Ärger–Neugier | Aggressivität (aggressiveness) | „Ich bin wütend und will es ändern" |
| 8–1 Neugier–Freude | Optimismus (optimism) | „Ich bin gespannt und freue mich darauf" |

---

## 3. Sechzehn kanonische Emotionen

Perzeption klassifiziert in 16 kanonische Emotionen plus `neutral`. Zwei pro Sektor — eine intensive (hoher Arousal) und eine moderate (niedrigerer Arousal):

| Sektor | Kern | Plutchik | Intensiv | Moderat |
|--------|------|----------|----------|---------|
| 1 Freude | hoch-positiv, aktiv | Joy | begeisterung | freude |
| 2 Zuversicht | stabiles Vertrauen | Trust | dankbarkeit | zufriedenheit |
| 3 Angst | aktiviert-negativ | Fear | stress | unsicherheit |
| 4 Überraschung | ambivalent, kurzlebig | Surprise | ueberrascht | verwundert |
| 5 Trauer | passiv-negativ | Sadness | verzweiflung | traurigkeit |
| 6 Enttäuschung | gerichtet-negativ | Disgust | frustration | enttaeuschung |
| 7 Ärger | aggressiv-negativ | Anger | wut | aerger |
| 8 Neugier | explorativ, nach außen | Anticipation | hoffnung | neugierig |

Sektorlos: `neutral` (keine emotionale Richtung, Arousal unter Schwellwert)

### 3.1 Synonym-Mapping

Die Perzeption soll die 16 kanonischen Emotionen verwenden. Liefert sie eine Variante, greift das Synonym-Mapping:

```python
EMOTION_SYNONYM_MAP: dict[str, str] = {
    # → Sektor 1 Freude
    "glueck": "freude", "euphorie": "begeisterung",
    "heiterkeit": "freude", "ekstase": "begeisterung",
    # → Sektor 1 Freude (ehemals eigener Sektor "Stolz")
    "stolz": "freude", "triumph": "freude",
    "genugtuung": "freude", "selbstvertrauen": "freude",
    "selbstsicherheit": "freude",

    # → Sektor 2 Zuversicht
    "erleichterung": "zufriedenheit",
    "gelassenheit": "zufriedenheit", "geborgenheit": "zufriedenheit",
    "vertrauen": "zufriedenheit",

    # → Sektor 3 Angst
    "angst": "stress", "furcht": "stress",
    "panik": "stress", "sorge": "unsicherheit",
    "nervositaet": "unsicherheit", "beklemmung": "unsicherheit",
    "anspannung": "stress",

    # → Sektor 4 Überraschung
    "schock": "ueberrascht", "ueberraschung": "ueberrascht",
    "fassungslos": "ueberrascht", "verbluefft": "verwundert",
    "perplex": "verwundert", "baff": "ueberrascht",

    # → Sektor 5 Trauer
    "resignation": "traurigkeit", "einsamkeit": "traurigkeit",
    "melancholie": "traurigkeit", "kummer": "verzweiflung",
    "niedergeschlagenheit": "traurigkeit", "nachdenklich": "traurigkeit",
    "leere": "traurigkeit",

    # → Sektor 6 Enttäuschung (inkl. Ekel-Achse)
    "frust": "frustration", "ernuechterung": "enttaeuschung",
    "verbitterung": "frustration", "desillusionierung": "enttaeuschung",
    "abscheu": "frustration", "ekel": "frustration",
    "verachtung": "frustration", "langeweile": "enttaeuschung",
    "ablehnung": "enttaeuschung", "desinteresse": "enttaeuschung",
    "gleichgueltigkeit": "enttaeuschung",

    # → Sektor 7 Ärger
    "zorn": "wut", "aggression": "wut",
    "gereizt": "aerger", "genervt": "aerger",
    "empoerung": "wut", "hass": "wut", "groll": "aerger",

    # → Sektor 8 Neugier
    "neugier": "neugierig", "neugierde": "neugierig",
    "interesse": "neugierig", "erwartung": "hoffnung",
    "vorfreude": "hoffnung", "gespannt": "neugierig",
}
```

### 3.2 Fehlerbehandlung

Drei Stufen:

1. **Kanonisch:** Emotion ist eine der 16 — direkt verwenden.
2. **Synonym:** Emotion steht im Synonym-Mapping — auf kanonische Form mappen.
3. **Unbekannt:** Emotion ist weder kanonisch noch Synonym — **Error-Log** werfen, damit sie ergänzt werden kann. Fallback auf Exponent 1.0 (sektorlos). → **Am 06.10.2026 entschieden:** Der unbekannte Wert wird durch `neutral` ersetzt, statt roh weiterzulaufen — in dieser Rechnung dieselbe Wirkung (§6.4), aber kein Wert außerhalb des Kanons mehr im Verlauf; die Fehlerzeile bleibt. `zuversicht` wird auf `zufriedenheit` gezogen (`PERZEPTION-EMOTION-AUSSER-KANON` in [`novaberg-bugs-charakter.md`](novaberg-bugs-charakter.md)).

```python
sektor = EMOTION_SEKTOR_MAP.get(emotion)

if sektor is None and emotion != "neutral":
    logger.error(
        f"Enricher: Unbekannte Emotion '{emotion}' — "
        f"nicht in EMOTION_SEKTOR_MAP und nicht in EMOTION_SEKTORLOS. "
        f"Muss in config.py ergänzt werden."
    )
```

### 3.3 Zuordnung zu Plutchik

Die Sektorreihenfolge folgt Plutchik 1:1. Die einzige inhaltliche Adaption:

| Plutchik | Nova | Begründung |
|----------|------|------------|
| Disgust (Ekel) | → Enttäuschung (Sektor 6) | Ekel als Primäremotion ist im Kontext eines KI-Assistenten selten. Enttäuschung (gebrochenes Vertrauen) tritt häufig auf und besetzt die gleiche antagonistische Position zu Zuversicht/Vertrauen. Die Plutchik-Varianten Abscheu, Langeweile und Verachtung werden als Synonyme in Sektor 6 (Enttäuschung) gemappt. |

Stolz und Erleichterung sind keine eigenen Sektoren mehr, sondern Synonyme: `stolz` → `freude` (Sektor 1), `erleichterung` → `zufriedenheit` (Sektor 2). Überraschung hat einen eigenen Sektor (4) erhalten — Plutchik-konform.

### 3.4 Nachdenklich als Traurigkeit

`nachdenklich` wird auf `traurigkeit` (Sektor 5) gemappt. Begründung: Nachdenklichkeit im Gesprächskontext ist ein Rückzug nach innen — grüblerisch, verlangsamend, leicht melancholisch. In Plutchiks Terminologie entspricht das der Schwermütigkeit (Außenring von Traurigkeit). Die explorative, neugierige Variante von „nachdenken" wird durch `neugierig` (Sektor 3) abgedeckt.

**Implikation für den Emotions-Vektor:** Im alten Modell war `nachdenklich` neutral und erzeugte den Vektor `stabilisierung` nach einer Krise. Im neuen Modell ist es Sektor 5 (negativ) und erzeugt `plateau` oder `spirale`. Das ist realistischer — Grübeln in der Krise ist kein Zeichen von Besserung.

---

## 4. Das Radar-Modell: Arousal als Radius

### 4.1 Grundidee

Plutchiks Rad zeigt intensive Emotionen innen und milde außen. Novas Radar **invertiert** das: Hoher Arousal liegt außen (größerer Radius), niedriger Arousal innen. Im Zentrum entsteht eine neutrale Zone.

```
     Außen (hoher Arousal):  Intensive Emotionen — weit auseinander
     Mitte (mittlerer Arousal): Moderate Emotionen — näher beieinander
     Zentrum (Arousal < Schwellwert): NEUTRAL — keine Sektor-Zuordnung
```

### 4.2 Warum invertiert?

Drei Gründe:

1. **Gegenüber-Distanz skaliert mit Arousal:** Begeisterung (Sektor 1, Arousal 0.8) und Verzweiflung (Sektor 5, Arousal 0.8) liegen maximal weit auseinander. Leichte Freude und leichte Traurigkeit (beide Arousal 0.3) sind räumlich näher — sie können koexistieren. Bitteres Lächeln, melancholische Zufriedenheit. Begeisterung und Verzweiflung können das nicht.

2. **Neutrale Mitte:** Bei Arousal unter dem Schwellwert (`EMOTION_NEUTRAL_SCHWELLE` — ~~in `config.py`~~, **am 16.08.2026 berichtigt: die Konstante existiert dort nicht**, siehe die Parametertabelle weiter unten, die sie seit jeher als offen führt) sind alle Sektoren verschmolzen. Ein Mensch im neutralen Zustand ist nicht „freudig-neutral" oder „ärgerlich-neutral" — er ist einfach da. Keine Richtung, nur Ruhe.

3. **Radar-Darstellung:** Größere Ausschläge nach außen = intensivere Emotion. Intuitiv lesbar: Ein ruhiges Radar (kleine Fläche) = neutraler Zustand. Ein zackiges Radar (große Ausschläge) = emotionale Aktivierung.

### 4.3 Arousal-skalierte Exponenten

Die sektorabhängige Normalisierung (Abschnitt 5) nutzt Exponenten, die selbst vom Arousal abhängen. Niedrige Arousal-Werte ziehen alle Exponenten Richtung 1.0 — weniger Separation, mehr Koexistenz. Hohe Arousal-Werte verstärken die Separation.

Formel:

```
effektiver_exponent = 1.0 + (basis_exponent - 1.0) × arousal_der_dominanten_emotion
```

Beispiel für den Gegenüber-Exponent (Basis 1.4):

| Arousal der Dominante | Effektiver Exponent | Effekt |
|-----------------------|---------------------|--------|
| 0.2 | 1.08 | Kaum Verdrängung — Koexistenz möglich |
| 0.5 | 1.20 | Moderate Verdrängung |
| 0.8 | 1.32 | Starke Verdrängung |
| 1.0 | 1.40 | Maximale Verdrängung |

Beispiel für den Nachbar-Exponent (Basis 0.7):

| Arousal der Dominante | Effektiver Exponent | Effekt |
|-----------------------|---------------------|--------|
| 0.2 | 0.94 | Kaum Schutz — fast normal |
| 0.5 | 0.85 | Moderater Schutz |
| 0.8 | 0.76 | Starker Schutz |
| 1.0 | 0.70 | Maximaler Schutz |

> **Geometrische Intuition:** Im Zentrum des Radars (niedriger Arousal) sind alle Emotionen nah beieinander — sie interagieren kaum. Am Rand (hoher Arousal) sind die Abstände maximal — Gegenüber verdrängen sich, Nachbarn stützen sich. Die Exponenten bilden diese Geometrie mathematisch ab.

---

## 5. Arousal-Decay: Emotionsspezifischer Energieverlust

### 5.1 Das Problem

Der bisherige Arousal-Wert einer Emotion bleibt konstant — der Arousal des neuesten Vorkommens wird gespeichert und nie verändert. Begeisterung mit Arousal 0.8 bei Turn 0 hat nach 10 Turns immer noch Arousal 0.8. Aber ein Mensch, der vor 10 Turns begeistert war, hat längst kein Dopamin mehr — die Begeisterung ist noch *da* (Gewichtung), aber sie *glüht nicht mehr* (Arousal).

Gleichzeitig gräbt sich Verzweiflung ein — Cortisol baut sich langsam ab. Nach 10 Turns ist die Verzweiflung immer noch heiß. Das bisherige System behandelt beides gleich.

### 5.2 Zwei unabhängige Decay-Dimensionen

| Dimension | Regelt | Mechanismus | Vorhanden? |
|-----------|--------|-------------|------------|
| **Gewichtungs-Decay** | Ist die Emotion noch *da*? | Arousal-basierter logarithmischer Decay (novaberg-pixie-decay.md) | ✅ Seit Chat 16 |
| **Arousal-Decay** | Wie viel *Energie* hat sie noch? | Emotionsspezifische exponentielle Abnahme | ✅ Seit Chat 18 |

### 5.3 Formel

```
gedämpfter_arousal = original_arousal × e^(-rate × position)
```

Die Rate bestimmt, wie schnell die Energie einer Emotion verfällt. Hohe Rate = schneller Energieverlust (Dopamin-Peak), niedrige Rate = langsamer Verlust (Cortisol).

### 5.4 Decay-Raten pro Emotion

```python
EMOTION_AROUSAL_DECAY: dict[str, float] = {
    # Sektor 1 — Freude: Dopamin-Peak, verfliegt schnell
    "begeisterung":  0.15,
    "freude":        0.10,
    # Sektor 2 — Zuversicht: stabile Grundstimmung
    "dankbarkeit":   0.08,
    "zufriedenheit": 0.05,
    # Sektor 3 — Angst: setzt sich fest
    "stress":        0.04,
    "unsicherheit":  0.05,
    # Sektor 4 — Überraschung: extrem kurzlebig
    "ueberrascht":   0.20,
    "verwundert":    0.15,
    # Sektor 5 — Trauer: gräbt sich ein (Cortisol)
    "verzweiflung":  0.02,
    "traurigkeit":   0.03,
    # Sektor 6 — Enttäuschung: bleibt als Groll
    "frustration":   0.04,
    "enttaeuschung": 0.05,
    # Sektor 7 — Ärger: intensiv aber abbaubar (Adrenalin)
    "wut":           0.08,
    "aerger":        0.06,
    # Sektor 8 — Neugier: flüchtig, springt weiter
    "hoffnung":      0.08,
    "neugierig":     0.12,
}
```

### 5.5 Energiekurven (validiert)

Anteil der verbleibenden Energie nach N Turns:

| Emotion | Rate | T=3 | T=5 | T=10 | T=20 |
|---------|------|-----|-----|------|------|
| verzweiflung | 0.02 | 94% | 90% | 82% | 67% |
| frustration | 0.04 | 89% | 82% | 67% | 45% |
| zufriedenheit | 0.05 | 86% | 78% | 61% | 37% |
| wut | 0.08 | 79% | 67% | 45% | 20% |
| freude | 0.10 | 74% | 61% | 37% | 14% |
| begeisterung | 0.15 | 64% | 47% | 22% | 5% |
| ueberrascht | 0.20 | 55% | 37% | 14% | 2% |

**Asymmetrie:** Verzweiflung nach 20 Turns: noch 67% Energie. Begeisterung nach 10 Turns: nur noch 22%. Negative Emotionen graben sich ein, positive verfliegen — neurochemisch korrekt.

**Wichtig:** Die Emotion *bleibt im Verlauf* — der Gewichtungs-Decay regelt die Präsenz. Der Arousal-Decay regelt nur, wie viel Durchschlagskraft sie noch hat.

### 5.6 Dominanz-Exponent

Die Bestimmung der dominanten Emotion nutzt einen **Effektivwert** statt des reinen Gewichts:

```
effektiv = gewicht × (gedämpfter_arousal ^ EI_AROUSAL_DOMINANZ)
```

`EI_AROUSAL_DOMINANZ` = 2.0 (konfigurierbar in `config.py`).

Der Exponent verstärkt den Arousal-Effekt exponentiell: Ein Schock (Arousal 0.9) hat Effektivwert 0.81 × Gewicht. Zufriedenheit (Arousal 0.3) hat Effektivwert 0.09 × Gewicht. Der Schock braucht also nur ein Neuntel des Gewichts um zu dominieren.

**Validierte Kipppunkte (n=2.0):**

| Szenario | OHNE Arousal-Decay | MIT Arousal-Decay |
|----------|-------------------|-------------------|
| 3× Begeisterung → Herzinfarkt (Verzweiflung 0.9) | ✗ block (0.81 < 1.74) | **✓ DURCH** (0.81 > 0.71) |
| 5× Zufriedenheit + 2× Begeisterung → Schock (Enttäuschung 0.8) | ✗ block (0.64 < 0.67) | **✓ DURCH** (0.64 > 0.27) |
| 5× Verzweiflung → Leise Hoffnung (Freude 0.4) | ✗ block | ✗ block (korrekt) |
| 5× Verzweiflung → Euphorie (Begeisterung 0.9) | ✗ block | ✗ block (korrekt) |
| 8× Zufriedenheit → Schock (Verzweiflung 0.9) | ✓ DURCH | ✓ DURCH (korrekt) |

---

## 6. Sektorabhängige Normalisierung

### 6.1 Einordnung in die Berechnung

Die Verlaufsberechnung im Enricher hat jetzt 6 Schritte:

```
Schritt 1: Nur User-Turns mit nicht-neutraler Emotion filtern
Schritt 2: Turn-0-Prinzip (Perzeption als neuester Datenpunkt)
Schritt 3: Arousal-basierter Gewichts-Decay + Akkumulation gleicher Emotionen
Schritt 4: ████ Arousal-Decay pro Emotion (NEU) ████
Schritt 5: ████ Sektorabhängige Normalisierung mit Effektivwert (NEU) ████
Schritt 6: Filter (EMOTION_MIN_WEIGHT) + Sortierung
```

### 6.2 Distanzmatrix

Die Distanz zwischen zwei Sektoren bestimmt den Basis-Exponent. In der Plutchik-Reihenfolge (1=Freude, 2=Zuversicht, 3=Angst, 4=Überraschung, 5=Trauer, 6=Enttäuschung, 7=Ärger, 8=Neugier):

| Von \ Zu | 1 Fr | 2 Zu | 3 An | 4 Üb | 5 Tr | 6 En | 7 Är | 8 Ne |
|----------|------|------|------|------|------|------|------|------|
| 1 Freude | — | 0.7 | 1.0 | 1.2 | **1.4** | 1.2 | 1.0 | 0.7 |
| 2 Zuversicht | 0.7 | — | 0.7 | 1.0 | 1.2 | **1.4** | 1.2 | 1.0 |
| 3 Angst | 1.0 | 0.7 | — | 0.7 | 1.0 | 1.2 | **1.4** | 1.2 |
| 4 Überraschung | 1.2 | 1.0 | 0.7 | — | 0.7 | 1.0 | 1.2 | **1.4** |
| 5 Trauer | **1.4** | 1.2 | 1.0 | 0.7 | — | 0.7 | 1.0 | 1.2 |
| 6 Enttäuschung | 1.2 | **1.4** | 1.2 | 1.0 | 0.7 | — | 0.7 | 1.0 |
| 7 Ärger | 1.0 | 1.2 | **1.4** | 1.2 | 1.0 | 0.7 | — | 0.7 |
| 8 Neugier | 0.7 | 1.0 | 1.2 | **1.4** | 1.2 | 1.0 | 0.7 | — |

Die Matrix ist symmetrisch. Gegenpaare (Distanz 4, fett): Freude↔Trauer, Zuversicht↔Enttäuschung, Angst↔Ärger, Überraschung↔Neugier.

### 6.3 Algorithmus

```
1. Kanonisierung: Alle Emotionen über EMOTION_SYNONYM_MAP normalisieren
2. Gewichts-Decay + Akkumulation (wie bisher)
3. Arousal-Decay: Für jede Emotion den Arousal positions-abhängig dämpfen:
   gedämpfter_arousal = original_arousal × e^(-EMOTION_AROUSAL_DECAY[emotion] × position)
4. Dominante Emotion bestimmen via Effektivwert:
   effektiv = gewicht × (gedämpfter_arousal ^ EI_AROUSAL_DOMINANZ)
5. Sektor der Dominanten bestimmen (aus EMOTION_SEKTOR_MAP)
6. Für jede andere Emotion:
   a. Sektor bestimmen
   b. Basis-Exponent aus Distanzmatrix lesen
   c. Effektiven Exponent berechnen:
      eff_exp = 1.0 + (basis_exp - 1.0) × gedämpfter_arousal_dominante
   d. Normalisiertes Gewicht berechnen:
      norm = (raw / max_raw) ^ eff_exp
7. Dominante Emotion auf 1.0 setzen
8. Filter: Emotionen unter EMOTION_MIN_WEIGHT entfernen
9. Sortieren nach Gewicht absteigend
```

### 6.4 Sektorlose Emotionen

`neutral` hat keinen Sektor. Liefert Perzeption `neutral`, wird die Emotion in den Verlauf aufgenommen, aber mit Exponent 1.0 zu allen Sektoren behandelt — wie bisher. In der Praxis filtert der bestehende Code neutrale Emotionen bereits vor der Verlaufsberechnung heraus (Zeile „emotion != neutral" im Enricher).

Unbekannte Emotionen (nicht in EMOTION_SEKTOR_MAP, nicht in EMOTION_SYNONYM_MAP, nicht `neutral`) erzeugen einen Error-Log und werden mit Exponent 1.0 behandelt. → **Seit dem 06.10.2026 entschieden:** Sie werden zu `neutral` (§3.2, Punkt 3).

---

## 7. Emotions-Gruppen (Vektor-Berechnung)

Die bestehenden 9 Emotions-Vektoren (absturz, spirale, stabilisierung, erholung, aufbluehen, eskalation, abkuehlung, einbruch, plateau) bleiben unverändert. Die Gruppen-Zuordnung leitet sich aus `SEKTOR_GRUPPE` ab — einem expliziten Dict, da positive und negative Sektoren in der Plutchik-Reihenfolge interleaved sind:

```python
SEKTOR_GRUPPE: dict[int, str] = {
    1: "positiv",    # Freude
    2: "positiv",    # Zuversicht
    3: "negativ",    # Angst
    4: "neutral",    # Überraschung (ambivalent)
    5: "negativ",    # Trauer
    6: "negativ",    # Enttäuschung
    7: "negativ",    # Ärger
    8: "positiv",    # Neugier
}
```

Die Funktion `_emotion_zu_gruppe()` nutzt dieses Dict:

```python
def _emotion_zu_gruppe(emotion: str) -> str:
    sektor = EMOTION_SEKTOR_MAP.get(emotion)
    if sektor is None:
        return "neutral"
    return SEKTOR_GRUPPE.get(sektor, "neutral")
```

Die drei separaten Sets `POSITIVE_EMOTIONEN`, `NEGATIVE_EMOTIONEN`, `NEUTRALE_EMOTIONEN` im Enricher entfallen. Eine Quelle der Wahrheit (die Sektor-Map) statt drei synchron zu haltende Listen.

> ⚠ **Am 16.08.2026 gegen den Code geprüft: Der Vorschlag ist nicht ausgeführt, und die Hälfte davon ist ein Defekt.**
>
> `ei/utils.py` leitet `POSITIVE_EMOTIONEN` und `NEGATIVE_EMOTIONEN` tatsächlich aus `EMOTION_SEKTOR_MAP` und `SEKTOR_GRUPPE` ab — insofern ist die eine Quelle der Wahrheit da. `NEUTRALE_EMOTIONEN` gibt es nirgends; der Name in diesem Absatz ist der Grund, warum die Doku-Prüfung hier angeschlagen hat.
>
> **Was sie dabei gefunden hat, wiegt schwerer:** ~~`services/shadow_delivery.py` schreibt **eine zweite** `NEGATIVE_EMOTIONEN` als Literal hin~~ — vier Emotionen gegen die acht der abgeleiteten Menge. Es fehlten `enttaeuschung`, `stress`, `verzweiflung` und `wut`. Diese zweite Fassung bediente den Emotions-Riegel der Zustellung, also **genau die Entscheidung, bei negativer Stimmung zu schweigen** — und drei der vier fehlenden fielen dort auf *erlaubt* durch.
>
> → **Am 23.08.2026 behoben** (`NEGATIVE-EMOTIONEN-DOPPELT`). Der Zustelldienst importiert die abgeleitete Menge; `stress` bleibt vor der Kanon-Prüfung stehen, weil dort auch die empathische Nachfrage zu viel ist, und die Reihenfolge trägt diese Unterscheidung. Zeuge über den ganzen Baum, dass es bei **einer** Definition bleibt: `tests/test_emotionsriegel_kanon.py::KanonquelleTest`.
>
> **Im Bestand ist der Fall nie eingetreten** — 729 `turn_roh`-Zeilen, 0 mit einer der drei durchgelassenen Emotionen. Der Riegel war nicht wirkungslos, sondern unvollständig, und nichts hätte es gemeldet.

**Auswirkung auf `EI_PASSIV_NEGATIVE`:** Die passiv-negativen Emotionen, die im EI-Plausibilitäts-Gate den Modus `emotional` erzwingen, werden ebenfalls über den Sektor definiert: Sektor 5 (Trauer) erzwingt immer `emotional`, unabhängig vom Arousal. Die übrigen negativen Sektoren (6–8) erzwingen ab Mid-Arousal.

---

## 8. Config-Variablen

Alle neuen Konfigurationswerte:

| Variable | Typ | Default | Beschreibung |
|----------|-----|---------|-------------|
| `EMOTION_SEKTOR_MAP` | `dict[str, int]` | siehe Abschnitt 3 | Kanonische Emotion → Sektor (1–8) |
| `EMOTION_SYNONYM_MAP` | `dict[str, str]` | siehe Abschnitt 3.1 | Variante → kanonische Emotion |
| `EMOTION_KANON` | `set[str]` | 16 Emotionen + neutral | Gültige kanonische Emotionen |
| `EMOTION_SEKTOR_DISTANZ` | `dict[tuple, float]` | 8×8 Matrix | (sektor_a, sektor_b) → Basis-Exponent |
| `EMOTION_AROUSAL_DECAY` | `dict[str, float]` | 16 Raten | Emotion → Arousal-Decay-Rate |
| `SEKTOR_GRUPPE` | `dict[int, str]` | 8 Einträge | Sektor → positiv/negativ/neutral |
| `EI_NORM_BENACHBART` | `float` | 0.7 | Exponent für Distanz 1 |
| `EI_NORM_NAH_DIAGONAL` | `float` | 1.0 | Exponent für Distanz 2 |
| `EI_NORM_FERN_DIAGONAL` | `float` | 1.2 | Exponent für Distanz 3 |
| `EI_NORM_GEGEN` | `float` | 1.4 | Exponent für Distanz 4 (gegenüber) |
| `EI_AROUSAL_DOMINANZ` | `float` | 2.0 | Exponent für Effektivwert-Berechnung |
| `EMOTION_NEUTRAL_SCHWELLE` | `float` | 📐 offen | Arousal-Schwellwert für neutrales Zentrum — noch nicht in config.py, Bedarf wird nach Smoking Tests bewertet |

Die Distanzmatrix wird aus den vier Exponenten und der Kreistopologie automatisch generiert — kein manuelles Befüllen nötig.

---

## 9. Betroffene Komponenten

| Komponente | Änderung | Umfang |
|------------|----------|--------|
| `config.py` | Sektor-Map, Synonym-Map, Kanon-Set, 4 Exponenten, Distanzmatrix | Neue Konstanten |
| Perzeption-Prompt | 16+1 statt 20+ Emotionen | Prompt-Anpassung |
| `enricher.py` → `_emotions_verlauf_berechnen()` | Potenz-Transformation nach Akkumulation (Schritt 4 ersetzt) | ~30 Zeilen |
| `enricher.py` → `_emotion_zu_gruppe()` | Sektor-Lookup statt 3 Sets | ~5 Zeilen |
| `enricher.py` → Emotion-Sets | `POSITIVE_EMOTIONEN`, `NEGATIVE_EMOTIONEN`, `NEUTRALE_EMOTIONEN` entfallen | Löschen |
| `enricher.py` → `_modus_plausibilitaet()` | Passiv-negative über Sektor 5 statt `EI_PASSIV_NEGATIVE` Set | ~5 Zeilen |
| `client/ui/emotionen_tab.py` | Oktagon statt Hexagon, Sektoren nach Plutchik, Arousal als Radius | QPainter-Umbau |
| TEST0 Testfälle | Emotionsnamen auf kanonische Form anpassen | YAML-Dateien |

### Was sich NICHT ändert

- Arousal-basierter Decay (Formel, `EI_AROUSAL_PERSISTENCE`)
- Akkumulation gleicher Emotionen (Spacing Effect)
- Vektor-Berechnung (9 Vektoren, 8-Turn-Fenster)
- Turn-0-Prinzip (Perzeption als neuester Datenpunkt)
- Ebbinghaus-Decay im LZG
- Responder bekommt die feingranulare kanonische Emotion, nicht den Sektor

---

## 10. Wissenschaftliche Grundlagen

| Quelle | Beitrag zu Novas Modell |
|--------|------------------------|
| Plutchik, R. (1980). *Emotion: A Psychoevolutionary Synthesis.* | 8 Primäremotionen, Kreisanordnung, Gegenpaare, Intensitätsringe |
| Russell, J.A. (1980). *A Circumplex Model of Affect.* | Valenz × Arousal als zwei Achsen; bestätigt Plutchiks Distanzen |
| Ekman, P. (1992). *An Argument for Basic Emotions.* | 6 Basisemotionen (zu negativ-lastig für Novas Zweck, aber Grundlage für die Reduktion von 20+ auf wenige Primärkategorien) |

---

## 11. Ausblick: Geometrische Vektor-Berechnung

### 11.1 Von Labels zu Geometrie

Die aktuelle Vektor-Berechnung (`_emotions_vektor_bestimmen()`) vergleicht die dominante Emotions-Gruppe älterer und neuerer Turns und mappt den Übergang auf eines von 9 Labels. Das funktioniert, verliert aber Information: Die *Stärke* der Verschiebung ist unsichtbar.

Das Oktagon mit Arousal als Radius bietet eine geometrische Alternative. Jede aktive Emotion hat eine Position auf dem Kreis (Sektorwinkel: Sektor × 45°) und eine Amplitude (Gewicht × Arousal als Radius). Der gewichtete Schwerpunkt aller aktiven Emotionen ergibt einen Punkt auf dem Radar. Zwei Schwerpunkte (ältere vs. neuere Turns) ergeben einen **Differenzvektor** mit Richtung und Länge.

```
Schwerpunkt_alt:  Sektor 4 (Zuversicht), Radius 0.6
Schwerpunkt_neu:  Sektor 5.5 (zwischen Trauer und Ärger), Radius 0.7

Vektor: Richtung = 4 → 5.5 = Absturz
        Länge = 0.73 = starke Verschiebung
```

### 11.2 Labels als Winkelbereiche

Die 9 bestehenden Vektor-Labels bilden sich als Winkelbereiche und Radius-Änderungen auf dem Kreis ab:

| Verschiebung | Vektor |
|-------------|--------|
| Positiv → Negativ (Sektoren 1–4 → 5–8) | absturz |
| Negativ → Positiv (5–8 → 1–4) | erholung |
| Innerhalb negativ, Radius wächst | spirale |
| Innerhalb positiv, Radius wächst | eskalation |
| Gleiche Position, kaum Bewegung | plateau |
| Negativ → Zentrum (Radius sinkt) | stabilisierung |
| Positiv → Zentrum (Radius sinkt) | abkuehlung |
| Zentrum → Negativ | einbruch |
| Zentrum → Positiv | aufbluehen |

### 11.3 Vektorlänge als neues Signal

Die **Länge** des Differenzvektors quantifiziert, wie dramatisch eine emotionale Verschiebung ist. Dieses Signal fehlt im aktuellen System:

| Länge | Bedeutung | Responder-Signal |
|-------|-----------|-----------------|
| 0.0–0.2 | Kaum Bewegung | Sanfte Anpassung, Grundstimmung stabil |
| 0.2–0.5 | Moderate Verschiebung | Spürbare Tonänderung |
| 0.5–0.8 | Starke Verschiebung | Deutliche Reaktion |
| > 0.8 | Emotionaler Schock | Alarm — unabhängig von der Richtung |

**Emotionaler Schock:** Eine heftige Verschiebung ist in *jeder* Richtung ein Schock — nicht nur bei Abstürzen. Auch ein plötzlicher Sprung von Verzweiflung zu Begeisterung (Länge > 0.8) ist keine sanfte Erholung, sondern ein emotionaler Umschwung, der Aufmerksamkeit verdient. Der Responder sollte darauf reagieren: nicht mit Euphorie mitgehen, sondern den Umschwung wahrnehmen und dem Moment Raum geben.

### 11.4 Einordnung

Die geometrische Vektor-Berechnung ist eine Verfeinerung, kein Ersatz. Voraussetzung ist das stabile Oktagon-Modell mit sektorabhängiger Normalisierung. Implementierungsreihenfolge:

1. ✅ Sektoren, 16 Emotionen, Distanzmatrix, Normalisierung (dieses Dokument)
2. 📋 Geometrische Schwerpunkt-Berechnung und Differenzvektor
3. 📋 Vektorlänge als Responder-Signal

---

→ EI-Konzept (Gesamtrahmen): novaberg-ei.md
→ Perzeption (erkennt Emotion + Arousal): novaberg-node-perception.md
→ Enricher (berechnet Verlauf + Normalisierung): novaberg-node-enricher.md
→ Arousal-basierter Decay: novaberg-pixie-decay.md, novaberg-ei-plutchik_l.md
→ Charakter-Profile (nutzt Emotions-Daten): novaberg-ei-character-profiles.md
→ Emotions-Vektoren (nutzt Gruppenlogik): novaberg-node-perception.md
→ Responder (nutzt Verlauf + Vektor): novaberg-node-responder.md