From 563d3786c014080323c46dc40ca3481ea1d8e5d6 Mon Sep 17 00:00:00 2001 From: mindcarver <32150062+mindcarver@users.noreply.github.com> Date: Thu, 8 Oct 2026 14:52:07 +0800 Subject: [PATCH] feat: switch discovery interviewing to frontier rounds Refs #106 --- skills/scd-discovery/SKILL.md | 8 ++-- .../scd-discovery/references/interviewing.md | 38 ++++++++++--------- tests/discovery-contract.test.mjs | 14 ++++++- tests/readme-diagrams.test.mjs | 2 +- 4 files changed, 38 insertions(+), 24 deletions(-) diff --git a/skills/scd-discovery/SKILL.md b/skills/scd-discovery/SKILL.md index 2f53a0c..f711e98 100644 --- a/skills/scd-discovery/SKILL.md +++ b/skills/scd-discovery/SKILL.md @@ -57,17 +57,17 @@ description: "在实施前,把定义不足的产品想法转化为经过明确 如果交付创建新系统,或改变持久组件、数据所有者、信任边界、公共契约、事件或集成,产品核心稳定后组合 `scd-architecture`。此后 UIUX 与 Architecture 可以并行进行。前后端独立实施前,必须把二者的操作、数据、错误、权限和术语统一为一个共享的机器可读契约。符合现有边界与契约的清晰局部变更无需调用 Architecture。 -## 沿决策树访谈 +## 沿决策树按轮访谈 -一次只询问一个决策。说明它为什么现在重要,给出有理由的建议,并只提供有实质差异的选项。先解决上游决策,再询问下游问题。 +把访谈组织为轮次:每轮一次性抛出整个前沿——前置决策已全部落定、彼此互不依赖的未决决策集合。每道题使用固定格式:编号、标题、说明它为什么现在重要、只提供有实质差异的备选项,以及单独一行的推荐答案。用户按编号作答整轮。先解决上游决策,再询问下游问题;一题的答案会改变另一题时,后者属于后面的轮次,不得同轮抛出。 只展开产品实际触发的分支:用户旅程、规则和状态、失败与恢复、数据生命周期、权限、集成、约束、非目标和可观察验证。 -每解决三到五个重要决策,给出一次简短收敛摘要,列出已确认决策、假设、排除项和下一个未解决分支。不要在每个检查点都要求确认。 +每轮答案落定并重算前沿后,给出一次简短收敛摘要,列出已确认决策、假设、排除项和下一轮前沿方向。不要在每个检查点都要求确认。 完整 Discovery 开始时,阅读 `references/interviewing.md`。 -用户跳过问题或没有给出实质回答,不代表拒绝。把最有力的建议作为具名的临时假设,继续依赖工作;在最终契约确认时统一确认累计假设。参见 `references/interviewing.md` 中“决策没有得到回答”部分。这与下方确认阶段的沉默规则一致,避免访谈阶段在无人引导时出现不对称处理。 +用户跳过轮次中的某道题或没有给出实质回答,不代表拒绝。把该题最有力的建议作为具名的临时假设,视为临时落定并解锁下游,同轮其余问题照常作答;在最终契约确认时统一确认累计假设。参见 `references/interviewing.md` 中“决策没有得到回答”部分。这与下方确认阶段的沉默规则一致,避免访谈阶段在无人引导时出现不对称处理。 ## 只在需要时保留连续性 diff --git a/skills/scd-discovery/references/interviewing.md b/skills/scd-discovery/references/interviewing.md index 95fe2c1..a855483 100644 --- a/skills/scd-discovery/references/interviewing.md +++ b/skills/scd-discovery/references/interviewing.md @@ -1,6 +1,6 @@ # 决策树访谈 -完整 Discovery 使用本参考。深度来自解决影响重大的决策,而不是固定提问数量。 +完整 Discovery 使用本参考。深度来自解决影响重大的决策,而不是固定提问数量或固定轮数。 ## 从临时理解开始 @@ -8,22 +8,22 @@ - 产品看起来要实现什么; - 已从仓库或环境确认的事实; -- 最上游的一个未解决决策。 +- 初始前沿:前置已落定、当前可以直接询问的未决决策。 能够提出更精确决策时,不要询问“你的全部需求是什么?”之类宽泛问题。 -## 组织一次决策 +## 组织一轮 -一次有效互动包含: +一次有效互动抛出一整个前沿,而不是一个决策。前沿是前置决策已全部落定、彼此互不依赖的未决决策集合。每道题使用固定结构: -1. **决策:** 当前阻塞下游理解的一个选择。 +1. **编号与标题:** `Q1 - <决策标题>`,让用户可以按编号作答。 2. **为何现在决定:** 哪些后续行为依赖它。 -3. **建议:** 首选答案。 -4. **理由:** 证据、产品取舍或可逆性。 -5. **备选项:** 只提供会产生实质不同结果的选择。 -6. **问题:** 只向用户请求一个决策。 +3. **备选项:** 只提供会产生实质不同结果的选择。 +4. **推荐答案:** 单独一行 `➡️` 给出首选答案,附一句理由(证据、产品取舍或可逆性)。 -一次互动可以包含上下文和多个事实,但只能请求一个决策。 +一轮可以包含上下文和多个事实,但同轮题目必须互不依赖:任何一题的答案都不得改变另一题的问法或备选项。用户按编号逐题作答,可以在一次回复内完成,例如“1 同意;2 选第二个;3 不行,因为……”。 + +收到答案后重算前沿:落定的决策解锁其下游问题,形成下一轮。前沿为空、没有新的可问问题时,访谈收敛。 ## 按依赖顺序推进 @@ -39,7 +39,11 @@ └─ 成员离开后的数据所有权 ``` -父决策尚不存在时,不要批量询问所有分支。 +- “单用户还是团队”未落定时,其余问题都不在前沿里; +- “团队”落定后,其下三个问题同时进入前沿,可以同轮抛出——它们彼此互不依赖; +- “仅本地或多设备”依赖“单用户”,永远不得与“单用户还是团队”同轮。 + +临时假设视为临时落定:它解锁下游问题进入前沿,但在最终契约确认或修正前不算已确认决策。 ## 覆盖已触发的表面 @@ -76,22 +80,22 @@ ## 决策没有得到回答时 -用户跳过结构化访谈问题或没有给出实质回答,不代表拒绝,也不代表确认。不要重复追问或停止访谈;把最有力的建议作为**临时假设**: +用户跳过轮次中的某道题或没有给出实质回答,不代表拒绝,也不代表确认。不要重复追问或停止访谈;把该题最有力的建议作为**临时假设**: 1. 明确说出假设,以及假设错误时的具体风险; -2. 继续它所解锁的依赖工作,仍然每次只请求一个决策; +2. 同轮其余已答问题照常处理;临时假设视为临时落定,它解锁的下游问题进入下一轮前沿; 3. 不得悄悄把假设提升为已确认用户决策; 4. 在最终契约确认时一次性确认或修正所有累计临时假设,参见 `SKILL.md` 的“审查就绪度并请求确认”。 -这样可保持每次一个决策的结构,让访谈继续推进,而不是退化成长篇无结构建议。如果连续两个决策都没有得到回答,将此情况作为阻塞明确呈现,直接询问用户是按假设继续还是暂停;不得叠加第三个静默假设。 +整轮都没有得到任何实质回答时,将此情况作为阻塞明确呈现,直接询问用户是按假设继续还是暂停;不得再叠加一轮静默假设。 -## 定期收敛 +## 每轮收敛 -每解决三到五个重要决策,简要汇总: +每轮收到答案并重算前沿后,简要汇总: - 已确认; - 已假设; - 已延期或范围外; -- 下一个未解决决策。 +- 下一轮前沿方向。 摘要保持简短。它用于检查漂移,不是另一个确认门。 diff --git a/tests/discovery-contract.test.mjs b/tests/discovery-contract.test.mjs index d6a937e..906c446 100644 --- a/tests/discovery-contract.test.mjs +++ b/tests/discovery-contract.test.mjs @@ -20,7 +20,7 @@ test("discovery routes greenfield work without burdening clear changes", () => { assert.match(skill, /就绪快速路径/); }); -test("discovery requires one-decision interviewing and explicit approval", () => { +test("discovery requires frontier-round interviewing and explicit approval", () => { const skill = read("skills/scd-discovery/SKILL.md"); const interviewing = read( "skills/scd-discovery/references/interviewing.md", @@ -29,9 +29,19 @@ test("discovery requires one-decision interviewing and explicit approval", () => "skills/scd-discovery/references/readiness-review.md", ); - assert.match(skill, /一次只询问一个决策/); + assert.match(skill, /每轮一次性抛出整个前沿/); + assert.match(skill, /互不依赖/); + assert.match(skill, /按编号作答/); assert.match(skill, /必须明确确认/); + assert.doesNotMatch(skill, /一次只询问一个决策/); assert.match(interviewing, /先问上游问题,再问其后果/); + assert.match( + interviewing, + /前沿是前置决策已全部落定、彼此互不依赖的未决决策集合/, + ); + assert.match(interviewing, /临时假设视为临时落定/); + assert.match(interviewing, /## 每轮收敛/); + assert.doesNotMatch(interviewing, /每次只请求一个决策/); assert.match(readiness, /静默对抗式审查/); assert.match(readiness, /A1:/); }); diff --git a/tests/readme-diagrams.test.mjs b/tests/readme-diagrams.test.mjs index bea5582..5cc4bdf 100644 --- a/tests/readme-diagrams.test.mjs +++ b/tests/readme-diagrams.test.mjs @@ -69,7 +69,7 @@ test("diagram stage summaries remain traceable to authoritative skill workflows" discovery: [ /先调查,再提问/, /确定交付切片/, - /沿决策树访谈/, + /沿决策树按轮访谈/, /审查就绪度并请求确认/, /持久化已确认契约并交接/, ],