撰寫任務
將 docs/specs/<slug>/_prd.md(以及當存在時的 _techspec.md)轉換為可執行的任務圖:每個任務一個 task_NN.md 加上 _tasks.md,這是 implement-task 和 Roundfix Daemon 排程所依據的清單。這些產物是合約——一個全新的代理工作階段必須能夠拿起一個任務檔案,並僅透過規格資料夾中的內容來建構它,無需其他上下文。
輕量層級規劃
一個 complexity: low 且非 QA 且未宣告任何受管理路徑的任務會在輕量層級上執行。作者可以在規劃 Pull Request 合併之前執行 roundfix spec judge <slug> --stage tasks 來獲得建議性的層級建議;該建議不會控制調度。
前提條件
$ARGUMENTS 指定了規格名稱。_prd.md 必須存在。如果一個具有實際架構表面(architectural surface)的功能缺少 _techspec.md,請先執行 write-techspec 然後再進行分解——撰寫遺失的產物是解決方案,絕不是停下來請求許可的理由。在自主工作下,這不需要確認:根據 docs/agents/autonomous-work.md,指導自主工作即授權對已核准佇列中每個規格的整個撰寫鏈。僅當明確被告知要在沒有技術規格的情況下進行分解時,才需要請求接受,然後在分解前透過更深入的程式碼庫探索來補償。
專案約束預檢
在推導或核准細分之前執行此預檢:
- 分類規格。位於已歸檔目錄下的規格(對於內建
docs/specs根目錄為docs/history/specs/,或對於外部或非預設根目錄為<spec-root>/_archived/),或已被證明在此合約適用之前已完成的規格,是已完成或已歸檔的舊版規格。保持每個舊版產物的位元組完全一致:不要回溯填充、重新格式化、重新產生或以其他方式重寫它。 - 對於每個活躍、未歸檔且尚未完成的規格,要求 PRD 和每個現有的 TechSpec 都包含完整的「專案約束」章節。每個章節必須記錄「識別碼策略」、「認證和 HTTP」、「活躍 ADR 義務」以及「工具權威」,視情況標記為適用或不適用並附上理由,且每一行必須引用其適用的
docs/agents/來源路徑。 - 如果任何一個活躍產物遺失或不完整,拒絕建立或更新
_tasks.md或任何任務檔案。指出每個遺失的列、理由或來源路徑,並將規格送回其擁有的撰寫技能。 - 檢查提議的切片中是否有任何建立、編輯、重新命名、移動或刪除儲存庫工具組態、腳本、忽略檔案、外掛宣告或版本固定的行為。僅當 PRD 和現有的 TechSpec 記錄了明確的維護者授權以及其所涵蓋的、與儲存庫相關的確切檔案邊界時,此類工作才被授權。一個泛型的實作請求、設定核准或任務指派並非授權。在同時缺少授權和邊界檔案的情況下,拒絕分解。
- 針對每個工具切片,解析位於
<spec-root>/<slug>/_authorization.md的操作記錄。一個缺失的記錄、一個「已提議」的記錄或一個沒有授權日期的記錄不授權任何事項;在存在可操作的授權之前,拒絕分解。一個新的或擴大的授權必須在消費性的 squash 交付之前落地到目標祖先分支,因此該授權或修正案不能摺疊到它所授權的變更中。 - 將邊界檔案清單複製到每個授權的工具任務的範圍和接受標準中。該任務只能變更那些路徑加上其自身的任務檔案;將任何需要不同邊界的工作拆分開來。
- 記錄的
operations清單必須授予規格將使用的每個交付操作。roundfix deliver start拒絕一個缺少implement、commit、push、pull_request或merge的記錄;一個沒有受管理路徑的規格記錄paths: []。 - 一個任務提交僅當其確切路徑列在規格授權記錄的 executables 下時,才保留一個未追蹤的可執行檔案;所有其他未追蹤的可執行檔案都會被拒絕。該清單必須在 Run 讀取它之前就在交付目標上。QA 報告和批次提交永遠不會保留未追蹤的可執行檔案。一個
core.fileMode設定為 false 的儲存庫會將該檔案記錄為 100644。
依賴關係僅由 _tasks.md 擁有;任務狀態僅由每個任務檔案擁有。預檢永遠不會轉移這兩個責任。
其他作業系統的程式碼需透過為該系統建構其非測試程式碼來驗證,例如 GOOS=windows go build -buildvcs=false ./<package>,並且永遠不要使用 go vet,因為它也會編譯為主機撰寫的測試。
所有權規則(什麼東西放在哪裡,以及為什麼)
- 依賴關係僅存在於
_tasks.md圖中。 永遠不要放在任務檔案中。邊界的兩個副本正是圖表產生偏差的原因。 - 狀態僅存在於每個任務檔案的 frontmatter 中。
_tasks.md擁有拓撲,而非進度——排程器會重新讀取任務檔案以取得狀態。 - 任務類型在每個任務檔案中都是必填的。 使用
backend、frontend、data、infra、docs、test、chore或qa中的一個。保留qa給由清單的qa:欄位命名的、唯一的撰寫終端閘道。實作命令會消費此值以進行路由,並拒絕缺失或未知的值;永遠不要留下佔位符或稍後推斷類型。 - 內容引用,絕不重複。 任務檔案透過名稱指向 PRD/TechSpec 章節;一個複述規格的任務在規格第一次被修訂時就會過時。在其採用後路徑(相對於該任務檔案的目的地)連結擁有該規格中已採用的來源,永遠不要在其採用前來源路徑上連結。一個次要規格連結主要擁有者的副本,且不採用任何內容。擁有者的歸檔會執行歸檔重新連結:它將該副本提升到
docs/references/並重寫次要規格的連結,如此一來來源保持一個擁有者,且次要規格不需要副本(ADR-0260, ADR-0083)。 - 上下文條目是標記的路徑。 僅當任務需要標準規格套件之外的特定指令或介面路徑時,才新增
## Context。使用形如- instruction: <path>、- interface: <path>、- creates: <path>或- deletes: <path>的項目符號。路徑必須是乾淨的、相對於儲存庫的且唯一的;一個任務最多可以宣告 50 個唯一條目。Daemon 會在填入 200 路徑的規格上下文套件(包含先前變更的檔案)之前保留這些路徑。 - 宣告的編輯和受管理路徑是明確的。 任務編輯的每個路徑都在
interface:或creates:下宣告;它移除的每個路徑僅在deletes:下宣告,從不在interface:也從不在instruction:下。一個在移除前讀取檔案的任務仍只列出該路徑一次,在deletes:下。刪除會被未解析引用檢查跳過,並計入範圍、受管理路徑和 Wave 衝突審計中。當一個宣告的刪除仍然存在時,Daemon 會在驗證之前拒絕結算,並顯示deletes: <path> still exists。一個instruction:路徑是唯讀的,且永遠不會導致兩個任務衝突。每個變更命令的任務會宣告它變更的一個命令檔案:.agents/skills/roundfix/references/<command>.md及其鏡像,以及docs/user-guide/commands/<command>.md,絕不觸及技能的SKILL.md或commands.md,除非它變更了入口檔案本身。兩個宣告相同檔案的任務不能共享一個 Wave,因此變更不同命令的任務可以一起執行,而變更相同命令的任務之間需要一條邊。 宣告的或驗證讀取的受管理路徑必須出現在規格的_authorization.mdpaths:以及「邊界檔案:」列中,否則撰寫將被拒絕並顯示SC-TOOLING-UNDECLARED。一個命名 CLI 表面的任務會透過自身或其所依賴的任務來命名其技能或指南;否則會回報SC-CLI-UNDOCUMENTED。
Daemon 會在提交時,在 ## Recorded paths 下記錄一個任務未經宣告而變更的路徑。QA 範圍審計會將該記錄的路徑視為已宣告,且記錄會揭露一個變更但不會保留任何內容。宣告每個可預見的路徑仍然是規則。
一個可能被兩個任務各自變更的測試輔助程式、假物件、測試固定或金鑰檔案是一個可預見的路徑。在每個可能變更它的任務中的 interface: 下宣告它,這樣當規格仍在撰寫中時,roundfix spec check --strict 會報告 SC-WAVE-COLLISION,而它所命名的 needs 邊會使這些任務序列化執行。記錄不會保留任何內容,且一個已完成的任務永遠不會衝突:一個任務的結算提交僅在兩個任務之一尚未完成時才是衝突證據,例如一個重新開啟為 pending 的任務,因此一個 Wave 中兩個任務在變更相同未宣告檔案後都完成的情況永遠不會被拒絕。宣告該檔案是唯一的防護措施。
針對變更行為表面的技能任務
當技能覆蓋地圖存在時,讀取位於 docs/references/skill-coverage.json 的儲存庫技能覆蓋地圖。對於每個被非 QA 任務在 interface:、creates: 或 deletes: 下宣告其來源的受覆蓋行為表面,包含一個非 QA 的技能任務,該任務在 interface: 或 creates: 下宣告其一個覆蓋技能檔案。SC-SKILLS-UNTASKED 會報告一個沒有此類任務的表面。
當變更不需要技能文字時,在 PRD 可選的 ## Skills 章節中記錄 - unchanged: <surface id> — <reason>,並包含一個在 interface: 或 creates: 下宣告該地圖的非 QA 任務,以記錄覆蓋審查。僅有條目並不能免除該表面。SC-SKILLS-MALFORMED 會報告其他形狀的條目、未知的表面或空白的理由。這兩個規則從新增地圖的提交開始生效;沒有地圖的儲存庫會跳過它們。
一個在 interface:、creates: 或 deletes: 下宣告 docs/user-guide/ 下 Markdown 頁面的非 QA 任務,也必須在 interface: 或 creates: 下宣告 docs/references/behavior-surfaces.json,並在需求中命名 -record-skill-coverage 步驟。另一個任務不能涵蓋它:指南任務自身的結算會檢查其指紋。規格的 _authorization.md 的 Limits 永遠不能禁止該記錄。SC-SURFACE-RECORD-UNTASKED 會從任務階段報告任一差距(無期限),在擁有該記錄的儲存庫中。
分解規則
其他作業系統的程式碼需透過為該系統建構其非測試程式碼來驗證,例如 GOOS=windows go build -buildvcs=false ./<package>,並且永遠不要使用 go vet,因為它也會編譯為主機撰寫的測試。
-
垂直切片。 每個任務都交付一條狹窄但完整的路徑,貫穿它所觸及的每一層,可獨立展示或驗證——這是一個追蹤子彈(tracer bullet),而非一個層級(「所有的 schema」是一個錯誤的任務;「過期的導入會重試並顯示其狀態」才是一個正確的任務)。
-
先進行預重構。 當一個切片需要鋪墊基礎時,將其本身作為一個領先的任務:先讓變更變得容易,然後再進行簡單的變更。
-
在撰寫期間表徵外部表面。 當一個規格跨越一個外部表面(例如轉接器、合約或資料庫)時,撰寫一個表徵任務,記錄真實邊界的作用,而不是假的的作用,這樣一個不受支援的前提會在規格仍在撰寫時失敗,而不是在 QA 閘道處失敗。
將其列在
needs中,而不僅僅是在檔案中較早出現。 每個前提依賴於該表徵的任務都會在_tasks.md的needs條目中命名該任務。執行 wave 僅由needs建構,因此一個僅在清單中較晚出現的任務可能與它所依賴的表徵在同一個 wave 中執行,並讀取一個尚未被任何人表徵的邊界。檔案順序不是依賴關係。一個表徵任務會觸及真實的邊界,因此要明確地約束它。 它的檔案會說明它將要達到的目標,透過名稱。它讀取多於寫入,或針對任務本身建立和移除的隔離實例執行;它預設不會針對共享或生產狀態進行表徵。它使用範圍限定於該目標且不超過範圍的憑證,尊重取消操作,並且即使失敗也會清理它所建立的內容。一個必須寫入的表徵需要該寫入操作如同任何其他不可逆操作一樣在任務中獲得授權——記錄邊界的作用並不等於擁有改變它的權限。
其驗證斷言的是記錄,而非邊界。 Daemon 會逐字地透過 shell 執行任務宣告的
## Verification命令,一次是在 Agent 回合存在之前針對未變更的樹執行,另一次是在結算時。該路徑中的任何內容都不會讀取上述的約束:它們約束的是 Agent,而 Daemon 不是 Agent。因此,一個觸及真實表面的驗證會無限制地觸及它兩次,包括在任何工作完成之前。驗證任務記錄的表徵——其形狀、其存在、下游任務將讀取的內容——並將邊界呼叫保留在 Agent 回合中,在那裡任務宣告的目標、隔離、憑證和寫入授權才適用。這是這些命令已經攜帶的封閉性規則,在此處說明是為了對抗打破它的最大誘惑:一個即時的外部表面是環境狀態,而依賴於它的命令不是封閉的。 -
適合一個全新工作階段的規模。 一個代理可以在一個連續的工作階段中,以全新的上下文完成的任務。超過約 7 個子任務或檔案就表示應該拆分。
-
測試內嵌,永不分割。 每個任務的接受標準都包含其自身的測試;一個結尾的「撰寫測試」任務意味著先前的任務從未完成。
-
可獨立實作。 一旦其
needs完成,一個任務必須不需要任何其他未完成的工作——這正是允許稍後跨工作樹進行平行執行的原因。 -
驗證必須是封閉的、可攜的、能證明效果的,且由 Daemon 擁有。 每個任務的
## Verification命令必須能夠在一個全新的工作樹中使用僅來自儲存庫本身的資源來滿足,不依賴於提示歷史、環境狀態或任何其他任務的輸出。它們必須證明任務產生了其宣告的效果,並且對目標系統來說是可攜的。Daemon 擁有這些命令的執行;任務永遠不會執行自身的驗證。