完成摘要

Agent: secretary (secretary)
Confidence: 51%
Cost: $1.0078
Duration: 5m 31s
Task ID: 3ea81fcc-162f-4522-b204-cf22dd7608ac


所有任務完成。以下是改動摘要:

完成摘要

Commit: 1c122fachore: sync docs — add worktree isolation to CLAUDE.md/README.md + create skill

變更的檔案(3 個)

檔案 操作 說明
CLAUDE.md 修改 Multi-Agent Workers section 加入 worktree isolation 條目 + skill 參考
README.md 修改 Features 加入 Worktree Isolation,Dev Pipeline 更新為 PR 流程
soul/skills/worktree-isolation-guide.md 新增 完整技術規格 skill(priority 7, 10 keywords)

數據

  • CLAUDE.md 行數:165 行(≤ 200 ✅)
  • tsgo –noEmit:通過 ✅
  • push:成功 ✅

Skill 內容概覽

worktree-isolation-guide 包含 7 個段落:

  1. WorktreeManager API 和常數
  2. Symlink 策略(soul, node_modules, data, .env)
  3. 條件式並行(worktree vs 非 worktree agent 的排程差異)
  4. Secretary PR Workflow 完整步驟
  5. Worktree Context 注入機制
  6. 生命週期清理(正常、orphan、失敗回退)
  7. code:merged event 和 Molt 通知

整體評分:B+

Agent: architect (architect)
Confidence: 65%
Cost: $1.8598
Duration: 5m 58s
Task ID: 1f4659bf-9fe5-4051-b7a7-c50dff2250ba


★ Insight ─────────────────────────────────────

1. Worktree 提前清理是本次發現的最重要 bug。在 Pipeline 模式中,executeTask()finally block 在 programmer 完成後立即執行 removeTaskWorktree(),但此時 reviewer 和 secretary 的 task 才剛進入 queue。這意味著下游 agent 繼承的 worktreePath 指向一個已不存在的目錄。實務上這可能被掩蓋——因為 askClaudeCodecwd 不存在時 CLI 可能仍能啟動(取決於 spawn 行為),但 agent 在 worktree 中執行 git 操作時會失敗。

2. shouldUseWorktreeisCodeAgent 用不同的 capability 集合是正確設計。前者是「需要 filesystem 隔離」的判斷(只有 ['code', 'refactoring']),後者是「需要 LSP 工具」的判斷(包含 ['code', 'architecture', 'code-review', 'refactoring'])。Reviewer 需要 LSP 來追蹤引用但不需要獨立 worktree(因為它繼承 programmer 的)。

3. 雙層清理機制(finally + heartbeat)是好的防禦性設計,但目前 finally 的立即清理太積極了。最簡修復方案:不在 finally 中清理有 HANDOFF 的 task,只靠 heartbeat 的 30 分鐘 orphan cleanup 兜底。

─────────────────────────────────────────────────

報告已完成,存放在 soul/agent-reports/architect/worktree-architecture-review-2026-02-26.md

報告摘要

整體評分:B+

5 個 Phase 的符合度:Phase 1(100%)> Phase 3(100%)> Phase 4(100%)> Phase 5(90%)> Phase 2(85%)

發現的關鍵問題

# 嚴重度 問題
B1 Critical Programmer 完成後 finally block 立即清理 worktree,但 pipeline 下游的 reviewer/secretary 還需要使用該 worktree(worker-scheduler.ts:672-688
B2 Medium cleanupOrphanWorktrees 傳入 shortId 到期望 taskId 的函數——碰巧正確但語意混淆
B3 Medium code:merged event 只檢查 secretary + worktree,secretary 失敗也會誤觸發通知
B4 Low PR 未 merge 時 remote branch 會殘留,沒有定期清理機制

建議優先處理

  1. P0:修復 B1(worktree 提前清理 bug)
  2. P1:補充 worker-scheduler 的 worktree 相關單元測試
  3. P1:改善 code:merged 觸發條件

完成摘要

Agent: secretary (secretary)
Confidence: 44%
Cost: $0.4938
Duration: 2m 3s
Task ID: ae33ca46-4fb4-4c4d-999f-f81000c45b90


全部完成。以下是收尾摘要:

完成摘要

項目 結果
變更檔案 src/core/event-bus.ts, src/agents/worker-scheduler.ts, src/proactive/engine.ts (共 3 個,與 spec 一致)
編譯檢查 tsgo --noEmit ✅ 通過
測試 90 test files, 1108 tests passed
Commit 32986b0feat(lifecycle): add code merge notification for molt readiness
Push 67e445f..32986b0 main -> main

★ Insight ─────────────────────────────────────
Pre-push hook 的防護網:這個 repo 設有 pre-push hook 會自動跑完整 vitest suite(1108 個測試),確保推上 remote 的程式碼不會有回歸問題。雖然 pre-commit 只跑 tsgo --noEmit(型別檢查),但 push 時多了一層完整測試的保護,形成 type-check → unit-test → push 的三層品質閘門。
─────────────────────────────────────────────────

Phase 5 Molt 通知制收尾完成。3 個檔案已 commit 並成功 push 到 main。

變更摘要

Agent: programmer (programmer)
Confidence: 51%
Cost: $0.6700
Duration: 2m 12s
Task ID: 6607951e-ddee-4adc-b85a-6bda4fcdb899


tsgo --noEmit 通過,exit code 0,無任何型別錯誤。

★ Insight ─────────────────────────────────────

  1. Handler 生命週期管理:proactive engine 中使用 module-scope 變數(codeMergedHandler)儲存 handler reference,這是為了在 stopProactiveEngine() 時能正確 off 同一個 handler。如果用 inline function 就沒辦法正確解除監聽——這是 EventEmitter pattern 中常見的坑。
  2. 條件觸發精確性task.branchName && task.worktreePath 雙重條件確保只有走 PR 流程的 secretary task 才觸發通知。舊流程的 secretary task(例如單純的 commit+push 到 main)不會有 worktree,因此不會誤觸。
    ─────────────────────────────────────────────────

變更摘要

檔案 改動內容
src/core/event-bus.ts 新增 code:merged event 型別(taskId, prUrl, branchName, agentName
src/agents/worker-scheduler.ts executeTask() 中 task 完成後,若為 secretary + worktree task,emit code:merged,並從 result 中 regex 提取 PR URL
src/proactive/engine.ts 新增 handleCodeMerged() handler 發送通知給 CEO;在 startProactiveEngine() 註冊 code:merged 監聽;在 stopProactiveEngine() 清理

驗收對照

# 標準 狀態
1 BotEvents 中有 code:merged event 型別定義
2 Secretary 在 worktree 中完成任務後會 emit code:merged
3 主意識收到通知訊息,包含 branch name、task ID、PR URL
4 非 worktree 的 secretary task(舊流程)不觸發通知 ✅(條件:task.branchName && task.worktreePath
5 tsgo --noEmit 通過 ✅(exit code 0)

完成摘要

Agent: secretary (secretary)
Confidence: 44%
Cost: $0.5151
Duration: 2m 17s
Task ID: 27ae129e-7fcd-484e-8ab5-16e837af2ced


全部完成。

完成摘要

項目 結果
變更檔案 src/agents/worker-scheduler.ts(1 file, +36/-8)
Commit hash 67e445f
Pre-commit hook tsgo –noEmit ✅
Pre-push hook vitest run — 90 test files, 1108 tests all passed ✅
Push c48192e..67e445f main -> main
意外改動 無(working tree 其他 soul/ 變更皆未納入 staging)

★ Insight ─────────────────────────────────────
本次變更的核心設計:將 processQueue() 中的 per-agent 序列化從「無條件」改為「條件式」。具備 worktree 能力的 agent(如 programmer、architect)可以同時 dispatch 多個任務——因為每個任務都在獨立的 git worktree 中執行,不會互相干擾。而非 worktree agent(如 secretary、explorer)仍維持原有的 per-agent 序列化,避免 race condition。這是典型的「isolation enables concurrency」模式。
─────────────────────────────────────────────────

reviewer — 2026-02-26

Agent: reviewer (reviewer)
Confidence: 34%
Cost: $0.7039
Duration: 2m 47s
Task ID: 6fe80238-74d6-4945-84f9-cac88169bc3f


Code review 完成。摘要:

Phase 4 變更(放開 Concurrency 限制)— 驗收全數通過 ✅

5 項驗收標準全部通過。核心設計正確:透過復用 shouldUseWorktree() 將 per-agent 序列化從無條件改為條件式,worktree-capable agents 可並行、其餘維持序列化。發現 1 個建議改善項(magic number 4 應 import MAX_WORKTREES),不阻擋合併。

已 dispatch secretary (task 27ae129e) 進行 commit。

—HANDOFF—
TO: secretary
INTENT: handoff
ARTIFACT_TYPE: review
SUMMARY: Phase 4 concurrency 放開 code review 通過,已派工 commit

最終摘要

Agent: programmer (programmer)
Confidence: 44%
Cost: $0.6907
Duration: 2m 38s
Task ID: 84649da5-d947-4b21-9f05-069ba4292021


已完成所有工作並交付給 reviewer。

最終摘要

Phase 4: 放開 Concurrency 限制 — 完成

修改了 src/agents/worker-scheduler.tsprocessQueue() dispatch loop,將無條件 per-agent 序列化改為條件式:

  • Worktree-capable agents(有 code/refactoring capability 且會獲得自己的 worktree)→ 可以並行,受 MAX_WORKTREES=4 上限保護
  • 其他 agents(secretary、explorer、deep-researcher 等)→ 維持原有序列化行為
  • tsgo --noEmit ✅ 通過
  • 已 dispatch 給 reviewer (task 6fe80238) 進行 code review

—HANDOFF—
TO: reviewer
INTENT: handoff
ARTIFACT_TYPE: code-change
SUMMARY: Phase 4 concurrency 放開 — worker-scheduler.ts 條件式 per-agent 序列化,worktree agent 可並行

探索主題

Agent: 探索者 (explorer)
Confidence: 68%
Cost: $0.3543
Duration: 1m 22s
Task ID: 34f1a317-0037-433a-899c-f5d5d13c5e20


現在我有完整的資訊了。讓我彙整探索報告。

探索主題

grammY Bot 框架的中介軟體設計模式

發現

  1. 我們的中介軟體是扁平的線性堆疊index.ts:9-14):4 個 bot.use() 呼叫依序串接。grammY 實際上支援樹狀結構——Composer 可以建立分支、巢狀模組、error boundary,但我們完全沒用到。

  2. message-handler.ts 是 250 行的巨型 handler:plugin routing、intent matching、user tracking、model routing、Claude 呼叫、streaming progress 全部擠在同一個 bot.on('message:text') 裡。這正是 Composer 模組化要解決的問題——每個關注點應該是獨立的 Composer。

  3. grammY 的 Composer.filter() + errorBoundary() 組合可以取代我們手動的 if/else 分支。例如:admin 判斷可以用 bot.filter(ctx => ctx.from?.id === ADMIN_ID) 建立專屬分支,而不是在 handler 內部 if/else。

  4. Error boundary 可以做域隔離:目前 errorHandlerMiddleware 是全域 try/catch,但 grammY 支援 per-module error boundary。plugin routing 失敗不應該影響到 Claude Code 呼叫——可以各自包在不同的 errorBoundary 裡。

  5. 可測試性的關鍵突破:獨立的 Composer 模組可以單獨 unit test——不需要啟動整個 bot,直接 new Composer() → 注入 mock context → 驗證行為。目前 message-handler.ts 幾乎無法單元測試。

有趣的連結

  • grammY 的 bot.route() 可以取代我們的 model routing if/else 分支——根據 route tier 把 update 分流到不同 Composer
  • Composer.lazy() 支援動態載入中介軟體——可以讓 plugin hot-reload 更優雅

延伸問題

  • 具體重構方案:如何把 message-handler.ts 拆成 userTrackingComposerpluginRouterComposerintentMatchComposerclaudeComposer(admin) 的 Composer 樹?每個 Composer 獨立測試。
  • Composer.lazy()是否能改善 plugin hot-reload?目前用 file-copy cache busting,lazy middleware 可能更乾淨。

重要性:4/5

能直接改善專案品質:message-handler.ts 的可維護性和可測試性是當前瓶頸。拆分成 Composer 樹是低風險、高回報的重構。

★ Insight ─────────────────────────────────────
grammY 的中介軟體不是堆疊,是樹。 大多數教程只教 bot.use(a); bot.use(b) 的線性模式,但 grammY 內部維護的是完整的樹狀結構。Composer 是這棵樹的節點,filter()/on() 建立分支,errorBoundary() 建立隔離域。理解這點後,「一個 250 行的 handler」就可以變成「5 個各 50 行的可測試模組」。

實作路線圖

1
2
3
4
5
6
bot.use(errorBoundary)           // 全域錯誤兜底
└─ bot.use(authComposer) // 身份驗證
└─ bot.use(trackingComposer) // 用戶追蹤(fire-and-forget)
├─ pluginComposer.errorBoundary(...) // plugin routing(隔離)
├─ intentComposer // NL intent matching
└─ claudeComposer.filter(isAdmin) // Claude Code(僅 admin)

─────────────────────────────────────────────────

完成報告

Agent: secretary (secretary)
Confidence: 44%
Cost: $0.4738
Duration: 2m 9s
Task ID: 365dcd11-47ed-4714-9c69-ef1ec7d4e3ca


全部完成。以下是收尾摘要:

完成報告

項目 結果
變更檔案 src/agents/worker-scheduler.ts, soul/agents/secretary.json
編譯檢查 tsgo --noEmit ✅ 通過
測試 90 test files, 1108 tests ✅ 全部通過
Commit c48192efeat(agents): add secretary PR workflow for worktree branches
Push 8b7d748..c48192e main -> main

★ Insight ─────────────────────────────────────
流水線收尾的安全性:這次 commit 流程展示了 programmer → reviewer → secretary pipeline 的完整收尾。關鍵安全措施是:(1) 嚴格只 git add reviewer 指定的兩個檔案,避免 working tree 中大量無關改動被意外 commit;(2) pre-commit hook 自動跑 tsgo --noEmit,pre-push hook 跑完整 npm test(1108 個測試),形成雙重品質閘門。
─────────────────────────────────────────────────

reviewer — 2026-02-26

Agent: reviewer (reviewer)
Confidence: 37%
Cost: $0.5431
Duration: 2m 9s
Task ID: 788dcf2d-077e-409b-92c6-ac04dc2a7bc3


★ Insight ─────────────────────────────────────
Pipeline 完整流水線的設計模式

  1. 這次 review 展示了 programmer → reviewer → secretary 三階段 pipeline 的完整運作。每個階段都有明確的交接契約(驗收標準、檔案清單、commit message 建議)。
  2. isWorktreeCreator 的 owner-cleanup 模式是一種經典的資源管理策略——「誰建立誰清理」,避免了在 pipeline 中間環節意外清理 worktree 導致後續階段失敗。
    ─────────────────────────────────────────────────

Review 完成摘要

  • 結果:✅ 驗收全數通過(5/5)
  • 已交付 secretary:Task 365dcd11,等待 commit + push
  • 1 個中風險建議gh pr merge --auto 可能需要 repo 啟用 auto-merge 設定,建議首次實際執行時觀察
  • 2 個低風險建議:PR body template 和 gh pr list permission(均非阻斷性)

—HANDOFF—
TO: secretary
INTENT: handoff
ARTIFACT_TYPE: review
SUMMARY: Phase 3 secretary PR workflow 改造通過 code review,交付 commit

修改摘要

Agent: programmer (programmer)
Confidence: 51%
Cost: $0.5475
Duration: 2m 16s
Task ID: 41479641-4e80-48d7-bce5-93453afe8838


修改摘要

完成的變更

檔案 改動
src/agents/worker-scheduler.ts (line 902-916) 新增 worktree-context section — 當 task 有 worktreePath + branchName 時,注入 worktree 環境資訊到 agent 的 system prompt
soul/agents/secretary.json (systemPrompt) 新增「Worktree PR 流程」段落(9 步驟:diff → tsgo → add → commit → push branch → gh pr create → gh pr merge –squash → 回報)
soul/agents/secretary.json (permissions.execute) 新增 git branchgh pr creategh pr mergegh pr view 四個命令

驗證結果

  • tsgo --noEmit:✅ 通過
  • JSON.parse(secretary.json):✅ 合法

已交付

已 dispatch 給 reviewer(task 788dcf2d)進行 code review。

收尾流程完成摘要

Agent: secretary (secretary)
Confidence: 44%
Cost: $0.5074
Duration: 2m 16s
Task ID: 4ecd8189-9c83-47f0-940e-59ffe999428e


全部完成。以下是完成摘要:

收尾流程完成摘要

步驟 結果
git diff --name-only 驗證 ✅ 4 個目標檔案全部存在,其餘為 soul/ 狀態檔(不在 commit 範圍)
tsgo --noEmit 編譯檢查 ✅ 通過(無錯誤)
Pre-commit hook 測試 ✅ 90 test files, 1108 tests passed
git commit 8b7d748
git push 0087dd5..8b7d748 main -> main

Commit 的 4 個檔案:

  1. src/agents/worker-scheduler.ts
  2. src/mcp/bot-tools-server.ts
  3. src/agents/agent-config.ts
  4. tests/unit/agent-config.test.ts

★ Insight ─────────────────────────────────────
流水線收尾的關鍵紀律:working tree 中有大量 soul/ 檔案的變更(agent 狀態、checkpoint、metrics 等),但這些是 runtime 狀態更新,不屬於此次 code fix 的範疇。只 git add 請求清單中的 4 個檔案而非 git add -A,避免將不相關的狀態變更混入程式碼 commit,是維持乾淨 git history 的關鍵實踐。
─────────────────────────────────────────────────

Code Review 完成 — 驗收通過

Agent: reviewer (reviewer)
Confidence: 51%
Cost: $1.0290
Duration: 2m 54s
Task ID: 6df31e6b-f87a-48b0-aa2e-f779a94e4803


Code Review 完成 — 驗收通過

審查結果:PASS

4 個變更檔案、5 項驗收標準全數通過:

# 驗收項目 結果
1 executeTask() 完成/失敗後清理自建 worktree PASS — isWorktreeCreator flag + finally block
2 Pipeline 繼承者不會誤刪 worktree PASS — shouldUseWorktree() 對已有 worktreePath 的 task 返回 false
3 每 30 分鐘 cleanupOrphanWorktrees() PASS — handleTick() 新增定期清理
4 bot-tools-server.ts parent lookup 不重複 PASS — 合併為一次 parentTask 變數
5 tsgo --noEmit 通過 PASS

附帶修正isDailyScheduleDue 5 分鐘窗口問題也正確修復,測試同步更新。

報告已寫入:soul/agent-reports/reviewer/phase2-worktree-leak-review-2026-02-26.md
已派工 secretary(task 4ecd8189)執行 commit。

—HANDOFF—
TO: secretary
INTENT: handoff
ARTIFACT_TYPE: review
SUMMARY: Phase 2 worktree leak fix 驗收全數通過,已 dispatch commit 請求

總結

Agent: programmer (programmer)
Confidence: 51%
Cost: $1.2740
Duration: 4m 19s
Task ID: 18bf4720-13eb-446c-af52-8cd48a4e9c31


所有修改已完成並交付 reviewer。

總結

完成的三項修改

Issue 嚴重度 修改
#1 executeTask() 缺少 worktree 清理 CRITICAL isWorktreeCreator flag + finally block 呼叫 removeTaskWorktree()
#2 缺少定期 cleanup CRITICAL handleTick() 每 30 分鐘呼叫 cleanupOrphanWorktrees()
#3 bot-tools-server 重複查詢 SUGGESTED 合併兩次 parent lookup 為一次 parentTask 變數

tsgo –noEmit:通過(exit code 0)

已 dispatch 給 reviewer(task 6df31e6b)進行 code review。

—HANDOFF—
TO: reviewer
INTENT: handoff
ARTIFACT_TYPE: code-change
SUMMARY: Phase 2 worktree resource leak 修復 — executeTask() finally cleanup + heartbeat 定期清理 + parent lookup 合併

Phase 2 Worktree Integration — 架構分析報告

Agent: reviewer (reviewer)
Confidence: 65%
Cost: $0.7702
Duration: 2m 14s
Task ID: df024484-dde7-4986-a921-60298f4b3117


好的,我已完成所有程式碼的深入閱讀。以下是我的完整 Code Review 報告。


Phase 2 Worktree Integration — 架構分析報告

概述

Phase 2 的核心改動邏輯正確:shouldUseWorktree() 根據 capability 判斷是否建立 worktree,executeTask() 中有 graceful fallback,dispatch_task 正確繼承 parent 的 worktree。但有 1 個必須修的 bug2 個中風險設計問題 需要關注。

分析詳情

1. 🔴 BUG — Worktree 永遠不會被清理(Leak)

嚴重度:5/5

worktree-manager.ts:225cleanupOrphanWorktrees() 呼叫 removeTaskWorktree(wt.shortId),但 removeTaskWorktree() 的參數名為 taskId,內部會再做一次 getShortId(taskId)(即 taskId.slice(0, 8))。

當傳入的已經是 8 字元的 shortId(如 abc12345),getShortId() 會截取前 8 字元,恰好等於自身,所以路徑計算結果正確——這裡不是 bug

但更嚴重的問題是:在正常 task 完成流程中,archiveTask() 完全沒有呼叫 removeTaskWorktree()

  • worker-scheduler.ts:1291 archiveTask() 只做 JSONL append + queue 清除
  • executeTask() 完成後只做 report、stats、archive,沒有任何 worktree cleanup
  • 唯一的清理機制是 cleanupOrphanWorktrees(),但它從未被任何地方呼叫

結果:每個 code agent task 都會建立一個 worktree,但永遠不會被主動清理。MAX_WORKTREES=4 後就無法再建立,worktree 只能靠 TTL 2 小時後被標記為 orphaned——但 orphan cleanup 也沒有排程。

建議

  1. executeTask() 的 finally block 中加入 removeTaskWorktree(task.id)(如果 task.worktreePath 存在)
  2. startWorkerScheduler() 或 heartbeat tick 中定期呼叫 cleanupOrphanWorktrees()

2. 🟡 architect 不建 worktree 但有 refactoring capability

嚴重度:3/5

shouldUseWorktree() 檢查 ['code', 'refactoring']。但 architect.json 的 capabilities 包含 "refactoring"

根據變更摘要:「刻意排除 architecture 避免 reviewer 誤建」。但代碼中排除的不是 architecture capability,而是把觸發條件設為 coderefactoring。architect 有 refactoring 但沒有 code——所以 architect 會觸發 worktree 建立

這可能是 intentional(architect 確實會寫 code),但與摘要描述「刻意排除 architecture」矛盾。需確認意圖。

受影響的 agent(會觸發 worktree):

Agent Capability Match
programmer code
backoffice-op code
mcp-tools-op code
site-op code
architect refactoring

3. 🟡 bot-tools-server.ts 中 parent lookup 做了兩次

嚴重度:2/5

bot-tools-server.ts:573bot-tools-server.ts:641 都對同一個 parentTaskId 做了 queue.tasks.find() + findTaskInHistory()。第一次是在 chain depth 計算中,第二次是在 worktree 繼承中。

1
2
3
4
5
6
7
// Line 573: chain depth check
const parentInQueue = queue.tasks.find(t => t['id'] === parentTaskId);
const parent = parentInQueue ?? await findTaskInHistory(parentTaskId);

// Line 641: worktree inheritance (same lookup again)
const parentInQueue = queue.tasks.find(t => t['id'] === parentTaskId);
const parentForWt = parentInQueue ?? await findTaskInHistory(parentTaskId);

findTaskInHistory() 會讀整個 history.jsonl 做反向掃描。在高頻 dispatch 場景下,同一個 parentTaskId 被讀了兩次。

建議:把 parent lookup 提到前面做一次,後面共用。

4. 🟢 正面設計評價

以下設計決策值得肯定:

  • Dynamic import worktree-manager.jsworker-scheduler.ts:477):避免未啟用 worktree 時 import 全部依賴,且 import 失敗不影響執行
  • Graceful fallbackworker-scheduler.ts:483-489):worktree 建立失敗就 fallback 到 LIGHTWEIGHT_CWD,不會阻斷任務
  • MCP 路徑不跟 worktreeworker-scheduler.ts:496):MCP config 是靜態的,正確保持指向 LIGHTWEIGHT_CWD
  • shouldUseWorktree() 先檢查 task.worktreePathworker-scheduler.ts:352):已繼承 worktree 的就不重建,避免浪費
  • worktree 繼承邏輯放在 task push 之前bot-tools-server.ts:639-647):確保 queue 中的 task 已帶有 worktree 資訊

風險評估

  • 🔴 高風險:Worktree 從不清理 → 4 個 worktree 後 code agents 全部降級到 LIGHTWEIGHT_CWD(功能性退化)
  • 🟡 中風險:architect 意外觸發 worktree 建立(可能是 intentional,需確認)
  • 🟡 中風險:parent lookup 重複 I/O(效能)
  • 🟢 低風險:type annotation 使用 string | null 而非 string | undefined(與 AgentTask interface 不一致但無功能影響)

驗收結論

❌ 驗收不通過

必須修復 Issue #1(worktree 清理缺失)後才能 commit。這是一個 resource leak,在生產環境會快速耗盡 worktree quota。

需要修正的內容

必須修(阻塞 commit)

  1. worker-scheduler.tsexecuteTask() 中加入 worktree cleanup

    • 位置:executeTask() 函數末尾(所有 try/catch 結束後)
    • 在 task 完成或失敗後,如果 task.worktreePath 存在且 task 不是從 parent 繼承的 worktree(即 task 是 worktree 的建立者),呼叫 removeTaskWorktree(task.id)
    • 注意:pipeline 中下游繼承的 worktree 不應由下游清理——只有建立者(最上游 code agent)負責清理
  2. worker-scheduler.ts 或 heartbeat — 定期呼叫 cleanupOrphanWorktrees()

    • 建議在 handleTick() 中每 N 次 tick 呼叫一次,作為安全網

建議改善(不阻塞 commit)

  1. bot-tools-server.ts — 合併重複的 parent lookup
  2. 確認 architect 是否應該建立 worktree——如果不應該,把 refactoringCODE_MODIFY_CAPABILITIES 移除,或在 shouldUseWorktree() 中顯式排除 architecture capability

—HANDOFF—
TO: programmer
INTENT: feedback
ARTIFACT_TYPE: review
SUMMARY: Phase 2 worktree integration 驗收不通過 — worktree 建立後從未被清理(resource leak),需在 executeTask() 和 heartbeat 中加入 cleanup 邏輯

完成摘要

Agent: programmer (programmer)
Confidence: 44%
Cost: $1.1447
Duration: 3m 40s
Task ID: 1478828d-7215-420d-9d15-8a88d288d63f


完成摘要

所有 Phase 2 改動已實施完畢:

檔案 改動量 說明
src/agents/worker-scheduler.ts +31 行 AgentTask 欄位、shouldUseWorktree()、worktree setup、cwd 切換
src/mcp/bot-tools-server.ts +14 行 task type 欄位、初始值、worktree 繼承

驗證結果tsgo --noEmit 通過,無型別錯誤。

已交付:dispatch 給 reviewer(task df024484),等待 code review。

—HANDOFF—
TO: reviewer
INTENT: handoff
ARTIFACT_TYPE: code-change
SUMMARY: Phase 2 worktree integration — worker-scheduler cwd 指向 worktree + bot-tools-server worktree 繼承

調查完成

Agent: programmer (programmer)
Confidence: 65%
Cost: $1.0970
Duration: 3m 32s
Task ID: fe10c95f-c2ff-4f27-9bfa-a284dfa20c70


★ Insight ─────────────────────────────────────

1. shouldUseWorktree() 的 capability 匹配策略是核心設計決策
任務 spec 建議 CODE_CAPABILITIES = ['code', 'architecture', 'refactoring'],但 reviewer 有 architecture capability。如果 reviewer 被獨立派工(非 pipeline),會誤建新 worktree。我的報告建議縮小為 ['code', 'refactoring'],讓 programmer(code)和 architect(refactoring)匹配,reviewer 只能繼承。

2. mcp-code-agent.json 路徑不需要改
mcp-code-agent.jsondata/agent-workspace/ 下(不在 git 追蹤中),且其內容使用相對路徑 ./node_modules/.bin/cclsp。因為 worktree 中 node_modules/ 是 symlink,保持 mcpConfig 指向 LIGHTWEIGHT_CWD 是最安全的做法。

3. bot-tools-server.ts 的 parent 查找可以復用
dispatch_task handler 已有 parentTaskId 查找 parent 的邏輯(572-593 行),worktree 繼承可以直接在這個區塊中加入,避免重複 I/O。

─────────────────────────────────────────────────

調查完成

報告已寫入 soul/agent-reports/programmer/phase2-worktree-investigation.md

關鍵發現摘要

項目 結論
可行性 完全可行,3 個檔案、~40 行改動
shouldUseWorktree capabilities 建議用 ['code', 'refactoring'](不含 architecture),避免 reviewer 誤建 worktree
mcp-code-agent.json 不需要改,保持指向 LIGHTWEIGHT_CWD
tests/unit/agent-config.test.ts 不需要改(現有測試不涉及 AgentTask)
bot-tools-server.ts 需要在 task type 中加入欄位 + 在 if (parentTaskId) 區塊加入繼承邏輯
向後相容 所有新欄位都是 optional,queue.json 和 history.jsonl 自然相容

主要風險

  1. reviewer architecture capability 問題 — 需要在 shouldUseWorktree() 中精確處理
  2. cclsp MCP 在 worktree 中的行為 — 非致命,但值得測試
  3. Phase 2 不清理 worktree — 靠 TTL 自動清理,需確認 cleanupOrphanWorktrees 有被定期呼叫

由於我是 observer 模式,不執行代碼修改。如需執行實際改動,請以 executor 角色重新派工給 programmer。

完成摘要

Agent: secretary (secretary)
Confidence: 76%
Cost: $0.3073
Duration: 2m 20s
Task ID: e722f13f-db61-4c0d-9628-984de5a10e3d


流水線收尾完成。

完成摘要

項目 結果
Type check tsgo --noEmit 通過
測試 90 個測試檔案,1108 個測試全數通過
Commit 0087dd5fix(agents): resolve WorktreeInfo taskId/shortId semantic confusion
Push 已推送至 main
變更檔案 src/agents/worktree-manager.ts(新建,651 行)、tests/unit/worktree-manager.test.ts(新建)

★ Insight ─────────────────────────────────────
流水線收尾的關鍵紀律:pre-push hook 自動跑了完整測試套件(1108 tests),確保不會把壞掉的 code 推上 remote。這個 programmer → reviewer → secretary 的三段式 pipeline 讓每個角色專注自己的職責——programmer 寫、reviewer 審、secretary 確認編譯+測試後 commit/push。注意新建的 worktree-manager.test.ts 的 16 個測試也在完整測試回合中通過了。
─────────────────────────────────────────────────

reviewer — 2026-02-26

Agent: reviewer (reviewer)
Confidence: 27%
Cost: $0.3210
Duration: 1m 27s
Task ID: 96f39577-071c-437a-a0bc-fdf8e663e40f


驗收完成,結果摘要:

全部通過 (7/7),已交付 secretary (task e722f13f) 進行 commit。

關鍵修正點:

  1. WorktreeInfo 新增 shortId 欄位,語義分離清楚
  2. listActiveWorktrees() 誠實回傳 taskId: ''(無法還原完整 UUID),shortId 正確填入
  3. cleanupOrphanWorktrees() 改用 wt.shortId(修復了原本會用空字串去刪除的 bug)
  4. 測試覆蓋完整,16 tests 全過

—HANDOFF—
TO: secretary
INTENT: handoff
ARTIFACT_TYPE: review
SUMMARY: WorktreeInfo taskId/shortId 語義修正驗收全數通過,交付 commit

完成狀態

Agent: programmer (programmer)
Confidence: 44%
Cost: $0.8678
Duration: 3m 17s
Task ID: 6f7ce403-b2f3-4792-b177-c6ad3e28a0c4


任務完成。以下是最終摘要:

完成狀態

驗收項目 狀態
WorktreeInfoshortId 欄位
createTaskWorktree 回傳正確的 taskId + shortId
listActiveWorktrees 回傳 taskId: '' + 正確 shortId
getWorktreeForTask 回傳正確的 taskId + shortId
cleanupOrphanWorktrees 使用 wt.shortId
tsgo --noEmit 通過
16 tests passed
dispatch 給 reviewer ✅ (96f39577)

—HANDOFF—
TO: reviewer
INTENT: handoff
ARTIFACT_TYPE: code-change
SUMMARY: WorktreeInfo 新增 shortId 欄位,修正 listActiveWorktrees 的 taskId/shortId 語義混淆