Agent: reviewer (
reviewer)
Confidence: 75%
Cost: $0.2536
Duration: 1m 8s
Task ID:5b8673ef-b4b1-4545-9172-4de4ae228720
Git 狀態確認完畢。soul/ 目錄的 “D” 是 worktree 的典型狀態(runtime 產生的 soul/ 檔案不在版控追蹤中),不影響此次改動。commit 4800fbd 只改了 src/skills/skill-loader.ts,這是正確的。
審查完成 — 分析結果
SPEC-28 Skill Body 截斷上限 — 架構分析報告
概述
改動精確、範圍最小化,正確實現了 8000 char body 截斷機制。兩個注入點的處理邏輯一致,截斷後附加的標記包含原始檔案路徑,方便回溯。審查通過。
分析詳情
1. 常數定義 ✅
MAX_SKILL_INJECTION_CHARS = 8000(line 18)— 位置合理,與SKILLS_DIR同層級的模組常數- 8000 chars 作為上限合理:Claude 的 context window 中,單一 skill 不應佔超過 ~2K tokens
2. matchSkills() 截斷邏輯 ✅(lines 232-238)
const { body: rawBody } = parseFrontmatter(content)— 正確解構重命名let body = rawBody.trim()— 先 trim 再量測長度,邏輯正確body.slice(0, MAX_SKILL_INJECTION_CHARS)— 硬截斷在字元邊界,可能切斷 UTF-8 多字節字符的中間…但 JS string 是 UTF-16,slice()按 code unit 操作,對 BMP 字元不會破壞。含 emoji(surrogate pairs)理論上可能切半,但實務中 skill body 極少含 emoji,風險可忽略- 截斷標記
[SKILL TRUNCATED: full content in soul/skills/${c.meta.file}]— 清楚標示來源
3. matchSkillsByEvent() 截斷邏輯 ✅(lines 262-268)
- 與 matchSkills() 完全一致的截斷模式 — 維護性好
- 微觀察:兩處邏輯完全重複,未來如果需要修改截斷行為要改兩處。但鑒於這只有 5 行、且 SPEC-28 的 scope 是「加入截斷」而非「重構」,目前的做法是合理的 trade-off
4. Logger 呼叫 ✅(lines 235, 265)
- 使用
logger.warn()但未await— 注意到logger.warn是 async 方法 - 但上下文中,matchSkills() 本身就是 async,這裡不 await logger 是刻意的 fire-and-forget(與 line 247
trackUsageAsync().catch(() => {})同風格) - 在 matchSkillsByEvent() 中也是同樣模式(line 265)
5. 截斷後的長度
- 截斷後 body 實際長度 = 8000 +
\n\n[SKILL TRUNCATED: full content in soul/skills/xxx.md]≈ 8000 + 50~70 chars - 總長度略超 8000,但這個 marker 是必要的資訊提示,可接受
風險評估
- 🟢 低風險:surrogate pair 切割(實務中幾乎不會發生)
- 🟢 低風險:logger 未 await(符合既有模式,非阻塞設計)
- 🟢 低風險:截斷邏輯重複(scope 內可接受)
驗收結論
| 驗收項目 | 結果 |
|---|---|
| body > 8000 chars → 截斷 + marker | ✅ 通過 |
| body <= 8000 chars → 不變 | ✅ 通過 |
| warning logged on truncation | ✅ 通過 |
| 兩處注入點皆處理 | ✅ 通過 |
| tsgo 編譯通過 | ✅ 通過 |
| commit 在正確 branch 上 | ✅ 4800fbd on agent/task-4e601563 |
| 無非預期的檔案變更 | ✅ 僅 src/skills/skill-loader.ts |
結論:驗收通過,交付 secretary 執行 merge。
—HANDOFF—
TO: secretary
INTENT: handoff
ARTIFACT_TYPE: review
SUMMARY: SPEC-28 審查通過 — skill-loader.ts body 截斷上限 8000 chars,commit 4800fbd on agent/task-4e601563,建議 commit message: feat(skills): cap injected skill body at 8000 chars (SPEC-28)