sdd-flow-kit 1.3.5 → 1.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/cli.js +66 -0
- package/dist/core/agentRemediateInvoke.js +188 -0
- package/dist/core/playwrightEnsure.js +142 -0
- package/dist/core/prdCoverage.js +398 -0
- package/dist/core/prdParse.js +88 -0
- package/dist/core/prdRemediate.js +300 -0
- package/dist/core/prdRemediateState.js +135 -0
- package/dist/core/prdSemanticDiff.js +365 -0
- package/dist/core/sessionState.js +2 -0
- package/dist/core/writeNext.js +5 -0
- package/dist/steps/runDeliver.js +13 -0
- package/dist/steps/runGate.js +34 -1
- package/dist/steps/runPhaseAdvance.js +4 -0
- package/dist/steps/runPrdDiff.js +71 -0
- package/dist/steps/runPrdRemediate.js +49 -0
- package/dist/steps/runPrdReview.js +73 -0
- package/dist/steps/runValidate.js +78 -52
- package/dist/steps/startFlow.js +5 -0
- package/package.json +1 -1
- package/src/templates/artifacts/06-agent-skill.template.md +23 -2
- package/src/templates/artifacts/07-opsx-auto-chain.template.md +15 -1
- package/src/templates/artifacts/08-PRD/344/270/200/350/207/264/346/200/247/345/244/215/346/237/245/346/212/245/345/221/212.template.md +93 -0
- package/src/templates/prompts/02-sdd-loop-prompt.md +5 -0
- package/src/templates/prompts/08-prd-consistency-review-prompt.md +49 -0
- package/src/templates/rules/sdd-no-implement-until-apply.mdc.template +6 -2
|
@@ -47,10 +47,16 @@ const projectRoots_1 = require("../core/projectRoots");
|
|
|
47
47
|
const sessionState_1 = require("../core/sessionState");
|
|
48
48
|
const fs_1 = require("../core/fs");
|
|
49
49
|
const openspecGate_1 = require("../core/openspecGate");
|
|
50
|
+
const playwrightEnsure_1 = require("../core/playwrightEnsure");
|
|
51
|
+
const prdCoverage_1 = require("../core/prdCoverage");
|
|
52
|
+
const runPrdReview_1 = require("./runPrdReview");
|
|
53
|
+
const prdRemediate_1 = require("../core/prdRemediate");
|
|
54
|
+
const runPrdDiff_1 = require("./runPrdDiff");
|
|
50
55
|
/** 验收回退最大次数,超过需用户确认 */
|
|
51
56
|
exports.MAX_VALIDATE_RETRIES = 3;
|
|
52
57
|
/**
|
|
53
|
-
*
|
|
58
|
+
* 验收命令:PRD 一致性复查门禁 + lint+type+unit + 强制 E2E(缺 Playwright 则自动安装)。
|
|
59
|
+
* 写入 .validate-pass.json 或 .validate-fail.json。
|
|
54
60
|
* 验收不通过时回退到 apply_in_progress,超过 MAX_VALIDATE_RETRIES 次则需用户确认。
|
|
55
61
|
*/
|
|
56
62
|
async function runValidate(options) {
|
|
@@ -72,7 +78,7 @@ async function runValidate(options) {
|
|
|
72
78
|
}
|
|
73
79
|
const installRoot = (0, projectRoots_1.resolveInstallRoot)(options.projectRoot);
|
|
74
80
|
const pkgRoot = await (0, projectRoots_1.resolvePackageRoot)(installRoot);
|
|
75
|
-
const agent = options.agent || "
|
|
81
|
+
const agent = options.agent || "claude-code";
|
|
76
82
|
if (options.dryRun) {
|
|
77
83
|
return { ok: true, detail: `dry-run: would validate in ${pkgRoot} (installRoot=${installRoot})`, needUserConfirm: false };
|
|
78
84
|
}
|
|
@@ -81,6 +87,65 @@ async function runValidate(options) {
|
|
|
81
87
|
if (!ensured.ready) {
|
|
82
88
|
return { ok: false, detail: "ensure-opsx 未就绪", needUserConfirm: false };
|
|
83
89
|
}
|
|
90
|
+
// ---- 检查0: PRD 一致性复查 + 自动修复循环(最多 3 次)----
|
|
91
|
+
await (0, runPrdReview_1.runPrdReview)({
|
|
92
|
+
projectRoot: options.projectRoot,
|
|
93
|
+
runId: loaded.resolved.runId,
|
|
94
|
+
dryRun: false,
|
|
95
|
+
});
|
|
96
|
+
let needUserConfirmFromRemediate = false;
|
|
97
|
+
const remediateLoop = await (0, prdRemediate_1.runPrdRemediateLoop)({
|
|
98
|
+
projectRoot: pkgRoot,
|
|
99
|
+
outputRoot: loaded.resolved.outputRoot,
|
|
100
|
+
runId: loaded.resolved.runId,
|
|
101
|
+
change: options.change,
|
|
102
|
+
agent,
|
|
103
|
+
dryRun: false,
|
|
104
|
+
maxAttempts: prdRemediate_1.MAX_PRD_FIX_RETRIES,
|
|
105
|
+
runDiff: async () => {
|
|
106
|
+
const diff = await (0, runPrdDiff_1.runPrdDiff)({
|
|
107
|
+
projectRoot: options.projectRoot,
|
|
108
|
+
runId: loaded.resolved.runId,
|
|
109
|
+
dryRun: false,
|
|
110
|
+
});
|
|
111
|
+
return { ok: diff.ok, semantic: diff.semantic };
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
if (remediateLoop.escalated) {
|
|
115
|
+
needUserConfirmFromRemediate = true;
|
|
116
|
+
}
|
|
117
|
+
let prdCoverage = await (0, prdCoverage_1.checkPrdCoverage)(loaded.resolved.outputRoot, pkgRoot);
|
|
118
|
+
if (!prdCoverage.ok) {
|
|
119
|
+
const failed = prdCoverage.checks.filter((c) => !c.ok).map((c) => `${c.name}: ${c.detail}`);
|
|
120
|
+
const payload = {
|
|
121
|
+
change: options.change,
|
|
122
|
+
verdict: "fail",
|
|
123
|
+
prdCoverageFailed: failed,
|
|
124
|
+
remediateAttempts: remediateLoop.attempts,
|
|
125
|
+
remediateEscalated: remediateLoop.escalated,
|
|
126
|
+
at: new Date().toISOString(),
|
|
127
|
+
};
|
|
128
|
+
await (0, fs_1.writeTextFileEnsuredDir)(path_1.default.join(loaded.resolved.outputRoot, ".validate-fail.json"), `${JSON.stringify(payload, null, 2)}\n`);
|
|
129
|
+
if (loaded.session) {
|
|
130
|
+
await (0, sessionState_1.writeSession)(loaded.resolved.outputRoot, {
|
|
131
|
+
...loaded.session,
|
|
132
|
+
prdFixRetryCount: remediateLoop.attempts,
|
|
133
|
+
status: remediateLoop.escalated ? "awaiting_user_confirmation" : "apply_in_progress",
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
ok: false,
|
|
138
|
+
detail: remediateLoop.escalated
|
|
139
|
+
? `${remediateLoop.detail}。请处理 08 待人工确认汇总后重试 validate`
|
|
140
|
+
: `prd-coverage 未通过: ${failed.slice(0, 3).join("; ")}`,
|
|
141
|
+
needUserConfirm: needUserConfirmFromRemediate || remediateLoop.needUserConfirm,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
await (0, prdCoverage_1.writePrdCoveragePassMarker)(loaded.resolved.outputRoot, {
|
|
145
|
+
change: options.change,
|
|
146
|
+
atomCount: (_b = (_a = prdCoverage.checks.find((c) => c.name === "prd-atoms")) === null || _a === void 0 ? void 0 : _a.detail) !== null && _b !== void 0 ? _b : "",
|
|
147
|
+
at: new Date().toISOString(),
|
|
148
|
+
});
|
|
84
149
|
// ---- 检查1: tasks.md 全完成 ----
|
|
85
150
|
const tasks = await (0, openspecGate_1.checkTasksAllDone)(installRoot, options.change);
|
|
86
151
|
// ---- 检查2: delivery-pipeline:short(lint + type check + unit test) ----
|
|
@@ -89,43 +154,13 @@ async function runValidate(options) {
|
|
|
89
154
|
stdio: "inherit",
|
|
90
155
|
shell: process.platform === "win32",
|
|
91
156
|
});
|
|
92
|
-
const shortExitCode = (
|
|
93
|
-
// ---- 检查3:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
if (hasPlaywrightScript) {
|
|
98
|
-
const e2eRet = (0, child_process_1.spawnSync)("pnpm", ["run", "test:e2e"], {
|
|
99
|
-
cwd: pkgRoot,
|
|
100
|
-
stdio: "inherit",
|
|
101
|
-
shell: process.platform === "win32",
|
|
102
|
-
env: { ...process.env, CI: "1" },
|
|
103
|
-
});
|
|
104
|
-
e2eExitCode = (_b = e2eRet.status) !== null && _b !== void 0 ? _b : 1;
|
|
105
|
-
e2eDetail = e2eExitCode === 0 ? "e2e/Playwright 全通过" : `e2e/Playwright 退出码 ${e2eExitCode}`;
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
// 尝试直接用 npx playwright test
|
|
109
|
-
const hasPlaywrightCli = (0, child_process_1.spawnSync)("npx", ["playwright", "--version"], {
|
|
110
|
-
cwd: pkgRoot,
|
|
111
|
-
stdio: "ignore",
|
|
112
|
-
}).status === 0;
|
|
113
|
-
if (hasPlaywrightCli) {
|
|
114
|
-
const e2eRet = (0, child_process_1.spawnSync)("npx", ["playwright", "test"], {
|
|
115
|
-
cwd: pkgRoot,
|
|
116
|
-
stdio: "inherit",
|
|
117
|
-
shell: process.platform === "win32",
|
|
118
|
-
env: { ...process.env, CI: "1" },
|
|
119
|
-
});
|
|
120
|
-
e2eExitCode = (_c = e2eRet.status) !== null && _c !== void 0 ? _c : 1;
|
|
121
|
-
e2eDetail = e2eExitCode === 0 ? "Playwright test 全通过" : `Playwright test 退出码 ${e2eExitCode}`;
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
e2eDetail = "未检测到 Playwright,跳过 e2e(建议配置 test:e2e 脚本)";
|
|
125
|
-
}
|
|
126
|
-
}
|
|
157
|
+
const shortExitCode = (_c = shortRet.status) !== null && _c !== void 0 ? _c : 1;
|
|
158
|
+
// ---- 检查3: 强制 E2E / Playwright(缺则自动安装) ----
|
|
159
|
+
const e2eResult = await (0, playwrightEnsure_1.runMandatoryE2e)(pkgRoot, false);
|
|
160
|
+
const e2eExitCode = e2eResult.exitCode;
|
|
161
|
+
const e2eDetail = e2eResult.detail;
|
|
127
162
|
// ---- 综合判定 ----
|
|
128
|
-
const allPassed = tasks.ok && shortExitCode === 0 &&
|
|
163
|
+
const allPassed = tasks.ok && shortExitCode === 0 && e2eResult.ok;
|
|
129
164
|
const verdict = allPassed ? "pass" : "fail";
|
|
130
165
|
const payload = {
|
|
131
166
|
change: options.change,
|
|
@@ -173,20 +208,11 @@ async function runValidate(options) {
|
|
|
173
208
|
needUserConfirm,
|
|
174
209
|
};
|
|
175
210
|
}
|
|
176
|
-
return {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
try {
|
|
182
|
-
const { readFile: readFileFs } = await Promise.resolve().then(() => __importStar(require("fs/promises")));
|
|
183
|
-
const pkgText = await readFileFs(path_1.default.join(pkgRoot, "package.json"), "utf8");
|
|
184
|
-
const pkg = JSON.parse(pkgText);
|
|
185
|
-
return Boolean((_a = pkg.scripts) === null || _a === void 0 ? void 0 : _a[scriptName]);
|
|
186
|
-
}
|
|
187
|
-
catch {
|
|
188
|
-
return false;
|
|
189
|
-
}
|
|
211
|
+
return {
|
|
212
|
+
ok: true,
|
|
213
|
+
detail: "验收通过(prd-coverage + lint+type+unit + 强制 e2e),可进入交付",
|
|
214
|
+
needUserConfirm: false,
|
|
215
|
+
};
|
|
190
216
|
}
|
|
191
217
|
/** 清理验收标记文件,重新实现后需要重新验收 */
|
|
192
218
|
async function cleanupValidateMarkers(outputRoot) {
|
package/dist/steps/startFlow.js
CHANGED
|
@@ -82,6 +82,11 @@ async function startFlowScaffold(options) {
|
|
|
82
82
|
await (0, fs_1.writeTextFileEnsuredDir)(path_1.default.join(outputRoot, "06-openspec-提案草稿.md"), openspecEntryTemplate);
|
|
83
83
|
const opsxAutoChainTemplate = await (0, templates_1.loadTemplateText)("artifacts/07-opsx-auto-chain.template.md");
|
|
84
84
|
await (0, fs_1.writeTextFileEnsuredDir)(path_1.default.join(outputRoot, "07-opsx-自动串联指引.md"), opsxAutoChainTemplate);
|
|
85
|
+
const prdReviewReportTemplate = await (0, templates_1.loadTemplateText)("artifacts/08-PRD一致性复查报告.template.md");
|
|
86
|
+
await (0, fs_1.writeTextFileEnsuredDir)(path_1.default.join(outputRoot, "08-PRD一致性复查报告.md"), prdReviewReportTemplate
|
|
87
|
+
.replace("{{ATOM_COUNT}}", "0")
|
|
88
|
+
.replace("{{REVIEW_TABLE_ROWS}}", "| (运行 prd-review 后生成) | | | | |")
|
|
89
|
+
.replace("{{GENERATED_AT}}", new Date().toISOString()));
|
|
85
90
|
const session = (0, sessionState_1.defaultSession)({
|
|
86
91
|
product: options.product,
|
|
87
92
|
version: options.version,
|
package/package.json
CHANGED
|
@@ -41,12 +41,33 @@ npx sdd-flow-kit run --product {{DEFAULT_PRODUCT}} --version <版本号> -y --ag
|
|
|
41
41
|
3. propose 后 **必须** `gate ac-ready`(P0 映射到 spec/tasks)才能 `phase impl`。
|
|
42
42
|
4. **仅当** `gate --expect impl-allowed` 通过后,才允许按 `tasks.md` 改业务代码。
|
|
43
43
|
5. **Apply 前必读**:`source/PRD.md` 对应章节 + `05-验收清单.md`(tasks 是子集,不能替代 PRD)。
|
|
44
|
-
6. **deliver 前必须** `gate
|
|
44
|
+
6. **deliver 前必须** `prd-diff` + `gate prd-coverage`(脚本 PRD 语义 diff + 08 复查)+ `gate ac-signed`。
|
|
45
45
|
7. 提案/实现 **必须** 读并执行:
|
|
46
46
|
- `.cursor/skills/opsx-superpowers-workflow/SKILL.md`
|
|
47
47
|
- `openspec-propose` → `openspec-apply-change` → `pnpm run opsx:delivery-pipeline -- <change>`
|
|
48
48
|
8. TDD/Playwright 遵循 `LAYERED-TESTING.md`(L2 交互契约、L3 每页 E2E)。
|
|
49
49
|
|
|
50
|
+
## 严格 SOP 模式(用户声明后强制生效,不可替代)
|
|
51
|
+
|
|
52
|
+
当用户明确声明「执行模式:严格SOP,不可替代」时,以下规则优先于默认自动串联:
|
|
53
|
+
|
|
54
|
+
1. 必须严格按仓库已安装的 `sdd-flow-kit` 流程执行,禁止“等价方式”替代。
|
|
55
|
+
2. Step1 必须执行用户指定的文档获取流程(Confluence/脚本链路);除非用户明确说“允许替代”,否则禁止用本地文件手动回填代替。
|
|
56
|
+
3. 阶段 B 产出的 `04-技术文档草稿.md` 必须是可执行技术方案,禁止模板占位;且需逐条引用 `05-验收清单.md` 的 AC-ID。
|
|
57
|
+
4. 阶段 C 必须执行 `/opsx-propose`(输入 **05 + 04 + 02 + UI**),禁止用 `npx sdd-flow-kit propose` 代替提案生成。
|
|
58
|
+
5. 每完成一个阶段,必须先输出:`门禁结果 + 证据文件路径 + 下一步命令`,等待用户确认后再继续。
|
|
59
|
+
6. 任一步骤不满足 SOP,必须立即停止并先询问用户,不得自行继续。
|
|
60
|
+
7. 禁止将“门禁通过”视为“流程正确”;必须同时满足:命令正确 + 产物正确 + 顺序正确。
|
|
61
|
+
8. 若需要替代方案,必须先提出并等待用户确认。
|
|
62
|
+
|
|
63
|
+
### 严格 SOP 的固定预执行动作
|
|
64
|
+
|
|
65
|
+
进入每个阶段前,先输出:
|
|
66
|
+
|
|
67
|
+
`本次计划命令清单(逐条)`
|
|
68
|
+
|
|
69
|
+
并等待用户确认后再执行命令。
|
|
70
|
+
|
|
50
71
|
## 阶段摘要
|
|
51
72
|
|
|
52
73
|
| 阶段 | 动作 |
|
|
@@ -56,7 +77,7 @@ npx sdd-flow-kit run --product {{DEFAULT_PRODUCT}} --version <版本号> -y --ag
|
|
|
56
77
|
| B | 用户确认后 **05→04→01/02** → `gate docs-closed` → `phase docs-done` |
|
|
57
78
|
| C | `propose` + artifacts → `gate propose-ready` + **`gate ac-ready`** → `phase propose-done` |
|
|
58
79
|
| D | `phase impl` → `gate impl-allowed` → `/opsx-apply`(读 PRD+05) |
|
|
59
|
-
| E | `
|
|
80
|
+
| E | `prd-review` → AI 填 08 → `prd-diff` → `gate prd-coverage` → `validate`(强制 E2E)→ **05 签收** → `deliver` |
|
|
60
81
|
|
|
61
82
|
## 环境
|
|
62
83
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **不要**在阶段 B 结束后停下来问用户「是否继续」或「是否 apply」。
|
|
4
4
|
> 除非用户明确说「只提案」「先别写代码」,或 `.session-state.json` 中 `autoChainOpsx: false`。
|
|
5
|
+
> 若用户声明「执行模式:严格SOP,不可替代」,则本文件的“自动串联”必须降级为“分阶段确认执行”:每阶段先输出`本次计划命令清单(逐条)`并等待用户确认。
|
|
5
6
|
|
|
6
7
|
## 输入(本 runId)
|
|
7
8
|
|
|
@@ -32,21 +33,34 @@
|
|
|
32
33
|
```
|
|
33
34
|
5. 更新 `06-openspec-提案草稿.md` 与 `.session-state.json`:`status: propose_done`
|
|
34
35
|
6. **禁止**在本阶段写 `src/` 或跑 delivery-pipeline
|
|
36
|
+
7. 阶段完成后先输出:`门禁结果 + 证据文件路径 + 下一步命令`;严格SOP模式下等待用户确认再进入阶段 D。
|
|
35
37
|
|
|
36
38
|
## 阶段 D — `/opsx-apply`(ac-ready 后**立即**执行,无需再等用户)
|
|
37
39
|
|
|
40
|
+
> 严格SOP模式下,本阶段不允许“立即执行”,必须先获得用户确认。
|
|
41
|
+
|
|
38
42
|
1. `npx sdd-flow-kit ensure-opsx --agent cursor -y`(仓库根)
|
|
39
43
|
2. 写 `.opsx-active-change` = change 名
|
|
40
44
|
3. **Apply 前必读**:`source/PRD.md` 对应章节 + `05-验收清单.md`
|
|
41
45
|
4. 读并执行:`openspec-apply-change` → `tdd-script`(分层测试策略)→ `openspec-superpowers-pipeline` → `opsx-dev-delivery-pipeline`
|
|
42
46
|
5. Red 断言须写死 PRD/05 原文(toast、tooltip、列序等)
|
|
43
47
|
6. `pnpm run opsx:delivery-pipeline -- <change-name>` 直至 **exit 0**
|
|
44
|
-
|
|
48
|
+
|
|
49
|
+
## 阶段 E — PRD 一致性复查 + 脚本语义 diff + 强制验收(交付前)
|
|
50
|
+
|
|
51
|
+
1. `npx sdd-flow-kit prd-review --project-root <repo> --run-id <runId>`
|
|
52
|
+
2. AI 执行 `08-PRD一致性复查提示词.md`:**最细粒度**逐条对比 PRD 原子 × 代码,禁止揣摩/兜底
|
|
53
|
+
3. `npx sdd-flow-kit prd-diff --project-root <repo> --run-id <runId>`(脚本 PRD×代码字面量 diff → `09-PRD语义diff报告.md`)
|
|
54
|
+
4. 若 diff 失败:`prd-remediate --change <name>` 或 `validate` 内置循环(按 09 调 `/opsx-apply` 修,**每项最多 3 次**、每轮只修剩余失败项,重试附带上次错误代码摘要;仍失败 → 08 待人工确认)
|
|
55
|
+
5. `npx sdd-flow-kit gate --project-root <repo> --run-id <runId> --expect prd-coverage`
|
|
45
56
|
|
|
46
57
|
## 完成判定
|
|
47
58
|
|
|
48
59
|
- [ ] `gate ac-ready` 通过(P0 已映射)
|
|
49
60
|
- [ ] `openspec/changes/<name>/` 下 applyRequires 全部 done
|
|
50
61
|
- [ ] `tasks.md` 全部 `- [x]` 且含 `[AC-XX]`
|
|
62
|
+
- [ ] `prd-diff` 通过(09 报告无 missing/partial/report_mismatch)
|
|
63
|
+
- [ ] `gate prd-coverage` 通过(08 报告 + 语义 diff + 全量 E2E 测试覆盖)
|
|
64
|
+
- [ ] `validate` 通过(含强制 e2e)
|
|
51
65
|
- [ ] `gate ac-signed` 通过
|
|
52
66
|
- [ ] delivery-pipeline exit 0
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# 08-PRD一致性复查报告
|
|
2
|
+
|
|
3
|
+
> **交付前强制门禁**。按 `source/PRD.md` **最细粒度**逐条对比已实现代码。
|
|
4
|
+
> **禁止**揣摩、禁止兜底方案;无法确认则标 `待人工确认`,不得自行假设。
|
|
5
|
+
|
|
6
|
+
## 复查状态
|
|
7
|
+
|
|
8
|
+
- **复查状态**:未复查(完成后改为 `复查完成`)
|
|
9
|
+
- **PRD 原子条目数**:{{ATOM_COUNT}}
|
|
10
|
+
- **生成时间**:{{GENERATED_AT}}
|
|
11
|
+
|
|
12
|
+
## 填写规则(强制)
|
|
13
|
+
|
|
14
|
+
1. **粒度**:本表每一行对应 `.prd-review-atoms.json` 中的一条 PRD 原子(标题 / 列表项 / 表格行 / 实质段落),不得合并或省略。
|
|
15
|
+
2. **代码证据**:必须写可核对位置,例如 `src/pages/foo/index.tsx:42`、E2E `e2e/foo.spec.ts` 中断言原文、DOM 选择器 + 期望文案。
|
|
16
|
+
3. **结论**(仅允许三选一):
|
|
17
|
+
- `一致` — 代码与 PRD 该条完全一致
|
|
18
|
+
- `不一致-按PRD修复` — 代码与 PRD 冲突,须按 PRD 改代码(不得改 PRD 迁就实现)
|
|
19
|
+
- `待人工确认` — 无法从 PRD 或代码得出确定结论,须人工裁定
|
|
20
|
+
4. **禁止措辞**(出现在证据/备注中将导致 gate 失败):推测、兜底、暂定、可能、大概、应该可以、或沿用、默认处理、先这样、暂时、估计、猜测、或许。
|
|
21
|
+
5. **不一致处理**:标 `不一致-按PRD修复` 的项必须在修复代码后改为 `一致`,方可 deliver。
|
|
22
|
+
6. **待人工确认**:不得自行「合理推断」;须在下方汇总表列出,交付前必须清零或用户明确签收。
|
|
23
|
+
|
|
24
|
+
## 填写示例(参考格式;示例在代码块内,不会被 gate 解析,填表时勿照抄 ID)
|
|
25
|
+
|
|
26
|
+
以下演示**合格写法**。填「逐条对比」表时:按 `.prd-review-atoms.json` 的真实 `PRD-001…` 逐条填写,证据粒度须达到示例水平。
|
|
27
|
+
|
|
28
|
+
### 示例 A — `一致`
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
| PRD-ID | PRD 原文(摘要) | 代码证据 | 结论 | 备注 |
|
|
32
|
+
| PRD-0xx | 列表页「导出」后 toast 为「导出成功,请稍后查看下载中心」 | src/views/order/List.vue:88 message.success('导出成功,请稍后查看下载中心'); E2E e2e/order-export.spec.ts:34 getByText('导出成功,请稍后查看下载中心') | 一致 | §3.2 列表操作 > 导出 L156 |
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 示例 B — `不一致-按PRD修复`
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
| PRD-ID | PRD 原文(摘要) | 代码证据 | 结论 | 备注 |
|
|
39
|
+
| PRD-0xx | 筛选「状态」默认选中「全部」 | List.vue:41 statusDefault:'pending'(PRD 要求「全部」) | 不一致-按PRD修复 | §3.1 筛选 > 状态 L142 |
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
修复追踪写法:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
| PRD-ID | 修复说明 | 修复后证据 | 状态 |
|
|
46
|
+
| PRD-0xx | statusDefault 改为 'all' | List.vue:41 + e2e/order-filter.spec.ts:12 断言默认「全部」 | 已关闭 |
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 示例 C — `待人工确认`
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
| PRD-ID | PRD 原文(摘要) | 代码证据 | 结论 | 备注 |
|
|
53
|
+
| PRD-0xx | 批量审核在选中 0 条时的交互 | BatchAudit.vue:67 仅 selected.length>0 时渲染按钮;PRD 未定义 0 条时行为 | 待人工确认 | §4.5 批量操作 L203 |
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
待人工确认汇总:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
| PRD-ID | PRD 原文 | 不确定原因 | 需确认人 |
|
|
60
|
+
| PRD-0xx | 批量审核 0 条交互 | PRD 未写隐藏/disabled/toast,代码为隐藏 | 产品负责人 |
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 不合格写法(gate 会失败)
|
|
64
|
+
|
|
65
|
+
- 「推测 PRD 意思是…」— 含禁止词
|
|
66
|
+
- 「先沿用旧版,后续再改」— 兜底措辞
|
|
67
|
+
- 「组件里应该有处理」— 无路径/行号/断言
|
|
68
|
+
- 「基本满足」— 结论不在三选一内
|
|
69
|
+
|
|
70
|
+
## 逐条对比(PRD 原子 × 代码)
|
|
71
|
+
|
|
72
|
+
| PRD-ID | PRD 原文(摘要) | 代码证据(路径+行号/选择器/断言) | 结论 | 备注(章节路径) |
|
|
73
|
+
|--------|-----------------|----------------------------------|------|-----------------|
|
|
74
|
+
{{REVIEW_TABLE_ROWS}}
|
|
75
|
+
|
|
76
|
+
## 待人工确认汇总
|
|
77
|
+
|
|
78
|
+
| PRD-ID | PRD 原文 | 不确定原因 | 需确认人 |
|
|
79
|
+
|--------|---------|-----------|---------|
|
|
80
|
+
| (无则写「无」) | | | |
|
|
81
|
+
|
|
82
|
+
## 不一致项修复追踪(须全部关闭)
|
|
83
|
+
|
|
84
|
+
| PRD-ID | 修复说明(按 PRD 改了什么) | 修复后证据 | 状态 |
|
|
85
|
+
|--------|---------------------------|-----------|------|
|
|
86
|
+
| (无则写「无」) | | | 已关闭 |
|
|
87
|
+
|
|
88
|
+
## 复查完成签收
|
|
89
|
+
|
|
90
|
+
- [ ] 全部 PRD 原子条目已逐条填写
|
|
91
|
+
- [ ] 无 `不一致-按PRD修复` 未关闭项
|
|
92
|
+
- [ ] 无未解决的 `待人工确认` 项
|
|
93
|
+
- [ ] 已将「复查状态」改为 `复查完成`
|
|
@@ -107,6 +107,11 @@
|
|
|
107
107
|
6. 更新 `.session-state.json`:`status: ready_for_propose`,`phase: B_done`。
|
|
108
108
|
7. **若 `autoChainOpsx !== false`(默认)且用户未说「只提案」**:同一回合继续读 `07-opsx-自动串联指引.md`,执行 `/opsx-propose`(输入 **05+04+02**+UI)→ `/opsx-apply`;**不要**要求用户再说「继续」。
|
|
109
109
|
8. 仅当 `autoChainOpsx === false` 时输出:`05/01/02/03/04 已更新。回复「继续」进入提案。`
|
|
110
|
+
9. 若用户已声明「执行模式:严格SOP,不可替代」:本路径必须改为“阶段确认制”:
|
|
111
|
+
- 每阶段执行前先输出:`本次计划命令清单(逐条)`
|
|
112
|
+
- 每阶段执行后输出:`门禁结果 + 证据文件路径 + 下一步命令`
|
|
113
|
+
- 等待用户确认后再进入下一阶段
|
|
114
|
+
- 禁止用等价命令替代用户指定命令链路
|
|
110
115
|
|
|
111
116
|
---
|
|
112
117
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# PRD 一致性复查提示词(最细粒度,禁止揣摩)
|
|
2
|
+
|
|
3
|
+
你正在执行 **PRD × 已实现代码** 的一致性复查。输入:
|
|
4
|
+
|
|
5
|
+
- `source/PRD.md`(唯一需求来源)
|
|
6
|
+
- `.prd-review-atoms.json`(已拆好的最细粒度 PRD 原子,**不得删行**)
|
|
7
|
+
- `08-PRD一致性复查报告.md`(待填写)
|
|
8
|
+
- `05-验收清单.md`(AC 映射参考,**不能替代** PRD 全文)
|
|
9
|
+
- 业务代码 `src/`、`frontend/src/`、相关 `e2e/` 测试
|
|
10
|
+
|
|
11
|
+
## 强制原则
|
|
12
|
+
|
|
13
|
+
1. **拆分粒度**:以 `.prd-review-atoms.json` 为准,**一条 PRD 原子 = 报告表格一行**,不得合并、不得跳过。
|
|
14
|
+
2. **只陈述可核对事实**:代码证据必须可定位(文件路径 + 行号,或 E2E 测试名 + 断言字符串)。
|
|
15
|
+
3. **禁止揣摩**:不得写「可能」「大概」「推测」「兜底」「暂定」「或沿用」「默认」等措辞。
|
|
16
|
+
4. **禁止兜底方案**:不得建议「先这样」「暂时接受」「后续再改」来绕过 PRD。
|
|
17
|
+
5. **不一致时**:结论标 `不一致-按PRD修复`,并在「不一致项修复追踪」登记;**以 PRD 为准改代码**,不得改 PRD 迁就实现。
|
|
18
|
+
6. **无法确认时**:结论标 `待人工确认`,写入「待人工确认汇总」,写清**缺什么信息**才能判断;**不得自行假设**。
|
|
19
|
+
|
|
20
|
+
## 填写格式
|
|
21
|
+
|
|
22
|
+
填表前阅读 `08-PRD一致性复查报告.md` 中的 **「填写示例」** 一节(含 `一致` / `不一致-按PRD修复` / `待人工确认` 三种合格写法,以及不合格反例)。
|
|
23
|
+
你的每一行须达到示例中的证据粒度(路径+行号 或 E2E 断言原文),不得照抄示例中的 PRD-ID 与业务内容。
|
|
24
|
+
|
|
25
|
+
## 执行步骤
|
|
26
|
+
|
|
27
|
+
1. 读取 `.prd-review-atoms.json`,确认共 {{ATOM_COUNT}} 条(与报告行数一致)。
|
|
28
|
+
2. 对每条 PRD 原子:
|
|
29
|
+
- 在 PRD 中定位原文(章节路径 + 行号)
|
|
30
|
+
- 在代码/测试中查找**直接实现**该条的证据
|
|
31
|
+
- 填写 `08-PRD一致性复查报告.md` 对应行
|
|
32
|
+
3. 若实现与 PRD 冲突 → `不一致-按PRD修复`
|
|
33
|
+
4. 若 PRD 要求明确但代码找不到对应实现 → `不一致-按PRD修复`
|
|
34
|
+
5. 若 PRD 表述模糊且代码有多种解读 → `待人工确认`(说明歧义点,不要猜)
|
|
35
|
+
6. 全部填完后:
|
|
36
|
+
- 更新「待人工确认汇总」「不一致项修复追踪」
|
|
37
|
+
- 将「复查状态」改为 `复查完成`(仅当无未关闭不一致、无待人工确认时)
|
|
38
|
+
|
|
39
|
+
## 完成后执行门禁
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx sdd-flow-kit prd-diff --project-root <repo> --run-id <runId>
|
|
43
|
+
npx sdd-flow-kit gate --project-root <repo> --run-id <runId> --expect prd-coverage
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`prd-diff` 会机械扫描 PRD 字面量是否在代码/测试中出现,并生成 `09-PRD语义diff报告.md`。
|
|
47
|
+
若 08 报告标「一致」但脚本 diff 为 `missing_in_code` / `report_mismatch`,gate 将失败。
|
|
48
|
+
|
|
49
|
+
gate 失败则根据 `09-PRD语义diff报告.md` 修正报告或代码,**不得**跳过 gate。
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: SDD 脚本门禁:必须执行 sdd-flow-kit gate/phase;docModeOnly 时禁止改 src;交付前必须 ac-signed + deliver 成功
|
|
2
|
+
description: SDD 脚本门禁:必须执行 sdd-flow-kit gate/phase;docModeOnly 时禁止改 src;交付前必须 prd-coverage + ac-signed + deliver 成功
|
|
3
3
|
alwaysApply: true
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -22,7 +22,7 @@ alwaysApply: true
|
|
|
22
22
|
- `npx sdd-flow-kit gate --expect docs-closed`(含 `05-验收清单.md` 已定义)
|
|
23
23
|
- `npx sdd-flow-kit gate --expect ac-ready --change <name>`(P0 已映射到 spec/tasks)
|
|
24
24
|
- `npx sdd-flow-kit phase advance --to impl` + `gate --expect impl-allowed`(阶段 D 前)
|
|
25
|
-
4. **禁止**在未执行 `gate ac-signed` 与 `npx sdd-flow-kit deliver` 成功前宣称需求开发完成。
|
|
25
|
+
4. **禁止**在未执行 `gate prd-coverage`、`gate ac-signed` 与 `npx sdd-flow-kit deliver` 成功前宣称需求开发完成。
|
|
26
26
|
|
|
27
27
|
## docModeOnly
|
|
28
28
|
|
|
@@ -59,6 +59,10 @@ npx sdd-flow-kit gate --project-root <repo> --run-id <runId> --expect ac-ready -
|
|
|
59
59
|
npx sdd-flow-kit phase advance --project-root <repo> --run-id <runId> --to impl --change <name>
|
|
60
60
|
# Apply 前必读 source/PRD.md + 05-验收清单.md
|
|
61
61
|
# … 实现 …
|
|
62
|
+
npx sdd-flow-kit prd-review --project-root <repo> --run-id <runId>
|
|
63
|
+
# AI 执行 08-PRD一致性复查提示词.md(最细粒度,禁止揣摩)
|
|
64
|
+
npx sdd-flow-kit prd-diff --project-root <repo> --run-id <runId>
|
|
65
|
+
npx sdd-flow-kit gate --project-root <repo> --run-id <runId> --expect prd-coverage
|
|
62
66
|
npx sdd-flow-kit validate --project-root <repo> --run-id <runId> --change <name>
|
|
63
67
|
# 05 签收:P0 已验收 + 签收状态已签收
|
|
64
68
|
npx sdd-flow-kit gate --project-root <repo> --run-id <runId> --expect ac-signed
|