From ddc72a404e3820aaefcbfcd2fa830f2a4555e99e Mon Sep 17 00:00:00 2001 From: Jeffery Date: Tue, 22 Sep 2026 15:06:25 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat(sdlc-feat):=20=E5=8A=A0=E5=85=A5?= =?UTF-8?q?=E4=BA=A4=E4=BB=98=E6=96=87=E4=BB=B6=E9=A0=90=E8=A6=BD=E5=88=86?= =?UTF-8?q?=E6=B5=81=E8=A6=8F=E5=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 將交付文件待辦與程式碼待辦分流,依環境能力決定直接預覽或逐題詢問,並保留 ELI5 與 API 契約邊界。 --- prompts/sdlc-feat.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/prompts/sdlc-feat.md b/prompts/sdlc-feat.md index 0435757..911d7ac 100644 --- a/prompts/sdlc-feat.md +++ b/prompts/sdlc-feat.md @@ -3,14 +3,35 @@ description: 僅由 /sdlc-feat 指令叫用。領取工作包、開分支、逐 # sdlc-feat -輸入一個工作包議題編號。若抽取結果有 `未處理留言數`,直接走 `/sdlc-sync` 的流程,完成後自動接回這裡;不要要求使用者重打指令。接回前重新抽取一次拿到更新後的描述。 +輸入一個工作包議題編號。先用 `scripts/wp-extract.js` 抽取;若抽取結果有 `未處理留言數`,直接走 `/sdlc-sync` 的流程,完成後自動接回這裡;不要要求使用者重打指令。接回前重新抽取一次拿到更新後的描述。 依工作包 `repos` 逐一準備 worktree;不在主工作區切換分支。逐項完成待辦並立即勾選對應驗收。交付優先項目位於待辦第一項時先完成;仍須遵守工作包的依賴與範圍邊界。 -完成後依既有 commit 分類規則提交,先用 `scripts/pr-create.js --dry-run` 檢查,再實跑開 PR。回報工作包、分支、worktree、完成待辦、commit 與 PR。 +## 交付文件待辦分流 + +先把每一項待辦判定為程式碼待辦或交付文件待辦;兩者不可共用無差別的實作流程。交付文件待辦是需求描述概要、WBS、流程圖、甘特圖、PERT 圖、關鍵路徑圖或 API 契約文件等文件產出,判定依 `references/delivery-types.md` 的內容與產出位置。 + +### 交付前逐一確認 + +每一份交付文件都要分開處理。產出前先列出該類型的必要內容骨架、已知來源、未決事項、建議與理由,再一次只問一題確認內容是否齊全;未確認的文件不可標成已交付。能從需求、工作包、相依或排程重新推導的內容,保留來源與推導規則,不自行編造決策。 + +### 預覽能力分流 + +以能力描述檢查目前環境是否能把該文件即時發佈成可開啟、可分享的預覽頁,並說明判定依據;不要靠固定清單或猜測環境。確認具備能力後直接產出預覽,回報實際位置與內容摘要。無法證明具備能力、預覽不可開啟或不可分享時,停止產出並一次只問一題,由 agent 依文件、來源與限制提出建議及理由,同時保留手動輸入,不替使用者決定交付方式。 + +API 契約文件只能交付在預覽位置或使用者確認的位置;不得寫入目標專案 repo,也不得藉由缺少預覽能力而改寫目標專案的設定檔或文件。預覽失效時回報實際限制,不捏造網址。 + +### ELI5 變體 + +使用者要求 ELI5 時,仍保留原文件的範圍、順序、相依、例外與驗收意義;把術語換成日常說法並補必要的短解釋,不刪除技術限制。圖表要重新繪製成容易閱讀的圖片式視覺,不把 Mermaid 原碼當成交付物,也不只用一個看似精確的日期隱藏 O/M/P 不確定性。 + +## 實作與交付 + +完成程式碼待辦後照既有測試與驗證慣例;文件待辦則依上述分流交付。完成後依既有 commit 分類規則提交,先用 `scripts/pr-create.js --dry-run` 檢查,再實跑開 PR。回報工作包、分支、worktree、完成待辦、commit 與 PR。 ## 邊界 - 不修改工作包範圍外的檔案。 - 不切換主工作區分支。 +- 不產生固定選項清單,不把平台工具名或呼叫語法寫入流程正本。 - 不操作碼錶、不補登工時、不產生耗時統計。 -- 2.53.0 From 0254c3abe1d6ca227d092b4cf7e9eefd60590839 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Tue, 22 Sep 2026 15:06:25 +0800 Subject: [PATCH 2/2] =?UTF-8?q?test(sdlc-feat-assets):=20=E8=A3=9C?= =?UTF-8?q?=E4=B8=8A=E4=BA=A4=E4=BB=98=E6=96=87=E4=BB=B6=E9=A0=90=E8=A6=BD?= =?UTF-8?q?=E6=AD=A3=E6=9C=AC=E6=B8=AC=E8=A9=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 驗證文件待辦分流、預覽能力判斷、逐題詢問、ELI5 與平台中立邊界。 --- test/sdlc-feat-assets.test.js | 70 +++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 test/sdlc-feat-assets.test.js diff --git a/test/sdlc-feat-assets.test.js b/test/sdlc-feat-assets.test.js new file mode 100644 index 0000000..37e3c9a --- /dev/null +++ b/test/sdlc-feat-assets.test.js @@ -0,0 +1,70 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { assertNeutralPrompt, readPrompt } from './helpers/prompt-doc.js'; + +const prompt = readPrompt('sdlc-feat'); +const 分流 = prompt.slice(prompt.indexOf('## 交付文件待辦分流'), prompt.indexOf('## 實作與交付')); + +// ── 正本基本契約 ─────────────────────────────────────────────────── + +test('正本平台中立,description 前綴正確', () => { + assertNeutralPrompt(prompt, 'sdlc-feat'); +}); + +test('輸入先抽取工作包並保留留言接回流程', () => { + assert.match(prompt, /scripts\/wp-extract\.js/); + assert.match(prompt, /未處理留言數/); + assert.match(prompt, /重新抽取一次/); +}); + +test('保留 worktree、依賴、驗收與 PR 的既有交付流程', () => { + assert.match(prompt, /依工作包 `repos` 逐一準備 worktree/); + assert.match(prompt, /立即勾選對應驗收/); + assert.match(prompt, /scripts\/pr-create\.js --dry-run/); +}); + +// ── 交付文件分流 ─────────────────────────────────────────────────── + +test('交付文件待辦與程式碼待辦走不同流程', () => { + assert.match(分流, /判定為程式碼待辦或交付文件待辦/); + assert.match(分流, /不可共用無差別的實作流程/); + assert.match(分流, /references\/delivery-types\.md/); +}); + +test('每份文件產出前逐一列骨架並一次確認一題', () => { + assert.match(分流, /每一份交付文件都要分開處理/); + assert.match(分流, /必要內容骨架、已知來源、未決事項、建議與理由/); + assert.match(分流, /一次只問一題確認內容是否齊全/); + assert.match(分流, /未確認的文件不可標成已交付/); +}); + +test('預覽能力以可開啟可分享能力判斷,具備時直接產出', () => { + assert.match(分流, /即時發佈成可開啟、可分享的預覽頁/); + assert.match(分流, /具備能力後直接產出預覽/); + assert.match(分流, /回報實際位置與內容摘要/); +}); + +test('預覽能力不足時一次一題詢問,建議由情境推導', () => { + assert.match(分流, /無法證明具備能力、預覽不可開啟或不可分享/); + assert.match(分流, /一次只問一題/); + assert.match(分流, /依文件、來源與限制提出建議及理由/); + assert.match(分流, /保留手動輸入/); + assert.match(分流, /不替使用者決定交付方式/); + assert.match(分流, /不要靠固定清單或猜測環境/); + assert.match(prompt, /不產生固定選項清單/); +}); + +// ── ELI5 與契約邊界 ───────────────────────────────────────────────── + +test('ELI5 保留技術意義並把圖表改成圖片式視覺', () => { + assert.match(分流, /保留原文件的範圍、順序、相依、例外與驗收意義/); + assert.match(分流, /不刪除技術限制/); + assert.match(分流, /重新繪製成容易閱讀的圖片式視覺/); + assert.match(分流, /不把 Mermaid 原碼當成交付物/); +}); + +test('API 契約只在預覽或確認位置交付,不寫入目標 repo', () => { + assert.match(分流, /API 契約文件只能交付在預覽位置或使用者確認的位置/); + assert.match(分流, /不得寫入目標專案 repo/); + assert.match(分流, /不捏造網址/); +}); -- 2.53.0