跨塔台與跨專案協作
一句話:塔台之間不共享對話,只共享檔案;所以 CT 用約定好的檔案(登記簿、留言板、統籌與受派工單、交辦稿)協調多個塔台,而且接收方只讀不寫對方的 repo,跨 session 訊息只當通知,正式紀錄永遠是檔案。
一個塔台還是多個
先決定要不要開第二座塔台:
| 條件 | 建議 |
|---|---|
| 子專案共用資料庫、共用 API、經常同步改動 | 一個塔台 |
| 子專案獨立部署、獨立資料庫、很少同時改動 | 各開一個塔台 |
子專案是跟團隊共用的獨立 repo(各有自己的 .git),隊友不用 CT | 一個塔台,工單集中在上層(見下方巢狀的獨立 repo);隊友也用 CT、或要用 worktree 隔離改子 repo,就各開一個塔台 |
| 不確定 | 先用一個,太雜再拆 |
| Feature 和 Hotfix 在不同分支 | 各開一個塔台,加上 worktree 隔離 |
原則是:協調成本低於 context 成本時才拆。一座塔台管太多子專案,它的 context 會被不相干的狀態塞滿;拆太細,就要花力氣在塔台之間傳話。
巢狀的獨立 repo:一個塔台管多個共用 repo
上層目錄底下有好幾個各自獨立的 git repo(各有自己的 .git 和 remote,通常跟團隊共用),你想用一個塔台管全部工單,又不想把執行紀錄寫進共用的 repo。v5.14.3 起 CT 寫明這種配置(下稱方案 1)。這是寫法,不是新規則:落點檢查、commit 規則和派工命令都沒變,CT 5.14.2 起就能這樣用。
工單常被寫進各子 repo、BAT 面板看不到,原因不是落點檢查要求這樣放,而是 Worker 在子 repo 執行:Worker 在自己 cwd 底下找工單,repo 又是 cwd 所在 repo 的目錄名。反過來讓 Worker 在上層執行,落點檢查一樣會過。
- 上層
git init:上層不是 git repo 時,落點檢查 C-0、C-1、C-3 全部跳過,等於沒有保護。上層的.gitignore逐一排除子 repo,BAT workspace 指向上層。 - 工單集中在上層
_ct-workorders/:repo填上層的目錄名,project填要改的子 repo,affects_files從上層寫起。面板看得到全部工單,編號連續。 - 子 repo 用
git -Ccommit,路徑要去掉子 repo 前綴:affects_files寫src/app-frontend/src/login.ts,commit 時是git -C src/app-frontend commit --only src/login.ts;工單本身在上層 commit。這些都要寫進工單步驟,包括先讀子 repo 的AGENTS.md/CLAUDE.md、先確認子 repo 身分。 - 限制:不能用 worktree 隔離(worktree 裡沒有被上層排除的子 repo);C-0 只證明 Worker 站在上層,不證明子 repo 是對的 clone。新目錄第一次派工時,Claude Code 會先問要不要信任這個資料夾,Worker 等你在分頁回答才開始,不必重派。
隊友也用 CT、需要 worktree 隔離改子 repo,或各 repo 很少同時改時,改用方案 2:每個 repo 各開一個 workspace 和塔台,跨 repo 的需求走下面的協調類型。方案 1 在拋棄式目錄用 CT 5.14.2 搭配 BAT 實機驗證過;面板一鍵派工、子 repo 有 remote 時的 push 還沒有實機驗證。
同一個專案的多個塔台
同一個專案開了兩座塔台(例如一座做 feature、一座處理 hotfix),記憶分成三層:
| 層級 | 內容 | 機制 |
|---|---|---|
| 共享層 | 工單檔、sprint-status.yaml、決策日誌、專案上下文 | 磁碟檔案,天然共享 |
| 協調層 | 塔台登記簿、跨塔台留言板 | 約定好的檔案,啟動時掃描 |
| 隔離層 | 對話內容、當下的推理、個人進度快照 | context window 天然隔離 |
塔台登記簿(_ct-workorders/_tower-registry.md)記下每座塔台的 ID、啟動時間、負責範圍、分支、最後心跳與鎖定的工單。規則有四條:啟動時寫入;每次派工或處理工單時更新心跳;超過兩小時沒有心跳就視為離線,它鎖定的工單可以被接管;不同塔台不可鎖定同一張工單。
跨塔台留言板(_ct-workorders/_cross-tower-notes.md)讓一座塔台把會影響另一座的事寫下來,例如「hotfix 改了連線池設定,若 Story 1.3 涉及這部分,feature 分支要 merge main」。塔台在啟動時、每次派新工單前、你說「sync」時檢查留言板。
五種協調類型
跨專案(各自有自己的 _ct-workorders/)的協調有五種類型,前三種是工單,後兩種不是:
| 類型 | 工單? | 說明 |
|---|---|---|
| LOCAL | 是 | 預設,單專案工單,不寫協調區段 |
| COORDINATED | 是 | 統籌工單,追蹤跨專案的整體進度,由主專案建立 |
| DELEGATE | 是 | 受派工單,接收專案依統籌工單或交辦稿的子任務建立 |
| HANDOVER | 否 | 受理前的發現加提案:我查到這些、我猜你們該這樣改,修法由對方決定 |
| ADVISORY | 否 | 純意見,明確不期待對方動作 |
原本只有前三種,後來補上兩種,是因為實際協作中遇到三個缺口:
- 沒有「受理前提案」的形狀。統籌工單假設發起方已經知道各專案該做什麼,但常見情況是發起方沒有權限、也沒有資訊替對方定義子任務。這就是 HANDOVER。
- 沒有「只是諮詢」的通道。為一個可選的強化意見開受派工單,等於把意見說成派工,逼對方替沒有承諾的事背一個狀態。這就是 ADVISORY。
- 沒有「更正來源前提」的位置。受派工單的回報區是完工用的,不是動工前反駁前提用的。
HANDOVER 和 ADVISORY 不進工單編號序列、不計入熱區統計、*sync 也不掃描它們。發起方把 _handover-<日期>-<主題>.md 寫在自己的 _ct-workorders/,接收方把 _reply-<日期>-<主題>.md 寫在自己的 _ct-workorders/;底線前綴讓它們落在工單序列之外。HANDOVER 的終點是 ACKNOWLEDGED 或 DECLINED,不是 DONE;被受理時,接收方建立一張 DELEGATE 工單並指回這份交辦稿。
回覆稿允許並鼓勵「更正來源前提」。理由是:接受錯誤的根因描述,就會做出錯誤的修法。實際發生過的例子是,來源塔台診斷「某個派工旗標不存在」,查證後發現旗標早就存在,真正的問題是一行派工指令的摘要看起來像完整的旗標清單。照原診斷去修只會補一個旗標,下一個被省略的旗標會原樣重演。異議段落要寫來源前提的原文、查證結果與證據、修正後的根因,以及對修法的影響。異議不是拒絕受理,兩者可以同時成立。
接收方只讀不寫來源專案的檔案。所有修改都只發生在自己專案的 _ct-workorders/,回覆稿寫在自己的 repo,由你轉交。
工單前綴與統籌權
跨專案時,工單編號要全局唯一。在專案設定裡設 project-prefix(例如 LC),塔台之後派工一律自動加前綴,產生 LC-T0001 這樣的 ID;全局層的專案索引會記下每個專案的前綴與工單目錄。跨塔台交辦也有既有的前綴慣例(例如 CP-)。前綴的合法格式只在工單 ID 的權威定義裡寫一次,見 工單系統;即使沒設 project-prefix,專案裡也可能出現帶前綴的工單。
跨專案協調的流程是:統籌塔台建立 COORDINATED 工單、列出各專案子任務;你到接收專案的塔台告知來源工單;接收塔台唯讀讀取來源工單後建立 DELEGATE 工單;Worker 執行;你回統籌塔台回報,統籌塔台讀取對方工單確認;全部子任務完成後統籌工單才 DONE。
統籌權不固定:誰先碰到需求、或誰受影響最大,誰就統籌;共用程式庫本身不設工單目錄,由受影響最大的服務代理統籌。原統籌專案發現別人更適合時,可以轉移統籌權:新統籌專案建立新的統籌工單並引用原工單,原工單改為受派工單。
跨 session 選收件人
Claude Code 塔台可以用跨 session 訊息(ListAgents 列出 session、SendMessage 送訊息)把交辦或回覆通知另一個專案的塔台。問題在於選對收件人:未命名的 session 在清單上只是「工作目錄名加兩個字元」,分不出塔台和 Worker,曾經就把完成回覆送給了對方的 Worker。
BAT >= 0.7.1-pre.1 開的 claude 分頁會帶名稱:<工作區> · Worker · <T####> 是 Worker,<工作區> · Tower 是以塔台方式開啟的分頁。選收件人依序:
- ListAgents 有
<目標工作區> · Tower就送它;同名多列附上該列的 ref。 - 自己在 BAT 裡、而且已宣告為塔台時,查 BAT 的塔台清單(
bat_list_terminals,scope: towers),找目標工作區的塔台、取它的 session 名稱,到 ListAgents 找完全相同的名稱再送。 - 都找不到(對方是 Codex 塔台、在另一台機器、非 BAT 等)就照原本的方式:回覆稿寫在自己的 repo,請你轉交。
名稱含 · Worker · 的 session 一律不是塔台,即使它是清單上唯一一個。也不得只靠目錄名、短 ID 或閒置/忙碌狀態推定收件人。訊息第一行要請收件人先確認自己是目標工作區的塔台,因為名稱只代表分頁的開啟方式。最重要的是:跨 session 訊息只是通知管道,正式紀錄仍是檔案,先把交辦稿或回覆稿寫好,訊息裡附路徑與摘要。Codex 塔台沒有這兩個工具,一律由你轉交。
跨專案契約變更
兩個專案都要改同一件事(例如訊息格式的一個欄位改名)時,最常見的錯誤是「一個做完,另一個照抄」。兩邊引用的不是同一份規格,而是對方的實作;AI 每次開新 session 的理解可能有細微差異,結果一邊叫 eventTime、另一邊叫 EventTimestamp。
做法是契約驅動,三步走:
- 先寫契約文件,明確列出「必須一致」的項目(欄位名、型別、序列化後的 key)和「允許不同」的項目(各自的函式庫用法、handler 實作、錯誤處理)。
- 兩邊各自引用契約、獨立實作,派給兩邊的工單都指向契約,而不是指向對方的程式碼。
- 最後派一張一致性驗證工單:確認舊名在兩邊都已清除、欄位型別一致、序列化結果一致。
塔台沒有主動分出「一致與不同」時,請它把清單寫進契約。一句話:先寫契約,各自實作,最後驗證,不要抄。
命令範例
本頁的檔名、欄位與選收件人步驟都是摘要,完整參數以 reference 為準。
延伸閱讀
control-tower/references/multi-tower-protocol.md§ 記憶分層、§ 塔台登記簿、§ 跨塔台留言板、§ 決策:一個塔台還是多個、§ 跨塔台 GP 編號協議control-tower/references/mono-repo-patterns.md§ 巢狀的獨立 repo(一個塔台、多個共用 repo)(v5.14.3+)control-tower/references/cross-project-coordination.md§ 五種協調類型、§ HANDOVER 與 ADVISORY(非工單跨塔台通道)、§ 跨 session 選收件人(v5.9.0+)、§ 工單前綴機制、§ 跨專案協調流程、§ 統籌權規則control-tower-guide/references/advanced-patterns.md§ 跨專案協調、§ 多塔台、§ 巢狀的獨立 repo:一個塔台管多個共用 repo(v5.14.3)docs/Control Tower 實戰補充/CT實戰補充(一-C)跨專案契約變更.md
摘要不具權威
Portal 是摘要,不具權威,與 reference 有出入時以 reference 為準。