File size: 4,740 Bytes
f646e0b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""μˆ¨μ€ μƒνƒœ 3κ°’ β€” μ‹ λ’°μΆ• / 쇠약도 / μ•Ž (P0 4μ’… μ—”μ§„ λͺ…μ„Έ μ€€κ±°).

κ·œμΉ™:
- μ‹ λ’°μΆ•: trust_score / doubt_score λˆ„μ  (μ‹œμ†Œ). μΆ• μ΄λ²€νŠΈκ°€ λ―Όλ‹€
- 쇠약도: 단쑰 μ¦κ°€λ§Œ ν—ˆμš© (λ˜λŒλ¦¬λŠ” μ½”λ“œλŠ” 결함)
- μ•Ž(μœ μ €): E01-01 λ„μž…μ—μ„œ 1회 확립 ν›„ λΆˆλ³€
- μœ μ €μ—κ²Œ μˆ«μžΒ·κ²Œμ΄μ§€ λ…ΈμΆœ κΈˆμ§€ β€” μƒνƒœλŠ” ν†€Β·κ²°Β·ν•΄κΈˆμœΌλ‘œλ§Œ ν‘œμΆœ (trust_level ν™˜μ‚°)
- κΆŒμœ„: 포켓 μ•ˆμ—μ„œλŠ” session.state, 포켓 μ’…λ£Œ μ‹œ μ—¬κΈ°λ‘œ 컀밋 (이쀑 κ°±μ‹  κΈˆμ§€)
"""

from __future__ import annotations

from dataclasses import dataclass, field

# μΆ• 이벀트 1νšŒλ‹Ή μ΄λ™λŸ‰ (μ—”μ§„ μ„€μ • β€” μ„œμ‚¬ λ‚΄μš© μ•„λ‹˜).
# E01~E06 μΆ• 이벀트 밀도 κΈ°μ€€μœΌλ‘œ μ—”λ”© 3쒅이 λͺ¨λ‘ 도달 κ°€λŠ₯ν•˜λ„λ‘ μ‘°μ •λœ κ°’.
AXIS_DELTA = 12

# μ‹ λ’° 레벨 ν™˜μ‚° 경계 (P0 0-3: 숫자 λŒ€μ‹  이 레벨이 ν†€Β·κ²°Β·ν•΄κΈˆμ„ κ²°μ •)
TRUST_LEVELS = ("doubt_high", "doubt_mid", "neutral", "trust_mid", "trust_high")


@dataclass
class HiddenState:
    trust_score: int = 0
    doubt_score: int = 0
    frailty: int = 0  # 쇠약도 β€” 단쑰 증가
    awareness_established: bool = False  # μ•Ž(μœ μ €) β€” λ„μž… 1회 확립
    axis_log: list[str] = field(default_factory=list)  # μ—°κ΅¬μš© 이λ ₯ (card_id:axis)

    # ── μ‹ λ’°μΆ• ──────────────────────────────────────────────
    def apply_axis(self, axis: str | None, source: str = "") -> None:
        if axis == "trust":
            self.trust_score += AXIS_DELTA
        elif axis == "doubt":
            self.doubt_score += AXIS_DELTA
        elif axis in (None, "neutral"):
            return
        else:
            raise ValueError(f"μ•Œ 수 μ—†λŠ” axis: {axis}")
        self.axis_log.append(f"{source}:{axis}")

    @property
    def seesaw(self) -> int:
        """μ˜μ‹¬μš°μ„Έ(-) ←─[0]─→ μ‹ λ’°μš°μ„Έ(+)"""
        return self.trust_score - self.doubt_score

    @property
    def trust_level(self) -> str:
        """P0 0-3 ν™˜μ‚° 좜λ ₯ β€” ν”„λ‘¬ν”„νŠΈμ˜ 'κ²°'κ³Ό ν•΄κΈˆμ„ κ²°μ •ν•œλ‹€."""
        s = self.seesaw
        if s >= 36:
            return "trust_high"
        if s >= 12:
            return "trust_mid"
        if s <= -36:
            return "doubt_high"
        if s <= -12:
            return "doubt_mid"
        return "neutral"

    @property
    def deep_unlock(self) -> bool:
        """심측 κ³ λ°± ν•΄κΈˆ (μ—”μ§„ D) β€” μ‹ λ’°ι«˜μ—μ„œλ§Œ."""
        return self.trust_level == "trust_high"

    # ── 쇠약도 ──────────────────────────────────────────────
    def advance_frailty(self, amount: int = 1) -> None:
        if amount < 0:
            raise ValueError("μ‡ μ•½λ„λŠ” λ˜λŒμ•„κ°€μ§€ μ•ŠλŠ”λ‹€")
        self.frailty += amount

    # ── μ•Ž ─────────────────────────────────────────────────
    def establish_awareness(self) -> None:
        self.awareness_established = True

    # ── μ˜μ†ν™” μŠ€λƒ…μƒ· (μ „ ν•„λ“œ β€” ν¬μΌ“μš© to_sessionκ³Ό λ³„κ°œ) ──
    def snapshot(self) -> dict:
        return {
            "trust_score": self.trust_score,
            "doubt_score": self.doubt_score,
            "frailty": self.frailty,
            "awareness_established": self.awareness_established,
            "axis_log": list(self.axis_log),
        }

    @classmethod
    def from_snapshot(cls, data: dict) -> "HiddenState":
        return cls(
            trust_score=int(data["trust_score"]),
            doubt_score=int(data["doubt_score"]),
            frailty=int(data["frailty"]),
            awareness_established=bool(data["awareness_established"]),
            axis_log=list(data.get("axis_log", [])),
        )

    # ── 포켓 컀밋 (session.state ↔ μ˜μ† μƒνƒœ 단일 경둜) ─────
    def to_session(self) -> dict:
        """포켓 μ§„μž… μ‹œ session.state에 μ‹€μ–΄ 보낼 μŠ€λƒ…μƒ·."""
        return {
            "hidden_trust": self.trust_score,
            "hidden_doubt": self.doubt_score,
            "trust_level": self.trust_level,
            "deep_unlock": self.deep_unlock,
        }

    def commit_from_session(self, state: dict, source: str = "pocket") -> None:
        """포켓 μ’…λ£Œ μ‹œ session.state의 μ¦λΆ„λ§Œ 컀밋 (μœ μΌν•œ μ—­λ°©ν–₯ 경둜)."""
        self.trust_score = max(self.trust_score, int(state.get("hidden_trust", self.trust_score)))
        self.doubt_score = max(self.doubt_score, int(state.get("hidden_doubt", self.doubt_score)))
        self.axis_log.append(f"{source}:commit")