跳至主要内容

文件解析遷移:規格類

狀態:P2-2 設計已通過審閱(20261016-docs-resolve-p2-2,第 2 輪,受審 revision r2-5e84d64ae316bd91;3 條意見均處置);P2-2 實作已通過審閱(20261016-docs-resolve-p2-2-impl,第 3 輪,受審 revision r3-68c366ec3bd9f80d;6 條意見均處置),實作中確認的修訂見 §9 依據:ADR-023 的 D4 與實作分期 P2;文件解析與索引規格(P2-1,已實作);追蹤項目 FU-142 本頁定義:規格類 8 個 skill(/roadmap、/feature-list、/epic、/us、/sbe、/checklist、/assess、/analyze)改用 docs.py resolve/register 時,各類型的範本欄位、工具的兩項補充,以及 skill 的改寫契約。

1. 範圍​

做不做
為 roadmap、feature-list、analysis-report、epic、us、sbe、checklist 加上 template/locate/params/key/example其他類型(P2-3~P2-5)
從 checklist 拆出 assess-summary(§2.2)_category_.json、epics/README.md 等目錄頁的範本(屬內容,§4.5)
resolve --list(§3.1);audit 新增 DR-DUPLICATE-KEY(§3.2)create 動詞(ADR D4 已修訂為不設)
8 個 skill 改用 resolve 取得路徑,建立或搬移頁面後執行 register改寫各 skill 的文件內容、提問流程與品質規則
下游導入的盤點與指引(§5)直接修改下游專案(各下游在 publish 後自行處理)

2. 類型欄位​

2.1 範本​

{D} 代表 {docsRoot}/docs/specs。slug 一律為 ^[a-z0-9]+(-[a-z0-9]+)*$(kebab-case)。

類型template(同時為唯一的 locate)paramskeyexample
roadmap{D}/roadmap.md———
feature-list{D}/feature-list.md———
analysis-report{D}/analysis-report.md———
epic{D}/epics/epic-{epic}-{slug}.mdepic ^[0-9]+$epic2/order-lifecycle
us{D}/user-stories/epic-{epic}/US-{us}-{slug}.mdepic ^[0-9]+$、us ^[0-9]{3,4}$us2/201/create-order
sbe{D}/sbe/epic-{epic}/US-{us}-{slug}/scenario-{scenario}-{scenarioSlug}.mdepic、us 同上;scenario ^[0-9]+[a-z]?$;scenarioSlug kebab-caseus、scenario2/201/create-order/1/happy-path
checklist{D}/checklists/US-{us}-checklist.mdus 同上us201
assess-summary(新){D}/checklists/{target}-assess-summary.mdtarget ^[A-Za-z0-9]+(-[A-Za-z0-9]+)*$targetUS-201
  • us 允許 4 位數,涵蓋 Epic 編號 ≥ 10 時的 US 編號;US 與 Epic 編號的對應規則仍由 /us 決定,resolve 只以 us 判定同一份文件,epic 是屬性。
  • sbe 的 scenario 允許字母後綴(實際存在 scenario-4b-…)。同一 US 的同一場景編號只能有一個檔案。
  • 單一文件(roadmap 等)的 key 為空:resolve 回傳該檔或新路徑。
  • 目前沒有任何類型需要舊佈局的 locate;fleet 的非方法論佈局以專案層類型處理(§5)。

2.2 從 checklist 拆出 assess-summary​

現行 checklist 類型同時涵蓋 *-checklist.md 與 *-assess-summary.md。兩者識別不同:檢核報告以 US 編號識別,Persona 評估摘要以評估標的識別(/assess 的 {doc-id}:US-001、epic-2、roadmap、feature-list、domain-model、domain-model-epic-2,以及既有的 api-specs-epic1 等)。一個類型只能有一個 template,因此拆成兩個類型:

類型paths產出者
checklist{D}/checklists/*-checklist.md/checklist
assess-summary{D}/checklists/*-assess-summary.md/assess

其他特性(persistent、page、downstream)與現行 checklist 相同。checklists/ 下其他命名的檔案(例如 US-101-checklist-v3.md、US-101-team-discussion-input.md)不屬這兩個類型,維持現狀(DR-UNREGISTERED)。

2.3 以 fleet 實際檔案驗證​

以上欄位已用 P2-1 的 resolve.Locator 對 fleet 9 個 workspace 的全部檔案驗證(R12 全部通過):

workspace可解析無法解析(RS-UNPARSED)重複 key
參考實作us 60、sbe 592、epic 7、checklist 56、assess-summary 63、三個單一文件00
florae-g1與參考實作相同規模00
almanac-g1、tps-g1、tms全部00
crm-v2、tts-v1只有 roadmap 或尚無規格00
nbsos—us 45(user-stories/{模組}/US-01 名稱.md)0
ictus 25、sbe 42 等us 19(user-stories/office/{分類}/US-01 名稱.md)sbe 2 組(同一 US 有兩個 scenario-3)

3. 工具補充​

3.1 docs.py resolve --list​

/epic 與 /us 以「現有最大編號 + 1」產生新編號(/us --epic=N 只看該 Epic)。resolve 只回答單一文件,因此新增列舉模式:

docs.py resolve --workspace {ws} --type {typeId} --list [--param name=value ...]
  • 列出該類型所有可解析的既有文件:items: [{path, params, legacy}],依路徑排序;給定的參數作為篩選條件(例如 --param epic=3),不要求 key。
  • 與單筆查詢相同的前置檢查與 fail-closed:類型無範本 RS-NO-TEMPLATE、參數錯誤 RS-PARAM/RS-UNSAFE、有無法解析的檔案 RS-UNPARSED。重複 key 不拒絕,items 照列,並在 duplicates 列出(由呼叫端決定)。
  • 唯讀,writes: 0。

3.2 audit:DR-DUPLICATE-KEY​

有 key 的類型中,兩個以上檔案的 key 相同時回報(warning,可豁免),列出這些檔案。resolve 遇到時回 RS-AMBIGUOUS;audit 讓下游在 skill 改用 resolve 前先看到並改號(ict 的兩組重複場景即屬此類)。

4. skill 改寫契約​

4.1 只對已遷移類型呼叫 resolve​

skill 只對 §2.1 已加範本的類型呼叫 resolve;其他類型(BR、Domain Model、API Spec、Test Plan、Sprint 等)沿用現行的位置規則,直到所屬批次遷移(P2-3~P2-5)。因此 RS-NO-TEMPLATE 不應在正常流程出現;出現時代表 skill 對未遷移類型呼叫了 resolve,屬 skill 錯誤,停止回報。

使用者直接給檔案路徑時(/checklist path/…、/assess {路徑} 等),照現行直接讀取,不經 resolve 改寫路徑。需要判斷該檔類型時(例如決定評估摘要的 {doc-id}、是否連動 SBE),以 docs.py classify 判定,不從路徑字樣推斷。

4.2 讀取來源與建立成果分開​

resolve 回答的是「這份文件在哪裡、若是新的該放哪裡」;查無時要做什麼由 skill 的用途決定,維持現行流程,不因改用 resolve 而改變(R1-01):

用途exists: trueexists: false
讀取來源(上游文件、評估或分析的對象)讀取回傳的 path照該 skill、該模式現行的查無處置(報錯並列出可用文件、警告後略過、結束、產生建議項),不把回傳的新路徑當成要建立的文件;處置見 §4.7
建立或更新成果(該 skill 產出的文件)更新回傳的 path;有 conflicts 時列出差異,以既有文件為準,不建立同編號的新文件有 path:建立該檔;missing 非空:依現行流程向使用者補問缺少的參數後再查一次

兩種用途共通的例外處置:

resolve 結果處置
RS-AMBIGUOUS列出候選,以 AskUserQuestion 讓使用者選擇(沿用現行「多筆命中由使用者選擇」);不猜
RS-UNPARSED停止,列出無法解析的檔案,提示先依 docs.py audit 的 DR-UNPARSED-LOCATION 處理(改名或專案層設定,§5);不改用寫死的路徑繞過
RS-PARAM、RS-UNSAFE、RS-KEY停止並回報參數問題
RS-NO-TEMPLATE見上:skill 錯誤,停止回報

4.3 新編號​

/epic 以 resolve --type epic --list 取現有 epic 最大值 + 1;/us --epic=N 以 resolve --type us --list --param epic=N 取 us 最大值 + 1。編號規則(Epic 與 US 的對應)不變,只改取得現有編號的方式。

4.4 文件間的連結​

Epic 的 US 清單、US 的 SBE 清單、Sprint 的連結、SBE 回到 US 的連結與 depends_on,一律由 resolve 回傳的路徑計算:Markdown 連結取兩檔的相對路徑;depends_on 取相對於 {docsRoot}/docs/ 的路徑(m-depends-on.md)。不手寫 ../user-stories/epic-{N}/… 這類路徑。

4.5 目錄頁與分類設定​

epics/README.md、user-stories/README.md 與 SBE 的 _category_.json 是內容(P2-1 §4.5、§5.1),照常由 skill 撰寫;位置由已解析文件的目錄推導,不另寫死:

檔案位置
epics/README.mdepic 文件所在目錄的 README.md
SBE 的 Epic 層 _category_.json場景檔上兩層目錄
SBE 的 US 層 _category_.json場景檔所在目錄

4.6 站台索引​

建立、刪除或搬移頁面後(只改內容、不影響路徑時不需要):

  1. 審閱預覽在跑時,等它重新載入(register --check 不再回 RG-ROUTES,最多等候一個合理時間),再執行 docs.py register。
  2. 仍為 RG-ROUTES(預覽未在跑、尚未重載,或改了設定需要重啟)時,不阻擋文件產出:在 skill 的結果報告列出「llms.txt 尚未同步」與重試指令(npm run build:docs-only 或重啟預覽後執行 docs.py register)。
  3. 完成條件:docs.py register --check exit 0。之後任何改寫後的 skill 建立頁面時都會再嘗試一次。
  4. docs.py audit 的提示依路由紀錄是否可信而不同(R1-03):紀錄可信時回報 DR-INDEX-STALE(warning),紀錄不可信時只回報 DR-INDEX-UNVERIFIED(info),不判定是否同步。兩者都代表上述完成條件尚未達成。

4.7 各 skill 的改動與查無處置​

「查無時」一欄是現行行為,改寫後保持不變(R1-01)。

skill/模式讀取來源(查無時)建立或更新成果連結與索引
/roadmaproadmap(不存在即新建流程)、epic --listroadmap.md、feature-list.md(新建時)epics/README.md 依 §4.5;register
/feature-list(A/B/C 路徑)roadmap、epics/README.mdfeature-list.md—
/feature-list --syncfeature-list(不存在:輸出「無 feature-list.md,無需 sync」並結束);us --list 取代 Glob只改「相關 US」欄—
/epicepic --param epic=N(不存在:搜尋 epics/README.md 與 roadmap.md,照現行)新 Epic 以 --list 取號後 resolve 取路徑epics/README.md 列;depends_on;register
/usus --param us=NNN(不存在:到 Epic 文檔找條目;再找不到則報錯並列出可用 Epic,照現行);指定 Epic 以 epic 查(不存在:報錯,照現行);feature-list(不存在:略過 features)US 路徑由 resolve 取得;--epic=N 以 --list --param epic=N 取號Epic 的 US 清單、Sprint 連結(Sprint 不存在則略過,照現行)、depends_on 依 §4.4;register
/sbeus(不存在:列出可用 US 供選擇,照現行);sbe --list --param us=NNN 取既有場景場景路徑由 resolve --type sbe 取得_category_.json(不存在才建立,照現行)依 §4.5;US 的 SBE 清單、depends_on;register
/checklistus(不存在:列出可用 US,照現行);epic(不存在:警告,略過上游對齊檢核項,照現行);roadmap(選用)checklist --param us=NNN(已存在:詢問覆寫或取消,照現行)報告中的連結依 §4.4;register
/assess依輸入:US、epic-{N}、roadmap、feature-list 以 resolve;BR、Domain Model 照現行偵測;SBE、API Spec、Test Plan 與其他直接路徑照現行直接讀取(§4.1)。找不到:報錯並列出可用文件(照現行)有 C/D 項時 assess-summary --param target={doc-id}(照現行覆寫);version 推進與 SBE 連動不變register(只在新建摘要時)
/analyze(全專案)roadmap、feature-list(不存在:產生 LOW 建議,照現行);epic/us/sbe --listanalysis-reportregister(新建時)
/analyze epic-N、/analyze US-NNN(局部)epic、us(不存在:報錯並列出可用項,照現行);--list 篩選該範圍不存檔,只輸出 console(照現行);不呼叫 resolve --type analysis-report—

各 skill 只改「取得路徑」與「索引」兩件事;文件結構、提問、檢核、輸出方式與 version 規則不變。

5. 下游導入​

P2 全部通過後一次 /methodology publish;各下游套用 /docs-site 後,在使用改寫後的 skill 前:

  1. 執行 docs.py audit,處理 DR-UNPARSED-LOCATION 與 DR-DUPLICATE-KEY。

  2. 非方法論的 US 佈局(nbsos 45 份、ict 19 份:以模組目錄分組、編號兩位數且跨模組重複、檔名含中文與空白)不是 us 類型的舊佈局,而是另一種文件。由該專案在專案層新增類型,以較高的 priority 把它們從 us 分出,例如:

    {"id": "module-user-story", "title": "模組需求說明", "category": "spec", "role": "document",
    "paths": ["{docsRoot}/docs/specs/user-stories/**/US-* *.md"], "priority": 5,
    "lifecycle": "persistent", "writer": {"mode": "open"}, "presentation": "page",
    "base": "other", "purpose": "專案既有的模組需求說明,非方法論 US"}

    樣式以「檔名含空白」區分(方法論 US 的檔名不含空白)。這類文件不加範本,/us 不處理它們。

  3. 重複的場景編號(ict 的 US-001、US-002 各有兩個 scenario-3)由專案改號後,/sbe 才能操作這兩個 US。

  4. FU-142 的發布檢查清單記錄以上三點與各下游的實際數量。

6. 測試​

類別測試
範本七個類型與 assess-summary 的 R12 通過;以參考實作的實際檔案執行 resolve(每類至少一個既有文件與一個新路徑)
--list列出全部、以參數篩選、RS-UNPARSED 時拒絕、重複 key 列在 duplicates
DR-DUPLICATE-KEY回報、豁免;無重複時不回報
類型拆分*-checklist.md 歸 checklist、*-assess-summary.md 歸 assess-summary;其他命名不歸兩者
skill以參考實作走查:/us 給不同 slug 時回到既有文件、/epic 取號、/sbe 的 _category_.json 位置、register 在預覽重載後更新索引;RS-UNPARSED 時停止(以隔離副本放入非方法論 US 重現)
查無處置(§4.2、§4.7)逐列核對改寫前後一致:/checklist 缺 Epic 時警告並略過上游對齊項、/feature-list --sync 缺清單時結束、局部 /analyze 只輸出 console 且不呼叫 analysis-report、/us 查無時改查 Epic 條目;讀取來源查無時不建立檔案
直接路徑(§4.1)/assess 以 SBE、API Spec、Test Plan 與其他路徑直接評估仍可運作,且不呼叫 resolve;類型以 classify 判定
索引重試(§4.6)預覽未重載時文件照常產出、報告列出「llms.txt 尚未同步」與重試指令;重試後 register --check exit 0;紀錄不可信時 audit 只出現 DR-INDEX-UNVERIFIED
fleet§2.3 的驗證腳本納入證據,送審時重跑

7. 會修改的檔案​

檔案變更
/docs-site 的 docs-registry.json七個類型的範本欄位;新增 assess-summary、checklist 的 paths 縮小
/docs-site 的 resolve.py、docs.py、測試--list;DR-DUPLICATE-KEY
8 個 skill 的 SKILL.md§4.7
m-features-link.md、m-depends-on.md以 resolve 取代 Glob 的描述(行為不變)
/docs-site SKILL.md、m-docs-site.md--list、DR-DUPLICATE-KEY
參考實作 app-docs投影更新
FU-142下游導入檢查清單(§5)

8. 待決與審閱重點​

待決:

  1. 非方法論 US 佈局以下游專案層類型處理(§5 第 2 點),或由共用 registry 提供一個通用類型。本設計採前者:這類佈局各專案不同,共用層不宜猜。
  2. assess-summary 的 target 採寬鬆的 kebab 樣式(涵蓋既有的 api-specs-epic1 等);或收斂為 /assess 目前的 {doc-id} 格式,舊檔改名。
  3. 重複 key 在 --list 中只列出、不拒絕,讓 /epic、/us 取號時不因其他文件的資料問題而停止;單筆查詢仍以 RS-AMBIGUOUS 拒絕。

請特別看:

  1. §4.2 與 §4.7 是否完整保留各 skill、各模式現行的查無處置與輸出方式(特別是 /checklist 缺 Epic、/feature-list --sync、局部 /analyze、/assess 的直接路徑)。
  2. §4.6 不讓 RG-ROUTES 阻擋文件產出,以及重試時機與完成條件。
  3. 拆分 checklist 對既有專案層豁免或其他引用的影響(目前 fleet 無專案層引用 checklist)。

9. 實作修訂​

項目原設計修訂理由
共用契約的落點(§4、§7)§4 的契約寫在規格頁,§7 未列共用檔案新增 /docs-site 的 references/doc-locations.md,8 個 skill 以 {docsPy} 變數連到它並先 Read;規格 §4 是它的來源m-docs-site.md 只在編輯 docs-site 相關檔案時載入,/us 等 skill 執行時讀不到;同一份契約不在 8 個 skill 重複(m-skill-format)
/roadmap 在尚無 Epic 時定位 epics/README.md(§4.5)「epic 文件所在目錄」已有 Epic 時取其目錄;尚無 Epic 時,以 Roadmap 中第一個 Epic 的編號與暫定 slug 呼叫 resolve --type epic 取回傳路徑的目錄,只用來定位,不建立該 Epic 檔Roadmap 建立 README 時往往還沒有任何 Epic 文件
/analyze 指定 US 時的 Epic 編號原流程以 US 編號的「首位數字」推導取自 resolve --type us 回傳的 params.epic位置已由 resolve 取得;首位數字在 Epic 編號 ≥ 10 時會算錯(fleet 已有 epic-11)
/sbe、/analyze 的場景數計算場景目錄中的 .md 檔數以 resolve --type sbe --list --param us={NNN} 的 items 數量計算目錄中的 README.md 等目錄頁不是場景
直接路徑的 metadata(§4.1,實作審閱 R1-01)「需要類型時以 classify 判定」docs.py classify 對已加範本的類型一併回傳以 locate 擷取的 params(無法擷取時為 null);直接給路徑時該檔即操作對象,US 編號、Epic、slug 取自這些 params,上游以之 resolve;params 為 null 時向使用者確認,不另查同編號文件只有類型不足以取得 /checklist、/sbe 後續需要的編號與上游
既有 US 的 Epic(§4.7,實作審閱 R1-02)未明訂/us 找到既有 US 時,{epicNumber} 一律採用回傳的 params.epic;只有查無文件的新建流程才從編號推導既有 US 可能不在編號推導的 Epic 目錄下,後續 Feature 對應與 Epic 回寫會落到錯誤 Epic
以名稱指稱的文件與目錄檢查(§4,實作審閱 R1-03)未明訂共用契約補充:skill 文字中提到的 roadmap.md、feature-list.md、Epic/US 檔等已遷移文件一律指 resolve 回傳的那份,存在與否以 exists/items 判定;「類型目錄」= 既有文件所在目錄,尚無文件時為新路徑的目錄。/epic、/us、/sbe、/checklist、/analyze 的目錄存在檢查與結構比對改用 --list;/us、/sbe 不再要求 US、SBE 目錄事先存在(新路徑由 resolve 產生,Write 建立目錄)專案層以 legacy/locate 把文件放在舊位置時,固定路徑或目錄會讓 skill 略過來源或誤報缺漏
直接路徑的前置檢查(§4.1,實作審閱 R2-01)未明訂直接給路徑時不執行與該檔無關的全域列舉前置檢查(/sbe、/checklist 的「確認已有 US 文件」)同類型其他無法解析的檔案會讓 --list 回 RS-UNPARSED,擋住使用者指定的操作對象
部分參數與篩選結果的完整性(§4.1、§4.3,實作審閱 R2-02)未明訂舊佈局可能只擷取部分參數(missing 也為空):skill 逐項檢查後續步驟需要的參數,缺少時向使用者確認並保留原路徑。--list 以參數篩選時缺少該參數的文件不會列出:取號後以 resolve 確認新編號未被占用;完整性比對(/analyze 的 Epic → US、指定 Epic 的範圍)改用不篩選的 --list 以 key 對應,缺少歸屬參數的項目另列key 參數一定存在(R12),屬性參數(例如 US 的 epic)不一定;只看 params 是否為 null,或以篩選結果判定缺漏,會讓 Epic 回寫缺依據、誤報缺漏或取到已被占用的編號
skill 版本—8 個 skill 與 /docs-site 各升一個 minor 版本路徑取得方式改變,行為與輸出不變