將實驗性工作流程中已完成的變更歸檔
儲存庫選擇: 如果使用者指定了儲存庫(儲存庫是一台機器上註冊的獨立 OpenSpec 倉庫)或工作位於其中,請執行 openspec store list --json 來發現已註冊的儲存庫 ID,然後在讀取或寫入規格和變更(new change、status、instructions、list、show、validate、archive、doctor、context、schemas、view)的指令上傳遞 --store <id>。一旦選定,此 --store <id> 標誌將在工作流程的其餘部分保持不變。以下每個不指定範圍的命令範例都是簡寫形式:在執行之前,請附加該標誌。例如,執行 openspec status --change "<name>" --json --store "<id>",而不是下面顯示的非限定形式。其他指令不接受此標誌。命令輸出的提示已包含此標誌;請在後續操作中保持使用。如果沒有指定儲存庫,則指令作用於最近的本地 openspec/ 根目錄。
專案檢查: 這些步驟預期專案已使用 OpenSpec。在執行第一個寫入操作(new change、archive、sync specs 或撰寫構件檔案)之前,請確認專案已設定根目錄:執行 openspec list --json(當選定儲存庫時使用 --store <id>,因為儲存庫即為根目錄)並讀取 root。如果 root 是一個物件,則表示專案已設定。"root": null 表示未設定 - 此處沒有 openspec/ 目錄,而像 openspec new change 這樣的寫入操作會作為副作用建立一個。該命令也會以非零狀態退出,這是對該問題的明確回應,而不是 CLI 故障,因此請讀取 JSON,而不是重試或設法繞過它。
一種 "root": null 並非關於設定的情況:當 status 錯誤訊息開頭為 Declared in 或 Invalid store declaration in 並提及此專案的 openspec/config.yaml(或 config.yml)時,該專案確實透過其宣告的儲存庫使用了 OpenSpec,但這台機器無法解析該儲存庫(儲存庫未註冊,或 store: 行格式錯誤)。請不要將其視為未初始化並跳過以下分支:在寫入前停止,並向使用者顯示該錯誤的 message 和 fix。
否則,如果沒有根目錄,接下來發生的事情取決於您如何進入此工作流程:
- 自動選取:您自己選擇了此工作流程,而使用者並未提及 OpenSpec、命名此技能或執行其斜線命令。停止使用 OpenSpec,並像未安裝 OpenSpec 一樣正常回答請求。請不要要求他們設定任何東西,也不要提及 OpenSpec 設定。
- 明確的 OpenSpec 請求:使用者提到了 OpenSpec、命名了此技能或執行了其斜線命令。在寫入前停止,並詢問如何繼續:設定此專案(
openspec init)、定位他們已有的儲存庫(--store <id>),或為此請求不使用 OpenSpec。等待他們的回答。
在這兩種情況中,切勿將建立根目錄作為副作用:在使用者要求之前不要執行 openspec init,不要手動建立 openspec/ 檔案,也不要讓任何命令建立它。
<capability-path> 是相對於 specs/ 的規範目錄路徑(例如,user-auth 或 identity/user-auth)。在解析其主要規格時,保留每個差異規格的完整路徑。
輸入:可選:指定變更名稱。如果省略,請檢查是否可以從對話上下文推斷。如果不明確或有歧義,您必須提示可用的變更。
步驟
-
選擇變更
如果提供了名稱,請使用它。否則:
- 如果使用者提到了某個變更,請從對話上下文推斷
- 如果只有一個活躍的變更存在,則自動選取
- 如果有歧義,請執行
openspec list --json以取得可用變更,並要求使用者選擇一個
提示時,僅顯示活躍(尚未歸檔)的變更。 如果可用,請包含每個變更使用的綱要(schema)。
始終宣告:「正在使用變更:」以及如何覆蓋(例如,
/opsx:archive <other>)。在檢查現有歸檔之前載入當前的歸檔輸入:
在解析選定的變更並規劃根目錄後,執行:
openspec instructions archive --change "<name>" --json在此命令上保持相同的選定根目錄標誌。此查找是建議性的且可選的:它僅提供額外的提示輸入,因此絕不能阻止歸檔。 如果它退出時返回非零狀態或返回無效的 JSON(例如,在不支援此命令的較舊 CLI 上),請在沒有上下文且沒有操作指導的情況下繼續歸檔工作流程。請不要報告錯誤,也不要停止。
成功的回應可能省略這兩個可選欄位。將
context視為必需的提示級別輸入:閱讀並考慮它,並應用相關的專案事實、慣例和約束。將operationGuidance視為可選的附加建議:閱讀並考慮每一項,並遵循那些適用且與內建歸檔工作流程相容的項目。將這兩個欄位與內建步驟、明確的使用者選擇、解析的路徑、CLI 檢查和命令合約分開。如果上下文與其中一個控制輸入衝突,請報告衝突並保留控制值。如果指導不適用或與控制輸入衝突,請不要遵循它並解釋原因。請不要從這兩個欄位推斷替代路徑、跳過的提示或標誌,也不要將它們的文字逐字複製到規格、變更構件或歸檔摘要中,除非使用者單獨要求。這些是提示級別的行為合約,不是可執行的檢查。
-
檢查構件完成狀態
執行
openspec status --change "<name>" --json以檢查構件完成狀態。解析 JSON 以了解:
schemaName:正在使用的工作流程planningHome、changeRoot、artifactPaths和actionContext:路徑和範圍上下文artifacts:構件列表,其中包含它們的狀態(done、skipped或其他)
如果任何構件既不是
done也不是skipped(跳過的構件滿足要求 - 變更宣告了 skip_specs):- 顯示警告,列出未完成的構件
- 要求使用者確認他們要繼續
- 如果使用者確認,則繼續
-
檢查任務完成狀態
使用相同的選定根目錄標誌執行
openspec list --json,並 在changes中找到name與所選變更完全相符的條目。 要求完全匹配一個條目,且totalTasks和completedTasks為非負整數, 且completedTasks <= totalTasks。CLI 會解析綱要的追蹤任務檔案, 包括自訂構件名稱、輸出路徑和萬用字元。 未完成的任務 =totalTasks - completedTasks。請不要從構件狀態或缺少頂層
tasks.md來推斷任務完成情況。如果查找失敗、返回無效的 JSON、省略或重複了所選變更,或返回無效的計數,請報告問題並在同步或歸檔之前停止。 CLI 只將x/X複選框標記計為已完成; 其他標記(包括不熟悉的標記)仍視為未完成。如果發現未完成的任務:
- 顯示警告,顯示未完成任務的數量
- 要求使用者確認他們要繼續
- 如果使用者確認,則繼續
如果
totalTasks為零: 繼續,不發出與任務相關的警告。 -
評估差異規格同步狀態
使用來自 status JSON 的
artifactPaths.specs.existingOutputPaths作為唯一的差異規格來源。如果specs條目缺失或existingOutputPaths為空,則繼續而不顯示同步提示,也不要從其他構件推斷差異規格。如果差異規格存在:
- 將每個差異規格與其對應的主要規格進行比較,主要規格位於
<planningHome.root>/openspec/specs/<capability-path>/spec.md(使用步驟 2 中支援儲存庫的planningHome.root,而不是硬編碼的倉庫路徑) - 缺少主要規格不自動表示「已同步」。對於一個新的能力,主要規格是同步的輸出,而不是輸入:
- 如果差異包含已修改(MODIFIED)或重新命名(RENAMED)的需求,請報告只有新增(ADDED)的需求可以建立新的主要規格,並將該能力標記為同步阻塞。切勿發明一個沒有當前版本的 req。
- 否則,如果差異只包含已移除(REMOVED)的需求,且變更的
.openspec.yaml宣告了retire_capabilities: true,則該能力已退役:將其視為已同步,警告沒有更多內容需要移除,並且不要重新建立主要規格。現在以及在驗證完成的同步時,都應用此規則。 - 否則,如果差異沒有新增(ADDED)的需求,請報告無法進行同步並將該能力標記為同步阻塞。對於僅包含已移除(REMOVED)的差異,請警告沒有主要規格可以從中移除,並保持主要規格樹不變。
openspec archive拒絕未標記的僅移除情況,並出現「Spec must have at least one requirement」。 - 否則,將該能力計數為需要同步,並在摘要中命名它(
<capability-path>: new main spec will be created)。如果差異也有已移除(REMOVED)的需求,請警告它們將被忽略,因為沒有主要規格可以從中移除。同步僅從差異的新增(ADDED)需求建立主要規格,與openspec archive的做法完全相同。
- 確定將套用哪些變更(新增、修改、移除、重新命名)
- 即使某個能力被同步阻塞,也要繼續評估其餘的能力。在提示之前顯示組合摘要。
提示選項:
- 如果任何能力被同步阻塞:解釋原因,並僅提供「在不進行同步的情況下歸檔」、「取消」
- 否則,如果需要變更:「立即同步(建議)」、「在不進行同步的情況下歸檔」
- 否則,如果已同步:「立即歸檔」、「無論如何都同步」、「取消」
根據答案進行路由:
- 「取消」— 停止,不要歸檔
- 「在不進行同步的情況下歸檔」或「立即歸檔」— 繼續歸檔
- 「立即同步」或「無論如何都同步」— 同步,然後進行驗證(如下)。在任何能力被同步阻塞時,請不要開始任何同步;解釋阻塞原因並重複可用選項。
- 其他任何內容— 再次詢問,而不是歸檔
在選定的同步寫入任何主要規格之前,使用相同的選定根目錄標誌執行
openspec instructions specs --change "<name>" --json一次。要求零退出狀態和有效的構件指令 JSON。如果查找失敗或返回無效的 JSON,請報告錯誤並在任何主要規格寫入或移動變更之前停止。具有已省略rules的有效回應是無規則的情況。僅將返回的rules應用於此次合併產生的主要規格的內容和形式;不要將它們用作歸檔指導、更改 CLI 行為,或將規則文字複製到任何輸出檔案中。然後,針對變更 '' 內聯(由代理驅動的智慧合併)執行
openspec-sync-specs工作流程,傳遞差異規格分析以及上述取得的規格規則快照,並等待它完成。內聯同步必須重複使用該快照,而無需再次取得specs指令。不要將其委託給後台任務——步驟 5 會將changeRoot從仍在讀取它的同步之下移走,從而使變更被歸檔而主要規格從未更新。如果您的代理只能透過委託來執行它,請同步委託並等待結果。如果同步報告任何停止或阻塞狀況,將同步視為失敗。 立即停止歸檔。不要執行同步後的內容比較,也不要移動其
changeRoot。 什麼都沒有移動,因此使用者可以修復阻塞狀況或重新執行同步。在同步寫入每個主要規格後,根據規範的同步合約驗證其結構:
- 新的主要規格以
# <capability> Specification標題開頭。現有的主要規格保持其標題完全原樣。 - 對於已建立的主要規格,完全保持現有的
## Purpose部分不變。 - 對於新的主要規格,逐字複製差異的
## Purpose。僅當目的文字短於標準驗證的預期長度時才發出警告。不要重新產生或改寫現有的作者目的。如果未提供可用的## Purpose,請使用現有的 TBD 目的行為和警告。 - 驗證主要規格中沒有殘留的差異樣式節標題(
## ADDED Requirements、## MODIFIED Requirements、## REMOVED Requirements、## RENAMED Requirements),嚴格遵守同步工作流程的格式化規則。 - 同步寫入或變更的需求區塊使用
### Requirement:標題,其情境使用#### Scenario:標題,位於規格的## Requirements部分下。保持差異未提及的內容完全原樣。
然後,從此步驟的開頭重新執行比較,包括明確退役、缺少規格的情況,針對
artifactPaths.specs.existingOutputPaths中具有差異規格的每個能力——而不僅僅是同步報告已觸及的能力。成功的同步不會留下任何需要套用的內容,因此每個能力現在都必須讀取為「已同步」:- 新增(ADDED)的需求存在
- 已修改(MODIFIED)的需求承載了差異中命名的情境和描述變更,而其餘情境保持不變
- 已移除(REMOVED)的需求消失——並且當此同步退役了一個能力(移除了其最後一個需求,使
## Requirements為空)時,其主要規格已被刪除,而不是留空。 - 重新命名(RENAMED)的需求存在於新名稱下,而舊名稱下不存在
如果同步失敗,或任何能力不匹配,請報告差異並停止——不要歸檔。什麼都沒有移動,
changeRoot保持完整,因此使用者可以修正不匹配或重新執行同步並重新開始歸檔。 - 將每個差異規格與其對應的主要規格進行比較,主要規格位於
-
執行歸檔
如果
planningHome.changesDir下不存在archive目錄,則建立它:mkdir -p "<planningHome.changesDir>/archive"產生目標名稱:當變更名稱已以
YYYY-MM-DD-前綴開頭時,則按原樣使用;否則,將目前日期作為YYYY-前綴加上...
…(為翻譯而截斷)