feat(modesty): 羞恥度動態化+三種出口(縮/炸/坦白),心裡話進得了記憶(v0.0.8 同批)

一、羞恥度高不等於話變少——三個出口(他指出來的,我上一版只做對一半)
  縮 shrink   :預設。一句嘴硬,說出口的那句在**迴避**心裡那句
  炸 spill    :慌了(焦慮 ≥55)/惱羞(憤怒 ≥45)/對方在生氣或逼你澄清
                → **4 句,但單句只有 22 字**:掩飾、急著否認、硬轉話題,碎而急
  坦白 confess:羞恥高+信任 ≥75+只有兩個人 → 3 句完整句,憋很久一次講完,
                而且**先寫完心裡話再開口**
  關鍵:句數與單句字數要**一起動**,只調句數分不出「碎念」與「演講」。
  `room post` 本來就同時擋這兩個,參數一改就生效。

二、羞恥度動態化(模擬跑過才實作)
  `modestyState()` = trait + 情緒推力 + 語氣層 + 上一輪餘溫,存進 `felt.jsonl`。
  護欄四道:`MODESTY_GAIN`=0.35(<1 才收斂,0.9 三輪就貼 100)、一輪最多動 15、
  推力上限 25、只算超出基線的部分(比較不開心不代表比較害羞)。
  慢的情緒推力打折(信任半衰期 720 分是底色,不是此刻的事)——
  沒有這條,桐人會因為長期信任高而永遠低於自己的 trait 二十分。
  斷路器是惱羞成怒:anger 權重是負的,被逗到極限翻臉,羞恥自己掉下來。

三、心裡話進得了記憶(但永遠不回顯)
  在這之前心裡話只進 `inner.jsonl`、只被注入最近三句,**永遠不會變成記憶**。
  對害羞的人格來說那是致命的——重要的東西幾乎都在心裡那句。
  現在:`recallInner()` 讓 `recall` 找得到(標「不要講給他聽」),
  `innerCandidates()` 把「24 小時內想過 ≥2 次的同一件事」列成固化候選。
  要不要固化仍由人格自己決定。`think` 的輸出還是只有「💭 心想 N 句」。

四、修掉一個踩到的坑
  `Number(null) === 0` —— 沒有上一輪時 `prev` 退回了 0 而不是 trait,
  害每個人格的羞恥度都從 0 起算。已加測試守著。

測試:328 項全過(新增 14 項)。切詞從貪婪的 {2,4} 改成兩字滑動視窗——
貪婪比對會把「那台舊鐘的齒輪」切成固定區塊,「齒輪」永遠不會單獨出現。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-31 06:12:18 +00:00
co-authored by Claude Opus 5
parent 5b52dd18c2
commit ab4ddb734d
6 changed files with 320 additions and 43 deletions
+11 -2
View File
@@ -36,8 +36,10 @@
睡眠仍然要驗鎖:目標正被另一個程序活鎖住時拒絕,死鎖可接手。
8. **人格講話要像人**:推導寫進 `think`(心裡話,只回報「💭 心想 N 句」,永不回顯內容)、
回話 1–3 句、短時間內不重說同一件事(`room post` 會直接擋下重複與過長的發言)。
句數上限**跟著羞恥度走**`speechBudget()`:越害羞的人話越少、心裡話越多,
而且說出口的那句常常在**迴避**心裡那句——台詞不可以是心裡話的摘要。
句數上限**跟著羞恥度走**`speechBudget()`,但羞恥度高**不等於話一定變少**——三個出口:
**縮**(一句嘴硬,台詞在迴避心裡那句)、**炸**(慌/惱羞/被逼澄清 → 4 句但單句只有 22 字,
碎而急)、**坦白**(信任高又獨處 → 3 句完整句,先寫完心裡話再開口)。
`room post` 同時擋句數與單句字數,兩個參數一起動才分得出「碎念」與「演講」。
再加四條講話的樣子:**短句**(一句 `MAX_SENTENCE_CHARS`=45 字內)、**日常用詞**、
**多講看得見的東西**(人、動作、物件、當下的場面)而不是概念,以及**不要解釋自己的話**
(「我的意思是」「換句話說」這類開頭由 `speechLint` 擋下,`said check` 也會一起檢)。
@@ -60,6 +62,13 @@
`headroom^EMOTION_SATURATION_K`,往 baseline 回不壓)與**單輪預算**
`EMOTION_TURN_BUDGET`=60),因為 delta 是人格自己挑的、只會往舒服的方向倒;
`emotion --audit` 把這個偏差印出來。
8d. **心裡話進得了記憶,但永遠不回顯**`recallInner()``recall` 找得到心裡話,
`innerCandidates()` 把「24 小時內想過 ≥2 次的同一件事」列成固化候選(兩字滑動視窗切詞,
扣掉虛詞)。要不要固化仍由人格自己決定。`think` 的輸出永遠只有「💭 心想 N 句」。
8e. **羞恥度是動態的**`modestyState()` = trait + 情緒推力 + 語氣層 + 上一輪餘溫。
護欄:`MODESTY_GAIN` < 1(正回饋要收斂)、`MODESTY_MAX_STEP``MODESTY_PUSH_CAP`
只算超出基線的部分、慢的情緒(半衰期長)推力打折。斷路器是惱羞成怒(anger 負權重)。
**注意 `Number(null) === 0`**:沒有上一輪時要退回 trait,不是退回 0(踩過)。
8c. **性別只給一個預設值,不是套在個性上的係數**`IDENTITY.md``Gender` 欄位
(女性/男性/非二元/未指定,建立時要問不要猜)唯一的作用是給**羞恥敏感度**一個預設
623850)。`modestyOf()` 會用 IDENTITY 與 SOUL 的描述往上或往下推(`MODESTY_SIGNALS`