Merge pull request 'feat/analyze-delivery-priority/main' (#82) from feat/analyze-delivery-priority/main into master
Reviewed-on: #82 Reviewed-by: 系統管理員 <1+admin@noreply.localhost>
This commit was merged in pull request #82.
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* /sdlc-analyze 的流程正本。
|
||||
*
|
||||
* 這些測試鎖定交付文件確認與排程前置條件;漏掉其中任一個閘門,
|
||||
* agent 就可能在使用者尚未確認時建立工作包或排程。
|
||||
*/
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import {
|
||||
assertNeutralPrompt,
|
||||
assertPromptListsSections,
|
||||
readPrompt,
|
||||
} from './helpers/prompt-doc.js';
|
||||
|
||||
const prompt = readPrompt('sdlc-analyze');
|
||||
const delivery = prompt.slice(prompt.indexOf('### 交付文件判斷'), prompt.indexOf('## 第二段'));
|
||||
const packages = prompt.slice(prompt.indexOf('## 第二段'), prompt.indexOf('## 第三段'));
|
||||
const schedule = prompt.slice(prompt.indexOf('## 第三段'), prompt.indexOf('## 邊界'));
|
||||
const boundary = prompt.slice(prompt.indexOf('## 邊界'));
|
||||
const TYPES = [
|
||||
'需求描述概要',
|
||||
'WBS(工作分解結構)',
|
||||
'流程圖',
|
||||
'甘特圖',
|
||||
'PERT 圖',
|
||||
'關鍵路徑圖',
|
||||
'API 契約文件',
|
||||
];
|
||||
|
||||
// ── 交付文件確認 ────────────────────────────────────────────────
|
||||
|
||||
test('正本讀取七種交付文件規則,且依規則順序逐項確認', () => {
|
||||
assert.match(delivery, /references\/delivery-types\.md/);
|
||||
assertPromptListsSections(delivery, TYPES);
|
||||
assert.match(delivery, /依序逐一詢問/);
|
||||
assert.match(delivery, /不得把七種文件合併成一次確認/);
|
||||
});
|
||||
|
||||
test('每種文件確認都保留必要內容、產出位置與 ELI5 規則', () => {
|
||||
assert.match(delivery, /必要內容骨架/);
|
||||
assert.match(delivery, /產出位置/);
|
||||
assert.match(delivery, /ELI5 變體規則/);
|
||||
});
|
||||
|
||||
test('交付文件未確認或遭拒時,所有後續副作用都被阻擋', () => {
|
||||
assert.match(delivery, /未確認或拒絕任何一項時,立即停止/);
|
||||
assert.match(delivery, /不建立工作包、不排程、不建立相依/);
|
||||
assert.match(delivery, /不寫入 Milestone、看板或其他後續資料/);
|
||||
});
|
||||
|
||||
// ── PERT 與工作包優先 ────────────────────────────────────────────
|
||||
|
||||
test('PERT 的 O、M、P 分別逐題確認,且不能用單一人天替代', () => {
|
||||
const pert = prompt.slice(prompt.indexOf('### PERT 三點估算'), prompt.indexOf('## 第二段'));
|
||||
assert.match(pert, /樂觀時間(O)/);
|
||||
assert.match(pert, /最可能時間(M)/);
|
||||
assert.match(pert, /悲觀時間(P)/);
|
||||
assert.match(pert, /分別逐題詢問/);
|
||||
assert.match(pert, /不得用單一人天估算代替/);
|
||||
assert.match(pert, /三個值都確認後才納入排程資料/);
|
||||
});
|
||||
|
||||
test('交付文件工作包優先,但以先決關係的拓撲順序為準', () => {
|
||||
assert.match(packages, /先放已確認的交付文件工作包,再放純程式碼工作包/);
|
||||
assert.match(packages, /不違反先決關係/);
|
||||
assert.match(packages, /拓撲順序/);
|
||||
});
|
||||
|
||||
test('每個工作包只承擔一種交付並保留驗收所需欄位', () => {
|
||||
assert.match(packages, /每顆工作包只做一種交付/);
|
||||
assert.match(packages, /文件類型、必要內容、產出位置與驗收方式/);
|
||||
assert.match(packages, /對應已確認交付項目的待辦置於第一項/);
|
||||
});
|
||||
|
||||
// ── 建立與排程邊界 ────────────────────────────────────────────────
|
||||
test('重跑需求會以既有議題與標題查重,不建立重複工作包', () => {
|
||||
assert.match(packages, /重跑同一需求時,先以既有議題與標題查重/);
|
||||
assert.match(packages, /不建立重複工作包/);
|
||||
});
|
||||
|
||||
test('工作包建立與排程仍要求 dry-run,且排程在相依確認後', () => {
|
||||
assert.match(packages, /issue-create\.js --dry-run/);
|
||||
assert.match(schedule, /所有工作包建立且相依關係確認後/);
|
||||
assert.match(schedule, /schedule\.js/);
|
||||
assert.match(schedule, /各腳本先 dry-run,再實跑/);
|
||||
});
|
||||
|
||||
test('共識、交付確認與 PERT 完成前不建立任何後續資料', () => {
|
||||
assert.match(boundary, /共識摘要、交付文件確認與 PERT 三點估算完成前/);
|
||||
assert.match(boundary, /不建立任何工作包、不排程、不寫入後續資料/);
|
||||
});
|
||||
|
||||
test('API 契約不寫入目標專案,且流程維持終端摘要與平台中立', () => {
|
||||
assert.match(delivery, /API 契約文件只能交付預覽或使用者確認的位置/);
|
||||
assert.match(delivery, /禁止寫入目標專案 repo/);
|
||||
assert.match(prompt, /摘要只印終端,不寫入 Gitea/);
|
||||
assert.match(boundary, /不把 API 契約文件寫入目標專案 repo/);
|
||||
assertNeutralPrompt(prompt, 'sdlc-analyze');
|
||||
});
|
||||
Reference in New Issue
Block a user