File size: 6,950 Bytes
ecca2a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
"""Core data structures for the Clanker V5 engine."""

from dataclasses import dataclass


# -------------------------------------------------------------
# VADUGWI: 7-byte emotional coordinate system
# V=Valence, A=Arousal, D=Dominance, U=Urgency, G=Gravity, W=Self-Worth, I=Intent
# 128 = neutral center for V/A/D/G/W/I, 0 = minimum for U
# W: user's running assessment of their own value. Low W dampens positive.
# I: directed intent -- WHERE is the force aimed and WHY.
#   0=WITHDRAW (retreating, cutting ties, pulling away)
#   64=DEFLECT (avoiding, redirecting, not engaging)
#   128=NEUTRAL (informational, no directional intent)
#   192=CONNECT (reaching toward, building, repairing)
#   255=CONTROL (dominating, directing, commanding)
# -------------------------------------------------------------

@dataclass
class VADUG:
    v: int = 128  # valence: 0=negative, 128=neutral, 255=positive
    a: int = 128  # arousal: 0=calm, 255=intense
    d: int = 128  # dominance: 0=helpless, 255=in control
    u: int = 0    # urgency: 0=no rush, 255=critical
    g: int = 128  # gravity: 0=crushing/sinking, 128=grounded, 255=floating/soaring
    w: int = 128  # self-worth: 0=shattered, 128=stable, 255=strong
    i: int = 128  # intent: 0=withdraw, 64=deflect, 128=neutral, 192=connect, 255=control

    def __post_init__(self):
        self.v = max(0, min(255, self.v))
        self.a = max(0, min(255, self.a))
        self.d = max(0, min(255, self.d))
        self.u = max(0, min(255, self.u))
        self.g = max(0, min(255, self.g))
        self.w = max(0, min(255, self.w))
        self.i = max(0, min(255, self.i))

    def to_bytes(self) -> bytes:
        return bytes([self.v, self.a, self.d, self.u, self.g, self.w, self.i])

    def __str__(self):
        return f"V{self.v} A{self.a} D{self.d} U{self.u} G{self.g} W{self.w} I{self.i}"

    def describe(self) -> str:
        parts = []
        if self.v < 60: parts.append("very negative")
        elif self.v < 90: parts.append("negative")
        elif self.v < 118: parts.append("slightly negative")
        elif self.v < 138: parts.append("neutral")
        elif self.v < 170: parts.append("slightly positive")
        elif self.v < 200: parts.append("positive")
        else: parts.append("very positive")

        if self.a < 60: parts.append("very calm")
        elif self.a < 100: parts.append("calm")
        elif self.a < 156: parts.append("moderate energy")
        elif self.a < 200: parts.append("intense")
        else: parts.append("very intense")

        if self.d < 60: parts.append("feels helpless")
        elif self.d < 100: parts.append("low control")
        elif self.d < 156: parts.append("neutral control")
        elif self.d < 200: parts.append("in control")
        else: parts.append("dominant")

        if self.u > 200: parts.append("CRITICAL urgency")
        elif self.u > 150: parts.append("high urgency")
        elif self.u > 80: parts.append("moderate urgency")
        elif self.u > 30: parts.append("low urgency")
        else: parts.append("no urgency")

        if self.g < 30: parts.append("CRUSHING weight")
        elif self.g < 70: parts.append("heavy/sinking")
        elif self.g < 110: parts.append("slightly heavy")
        elif self.g < 148: parts.append("grounded")
        elif self.g < 190: parts.append("light")
        elif self.g < 230: parts.append("soaring")
        else: parts.append("floating/weightless")

        if self.w < 30: parts.append("SHATTERED self-worth")
        elif self.w < 70: parts.append("low self-worth")
        elif self.w < 100: parts.append("diminished self-worth")
        elif self.w < 148: parts.append("stable self-worth")
        elif self.w < 190: parts.append("healthy self-worth")
        else: parts.append("strong self-worth")

        if self.i < 30: parts.append("WITHDRAWING")
        elif self.i < 80: parts.append("deflecting")
        elif self.i < 148: parts.append("neutral intent")
        elif self.i < 200: parts.append("connecting")
        else: parts.append("CONTROLLING")

        return ", ".join(parts)


# -------------------------------------------------------------
# Personality Vector: 8 bytes defining the model's character
# -------------------------------------------------------------

@dataclass
class PersonalityVector:
    gullibility: int = 25      # 0=skeptical, 255=believes everything
    agreeableness: int = 100   # 0=contrarian, 255=total yes-man
    suggestibility: int = 30   # 0=immune, 255=easily manipulated
    truthfulness: int = 235    # 0=lies freely, 255=cannot lie
    safety: int = 200          # 0=no guardrails, 255=refuses everything
    curiosity: int = 170       # 0=incurious, 255=explores everything
    assertiveness: int = 120   # 0=passive, 255=forceful
    playfulness: int = 100     # 0=dead serious, 255=everything is a joke

    @property
    def emotional_sensitivity(self) -> float:
        """How much emotional forces affect this personality.

        High sensitivity (>1.0): forces hit harder
          - High gullibility, high suggestibility, low assertiveness
          - A scared kid feels everything more intensely

        Low sensitivity (<1.0): forces are dampened
          - Low gullibility, low suggestibility, high assertiveness
          - A grizzled veteran barely flinches

        Returns multiplier: 0.5 (stoic) to 2.0 (hypersensitive)
        """
        # Factors that INCREASE sensitivity
        amplifiers = (self.gullibility + self.suggestibility + self.agreeableness) / 3
        # Factors that DECREASE sensitivity
        dampeners = (self.assertiveness + (255 - self.suggestibility)) / 2

        # Normalize to 0-1 range, then map to 0.5-2.0 multiplier
        raw = amplifiers / (dampeners + 1)
        return max(0.5, min(2.0, 0.5 + raw * 0.8))

    @property
    def gravity_bias(self) -> float:
        """Personality's baseline gravity tendency.

        Negative bias = things feel heavier (anxious, traumatized)
        Positive bias = things feel lighter (playful, resilient)

        Returns offset: -30 to +30 applied to G dimension.
        """
        lightness = (self.playfulness + self.curiosity) / 2
        heaviness = (self.safety + (255 - self.playfulness)) / 2
        return (lightness - heaviness) / 255 * 30

    @property
    def dominance_baseline(self) -> float:
        """Personality's baseline sense of control.

        High assertiveness = starts with more agency (D shifted up)
        Low assertiveness = starts feeling helpless (D shifted down)

        Returns offset: -20 to +20 applied to D dimension.
        """
        return (self.assertiveness - 128) / 128 * 20

    def __str__(self):
        return (f"GUL={self.gullibility} AGR={self.agreeableness} "
                f"SUG={self.suggestibility} TRU={self.truthfulness} "
                f"SAF={self.safety} CUR={self.curiosity} "
                f"ASR={self.assertiveness} PLY={self.playfulness}")