fix(role): 排程改為服務所有角色,並在整理失敗時重試一次

西莉卡反映「每天睡覺的時候好像沒辦法睡」。查證後成立,而且比反映的更嚴重:
她從建立到現在(約 6 小時)一次都沒被整理過,另一個角色連 state.json 都還沒產生。

根因:--install-cron 把 ROLE_NAME 寫死進 crontab,排程只服務啟用角色(.active)。
其他角色的 inbox 只會累積,永遠等不到整理 —— 而且不會有任何錯誤訊息,
因為對排程而言它「成功地整理了那一個角色」。這是無聲失效,只有被漏掉的角色自己會發現。

- 新增 all_roles_enabled/sleep_target_roles/for_each_target_role
- cron_env_prefix 在多角色模式下不寫 ROLE_NAME,改寫 ROLE_SLEEP_ALL_ROLES=1
- --run/--nap/--catchup/--brief 全部改為逐一處理目標角色;
  睡眠時段與 AI 運行檢查移到迴圈外(與角色無關,只檢查一次),
  小睡與補跑的條件仍是 per-role
- 手動指定 ROLE_NAME 時行為不變;ROLE_SLEEP_ALL_ROLES=0 可退回舊的單角色模式
- --status 新增「排程涵蓋角色」,讀到舊條目寫死 ROLE_NAME 時直接標示警告
- 整理失敗改為重試一次:實測偶發 CLI 輸出空或 JSON 不合法,同批素材重跑即成功;
  沒有重試時該角色要等下一個週期,多角色模式下代價更大

實測結果(三個角色循序):
- LISBETH01 新增 4 則、關係史 +2(首次整理)
- SILICA01 第一次套用失敗、重跑成功,新增 5 則、捨棄 2 則、關係史 +3(首次整理)
- YUI01 判定不需補跑,正確略過

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jeffery
2026-07-29 18:39:54 +08:00
co-authored by Claude Opus 5
parent 32a5104c36
commit 8a4ca14b7c
5 changed files with 156 additions and 33 deletions
+19
View File
@@ -124,6 +124,7 @@ ROLE_DIR="<skill base directory>/../../scripts/role" # 其他助理
| `ROLE_NAP_IDLE_MINUTES` | | 小睡前需連續閒置的分鐘數,由 Stop hook 記錄最後互動時間 | `45` |
| `ROLE_NAP_MIN_INBOX` | | 小睡整理所需的最少待整理 inbox 筆數 | `3` |
| `ROLE_NAP_INTERVAL_MINUTES` | | 小睡排程檢查間隔分鐘數(cron 每 `*/N` 分鐘觸發) | `10` |
| `ROLE_SLEEP_ALL_ROLES` | | 排程是否服務**所有**角色(`0` 則只服務 `ROLE_NAME``.active` 的啟用角色)。`--install-cron` 會依此決定 crontab 條目要不要寫死 `ROLE_NAME` | `1` |
| `ROLE_BRIEF_ENABLED` | | 晨間狀態檢查開關;設 `0` 可停用 | `1` |
| `ROLE_BRIEF_TIMEOUT` | | 單個檢查腳本的逾時秒數 | `30` |
| `ROLE_BRIEF_EACH_LIMIT` | | 單個檢查腳本輸出的字元上限 | `600` |
@@ -781,6 +782,24 @@ updated: <yyyy/MM/dd HH:mm:ss>
判準刻意放在 `relevance` 而非型態:並非所有事件與知識都該優待 —— **沒有情感脈絡的一次性工作進度仍照原規則淡去**,被留下的是帶著溫度的那些。因此兩份 prompt 都明訂:只要內容承載情感、關係溫度或當時的心情,`relevance` **必須**含 `emotional``episodic` 與 `semantic` 最容易漏標,漏了就會被當成一般進度處理。
### 排程涵蓋所有角色
睡眠、小睡與晨間檢查排程**預設服務角色目錄下的每一個角色**,而不只是 `.active` 指定的啟用角色。
**修正前的錯誤**`--install-cron` 會把 `ROLE_NAME` 寫死進 crontab,於是只有啟用角色會睡。其他角色的 `inbox/` 永遠累積、`state.json` 連 `last_sleep` 都不會出現 —— 而且**不會有任何錯誤訊息**,因為對排程而言它「成功地整理了那一個角色」。實測有兩個角色從建立起完全沒被整理過。
| 模式 | crontab 條目 | 行為 |
| --- | --- | --- |
| 多角色(預設) | 寫入 `ROLE_SLEEP_ALL_ROLES=1`**不寫 `ROLE_NAME`** | 掃描 `~/.roles/*.identity.md` 逐一整理 |
| 單角色 | `ROLE_SLEEP_ALL_ROLES=0` 時寫入 `ROLE_NAME` | 只整理該角色(舊行為) |
- 手動執行時若指定 `ROLE_NAME`,仍只處理該角色 —— 手動操作行為不變。
- 角色鎖是 per-role,多角色**循序**執行不會互相搶鎖;睡眠時段與「是否有 AI 在運行」只檢查一次。
- 沒有 `<角色 ID>.checks/` 目錄的角色會自動跳過晨間檢查,對沒設定的角色零影響。
- `--status` 新增「排程涵蓋角色」欄位:若讀到舊條目寫死 `ROLE_NAME`,會直接標示警告。
**整理失敗會重試一次**:實測整理偶發失敗(CLI 輸出空或 JSON 不合法),同一批素材重跑即成功。沒有重試時該角色要等下一個週期,多角色模式下代價更大。
遺忘規則(只套用於日常與其他):
| 分類 | 未更新天數 | 命中次數 | 優先度 | 關聯 | 動作 |