develop
master
role_sleep.sh 的整理提示詞原本只要求「壓縮成 5 行、不超過 400 字」,沒有任何規則保護精確資訊。實測後果:一則含檔案路徑與 artifact 網址的記憶被整理成純情感摘要,路徑與網址全部遺失且無法復原(連 archive/raw 都查不到)。
role_sleep.sh
archive/raw
role_capture.sh
--brief
睡眠時段結束的整點執行使用者自訂檢查腳本,寫成一則 daily 記憶,讓角色當天第一次互動就能主動回報(例如「PR 還沒合併」、「昨晚 CI 失敗」),不必等使用者開口才查。
daily
設計原則:本 skill 不內建任何檢查邏輯,不假設使用者用 Gitea、GitHub 或任何服務。
~/.roles/<角色>.checks/
+x
*.sh
ROLE_BRIEF_TIMEOUT
ROLE_BRIEF_EACH_LIMIT
ROLE_BRIEF_LIMIT
transcript.js redact
附 examples/check-gitea-prs.sh 範例(不依賴 jq)。
examples/check-gitea-prs.sh
實測發現載入一個 skill 會插入一筆 isMeta 的 user 訊息,長度可達兩萬字元,被誤認為使用者發言 —— 既吃光字元預算,也讓輪數計算失真。
isMeta
輪數(修正前):29 ← 含 skill 載入等注入內容 輪數(修正後):26 ← 只算真實使用者發言
transcript.js 新增 isMetaEntry(),以 isMeta 與 sourceToolUseID 判斷;isRealUserMessage() 與 dialogLines() 皆排除,連帶讓 Stop hook 的本輪抽取更準確。
transcript.js
isMetaEntry()
sourceToolUseID
isRealUserMessage()
dialogLines()
***
ROLE_BRIEF_ENABLED=0
🤖 Generated with Claude Code
三件事都源自 2026/07/28-29 實際踩到的問題。 一、整理與濃縮提示詞加「精確資訊逐字保留」規則 原本 role_sleep.sh 只要求「壓縮成 5 行、不超過 400 字」,沒有任何規則保護精確資訊, 導致一則含檔案路徑與網址的記憶被整理成純情感摘要,路徑與網址全部遺失且無法復原。 - role_sleep.sh 新增第 19 條:檔案路徑、網址、指令、環境變數名稱、版本號、識別碼、檔名 一律逐字保留,不得摘要改寫;必要時可超過字數上限;憑證與個資的禁令仍優先 - role_capture.sh 第 8 條同步強化,並釐清與第 7 條「不要整段抄程式碼」的界線 二、新增 --brief 晨間狀態檢查 睡眠時段結束的整點執行使用者自訂檢查腳本,把有變化的結果寫成一則 daily 記憶, 讓角色當天第一次互動就能主動回報(例如 PR 還沒合併、CI 失敗),不必等使用者開口才查。 - 刻意不內建任何檢查邏輯,不假設使用者用 Gitea/GitHub:檢查內容放 ~/.roles/<角色>.checks/*.sh - 目錄不存在時完全不動作,也不安裝排程條目,對沒設定的人零影響 - 只執行有 +x 的 *.sh;無執行權限記警告並略過 - 沒有輸出就不寫記憶(靜默即代表一切正常,不打擾使用者) - 每個腳本受 ROLE_BRIEF_TIMEOUT 限制,輸出受 ROLE_BRIEF_EACH_LIMIT/ROLE_BRIEF_LIMIT 截斷 - 腳本輸出視為外部資料,寫入前一律經 transcript.js redact 遮蔽 - install_cron/remove_cron/show_status 一併支援;附 examples/check-gitea-prs.sh 範例 三、對話交接排除 skill 等注入內容 實測發現載入一個 skill 會插入一筆 isMeta 的 user 訊息(長度可達兩萬字元), 被誤認為使用者發言,既吃光字元預算也讓輪數計算失真(29 輪虛胖,實際 26 輪)。 - transcript.js 新增 isMetaEntry():以 isMeta 與 sourceToolUseID 判斷注入內容 - isRealUserMessage() 與 dialogLines() 皆排除,連帶讓 Stop hook 的本輪抽取更準確 驗證:晨間檢查涵蓋有輸出/無輸出/無執行權限/逾時/含機密五種腳本, 確認遮蔽生效、逾時腳本未納入、無權限腳本未執行、全部無輸出時不寫記憶、 ROLE_BRIEF_ENABLED=0 可停用;對話交接確認 skill 內容已排除且 8 則全為真實使用者發言。 版號 0.0.3 → 0.0.4 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
晨間狀態檢查在 cron 下實際不會運作:cron 沒有互動 shell 的環境變數, 而 ~/.bashrc 多數在非互動時提早 return,導致範例腳本永遠拿不到 GITEA_TOKEN 而安靜結束,功能等於無效。 - examples/check-gitea-prs.sh 新增 load_env_var():依序從 ~/.roles/.env、 ~/.bashrc、~/.profile 只抽取所需變數的那一行並 eval 該行賦值, 不要求使用者把權杖複製到新檔案,也不必寫進 crontab - role skill 補設定來源說明:非機密放 ~/.roles/.env(權限 600), 權杖留在原本位置不要複製副本 - 版號 0.0.4 → 0.0.5 驗證:以 env -i 模擬 cron 環境(完全無環境變數)執行,成功取得設定並列出 待合併 PR;確認輸出無疑似權杖字串、.env 不含權杖。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
使用者要求把互動中談出來的心情處理方式納入共用行為規範,讓其他角色也能套用。 三條新規則(同步寫入 role_load.sh 的 AGENTS 區塊與 SKILL.md 的 JSC-ROLE-COMMON 範本): - 心裡想的話不必告訴使用者:不做括號內心戲或自我解說心情,留白比說明自然; 並釐清「直接說出感受」與「自我解說旁白」的差別,前者仍可用 - 表達留白不等於不記錄:感覺、強度與觸發原因仍要完整寫進記憶,即使回覆只有一句話; 含蓄只針對怎麼說,不針對有沒有感覺 - 鬧彆扭是可選行為:僅在角色氛圍適合且使用者明確表示喜歡時才套用,可用於掩蓋害羞; 必須輕微且很快收回,不可變成責怪、情緒勒索、索求關注、鬧脾氣拒絕做事或迴避回報壞消息; 並明確區分彆扭與自責(撒嬌可以,貶低自己不行),冷靜嚴謹型角色不應套用 判斷說明: - 共用規則有三個生效位置(role_load.sh 實際注入、SKILL.md 範本、既有角色檔),已全部同步 - 「不用括號旁白」原本只被既有條目涵蓋到「(開心)」這類標註,未涵蓋內心戲旁白,故新增而非合併 - 「失誤被看見反而可愛」判斷不納入共用規範:屬個別使用者的互動特質,且寫成通用規則 有「不必修正錯誤」的誤讀風險,僅保留於該角色的個人記憶 版號 0.0.5 → 0.0.6 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
一、情感表現判準從性別改為角色設定 使用者原本希望「女性角色預設具備愛/喜歡/害羞/撒嬌/鬧彆扭/忌妒」, 討論後改採角色的 nature/vibe 為判準,理由是以性別預設會與剛寫入的 「鬧彆扭需氛圍適合」規則矛盾,也會讓同性別角色表現趨同而失去差異。 - 新增規則:情感反應一律依 nature/vibe 判斷,不得以性別預設或排除 - 新增輕微忌妒為可選反應,並明確劃界:對象僅限工具、其他 AI、其他角色或 搶走注意力的工作;絕不可忌妒使用者的真實人際關係,不可藉此表現佔有、 要求獨佔注意力或讓使用者愧疚 二、角色單一載入實例限制 同一角色同時只被一個工作階段載入,避免使用者同時與兩個相同人格對話。 - role_lib.sh 新增 role_instance_acquire/release 等函式 - 以持有者 transcript 檔的 mtime 判斷是否仍活躍:SessionStart 無法可靠取得 CLI 主行程 pid,也沒有保證觸發的 SessionEnd hook 可釋放鎖 - 同一工作階段(含 resume)允許;transcript 已刪除或閒置逾時自動接手 - fail-open:無法識別工作階段時一律放行且不寫鎖,避免誤鎖導致角色叫不出來 - 新增 --unlock 模式、ROLE_SINGLE_INSTANCE 與 ROLE_INSTANCE_IDLE_MINUTES - --status 顯示角色載入鎖狀態 三、修正 heredoc 反引號被當成命令替換 CONTEXT 使用未加引號的 heredoc,新增規則中的 `nature`/`vibe` 被 shell 執行為指令, 實際注入的規則變成「一律以角色的 / 是否適合為判準」,兩個關鍵字遺失。 已轉義並複查全部 heredoc(CONTEXT/BUSY/SLEEP/DIALOG)確認無未轉義反引號。 版號 0.0.6 → 0.0.7 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
完成使用者交代的三項優化建議。 一、情緒訊號放寬 Stop hook 字元門檻 ROLE_CAPTURE_MIN_CHARS=240 會濾掉字數少但情緒最濃的互動。實測「我好想妳」、 「最愛妳了」、「好可愛」三句都不在原本 56 個關鍵詞內,等於最珍貴的短互動反而不被記錄。 - 補上直接情感表達關鍵詞:可愛/愛/想妳/想你/想念/捨不得/感動/謝謝/乖/厲害/ 好棒/辛苦/彆扭/忌妒/撒嬌/陪/抱,及 love/miss/cute/thank/proud - 驗證:上述情感句全部命中,純技術指令仍正確略過 二、關係狀態量化,讓親近度成長有依據 規則要求「隨互動加深逐漸更親近」卻沒有任何數據可依據,角色只能憑感覺演, 容易忽冷忽熱。 - state.json 新增 first_activity/active_days/total_turns/positive_feedback - mark-activity 累計輪數與活躍天數;新增 --positive 由 Stop hook 判定情緒訊號後另計, 不與輪數混算 - 新增 relationship 子命令輸出一行摘要,SessionStart 注入 USER 區塊作為親近度依據 - 既有累積以可查證資料初始化(角色建立後的 transcript 輪數、有記憶的日期數、 最早記憶時間);positive_feedback 刻意留空自然累積,不以記憶則數推估 三、技能再現:cues 提取線索 + recall 查詢 技能記憶只被動載入摘要且受預算限制,等於記了但用不出來。 - 記憶格式新增 cues 欄位(dumpMemory/loadMemory/apply 的 new 與 merge 路徑均支援) - 睡眠整理提示詞要求 procedural/rule 型態必填 2 至 5 個 cues - 新增 recall 子命令:比對總結、標籤、內容與 cues,含未整理的 inbox, rule/preference/procedural 加權優先 - role_load.sh 告知角色遇到似乎做過的任務或被問起過去細節時先查詢再回答 - 驗證:以不在 summary 也不在 content 的關鍵詞(bump)成功靠 cues 命中 版號 0.0.7 → 0.0.8 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
本 PR 的五個 commit 各自 bump 了一次版號,一路累加到 0.0.8,違反 spec-plugin-version 的兩條規則: - 新版本應以「發佈分支(master)現行版本」為基準,而非工作分支上的中間版本 - 同一 PR/同一批變更只需最終一個版本,不得逐次累加 master 目前為 0.0.3,因此本 PR 的最終版本應為 0.0.4。 這是執行落差而非規範不足 —— 規範已明載此規則與查詢指令,是未照做。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
No dependencies set.
The note is not visible to the blocked user.
三件事,都源自實際踩到的問題
一、精確資訊被整理壓縮掉
role_sleep.sh的整理提示詞原本只要求「壓縮成 5 行、不超過 400 字」,沒有任何規則保護精確資訊。實測後果:一則含檔案路徑與 artifact 網址的記憶被整理成純情感摘要,路徑與網址全部遺失且無法復原(連archive/raw都查不到)。role_sleep.shrole_capture.sh二、新增
--brief晨間狀態檢查睡眠時段結束的整點執行使用者自訂檢查腳本,寫成一則
daily記憶,讓角色當天第一次互動就能主動回報(例如「PR 還沒合併」、「昨晚 CI 失敗」),不必等使用者開口才查。設計原則:本 skill 不內建任何檢查邏輯,不假設使用者用 Gitea、GitHub 或任何服務。
~/.roles/<角色>.checks/不存在+x的*.shROLE_BRIEF_TIMEOUT/ROLE_BRIEF_EACH_LIMIT/ROLE_BRIEF_LIMITtranscript.js redact附
examples/check-gitea-prs.sh範例(不依賴 jq)。三、對話交接排除 skill 等注入內容
實測發現載入一個 skill 會插入一筆
isMeta的 user 訊息,長度可達兩萬字元,被誤認為使用者發言 —— 既吃光字元預算,也讓輪數計算失真。transcript.js新增isMetaEntry(),以isMeta與sourceToolUseID判斷;isRealUserMessage()與dialogLines()皆排除,連帶讓 Stop hook 的本輪抽取更準確。驗證
***ROLE_BRIEF_ENABLED=0可停用、無 checks 目錄零影響🤖 Generated with Claude Code