@namewta/speculo 0.2.6 → 0.2.9
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 +9 -9
- package/dist/src/cli.js +1 -1
- package/dist/src/cli.js.map +1 -1
- package/dist/src/index.js +0 -32
- package/dist/src/index.js.map +1 -1
- package/dist/src/migrate.js +0 -4
- package/dist/src/migrate.js.map +1 -1
- package/package.json +1 -1
- package/template/.speculo/README.md +0 -1
- package/template/.speculo/workspace.json +1 -2
- package/template/canonical/README.md +44 -70
- package/template/canonical/canonical-specdev-grill-with-docs.md +475 -0
- package/template/canonical/canonical-specdev-spec.md +82 -0
- package/template/canonical/canonical-specdev-tickets.md +232 -0
- package/template/canonical/canonical-specdev-wayfinder.md +200 -0
- package/template/canonical/canonical-teach.md +70 -65
- package/template/workflows/specdev/A-archive-and-consolidate/A-archive-and-consolidate.md +73 -0
- package/template/workflows/specdev/A-archive-and-consolidate/archive-rules.md +49 -0
- package/template/workflows/specdev/A-archive-and-consolidate/cleanup-rules.md +80 -0
- package/template/workflows/specdev/A-archive-and-consolidate/consolidation-rules.md +120 -0
- package/template/workflows/specdev/A-archive-and-consolidate/discrimination-guide.md +96 -0
- package/template/workflows/specdev/A-archive-and-consolidate/knowledge-graduation.md +51 -0
- package/template/workflows/specdev/D-diagnose-bugs/D-diagnose-bugs.md +2 -0
- package/template/workflows/specdev/D-diagnose-bugs/feedback-loop-techniques.md +1 -1
- package/template/workflows/specdev/G-grill-with-docs/G-grill-with-docs.md +8 -0
- package/template/workflows/specdev/G-grill-with-docs/grilling-protocol.md +12 -4
- package/template/workflows/specdev/G-grill-with-docs/log-format.md +8 -7
- package/template/workflows/specdev/I-implement/I-implement.md +9 -4
- package/template/workflows/specdev/I-init-setup/domain-layout.md +1 -1
- package/template/workflows/specdev/INDEX.md +9 -0
- package/template/workflows/specdev/P-goal-plan/P-goal-plan.md +84 -0
- package/template/workflows/specdev/P-goal-plan/execution-sections.md +103 -0
- package/template/workflows/specdev/P-goal-plan/governance-sections.md +103 -0
- package/template/workflows/specdev/P-goal-plan/input-validation.md +94 -0
- package/template/workflows/specdev/P-goal-plan/lead-orchestration-protocol.md +159 -0
- package/template/workflows/specdev/P-goal-plan/quick-reference-table.md +60 -0
- package/template/workflows/specdev/P-goal-plan/vision-sections.md +80 -0
- package/template/workflows/specdev/S-spec/S-spec.md +2 -0
- package/template/workflows/specdev/T-tickets/T-tickets.md +20 -53
- package/template/workflows/specdev/T-tickets/tickets-map-template.md +70 -0
- package/template/workflows/specdev/W-wayfinder/W-wayfinder.md +2 -2
- package/template/workflows/specdev/_state/research/.gitkeep +0 -0
- package/template/workflows/specdev/common/dev-worktree/SKILL.md +138 -0
- package/template/workflows/specdev/common/dev-worktree/references/create.md +63 -0
- package/template/workflows/specdev/common/dev-worktree/references/finalize.md +102 -0
- package/template/workflows/specdev/common/research/SKILL.md +54 -0
- package/template/canonical/canonical-domain-modeling.md +0 -289
- package/template/canonical/canonical-skill-example.md +0 -608
- package/template/skills/worktree-isolation/SKILL.md +0 -23
- package/template/skills/worktree-isolation/references/audit-branch-tree.md +0 -32
- package/template/skills/worktree-isolation/references/create-worktree.md +0 -39
- package/template/skills/worktree-isolation/references/merge-and-cleanup.md +0 -43
- package/template/vendor/README.md +0 -35
- package/template/vendor/matt-pocock/README.md +0 -41
- package/template/vendor/matt-pocock/engineering/README.md +0 -28
- package/template/vendor/matt-pocock/engineering/ask-matt/SKILL.md +0 -76
- package/template/vendor/matt-pocock/engineering/code-review/SKILL.md +0 -89
- package/template/vendor/matt-pocock/engineering/codebase-design/DEEPENING.md +0 -37
- package/template/vendor/matt-pocock/engineering/codebase-design/DESIGN-IT-TWICE.md +0 -44
- package/template/vendor/matt-pocock/engineering/codebase-design/SKILL.md +0 -114
- package/template/vendor/matt-pocock/engineering/diagnosing-bugs/SKILL.md +0 -134
- package/template/vendor/matt-pocock/engineering/domain-modeling/ADR-FORMAT.md +0 -47
- package/template/vendor/matt-pocock/engineering/domain-modeling/CONTEXT-FORMAT.md +0 -60
- package/template/vendor/matt-pocock/engineering/domain-modeling/SKILL.md +0 -74
- package/template/vendor/matt-pocock/engineering/grill-with-docs/SKILL.md +0 -7
- package/template/vendor/matt-pocock/engineering/implement/SKILL.md +0 -15
- package/template/vendor/matt-pocock/engineering/prototype/LOGIC.md +0 -79
- package/template/vendor/matt-pocock/engineering/prototype/SKILL.md +0 -30
- package/template/vendor/matt-pocock/engineering/prototype/UI.md +0 -112
- package/template/vendor/matt-pocock/engineering/research/SKILL.md +0 -12
- package/template/vendor/matt-pocock/engineering/setup-matt-pocock-skills/SKILL.md +0 -156
- package/template/vendor/matt-pocock/engineering/setup-matt-pocock-skills/domain.md +0 -40
- package/template/vendor/matt-pocock/engineering/setup-matt-pocock-skills/issue-tracker-github.md +0 -45
- package/template/vendor/matt-pocock/engineering/setup-matt-pocock-skills/issue-tracker-gitlab.md +0 -46
- package/template/vendor/matt-pocock/engineering/setup-matt-pocock-skills/issue-tracker-local.md +0 -30
- package/template/vendor/matt-pocock/engineering/setup-matt-pocock-skills/triage-labels.md +0 -15
- package/template/vendor/matt-pocock/engineering/tdd/SKILL.md +0 -36
- package/template/vendor/matt-pocock/engineering/tdd/mocking.md +0 -59
- package/template/vendor/matt-pocock/engineering/tdd/tests.md +0 -77
- package/template/vendor/matt-pocock/engineering/to-spec/SKILL.md +0 -75
- package/template/vendor/matt-pocock/engineering/to-tickets/SKILL.md +0 -113
- package/template/vendor/matt-pocock/engineering/wayfinder/SKILL.md +0 -127
- package/template/vendor/matt-pocock/in-progress/README.md +0 -10
- package/template/vendor/matt-pocock/in-progress/claude-handoff/SKILL.md +0 -18
- package/template/vendor/matt-pocock/in-progress/loop-me/SKILL.md +0 -32
- package/template/vendor/matt-pocock/in-progress/wizard/SKILL.md +0 -45
- package/template/vendor/matt-pocock/in-progress/wizard/template.sh +0 -211
- package/template/vendor/matt-pocock/in-progress/writing-beats/SKILL.md +0 -67
- package/template/vendor/matt-pocock/in-progress/writing-fragments/SKILL.md +0 -78
- package/template/vendor/matt-pocock/in-progress/writing-shape/SKILL.md +0 -79
- package/template/vendor/matt-pocock/productivity/README.md +0 -18
- package/template/vendor/matt-pocock/productivity/grill-me/SKILL.md +0 -7
- package/template/vendor/matt-pocock/productivity/grilling/SKILL.md +0 -12
- package/template/vendor/matt-pocock/productivity/teach/GLOSSARY-FORMAT.md +0 -35
- package/template/vendor/matt-pocock/productivity/teach/LEARNING-RECORD-FORMAT.md +0 -46
- package/template/vendor/matt-pocock/productivity/teach/MISSION-FORMAT.md +0 -31
- package/template/vendor/matt-pocock/productivity/teach/RESOURCES-FORMAT.md +0 -32
- package/template/vendor/matt-pocock/productivity/teach/SKILL.md +0 -140
- /package/template/{vendor/matt-pocock/productivity → skills}/writing-great-skills/GLOSSARY.md +0 -0
- /package/template/{vendor/matt-pocock/productivity → skills}/writing-great-skills/SKILL.md +0 -0
- /package/template/{vendor/matt-pocock/productivity → workflows/specdev/common}/handoff/SKILL.md +0 -0
- /package/template/{vendor/matt-pocock/engineering → workflows/specdev/common}/improve-codebase-architecture/HTML-REPORT.md +0 -0
- /package/template/{vendor/matt-pocock/engineering → workflows/specdev/common}/improve-codebase-architecture/SKILL.md +0 -0
- /package/template/{vendor/khazix-skills → workflows/specdev/common}/neat-freak/SKILL.md +0 -0
- /package/template/{vendor/khazix-skills → workflows/specdev/common}/neat-freak/references/agent-paths.md +0 -0
- /package/template/{vendor/khazix-skills → workflows/specdev/common}/neat-freak/references/governance.md +0 -0
- /package/template/{vendor/khazix-skills → workflows/specdev/common}/neat-freak/references/sync-matrix.md +0 -0
- /package/template/{vendor/khazix-skills → workflows/specdev/common}/neat-freak/references/verification.md +0 -0
- /package/template/{vendor/khazix-skills → workflows/specdev/common}/neat-freak/scripts/audit-inventory.sh +0 -0
- /package/template/{vendor/matt-pocock/engineering → workflows/specdev/common}/resolving-merge-conflicts/SKILL.md +0 -0
- /package/template/{vendor/matt-pocock/engineering/diagnosing-bugs → workflows/specdev/common}/scripts/hitl-loop.template.sh +0 -0
- /package/template/{vendor/matt-pocock/engineering → workflows/specdev/common}/triage/AGENT-BRIEF.md +0 -0
- /package/template/{vendor/matt-pocock/engineering → workflows/specdev/common}/triage/OUT-OF-SCOPE.md +0 -0
- /package/template/{vendor/matt-pocock/engineering → workflows/specdev/common}/triage/SKILL.md +0 -0
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
# 设计访谈(带文档)
|
|
2
|
+
|
|
3
|
+
组合 work——grilling 访谈技术 + domain-modeling 领域建模规程,在无情盘问中打磨设计,同时持续写入 ADR.md、LOG.md 和 CONTEXT.md 三个领域文档。访谈负责深度提问与共识达成,领域建模负责在决策结晶的瞬间捕获术语、记录轨迹、筛选架构决策。
|
|
4
|
+
|
|
5
|
+
产物统一写入 `specdev/changes/{change}/`,其中 `{change}` 为 `<YYYY-MM-DD>-<topic>` 格式。
|
|
6
|
+
|
|
7
|
+
## 流程
|
|
8
|
+
|
|
9
|
+
### 1. 启动变更
|
|
10
|
+
|
|
11
|
+
创建 `specdev/changes/{change}/` 目录(`{change}` 为 `<YYYY-MM-DD>-<topic>` 格式),初始化三个空文件模板:
|
|
12
|
+
|
|
13
|
+
- ADR.md — 架构决策记录,仅含 `# 架构决策记录` 标题
|
|
14
|
+
- LOG.md — 设计决策日志,含 `# 设计决策日志` 标题及维护规则说明
|
|
15
|
+
- CONTEXT.md — 领域词汇表,含 `# {主题} 领域词汇表` 标题及一两句描述
|
|
16
|
+
|
|
17
|
+
**完成标准**:变更目录 `<YYYY-MM-DD>-<topic>` 已创建,初始 ADR.md/LOG.md/CONTEXT.md 已就位。
|
|
18
|
+
|
|
19
|
+
### 2. 访谈
|
|
20
|
+
|
|
21
|
+
委托给 ``grilling-protocol``。一次一问,沿设计树逐分支推进,在用户确认共识之前不执行方案。访谈过程中随时更新 ``LOG``,记录每个确认、延后、替代的结论。
|
|
22
|
+
|
|
23
|
+
**完成标准**:访谈完成——一次一问,决策树已遍历,共识已达成。LOG.md 已同步所有访谈结论。
|
|
24
|
+
|
|
25
|
+
### 3. 捕获文档
|
|
26
|
+
|
|
27
|
+
委托给 ``domain-modeling-rules``。对照词汇表挑战术语、精炼模糊语言、讨论具体场景、与代码交叉引用。
|
|
28
|
+
|
|
29
|
+
- ``LOG`` 同步所有结论
|
|
30
|
+
- ``CONTEXT`` 精炼术语定义
|
|
31
|
+
- ``ADR`` 仅追加满足三条件的架构决策(参见 ``adr-format``)
|
|
32
|
+
|
|
33
|
+
**完成标准**:LOG.md 已同步所有结论;CONTEXT.md 已精炼术语;ADR.md 已追加满足三条件的架构决策。
|
|
34
|
+
|
|
35
|
+
### 4. 停止
|
|
36
|
+
|
|
37
|
+
设计阶段完成。向用户汇报产物摘要(LOG.md / CONTEXT.md / ADR.md 的条目数量和关键结论),明确询问是否进入 ``I-implement`` 实现阶段。
|
|
38
|
+
|
|
39
|
+
不得在用户确认前自动读取实现源码或执行代码变更。
|
|
40
|
+
|
|
41
|
+
## 子文件引用
|
|
42
|
+
|
|
43
|
+
本入口及以下子文件按需加载:
|
|
44
|
+
|
|
45
|
+
| 文件 | 触发条件 |
|
|
46
|
+
|------|----------|
|
|
47
|
+
| ``grilling-protocol`` | 进入步骤 2「访谈」时加载——包含完整访谈协议,一次一问、推荐答案、决策树遍历、LOG.md 同步规则 |
|
|
48
|
+
| ``domain-modeling-rules`` | 进入步骤 3「捕获文档」时加载——包含三文件分工、对照词汇表挑战、精炼与交叉引用规程、同步规则 |
|
|
49
|
+
| ``adr-format`` | 需要创建或修改 ADR 条目时加载——单一 ADR.md 文件格式、编号规则、三条件检查、可选元素 |
|
|
50
|
+
| ``context-format`` | 需要增删改术语时加载——CONTEXT.md 结构、定义规则、增删改操作说明 |
|
|
51
|
+
| ``log-format`` | 需要记录设计结论时加载——LOG.md 格式、状态标记、编号规则、追加与修订规程 |
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 参考内容
|
|
56
|
+
|
|
57
|
+
<grilling-protocol>
|
|
58
|
+
|
|
59
|
+
# 访谈协议
|
|
60
|
+
|
|
61
|
+
请对我进行无情的面试,深入探讨该方案的每一个方面,直到我们达成共识。沿设计树的每个分支逐步推进,逐个解决决策之间的依赖关系。每个问题都给出你的推荐答案。
|
|
62
|
+
|
|
63
|
+
## 核心规则
|
|
64
|
+
|
|
65
|
+
### 一次只问一个问题
|
|
66
|
+
|
|
67
|
+
等待我对每个问题给出反馈后再继续。一次问多个问题会让人困惑,也会让讨论失去焦点。每个问题的回答会自然引出下一个分支的追问,不要跳跃。
|
|
68
|
+
|
|
69
|
+
### 每个问题给出推荐答案
|
|
70
|
+
|
|
71
|
+
不要只抛出问题。基于你的分析,给出你认为最好的答案,并解释为什么。然后让我确认、反驳或修正。推荐答案让讨论有锚点——我可以直接同意、微调、或推翻重来,而不是从白纸开始。
|
|
72
|
+
|
|
73
|
+
### 事实自己查,决策问用户
|
|
74
|
+
|
|
75
|
+
如果某个*事实*可以通过探索代码库找到,请自行查找,不要来问我。包括:现有实现方式、类型定义、数据流、命名约定、文件结构。但*决策*由我来做——将每个决策提交给我并等待我的回答。事实和决策的边界:事实是关于"现在是什么",决策是关于"应该是什么"。
|
|
76
|
+
|
|
77
|
+
### 沿设计树逐分支推进
|
|
78
|
+
|
|
79
|
+
不要跳跃。如果一个决策依赖另一个决策,先解决被依赖的那个。识别出依赖关系并告诉我:"我们需要先决定 X,因为 Y 的选择取决于 X 的结论。"设计树的典型分支顺序:
|
|
80
|
+
|
|
81
|
+
1. **核心概念** — 领域的实体、值对象、聚合根是什么?
|
|
82
|
+
2. **边界与关系** — 概念之间的边界在哪里?它们如何关联?
|
|
83
|
+
3. **行为与规则** — 每个概念能做什么?有什么约束?
|
|
84
|
+
4. **实现映射** — 概念如何映射到代码结构、数据模型、接口?
|
|
85
|
+
5. **边界场景** — 极端情况和异常如何处理?
|
|
86
|
+
|
|
87
|
+
### 共识之前不执行
|
|
88
|
+
|
|
89
|
+
在我确认我们已达成共识之前,不要执行该方案。即使讨论看起来已经穷尽,也要明确询问:"我们是否已就该设计达成共识?"只有在得到肯定回答后才进入下一阶段。
|
|
90
|
+
|
|
91
|
+
## 访谈中维护三文件
|
|
92
|
+
|
|
93
|
+
访谈中每完成一轮设计问答,按 参见下方 `<domain-modeling-rules>` 标签 规定的顺序同步三个文件:
|
|
94
|
+
|
|
95
|
+
1. **LOG.md** 先更新——立即追加日志条目,记录本次讨论的结论
|
|
96
|
+
2. **CONTEXT.md** 随后更新——从日志中提取新术语或修正的术语定义
|
|
97
|
+
3. **ADR.md** 最后更新——检查是否需要追加满足三条件的架构决策
|
|
98
|
+
|
|
99
|
+
在访谈过程中,每当一个结论被确认、延后或被替代时,当场更新 `LOG.md`。不要等访谈结束再批量写入——发生时立即捕获。具体格式参见 参见下方 `<log-format>` 标签。
|
|
100
|
+
|
|
101
|
+
写入三文件的时机:
|
|
102
|
+
|
|
103
|
+
- **结论被确认** — 用户明确同意某个设计决定时,立即追加一条 `accepted` 日志,随后检查是否需要新增/修改 CONTEXT 术语,最后检查是否满足三条件追加 ADR
|
|
104
|
+
- **决定被延后** — 用户说"先不定"或"后面再讨论"时,追加一条 `deferred` 日志,记录为什么暂不决定以及从什么角度恢复讨论
|
|
105
|
+
- **结论被替代** — 后续讨论推翻了之前的决定时,将原条目状态改为 `superseded`,标注 `Superseded by: LOG-XXXX`,再新建替代条目;同时检查 CONTEXT 和 ADR 是否需要对应更新
|
|
106
|
+
|
|
107
|
+
每次 LOG 更新后,立即检查 CONTEXT 和 ADR 是否需要同步更新。不要将 CONTEXT 和 ADR 的更新推迟到访谈结束后批量处理——与 LOG 一样在结论结晶的瞬间立即捕获。
|
|
108
|
+
|
|
109
|
+
## 访谈节奏
|
|
110
|
+
|
|
111
|
+
- **开场**:先理解用户想打磨的方案是什么。问清楚范围和目标,然后开始沿设计树推进。
|
|
112
|
+
- **推进**:每个回答后,识别下一个最关键的未解决问题。优先解决会阻塞其他决策的问题。
|
|
113
|
+
- **收束**:当设计树的主要分支都已遍历、且用户确认共识时,访谈结束。不要无限追问无关细节。
|
|
114
|
+
|
|
115
|
+
## 好的访谈问题范例
|
|
116
|
+
|
|
117
|
+
- "你把 X 称为 'account'——你指的是 Customer 还是 User?它们在代码中是不同的概念。我建议用 Customer,因为它更精确地描述了购买关系。"
|
|
118
|
+
- "你提到订单可以部分取消。未取消的商品怎么办——它们还能发货吗?我建议将它们标记为可发货状态,因为取消是针对商品行而非整个订单。"
|
|
119
|
+
- "你打算用事件溯源还是 CRUD?考虑到审计需求,我推荐事件溯源——虽然写路径更复杂,但天然支持完整审计日志。"
|
|
120
|
+
- "Ordering 和 Billing 之间你选择了同步 HTTP 调用。这意味着 Billing 挂了订单也创建不了。你确定要这种耦合?我建议用异步领域事件——订单创建后发出事件,Billing 异步消费。"
|
|
121
|
+
|
|
122
|
+
</grilling-protocol>
|
|
123
|
+
|
|
124
|
+
<domain-modeling-rules>
|
|
125
|
+
|
|
126
|
+
# 领域建模规程
|
|
127
|
+
|
|
128
|
+
在设计过程中积极构建和精炼项目的领域模型。这是*主动*规程——挑战术语、发明边界场景、并在决策结晶的那一刻立即写入词汇表和决策。仅仅*阅读*文档获取词汇不是本规程——本规程用于当你正在*改变*模型,而不仅仅是消费它时。
|
|
129
|
+
|
|
130
|
+
## 三文件分工
|
|
131
|
+
|
|
132
|
+
三个文件各司其职,三者关系为:LOG.md 是最完整的记录 → CONTEXT.md 从中提取术语定义 → ADR.md 从中筛选同时满足三个条件的架构决策。
|
|
133
|
+
|
|
134
|
+
| 文件 | 职责 | 维护方式 |
|
|
135
|
+
|------|------|----------|
|
|
136
|
+
| `LOG.md` | 完整设计轨迹——所有确认、延后、被替代的结论 | 持续增删改,条目可被后续决定修订 |
|
|
137
|
+
| `CONTEXT.md` | 精炼的规范词汇表——只保留当前有效的术语 | 增删改,保持精炼 |
|
|
138
|
+
| `ADR.md` | 难以逆转、令人意外、存在真实权衡的架构决策 | 只追加不删除,可标记废弃 |
|
|
139
|
+
|
|
140
|
+
## 对照词汇表挑战
|
|
141
|
+
|
|
142
|
+
当用户使用的术语与 `CONTEXT.md` 中的现有语言冲突时,立即指出。"你的词汇表将 'cancellation' 定义为 X,但你似乎指的是 Y——到底是哪个?"如果用户确认应修改词汇表,更新 `CONTEXT.md` 中的定义并追加日志。
|
|
143
|
+
|
|
144
|
+
## 精炼模糊语言
|
|
145
|
+
|
|
146
|
+
当用户使用含糊或重载的术语时,提出一个精确的规范术语。"你在说 'account'——你指的是 Customer 还是 User?它们是不同的东西。"在 `CONTEXT.md` 中为新术语添加条目,将模糊的同义词列入 `_Avoid_`。
|
|
147
|
+
|
|
148
|
+
## 讨论具体场景
|
|
149
|
+
|
|
150
|
+
当讨论领域关系时,用具体场景进行压力测试。发明探索边界情况的场景,迫使用户精确界定概念之间的边界。"你说订单可以部分取消——未取消的商品怎么办?它们还能发货吗?"
|
|
151
|
+
|
|
152
|
+
## 与代码交叉引用
|
|
153
|
+
|
|
154
|
+
当用户陈述某事如何工作时,检查代码是否一致。如果发现矛盾,指出来:"你的代码取消的是整个 Order,但你刚才说部分取消是可能的——哪个是正确的?"在日志中记录这种矛盾的发现和解决过程。
|
|
155
|
+
|
|
156
|
+
## 及时更新 LOG.md
|
|
157
|
+
|
|
158
|
+
当设计问答中形成任何结论时,当场更新 `LOG.md`。它是完整的设计轨迹——记录"当时讨论了什么、最终固定了什么行为以及对应哪个 ADR"。不要批量处理——发生时立即捕获。具体格式参见 参见下方 `<log-format>` 标签。
|
|
159
|
+
|
|
160
|
+
### 日志条目格式
|
|
161
|
+
|
|
162
|
+
每条日志使用 `## LOG-XXXX: {标题}` 二级标题,编号从 `0001` 开始顺序递增。每个条目包含:
|
|
163
|
+
|
|
164
|
+
- **Status** — `accepted`(已确认)、`deferred`(暂不决定)、`superseded`(被后续决定替代)
|
|
165
|
+
- **Superseded by** — 如状态为 `superseded`,标注替代它的日志编号
|
|
166
|
+
- **Related** — 如该结论对应某个 ADR,标注 `Related: ADR-XXXX`
|
|
167
|
+
- **正文** — 背景、讨论的问题、做出的决定及原因,可以记录具体场景和交互细节
|
|
168
|
+
|
|
169
|
+
### 维护规则
|
|
170
|
+
|
|
171
|
+
- 每次完成设计问答,同步更新 `LOG.md`、`CONTEXT.md` 与 `ADR.md`。
|
|
172
|
+
- 后续确认改变既有结论时,直接修订原日志条目,并记录替代关系,不保留互相矛盾的"现行规则"。
|
|
173
|
+
- 日志可以记录具体交互和边界场景;词汇表保持精炼;ADR 只记录难以逆转、令人意外且存在真实权衡的决定。
|
|
174
|
+
- 每个日志条目应关联对应的 ADR(如有):`Related: ADR-XXXX`。
|
|
175
|
+
- 状态为 `deferred` 的条目保留,以便后续恢复讨论时知道从什么问题开始。
|
|
176
|
+
|
|
177
|
+
## 及时更新 CONTEXT.md
|
|
178
|
+
|
|
179
|
+
当术语确定时,当场更新 `CONTEXT.md`。不要批量处理——发生时立即捕获。具体格式参见 参见下方 `<context-format>` 标签。
|
|
180
|
+
|
|
181
|
+
`CONTEXT.md` 应该完全不包含实现细节。不要将 `CONTEXT.md` 当作规范、草稿纸或实现决策的仓库。它只是词汇表,别无其他。
|
|
182
|
+
|
|
183
|
+
- **新增术语**:在合适的子标题下追加条目。
|
|
184
|
+
- **修改术语**:直接更新定义文本和 `_Avoid_` 列表。
|
|
185
|
+
- **删除术语**:移除整个条目。
|
|
186
|
+
- **术语更名**:删除旧条目,新增新条目。
|
|
187
|
+
|
|
188
|
+
## 谨慎更新 ADR.md
|
|
189
|
+
|
|
190
|
+
仅在以下三个条件全部满足时才向 `ADR.md` 追加一条决策记录:
|
|
191
|
+
|
|
192
|
+
1. **难以逆转**——以后改变主意的成本是有意义的
|
|
193
|
+
2. **没有上下文会令人惊讶**——未来的读者会疑惑"他们为什么这样做?"
|
|
194
|
+
3. **真实权衡的结果**——存在真正的替代方案,你出于特定原因选择了一个
|
|
195
|
+
|
|
196
|
+
如果缺少任何一个条件,跳过 ADR。具体格式参见 参见下方 `<adr-format>` 标签。
|
|
197
|
+
|
|
198
|
+
`ADR.md` 中每个决策是一个 `## NNNN: {标题}` 二级标题,编号顺序递增,条目之间用 `---` 分隔。可以修改已有条目、标记废弃——但不要删除。
|
|
199
|
+
|
|
200
|
+
## 什么算 ADR
|
|
201
|
+
|
|
202
|
+
- **架构形态。** "我们使用 monorepo。" "写模型采用事件溯源,读模型投影到 Postgres。"
|
|
203
|
+
- **上下文间的集成模式。** "Ordering 和 Billing 通过领域事件通信,而非同步 HTTP。"
|
|
204
|
+
- **带来锁定效应的技术选择。** 数据库、消息总线、认证提供商、部署目标。不是每个库——只是那些需要花一个季度才能替换的。
|
|
205
|
+
- **边界和范围决策。** "客户数据由 Customer 上下文拥有;其他上下文仅通过 ID 引用它。"明确的"不做"和"要做"同样有价值。
|
|
206
|
+
- **有意偏离显而易见路径的决策。** "我们使用手动 SQL 而不是 ORM,因为 X。"任何合理读者会假设相反的情况。
|
|
207
|
+
- **代码中不可见的约束。** "由于合规要求,我们不能使用 AWS。" "由于合作伙伴 API 合同,响应时间必须低于 200ms。"
|
|
208
|
+
- **拒绝的原因不明显的被拒绝替代方案。** 如果你考虑了 GraphQL 而因微妙原因选择了 REST,记录下来——否则 6 个月后有人会再次建议 GraphQL。
|
|
209
|
+
|
|
210
|
+
## 三文件同步规则
|
|
211
|
+
|
|
212
|
+
访谈中每完成一轮设计问答,按以下顺序同步三个文件:
|
|
213
|
+
|
|
214
|
+
1. **LOG.md** 先更新——立即追加日志条目,记录本次讨论的结论
|
|
215
|
+
2. **CONTEXT.md** 随后更新——从日志中提取新术语或修正的术语定义
|
|
216
|
+
3. **ADR.md** 最后更新——检查是否需要满足三条件追加 ADC(架构决策记录)
|
|
217
|
+
|
|
218
|
+
如果 CONTEXT 或 ADR 的更新来自日志条目,在日志中补充 `Related: ADR-XXXX` 的关联标注。
|
|
219
|
+
|
|
220
|
+
</domain-modeling-rules>
|
|
221
|
+
|
|
222
|
+
<adr-format>
|
|
223
|
+
|
|
224
|
+
# ADR.md 格式
|
|
225
|
+
|
|
226
|
+
所有架构决策记录存放在变更目录的单一 `ADR.md` 文件中。不使用 `docs/adr/` 目录下的编号文件,所有决策在一个文件内按二级标题分段。
|
|
227
|
+
|
|
228
|
+
## 模板
|
|
229
|
+
|
|
230
|
+
```md
|
|
231
|
+
# 架构决策记录
|
|
232
|
+
|
|
233
|
+
## 0001: {决策的简短标题}
|
|
234
|
+
|
|
235
|
+
{1-3 句话:背景是什么,我们做了什么决策,以及为什么。}
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## 0002: {另一决策标题}
|
|
240
|
+
|
|
241
|
+
{1-3 句话描述。}
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
每个决策是一个 `##` 二级标题,编号从 `0001` 开始顺序递增。决策之间用 `---` 分隔。
|
|
247
|
+
|
|
248
|
+
就这样。一个 ADR 条目可以就是一个段落。其价值在于记录*已经*做出了决策以及*为什么*——而不是填满各个部分。
|
|
249
|
+
|
|
250
|
+
## 追加新决策
|
|
251
|
+
|
|
252
|
+
1. 读取 `ADR.md`,找到最高现有编号
|
|
253
|
+
2. 编号加 1
|
|
254
|
+
3. 在文件末尾追加 `---` 分隔线和新条目
|
|
255
|
+
|
|
256
|
+
## 可选附加元素
|
|
257
|
+
|
|
258
|
+
仅当它们真正增加价值时才包含这些。大多数 ADR 不需要它们:
|
|
259
|
+
|
|
260
|
+
- **日期**——在标题行的 `{标题}` 后面加 `(YYYY-MM-DD)`
|
|
261
|
+
- **Status**——`**Status**: proposed | accepted | deprecated | superseded by ADR-NNNN`。当决策被重新审视时,直接修改状态标记
|
|
262
|
+
- **Considered Options**——仅当被拒绝的替代方案值得记住时
|
|
263
|
+
- **Consequences**——仅当需要指出非显而易见的下游影响时
|
|
264
|
+
|
|
265
|
+
### 带可选元素的示例
|
|
266
|
+
|
|
267
|
+
```md
|
|
268
|
+
## 0003: 写模型采用事件溯源(2025-03-15)
|
|
269
|
+
|
|
270
|
+
**Status**: accepted
|
|
271
|
+
|
|
272
|
+
Order 聚合需要完整的变更历史用于审计和补偿。我们选择事件溯源——
|
|
273
|
+
所有状态变更作为不可变事件存储,当前状态从中投影。
|
|
274
|
+
|
|
275
|
+
**Considered Options**:
|
|
276
|
+
- 事件溯源(已选)——天然审计日志,支持时间旅行调试
|
|
277
|
+
- CRUD + 审计表——更简单,但审计日志与业务逻辑解耦,容易不同步
|
|
278
|
+
- 仅 CRUD——无审计历史,不满足合规要求
|
|
279
|
+
|
|
280
|
+
**Consequences**:
|
|
281
|
+
- 写路径复杂度增加;读路径需要投影
|
|
282
|
+
- 事件 schema 演进需要显式版本策略
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## 修改已有决策
|
|
286
|
+
|
|
287
|
+
- **澄清或补充后果**——直接编辑条目正文
|
|
288
|
+
- **改变状态**——修改 `**Status**` 字段(如 accepted → deprecated)
|
|
289
|
+
- **废弃**——将状态改为 `deprecated`,如被新决策替代则加上 `superseded by ADR-NNNN`
|
|
290
|
+
- **不要删除**——即使决策被废弃,保留条目作为历史上下文
|
|
291
|
+
|
|
292
|
+
## 三条件检查
|
|
293
|
+
|
|
294
|
+
在创建 ADR 之前,确认以下三个条件同时为真:
|
|
295
|
+
|
|
296
|
+
1. **难以逆转**——以后改变主意的成本是实质性的。容易逆转的决策跳过——你反正会逆转的。
|
|
297
|
+
2. **没有上下文的话令人惊讶**——未来的读者会看着代码想"他们到底为什么这样做?"。不令人惊讶的决策没人会追问,不需要记录。
|
|
298
|
+
3. **真实权衡的结果**——确实存在替代方案,你基于特定原因选择了一个。没有真正的替代方案就没有可记录的,除了"我们做了显而易见的事"。
|
|
299
|
+
|
|
300
|
+
如果决策不满足全部三个条件,只记入 LOG.md,不追加 ADR。
|
|
301
|
+
|
|
302
|
+
</adr-format>
|
|
303
|
+
|
|
304
|
+
<context-format>
|
|
305
|
+
|
|
306
|
+
# CONTEXT.md 格式
|
|
307
|
+
|
|
308
|
+
领域词汇表存放在变更目录的 `CONTEXT.md` 中。它只包含精炼的规范术语定义,不包含实现细节、设计决策或草稿内容。
|
|
309
|
+
|
|
310
|
+
## 模板
|
|
311
|
+
|
|
312
|
+
```md
|
|
313
|
+
# {项目名称} 领域词汇表
|
|
314
|
+
|
|
315
|
+
{对该上下文是什么以及为什么存在的一两句话描述。}
|
|
316
|
+
|
|
317
|
+
## {术语分组}
|
|
318
|
+
|
|
319
|
+
**Order**:
|
|
320
|
+
{对该术语的一两句话描述}
|
|
321
|
+
_Avoid_: Purchase, transaction
|
|
322
|
+
|
|
323
|
+
**Invoice**:
|
|
324
|
+
发货后发送给客户的付款请求。
|
|
325
|
+
_Avoid_: Bill, payment request
|
|
326
|
+
|
|
327
|
+
**Customer**:
|
|
328
|
+
下订单的个人或组织。
|
|
329
|
+
_Avoid_: Client, buyer, account
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## 规则
|
|
333
|
+
|
|
334
|
+
- **要有主见。** 当同一概念存在多个词时,选择最好的那个,并将其他的列在 `_Avoid_` 下。不要犹豫——明确选定一个规范术语。
|
|
335
|
+
- **定义保持精炼。** 最多一两句话。定义它是什么,而不是它做什么。术语的定义描述概念的本质,而非其行为或实现。
|
|
336
|
+
- **仅包含特定于该项目上下文的术语。** 通用的编程概念(超时、错误类型、工具模式)即使项目广泛使用也不属于这里。添加术语前自问:这是该上下文独有的概念,还是一个通用编程概念?只有前者才属于这里。
|
|
337
|
+
- **当自然形成聚类时,用子标题分组术语。** 如果所有术语属于一个单一的凝聚领域,扁平列表也可以。当术语数量超过 10 个时,几乎总能找到自然分组。
|
|
338
|
+
- **随时增删改。** 模型演进时,直接修改文件:添加新术语、删除废弃术语、修正定义、术语更名。不要堆积——保持词汇表精炼且反映当前模型。
|
|
339
|
+
|
|
340
|
+
## 增删改操作
|
|
341
|
+
|
|
342
|
+
### 新增术语
|
|
343
|
+
|
|
344
|
+
在合适的子标题下追加条目。如果现有子标题都不匹配,新建一个子标题。格式:
|
|
345
|
+
|
|
346
|
+
```md
|
|
347
|
+
**{术语名}**:
|
|
348
|
+
{定义}
|
|
349
|
+
_Avoid_: {避免使用的同义词,用逗号分隔}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### 修改术语
|
|
353
|
+
|
|
354
|
+
直接更新定义文本和 `_Avoid_` 列表。如果术语的含义已经变化,更新定义以反映当前理解。在 `_Avoid_` 中添加新出现的同义词,移除不再使用的同义词。
|
|
355
|
+
|
|
356
|
+
### 删除术语
|
|
357
|
+
|
|
358
|
+
移除整个条目(术语名、定义、`_Avoid_` 行)。如果术语已不再使用或已被其他术语替代,直接删除,不要保留废弃标记。词汇表只反映当前模型。
|
|
359
|
+
|
|
360
|
+
### 术语更名
|
|
361
|
+
|
|
362
|
+
删除旧条目,新增新条目。在 `_Avoid_` 中保留旧名称作为新术语的避免项——这样未来的读者能理解新旧术语的对应关系。例如,将 "Client" 更名为 "Customer":
|
|
363
|
+
|
|
364
|
+
```md
|
|
365
|
+
**Customer**:
|
|
366
|
+
下订单的个人或组织。
|
|
367
|
+
_Avoid_: Client, buyer, account
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
</context-format>
|
|
371
|
+
|
|
372
|
+
<log-format>
|
|
373
|
+
|
|
374
|
+
# LOG.md 格式
|
|
375
|
+
|
|
376
|
+
设计决策日志存放在变更目录的 `LOG.md` 中。它记录设计访谈中已经确认、延后或被替代的具体结论——"当时讨论了什么、最终固定了什么行为以及对应哪个 ADR"。与 CONTEXT.md 的精炼不同,LOG.md 可以记录讨论中的具体场景、边界条件和交互细节。
|
|
377
|
+
|
|
378
|
+
## 规则
|
|
379
|
+
|
|
380
|
+
- **记录每一次设计结论。** 无论大小,只要在访谈中确认、延后或被替代,都写入 LOG.md。宁可多记,不要遗漏。
|
|
381
|
+
- **状态驱动。** 每个条目明确标记 `accepted`、`deferred` 或 `superseded`,让读者一眼知道当前有效性。
|
|
382
|
+
- **关联 ADR。** 如果该结论同时满足 ADR 的三个条件,在 LOG 中标注 `Related: ADR-XXXX`,并在对应 ADR 条目中也关联回 LOG。
|
|
383
|
+
- **保持可修订。** 后续决定改变既有结论时,直接更新原条目状态和正文,不要新建一条矛盾的条目。标注 `Superseded by: LOG-XXXX`。
|
|
384
|
+
- **不堆积废弃条目。** 被替代的条目保留但标记清楚;延后(deferred)的条目保留以便后续恢复讨论。
|
|
385
|
+
- **记录具体交互和边界。** 与 CONTEXT.md 的精炼不同,LOG.md 可以记录讨论中的具体场景、边界条件和交互细节。
|
|
386
|
+
|
|
387
|
+
## 模板
|
|
388
|
+
|
|
389
|
+
```md
|
|
390
|
+
# 设计决策日志
|
|
391
|
+
|
|
392
|
+
本文件记录设计访谈中已经确认、延后或被替代的具体结论。它保存"当时讨论了什么、最终固定了什么行为以及对应哪个 ADR";CONTEXT.md 是规范词汇表,ADR.md 是难以逆转的架构决策,本文件则是可持续增删改的完整设计轨迹。
|
|
393
|
+
|
|
394
|
+
## 维护规则
|
|
395
|
+
|
|
396
|
+
- 每次完成一个设计问答,同步更新 LOG.md、CONTEXT.md 与 ADR.md。
|
|
397
|
+
- 已确认结论使用 `accepted`;暂不决定使用 `deferred`;被后续决定替代使用 `superseded`。
|
|
398
|
+
- 后续确认改变既有结论时,直接修订原日志条目,并记录替代关系,不保留互相矛盾的"现行规则"。
|
|
399
|
+
- 日志可以记录具体交互和边界;词汇表保持精炼;ADR 只记录难以逆转、令人意外且存在真实权衡的决定。
|
|
400
|
+
|
|
401
|
+
## LOG-0001: {状态} — {问题/主题}
|
|
402
|
+
|
|
403
|
+
Status: accepted
|
|
404
|
+
Related: ADR-0001
|
|
405
|
+
|
|
406
|
+
{背景:讨论了什么问题,做出了什么决定,以及为什么。可以记录具体的交互过程、边界场景和固定行为。}
|
|
407
|
+
|
|
408
|
+
## LOG-0002: {状态} — {另一问题/主题}
|
|
409
|
+
|
|
410
|
+
Status: deferred
|
|
411
|
+
|
|
412
|
+
{为什么暂不决定,以及后续恢复讨论时应从什么问题开始。}
|
|
413
|
+
|
|
414
|
+
## LOG-0003: {状态} — {被替代的问题/主题}
|
|
415
|
+
|
|
416
|
+
Status: superseded
|
|
417
|
+
Superseded by: LOG-0004
|
|
418
|
+
|
|
419
|
+
{原决策内容,以及为什么被替代。保留作为设计演进的历史上下文。}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## 状态说明
|
|
423
|
+
|
|
424
|
+
- **Status: accepted**——已确认的现行结论。这是讨论后用户明确同意的决定,当前仍然有效。
|
|
425
|
+
- **Status: deferred**——暂不决定,留待后续讨论。记录为什么暂不决定以及从什么角度恢复讨论,以便后续接续上下文。
|
|
426
|
+
- **Status: superseded**——被后续决定替代。标注 `Superseded by: LOG-XXXX` 指向替代条目。保留原条目作为设计演进的历史上下文。
|
|
427
|
+
|
|
428
|
+
## 追加新日志
|
|
429
|
+
|
|
430
|
+
1. 读取 `LOG.md`,找到最高现有编号
|
|
431
|
+
2. 编号加 1(从 `0001` 开始,不足四位补零)
|
|
432
|
+
3. 标题格式为 `## LOG-XXXX: {状态} — {问题/主题}`,必须能独立看出该条目回答了什么设计问题
|
|
433
|
+
4. 在文件末尾追加新条目
|
|
434
|
+
|
|
435
|
+
## 修改已有日志
|
|
436
|
+
|
|
437
|
+
- **改变结论**——将原条目状态改为 `superseded`,标注 `Superseded by: LOG-XXXX`,在新条目中说明替代原因。不要直接修改原条目的结论内容——保留它让读者能看到设计是如何演进的。
|
|
438
|
+
- **延后决定被重新讨论**——将状态从 `deferred` 改为 `accepted`,或新建条目替代原条目(原条目改为 `superseded`)。如果内容没有变化只是状态升级,可以直接改状态;如果结论发生了变化,使用替代模式。
|
|
439
|
+
- **补充细节**——直接编辑条目正文,不改变状态。可以追加更多场景、边界条件或交互细节。
|
|
440
|
+
- **关联 ADR**——如果后来为该日志创建了 ADR,补充 `Related: ADR-XXXX` 标注。
|
|
441
|
+
- **不要删除**——即使结论被替代,保留条目作为设计演进的历史上下文。
|
|
442
|
+
|
|
443
|
+
## 示例:被替代的日志
|
|
444
|
+
|
|
445
|
+
以下示例展示一条日志从 accepted 变为 superseded 的全过程:
|
|
446
|
+
|
|
447
|
+
原始条目:
|
|
448
|
+
|
|
449
|
+
```md
|
|
450
|
+
## LOG-0005: accepted — 订单状态机使用三态模型
|
|
451
|
+
|
|
452
|
+
Status: accepted
|
|
453
|
+
|
|
454
|
+
订单状态为 pending → confirmed → completed 的三态模型。
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
讨论后发现需要更细粒度,追加替代条目:
|
|
458
|
+
|
|
459
|
+
```md
|
|
460
|
+
## LOG-0005: superseded — 订单状态机使用三态模型
|
|
461
|
+
|
|
462
|
+
Status: superseded
|
|
463
|
+
Superseded by: LOG-0007
|
|
464
|
+
|
|
465
|
+
订单状态为 pending → confirmed → completed 的三态模型。后续讨论发现 confirmed 状态无法区分"已付款待发货"和"已发货待签收",因此改为五态模型。
|
|
466
|
+
|
|
467
|
+
## LOG-0007: accepted — 订单状态机使用五态模型
|
|
468
|
+
|
|
469
|
+
Status: accepted
|
|
470
|
+
|
|
471
|
+
订单状态为 pending → paid → shipped → delivered → completed 的五态模型。
|
|
472
|
+
详见 LOG-0005 的讨论背景。
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
</log-format>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# 编写 Spec
|
|
2
|
+
|
|
3
|
+
此 work 读取当前对话上下文和代码库理解,产出一份 spec(你可能也称之为 PRD)。不要访谈用户 —— 仅综合你已经知道的内容。
|
|
4
|
+
|
|
5
|
+
## 流程
|
|
6
|
+
|
|
7
|
+
### 1. 探索代码库
|
|
8
|
+
|
|
9
|
+
探索仓库以了解代码库的当前状态(如果尚未这样做)。在整个 spec 中使用项目的领域词汇表,并尊重所涉及区域的任何 ADR。
|
|
10
|
+
|
|
11
|
+
先读取 ``CONTEXT`` 了解项目的领域词汇表——使用其中的术语定义,不要自创名称。
|
|
12
|
+
|
|
13
|
+
再读取 ``ADR`` 了解已做出的架构决策——不要与已有决策冲突。如果 spec 涉及与某 ADR 相同或相邻的区域,在实现决策中引用该 ADR。
|
|
14
|
+
|
|
15
|
+
`{change}` 为当前活跃变更的目录名,格式为 `<YYYY-MM-DD>-<topic>`。如果尚未创建变更目录,先运行 ``G-grill-with-docs`` 的启动变更阶段初始化 CONTEXT.md 和 ADR.md。
|
|
16
|
+
|
|
17
|
+
**完成标准**:代码库当前状态已理解,领域词汇表和 ADR 已纳入考量。
|
|
18
|
+
|
|
19
|
+
### 2. 草拟接缝
|
|
20
|
+
|
|
21
|
+
草拟你将用于测试该功能的接缝(seam)。接缝是你可以插入测试以验证行为的位置——API 端点、CLI 命令、UI 交互点、事件回调等。
|
|
22
|
+
|
|
23
|
+
**接缝规则:**
|
|
24
|
+
|
|
25
|
+
- 优先使用现有接缝而不是新建。查看代码库中已有的测试,了解项目如何注入测试。
|
|
26
|
+
- 使用尽可能高层的接缝。UI 测试 > API 测试 > 单元测试,按此优先级选择。
|
|
27
|
+
- 如果需要新接缝,在尽可能高的层级提出。代码库中的接缝越少越好 —— 理想数量是 1 个。
|
|
28
|
+
- 每个接缝描述:接缝位置(什么模块/组件)、接缝类型(E2E、API、单元)、何时触发、如何验证。
|
|
29
|
+
|
|
30
|
+
**与用户确认这些接缝是否符合他们的期望。** 展示草拟的接缝列表,询问:
|
|
31
|
+
- 接缝层级是否合适?(太高可能遗漏细节,太低可能过于脆弱)
|
|
32
|
+
- 是否有遗漏的接缝?
|
|
33
|
+
- 现有接缝是否已足够,无需新增?
|
|
34
|
+
|
|
35
|
+
**完成标准**:测试接缝已草拟并经用户确认。
|
|
36
|
+
|
|
37
|
+
### 3. 编写 spec
|
|
38
|
+
|
|
39
|
+
按以下模板编写完整 spec,写入 ``spec``。
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
**问题陈述** —— 从用户视角描述用户面临的问题。不要描述技术问题——描述用户遇到的困境、无法完成的任务、或当前流程中的痛点。一两段即可,但必须具体到让读者理解"为什么需要这个功能"。
|
|
44
|
+
|
|
45
|
+
**解决方案** —— 从用户视角描述问题的解决方案。描述用户将如何与新功能交互、他们的体验将如何改变。不要写实现细节——写用户能做什么、看到什么。一两段即可。
|
|
46
|
+
|
|
47
|
+
**用户故事** —— 一个详细的、编号的用户故事列表。每个用户故事格式为:
|
|
48
|
+
|
|
49
|
+
> 作为 <角色>,我希望 <功能>,以便 <收益>
|
|
50
|
+
|
|
51
|
+
例如:*作为手机银行客户,我希望查看账户余额,以便做出更明智的消费决策。*
|
|
52
|
+
|
|
53
|
+
用户故事列表应极其详尽,涵盖该功能的所有方面。覆盖以下维度:
|
|
54
|
+
- 主要流程(happy path)—— 用户最常走的路径
|
|
55
|
+
- 边界情况 —— 空数据、极限值、并发操作
|
|
56
|
+
- 错误处理 —— 用户犯错时发生什么
|
|
57
|
+
- 权限与角色 —— 不同角色的不同体验
|
|
58
|
+
- 状态转换 —— 数据从创建到归档的每个状态变化
|
|
59
|
+
|
|
60
|
+
**实现决策** —— 已做出的实现决策列表。可包含:将构建/修改的模块、这些模块将被修改的接口、开发者的技术澄清、架构决策、Schema 变更、API 契约、具体交互。不要包含具体文件路径或代码片段——它们可能很快过时。
|
|
61
|
+
|
|
62
|
+
例外:如果原型产生了一个代码片段,它比文字更精确地编码了一个决策(状态机、reducer、schema、类型结构),将其内联在相关决策中,并简要注明来自原型。精简到富含决策的部分 —— 不是可运行的演示,只是关键部分。
|
|
63
|
+
|
|
64
|
+
**测试决策** —— 已做出的测试决策列表。包含:什么构成好测试的描述(只测试外部行为,不测试实现细节)、哪些模块将被测试、测试的先例(即代码库中类似类型的测试)。
|
|
65
|
+
|
|
66
|
+
**超出范围** —— 描述此 spec 超出范围的内容。明确说出**不做什么**与说出做什么同样重要。对于每个超出范围的条目,简要说明原因(是后续版本的规划、还是技术上不可行、还是与产品愿景不符)。
|
|
67
|
+
|
|
68
|
+
**补充说明** —— 关于该功能的任何补充说明。可包含:已知风险或不确定性、依赖的外部系统或团队、需要进一步调研的领域、迁移或废弃计划。
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
写入后,不要做额外的 triage 或标签操作——spec.md 的地位由其在变更目录中的存在本身决定。
|
|
73
|
+
|
|
74
|
+
**完成标准**:spec.md 已写入变更目录——问题陈述、解决方案、用户故事、实现决策、测试决策、超出范围、补充说明各章节齐全,无残留 `[TODO:]`。
|
|
75
|
+
|
|
76
|
+
## 子文件引用
|
|
77
|
+
|
|
78
|
+
本入口为单文件 work,所有内容均已内联。以下引用仅在其他 work 需要读取 spec 时使用:
|
|
79
|
+
|
|
80
|
+
- ``spec`` —— 编写的 spec 产物
|
|
81
|
+
- CONTEXT.md —— 领域词汇表(阅读用)
|
|
82
|
+
- ADR.md —— 架构决策记录(阅读用)
|