C4 Plan
人類理解計畫的結構和邊界;AI 在聊天中獲得批准後再執行。此技能不會取代計畫:它產生計畫的視覺層和一個執行摘要。
它也可以記錄現有系統 (kind: system):使用相同的圖表和流程,沒有狀態、步驟或批准。請參閱第 5 節。
聊天是事實來源。 檢視器僅顯示計畫:人類不會在那裡編輯任何內容。疑問和修改請求以註釋(或貼到聊天中)的形式送達,您在聊天中回覆,所有變更都透過 YAML 進行。
您永遠不會手動編寫 HTML 或建構 URL。您編寫一個 YAML;腳本驗證、產生連結並產生摘要。
計畫 ─► arch.yaml ─► encode ─► link ─► 人類檢視並評論 ─► 您調整 YAML ─► 聊天中確認 ─► 摘要 ─► 執行
腳本:python3 <技能目錄>/scripts/arch_url.py(僅 stdlib + PyYAML;jsonschema 可選)。
1. 從計畫產生 arch.yaml
將它儲存在計畫旁邊,命名為 <計畫名稱>.arch.yaml。結構:schema/arch.v1.json。完整範例:examples/pix.arch.yaml。
規則:
- 這是計畫的架構,不是整個系統的。 包含計畫建立、更改或移除的內容,以及理解所需的最小上下文(誰呼叫、誰被呼叫)。不要對整個系統建模。
status:new/changed/removed/unchanged(預設)。上下文元素保持unchanged。- C4 層級:根層級為
person、system、external;system(或根層級)內為container、database、queue;container、database(表格、遷移)或queue(事件)內為component;component內只能有code。 - 計畫建立或更改的所有內容都會展開到程式碼層級。 每個
status為new/changed的system、container、database、queue和component都有children,向下展開到code(validate會在缺少時發出警告)。不變的內容保持折疊:這是上下文。 - 第 4 層 (
code):計畫建立或更改的檔案、類別、模組或函數,並填寫path。已經存在且會更改的檔案為status: changed。列出更改的內容,而不是元件的所有程式碼(每個元件 2 到 4 個通常就夠了)。 - 關係連接最具體的元素(存在時為 code → code)。檢視器會為上層層級彙總。
steps:計畫每個步驟一個,順序和標題相同。touches= 該步驟建立或更改的元素。flows:系統在計畫後如何運作(steps說明建置順序;flows說明執行順序)。1 到 3 個流程:主要路徑和最重要的失敗路徑(例如:「客戶使用 PIX 付款」、「QR Code 過期」)。每個hops[]是{from, to, label},需要遵循現有關係的方向,或相反方向用於回應。使用最具體的元素 (code) 並將label寫成所發生的事情(「在呼叫 PSP 前儲存 txid」),而不是關係名稱。檢視器會自動下降到每個跳躍的層級。constraints:實作必須遵守的事項,例如可驗證的規則(「透過 txid 達到冪等性」、「加法遷移,無表鎖定」),而不是描述。在重要的決策點放置:合約、與外部系統的邊界、安全性、資料、遷移、核心業務邏輯。沒有約束的內容由您在執行時自行決定。- 如果合約存在於儲存庫中,請在
relations[].contract中引用。
2. 驗證並提供連結
python3 scripts/arch_url.py encode <計畫名稱>.arch.yaml
- 錯誤:修正 YAML 並重新執行。未通過驗證前不要提供連結。
- 警告:如果合理就修正(例如:有新內容但未展開到程式碼層級)。
- 在一行中向人類提供連結,並附上一個簡短的摘要,說明計畫更改了什麼(例如:「3 個新元素,2 個已更改」)。告知他們可以按 C(或評論),點擊卡片並提問或要求修改,並且批准是在此聊天中進行。
檢視器:encode 產生指向已發布版本的連結,https://gustavorana25.github.io/c4-model-skill/(靜態;計畫位於 #hash 中,不會到達伺服器)。$C4PLAN_VIEWER_URL 用於切換主機,--local 使用本地建置 viewer/dist/index.html(僅用於測試檢視器本身的變更)。
2b. 如果您有內嵌瀏覽器:監聽頁面
如果您有瀏覽器工具(Claude Code 的瀏覽器面板、Cursor 的瀏覽器、Chrome 中的 Claude),請在那裡開啟連結,而不僅僅是提供連結,並在人類檢視計畫時監聽頁面。
聊天是事實來源。 頁面只是一個快捷方式:人類指出一個或多個卡片並評論,您在聊天中回覆,絕不在頁面上回覆。您唯一在頁面上更改的是計畫,使用 load(),當對話改變結構時。
像這樣開啟 encode 產生的連結:它已經是 https://。(使用 --local 時,透過 http:// 提供 viewer/dist/ 服務,例如:python3 -m http.server;某些內嵌瀏覽器會丟棄 file:// 連結的 #hash。)
頁面暴露 window.c4plan(使用瀏覽器的 JavaScript 工具執行):
| 呼叫 | 作用 |
|---|---|
await c4plan.next(30000) | 等待最多 30 秒的下一個事件。返回事件或 null。最大值為 40 秒(工具會在大約 45 秒時切斷)。 |
await c4plan.state() | 當前狀態:url、plan、focus(開啟的層級)、selected(人類正在查看的內容)、idleMs(人類多久沒有操作頁面)、doc。 |
c4plan.load(urlOuHash) | 在不重新載入頁面的情況下,用新版本替換圖表。 |
c4plan.stop() | 通知頁面您已停止監聽。 |
next() 的事件:
{event:"comment", targets:[{id,name}], view, text}:人類對這些元素發表了評論(可能沒有、一個或多個;view是開啟的層級)。在聊天中回覆,以名稱開頭:「關於 API Pix 和 清算佇列:…」。如果是修改請求,請更改 YAML,執行encode,呼叫load(新連結),並在聊天中說明更改了什麼。然後繼續監聽。{event:"stop", reason:"idle"}:人類 10 分鐘沒有操作頁面,監聽自動結束。說出停止語句(步驟 3)並離開迴圈。
迴圈:
- 在開始之前,在聊天中用一行說明:「我已瀏覽器中打開圖表,並在您操作它時監聽。按 C(或評論),點擊卡片並寫下內容:我在這裡回覆。當一切正常時,請在這裡告訴我您批准。」 如果沒有這個警告,人類會操作頁面,聊天中不會顯示任何內容,他們不知道發生了什麼。
- 重複
await c4plan.next(30000)並處理每個事件。null僅表示「還沒有任何事件」:再次呼叫,不要在聊天中評論。監聽會持續,只要人類與頁面互動(每次點擊、按鍵或滾動都會重置時鐘);結束由頁面決定,使用stop。 - 當
stop到達時停止。在stop時,在聊天中說:「我停止監聽圖表,因為它處於閒置狀態。當您需要時請在聊天中評論,或要求我再次監聽。」 如果您因其他原因需要提前停止,請呼叫c4plan.stop()並說同樣的話。 - 如果您在監聽時人類在聊天中發送訊息,迴圈結束:回覆該訊息。然後讀取
(await c4plan.state()).idleMs:如果小於 10 分鐘,他們仍在頁面上,因此返回迴圈,無需再次警告。如果他們批准,呼叫c4plan.stop()並按照第 3 節進行。 - 如果人類在聊天中詢問關於「這個」或「這個元素」,請讀取
state().selected以了解他們在說什麼。 - 在您沒有監聽的情況下,評論按鈕會複製一段文字,例如「關於圖表中的 "API Pix" (pix-api):…」,讓人類貼到聊天中。括號中的 ID 是 YAML 中的 ID。
3. 當人類在聊天中批准時
只有他們批准,並且只在聊天中(「已批准」、「可以繼續」、「好,執行」)。沉默、監聽結束或沒有評論不等於批准。
- 在
<計畫名稱>.arch.yaml中標記approved: true,並從檔案產生摘要:python3 scripts/arch_url.py brief <計畫名稱>.arch.yaml -o <計畫名稱>.arch.md - 用幾行文字總結由於對話而與第一個連結相比發生了什麼變化(約束、結構、流程)。
- 在計畫中新增對
<計畫名稱>.arch.md的引用,然後繼續執行。
如果人類貼上檢視器的連結(例如,在普通瀏覽器中開啟),它僅供查看:有效版本是您的 <計畫名稱>.arch.yaml。
4. 執行時遵守摘要
<計畫名稱>.arch.md 在執行期間是強制性的:
- 遵循結構(元素、關係、流程)和所有約束。如果實作要求更改結構或違反約束,請停止並詢問。
- 被引用的合約 (
contract) 未經詢問不得更改。 - 在約束之外,選擇最簡單的方法並遵循現有程式碼的模式。
- 人類在聊天中要求的內容優先於您最初的提案。
- 最後,將實作的內容與 YAML 進行比較,並報告差異(未預料的新元件、關係之外的依賴項、已更改的合約)。
5. 記錄現有系統 (kind: system)
當請求是理解或記錄已存在的內容時(「記錄架構」、「這個系統如何運作」、入職),沒有計畫:您閱讀儲存庫並產生相同的 YAML,但使用 kind: system。完整範例:examples/loja.arch.yaml。
version: 1
kind: system
title: 線上商店
description: 關於系統功能的一兩句話。
如何建構:
- 先閱讀再寫。 入口點(路由、處理器、消費者、工作)、清單 (
package.json、docker-compose、基礎設施)、遷移和外部服務的客戶端會告訴您有哪些容器、資料庫、佇列和外部服務。不要發明程式碼中沒有的部分;如果不確定,請在聊天中提出。 - 沒有
status、steps和approved。 一切都是系統當前的樣子(validate會在遺留任何內容時發出警告)。 - 流程是主要的。 2 到 4 個:對業務最重要的路徑、主要的後台任務以及最常見的失敗案例。新進人員透過這些來理解系統。
- 深度: 僅在流程經過的地方下降到
code,並使用真實的path(確認檔案存在)。其餘的保持在container或component層級,並保持折疊。 constraints變成開發者需要知道的規則(冪等性、誰可以寫入哪個表格、不變的合約)。- 關係和流程遵循與計畫相同的規則(第 1 節)。
交付:encode 像計畫一樣產生連結。用一行說明系統包含什麼(「5 個容器、2 個外部服務、2 個流程」),並且可以在「流程」選項卡中追蹤流程並使用 C 提問。如果有瀏覽器,請監聽頁面(第 2b 節):評論是問題,您在聊天中回覆,或是對文件的更正,您將其應用到 YAML 並使用 load() 重新載入。
對於儲存庫中可版本化的文字,brief 會產生 Markdown 格式的文件(元素、關係和流程):
python3 scripts/arch_url.py brief docs/arquitetura.arch.yaml -o docs/arquitetura.md
稍後,針對此系統的計畫可以從此 YAML 開始:複製它,將 kind 更改為 plan,並用 status 標記更改的內容。