@namewta/speculo 0.1.16 → 0.1.18
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/package.json +1 -1
- package/template/skills/speculo-write/SKILL.md +7 -4
- package/template/skills/speculo-write/references/asset-selection-sop.md +2 -0
- package/template/skills/speculo-write/references/authoring-quality-levers.md +61 -0
- package/template/skills/speculo-write/references/command-authoring-sop.md +1 -1
- package/template/skills/speculo-write/references/skill-authoring-sop.md +10 -0
- package/template/skills/speculo-write/references/validation-checklist.md +10 -0
- package/template/skills/speculo-write/references/workflow-authoring-sop.md +2 -0
- package/template/vendor/codebase-design/DEEPENING.md +37 -0
- package/template/vendor/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/template/vendor/codebase-design/SKILL.md +114 -0
- package/template/vendor/resolving-merge-conflicts/SKILL.md +14 -0
- package/template/workflows/dev/00-INDEX.md +7 -1
- package/template/workflows/dev/01-grill-with-docs/01-grill-with-docs.md +2 -2
- package/template/workflows/dev/01-grill-with-docs/grill-decision.md +2 -2
- package/template/workflows/dev/02-prd/02-prd.md +2 -0
- package/template/workflows/dev/03-tdd/03-tdd.md +12 -6
- package/template/workflows/dev/03-tdd/mocking.md +9 -26
- package/template/workflows/dev/03-tdd/tdd-plan.md +1 -1
- package/template/workflows/dev/04-finalize/04-finalize.md +1 -0
- package/template/workflows/dev/A-improve-architecture/A-improve-architecture.md +143 -0
- package/template/workflows/dev/A-improve-architecture/HTML-REPORT.md +123 -0
- package/template/workflows/dev/D-docs-sync/D-docs-sync.md +2 -0
- package/template/workflows/dev/H-diagnose/diagnose-guide.md +1 -1
- package/template/workflows/dev/I-to-issues/I-to-issues.md +1 -0
- package/template/workflows/dev/I-to-issues/issues-slices.md +2 -0
- package/template/workflows/dev/{01-grill-with-docs → M-domain-modeling}/ADR-FORMAT.md +4 -4
- package/template/workflows/dev/{01-grill-with-docs → M-domain-modeling}/CONTEXT-FORMAT.md +4 -2
- package/template/workflows/dev/M-domain-modeling/M-domain-modeling.md +118 -0
- package/template/workflows/dev/_templates/domain-model-log-template.md +20 -0
- package/template/workflows/dev/03-tdd/deep-modules.md +0 -33
- package/template/workflows/dev/03-tdd/interface-design.md +0 -31
package/package.json
CHANGED
|
@@ -7,6 +7,8 @@ description: 创建或改造 Speculo workflows、skills、commands 的原子能
|
|
|
7
7
|
|
|
8
8
|
# Speculo Write
|
|
9
9
|
|
|
10
|
+
创作任何 Speculo 资产的根本美德是**可预测性**——让代理每次运行采用相同的*过程*(而非相同输出)。本 skill 自带全部 Speculo 规范(路径、frontmatter、持久化)与质量杠杆(`references/authoring-quality-levers.md`),并以身作则遵守它们。
|
|
11
|
+
|
|
10
12
|
## 何时使用
|
|
11
13
|
|
|
12
14
|
当任务是新增、迁移、融合或改造 Speculo 的 `workflows/`、`skills/`、`commands/`、配套模板、引用资料或 `speculo/.speculo/` 状态骨架时使用。
|
|
@@ -37,13 +39,14 @@ description: 创建或改造 Speculo workflows、skills、commands 的原子能
|
|
|
37
39
|
|
|
38
40
|
1. **判定资产类型** —— workflow、skill、command,或组合。规则见 `references/asset-selection-sop.md`。
|
|
39
41
|
2. **读取同类资产** —— 看目标目录里现有资产的真实写法,对齐风格,不直接套用外部技能格式。
|
|
40
|
-
3. **提取可复用行为** —— 从参考材料保留核心内容(触发、输入输出、铁律、边界、失败恢复、模板),只规范化路径、frontmatter
|
|
41
|
-
4. **设计文件结构** ——
|
|
42
|
-
5. **实施** ——
|
|
43
|
-
6. **验证** ——
|
|
42
|
+
3. **提取可复用行为** —— 从参考材料保留核心内容(触发、输入输出、铁律、边界、失败恢复、模板),只规范化路径、frontmatter、产物和渐进披露;跨资产共享的规范**引用单一事实源、不复制**。
|
|
43
|
+
4. **设计文件结构** —— 入口、别名、状态字段、产物路径和验证清单;按**信息层级**(步骤 / 文件内参考 / 已披露参考)排布,保持入口阶梯顶部清晰,能下推就下推(见 `references/authoring-quality-levers.md`)。
|
|
44
|
+
5. **实施** —— 实施前确认不会覆盖用户已有改动;用**主导词**锚定执行与调用,完成准则做到可检验且在重要处穷尽;实施后同步索引、文档和测试。
|
|
45
|
+
6. **验证** —— 旧路径和旧工具名没有回流,运行项目测试或记录无法运行原因;对照 `references/authoring-quality-levers.md` 的失败模式与空操作测试逐句修剪;提交前过一遍 `references/validation-checklist.md`。
|
|
44
46
|
|
|
45
47
|
## 渐进披露
|
|
46
48
|
|
|
49
|
+
- `references/authoring-quality-levers.md`:贯穿全程的质量理论——可预测性、主导词、信息层级、完成标准、何时拆分、修剪与失败模式;设计结构、措辞、修剪和验收时读取。
|
|
47
50
|
- `references/asset-selection-sop.md`:判断应做 workflow、skill 还是 command 时读取。
|
|
48
51
|
- `references/workflow-authoring-sop.md`:创建或改造 workflow、phase、template、索引和状态字段时读取。
|
|
49
52
|
- `references/skill-authoring-sop.md`:创建原子 skill、迁移外部技能、拆分 references 时读取。
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
把用户的“做一个能力”翻译成 Speculo 的正确资产形态:workflow、skill、command,或它们的组合。
|
|
6
6
|
|
|
7
|
+
> **粒度即拆分成本**(见 `authoring-quality-levers.md`「何时拆分」):把流程切成 workflow 的多个 phase,是为了把**后续步骤**移出视野、防过早完成(**按序列拆分**);把能力抽成可复用 skill,是为了独立触达、值回其 `description` 常驻系统提示的负载(**按调用拆分**)。每次切割都有成本,只在物有所值时拆。
|
|
8
|
+
|
|
7
9
|
## 判定规则
|
|
8
10
|
|
|
9
11
|
### 做 Workflow
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Authoring Quality Levers
|
|
2
|
+
|
|
3
|
+
把「编写出色技能」的领域模型内化到 Speculo 资产创作(workflow / skill / command)。**所有杠杆都服务一个根本美德:可预测性**——让代理每次运行采用相同的*过程*(而非相同的输出)。成本与可维护性是它的症状,不是对手。
|
|
4
|
+
|
|
5
|
+
本文是质量理论的**单一事实源**:`skill-authoring-sop.md`、`workflow-authoring-sop.md`、`command-authoring-sop.md`、`validation-checklist.md` 按需引用本文,不复述其内容。
|
|
6
|
+
|
|
7
|
+
## 主导词(Leading Word)
|
|
8
|
+
|
|
9
|
+
一个已存在于模型预训练中的紧凑概念(如 *lesson*、*fog of war*、*tracer bullet*;Speculo 里的*切片 / 接缝 / 红绿重构 / 门控 / 深模块*),代理运行资产时用它思考。作为一个 token 反复出现(而非整句),用最少 token 锚定整个行为区域。
|
|
10
|
+
|
|
11
|
+
它两次服务可预测性:在正文锚定**执行**(每次遇到该词都采取相同行为);在 `description` 与别名里锚定**调用**(同一个词出现在提示、文档、代码里,代理更可靠地触发该资产)。
|
|
12
|
+
|
|
13
|
+
- 优先用预训练已有的词;自造词不招募任何先验,要用定义 token 付费。
|
|
14
|
+
- 在 `description`、phase 名、完成准则里用你*真正会用来唤起该资产*的主导词。
|
|
15
|
+
- 把「在三处拼写出的三元组」「用一句话指一个想法」折叠成一个 token。
|
|
16
|
+
|
|
17
|
+
## 信息层级(Information Hierarchy)
|
|
18
|
+
|
|
19
|
+
内容按代理需要它的紧迫程度排成**一个阶梯**,由两次切分产生:
|
|
20
|
+
|
|
21
|
+
1. **步骤**——入口里的有序操作(workflow 的 `## 阶段`、skill 的 `## 执行步骤`)。主层级。每个步骤以**完成标准**结束。
|
|
22
|
+
2. **文件内参考**——入口里随手查阅的定义 / 规则 / 事实。次层级。常是合法的扁平同级集合(审查类技能每条规则平级,不是坏味道)。
|
|
23
|
+
3. **已披露参考**——推到 `references/` 或 phase 文件,经**上下文指针**按需加载。
|
|
24
|
+
|
|
25
|
+
不是每个资产都有步骤:可以全是步骤、全是参考、或两者兼有。保持阶梯顶部清晰,能下推就下推。
|
|
26
|
+
|
|
27
|
+
**渐进披露**=沿阶梯下移以保护层级(主要不是 token 优化)。由**分支**授权:只把*部分*运行才需要的材料推到指针后,每条路径都需要的内联。**上下文指针的措辞**(而非目标)决定代理何时、多可靠地取用——指针对必备材料触发不可靠时,先改措辞,失败才内联。
|
|
28
|
+
|
|
29
|
+
**就近放置(Co-location)**:一个概念的定义、规则、注意事项放在同一标题下,而非散落——读一部分就连带看到相邻内容。与「重复」相反:重复是一个含义出现在多处,散落是一个含义被拆到多处。
|
|
30
|
+
|
|
31
|
+
## 完成标准(Completion Criterion)
|
|
32
|
+
|
|
33
|
+
告诉代理一个工作单元已完成的判断条件。两个属性使它成为杠杆,而不只是质量指标:
|
|
34
|
+
|
|
35
|
+
- **可检验**:代理能区分完成与未完成吗?模糊的界限(「理解达到」)让代理宣布完成并滑向下一步(**过早完成**)。
|
|
36
|
+
- **穷尽**:「每个修改过的模型都已纳入」强于「生成变更列表」。穷尽轴*不受步骤限制*,也约束扁平参考(「每条规则都已应用」)——这正是无步骤资产仍能驱动彻底**调研工作**的力量。
|
|
37
|
+
|
|
38
|
+
最强的完成标准既可检验又穷尽。Speculo 的「`xxx.md` 无残留 `[TODO:]`」是可检验的最低线;在重要处补穷尽项。
|
|
39
|
+
|
|
40
|
+
## 何时拆分
|
|
41
|
+
|
|
42
|
+
每次切割都消耗成本,只在物有所值时拆:
|
|
43
|
+
|
|
44
|
+
- **按序列拆分**——当一个步骤的**后续步骤**诱使代理匆忙了事(过早完成)时,把序列拆成两段、把后续步骤移出视野。这正是 Speculo 把 workflow 切成 phase、把 phase 隔离到独立文件的原因。注意反面:把序列并回一个文件,会把后续步骤暴露给当前步骤。
|
|
45
|
+
- **按复用 / 调用拆分**——当一段能力会被多个入口复用,或需要独立触发时,抽成 skill。你为它的 `description`(常驻系统提示)付出代价,因此这种独立触达必须值回票价。判定细节见 `asset-selection-sop.md`。
|
|
46
|
+
|
|
47
|
+
## 修剪
|
|
48
|
+
|
|
49
|
+
- **单一事实来源**:每个含义只存在于唯一权威位置,改行为只需一处编辑。跨资产共享的规范放进被引用的单一文件(如 `vendor/codebase-design`、本文),引用方**不复制**。
|
|
50
|
+
- **相关性**:逐行问「它是否仍影响资产行为?」——越短的资产越容易保持相关。
|
|
51
|
+
- **空操作测试**:逐*句*问「相对默认行为,这句改变了什么吗?」模型默认就会做的事=空操作,付出负载却什么都没说。果断删整句,而非修剪词语。弱主导词(代理本就 thorough 时还说 *be thorough*)是空操作——换更强的词(*relentless*),而非换技术。
|
|
52
|
+
|
|
53
|
+
## 失败模式
|
|
54
|
+
|
|
55
|
+
用于诊断资产问题:
|
|
56
|
+
|
|
57
|
+
- **过早完成**——步骤真正完成前就收尾,注意力滑向「完成态」。先锐化完成标准(廉价、局部);只有当它本质模糊*且*确实观察到匆忙时,才用序列拆分隐藏后续步骤(且只在真正的上下文边界——command 交接 / 子代理派发——才有效,内联的引用清不掉后续步骤)。
|
|
58
|
+
- **重复**——同一含义有多个事实来源。涨维护成本与 token,并夸大该含义在阶梯上的权重。是主导词的意外逆操作(主导词有意重复一个 *token* 而非*含义*)。
|
|
59
|
+
- **沉积**——陈旧层因「加安全、删有风险」而堆积,得钻过它们才找到仍有效的内容。无修剪纪律资产的默认命运。
|
|
60
|
+
- **蔓延**——单纯太长(即便每行都鲜活、独特)。解药是信息层级:把参考推到指针后,按分支或序列拆分。
|
|
61
|
+
- **空操作**——见上「修剪」。
|
|
@@ -93,4 +93,4 @@ command 产物模板内联在文件末尾。模板占位符使用 `[TODO: ...]`
|
|
|
93
93
|
- 归档路径是否位于 `speculo/.speculo/commands/<YYYY-MM-DD>-<command>-<topic>/`
|
|
94
94
|
- 被调用 skill 是否没有自选 `temp/`、系统临时目录或项目根目录作为持久化位置
|
|
95
95
|
|
|
96
|
-
`speculo/.speculo/commands/` 归档路径、frontmatter 最小集与写入责任见 `persistence-contract-sop.md`。
|
|
96
|
+
`speculo/.speculo/commands/` 归档路径、frontmatter 最小集与写入责任见 `persistence-contract-sop.md`;`description`、完成准则与修剪的质量杠杆见 `authoring-quality-levers.md`。
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
本文是 Speculo 原子 skill 的编写规范,复刻通用「编写技能」流程并收敛到 Speculo 约束。
|
|
4
4
|
本文已内化全部所需规范;编写 skill 时**不读仓库 `docs/`**,只读本 skill 的 `references/`。
|
|
5
5
|
|
|
6
|
+
质量理论(**可预测性**、**主导词**、**信息层级**、**完成标准**、**修剪**、**失败模式**)是所有 Speculo 资产共享的单一事实源,见 `authoring-quality-levers.md`;本文只补 skill 特有的流程与约束,不复述理论。
|
|
7
|
+
|
|
6
8
|
## 流程
|
|
7
9
|
|
|
8
10
|
1. **收集需求** —— 向用户确认:
|
|
@@ -60,6 +62,8 @@ description 是 **agent 决定加载哪个 skill 时唯一能看到的内容**
|
|
|
60
62
|
- 第三人称
|
|
61
63
|
- 第一句:做什么
|
|
62
64
|
- 第二句:「当 [具体触发条件] 时使用」
|
|
65
|
+
- 用**主导词**措辞触发条件——你真正会用来唤起该 skill 的那个词;同一个词出现在描述、文档、代码里会更可靠地触发(见 `authoring-quality-levers.md`)
|
|
66
|
+
- 每个分支只写一个触发器:换名重写同一分支是**重复**,折叠它
|
|
63
67
|
|
|
64
68
|
**好的例子**:
|
|
65
69
|
|
|
@@ -132,6 +136,8 @@ description: <能力 + 触发场景,第三人称>
|
|
|
132
136
|
|
|
133
137
|
reference 文件用 kebab-case,**按任务而非来源**命名(`workflow-authoring-sop.md`,不是 `from-specforge.md`)。
|
|
134
138
|
|
|
139
|
+
渐进披露的本质是保护**信息层级**、让入口阶梯顶部保持清晰(不只是省 token),由**分支**授权:只把*部分*运行才需要的材料推到指针后,每条路径都需要的内联。指针的**措辞**决定取用时机与可靠性——必备材料触发不可靠时先改措辞、失败才内联(见 `authoring-quality-levers.md`)。
|
|
140
|
+
|
|
135
141
|
## 何时添加脚本
|
|
136
142
|
|
|
137
143
|
**加 `scripts/`**,当操作确定且反复执行:
|
|
@@ -199,4 +205,8 @@ skill **禁止自行选择**持久化位置,包括:
|
|
|
199
205
|
- [ ] 没有 README / INSTALLATION / CHANGELOG 等冗余文件
|
|
200
206
|
- [ ] 没有时效性信息、旧项目路径、旧工具名或绝对路径绑定
|
|
201
207
|
- [ ] 术语一致、含具体示例、引用只有一层深度
|
|
208
|
+
- [ ] description 与正文用**主导词**锚定调用与执行
|
|
209
|
+
- [ ] 完成标准 / 审查项**可检验**,重要处**穷尽**(驱动彻底调研工作,防过早完成)
|
|
210
|
+
- [ ] 逐句过**空操作测试**(删掉模型默认就会做的句子),无**重复 / 沉积 / 蔓延**
|
|
211
|
+
- [ ] 跨资产共享规范引用**单一事实源**、未复制
|
|
202
212
|
- [ ] 若是内置资产,CLI tests 覆盖复制该 skill
|
|
@@ -16,6 +16,16 @@
|
|
|
16
16
|
- [ ] command frontmatter 包含 `id`、`type: command`、`name`、`description`,可选 `keywords`
|
|
17
17
|
- [ ] 没有把 phases、templates、depends_on、status_extensions 写进 frontmatter
|
|
18
18
|
|
|
19
|
+
## 质量杠杆检查
|
|
20
|
+
|
|
21
|
+
> 适用于所有资产类型;理论见 `authoring-quality-levers.md`。
|
|
22
|
+
|
|
23
|
+
- [ ] description / 入口用**主导词**锚定调用,正文用同一主导词锚定执行
|
|
24
|
+
- [ ] 内容按**信息层级**排布(步骤 / 文件内参考 / 已披露参考),入口阶梯顶部清晰
|
|
25
|
+
- [ ] 每个步骤 / phase 的**完成标准**可检验,重要处穷尽
|
|
26
|
+
- [ ] 跨资产共享含义只有**单一事实源**,引用方未复制
|
|
27
|
+
- [ ] 逐句过**空操作测试**,无**过早完成 / 重复 / 沉积 / 蔓延**诱因
|
|
28
|
+
|
|
19
29
|
## Workflow 检查
|
|
20
30
|
|
|
21
31
|
- [ ] 入口正文包含 `## 阶段`
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# 深化(Deepening)
|
|
2
|
+
|
|
3
|
+
如何在给定依赖关系的情况下,安全地深化一组浅模块。假定使用 [SKILL.md](SKILL.md) 中的术语——**module(模块)**、**interface(接口)**、**seam(接缝)**、**adapter(适配器)**。
|
|
4
|
+
|
|
5
|
+
## 依赖分类
|
|
6
|
+
|
|
7
|
+
在评估深化候选时,对其依赖进行分类。分类决定了深化后的模块如何跨接缝进行测试。
|
|
8
|
+
|
|
9
|
+
### 1. 进程内(In-process)
|
|
10
|
+
|
|
11
|
+
纯计算、内存状态、无 I/O。始终可深化——合并模块,直接通过新接口进行测试。不需要适配器。
|
|
12
|
+
|
|
13
|
+
### 2. 本地可替换(Local-substitutable)
|
|
14
|
+
|
|
15
|
+
具有本地测试替代方案的依赖(Postgres 用 PGLite、内存文件系统)。如果存在替代方案则可深化。深化后的模块在测试套件中运行替代方案进行测试。接缝是内部的;模块外部接口处没有端口。
|
|
16
|
+
|
|
17
|
+
### 3. 远程但自有(Remote but owned)(端口与适配器)
|
|
18
|
+
|
|
19
|
+
跨网络边界的自有服务(微服务、内部 API)。在接缝处定义一个**端口(port)**(接口)。深度模块拥有逻辑;传输层作为**适配器(adapter)**注入。测试使用内存适配器。生产环境使用 HTTP/gRPC/队列适配器。
|
|
20
|
+
|
|
21
|
+
推荐形式:*"在接缝处定义一个端口,为生产环境实现 HTTP 适配器,为测试实现内存适配器,这样即使逻辑部署跨网络,仍位于一个深度模块中。"*
|
|
22
|
+
|
|
23
|
+
### 4. 真正外部(True external)(Mock)
|
|
24
|
+
|
|
25
|
+
你无法控制的第三方服务(Stripe、Twilio 等)。深化后的模块将外部依赖作为注入端口接收;测试提供 mock 适配器。
|
|
26
|
+
|
|
27
|
+
## 接缝纪律
|
|
28
|
+
|
|
29
|
+
- **一个适配器意味着假设的接缝。两个适配器才意味着真正的接缝。** 除非至少有两个适配器是合理的(通常是生产 + 测试),否则不要引入端口。单适配器接缝只是间接层。
|
|
30
|
+
- **内部接缝 vs 外部接缝。** 深度模块可以有内部接缝(对其实现私有,由其自身测试使用)以及其接口处的外部接缝。不要因为测试使用了内部接缝就通过接口暴露它们。
|
|
31
|
+
|
|
32
|
+
## 测试策略:替换,而非叠加
|
|
33
|
+
|
|
34
|
+
- 一旦深化模块接口层面的测试存在,浅模块的旧单元测试就成为废料——删除它们。
|
|
35
|
+
- 在深化模块的接口层面编写新测试。**接口就是测试面**。
|
|
36
|
+
- 测试通过接口断言可观察的结果,而非内部状态。
|
|
37
|
+
- 测试应能经受内部重构——它们描述的是行为,而非实现。如果一个测试在实现变更时必须随之改变,那它就是在测试接口背后的内容。
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# 设计两次(Design It Twice)
|
|
2
|
+
|
|
3
|
+
当用户想要为选定的深化候选探索替代接口时,使用此并行子代理模式。基于"设计两次"(Ousterhout)——你的第一个想法不太可能是最好的。
|
|
4
|
+
|
|
5
|
+
使用 [SKILL.md](SKILL.md) 中的术语——**module(模块)**、**interface(接口)**、**seam(接缝)**、**adapter(适配器)**、**leverage(杠杆)**。
|
|
6
|
+
|
|
7
|
+
## 流程
|
|
8
|
+
|
|
9
|
+
### 1. 界定问题空间
|
|
10
|
+
|
|
11
|
+
在生成子代理之前,为选定候选编写面向用户的问题空间说明:
|
|
12
|
+
|
|
13
|
+
- 任何新接口需要满足的约束
|
|
14
|
+
- 它将依赖的依赖项,以及它们属于哪个类别(参见 [DEEPENING.md](DEEPENING.md))
|
|
15
|
+
- 一个粗略的说明性代码草图,用于将约束具体化——不是提案,只是将约束变得具体的方式
|
|
16
|
+
|
|
17
|
+
将此展示给用户,然后立即进入第 2 步。用户在子代理并行工作时阅读和思考。
|
|
18
|
+
|
|
19
|
+
### 2. 生成子代理
|
|
20
|
+
|
|
21
|
+
使用 Agent 工具并行生成 3 个以上的子代理。每个子代理必须为深化后的模块生成一个**截然不同**的接口。
|
|
22
|
+
|
|
23
|
+
为每个子代理提供一个单独的技术概要(文件路径、耦合细节、来自 [DEEPENING.md](DEEPENING.md) 的依赖类别、接缝背后的内容)。该概要独立于第 1 步中面向用户的问题空间说明。给每个代理不同的设计约束:
|
|
24
|
+
|
|
25
|
+
- 代理 1:"最小化接口——目标是最多 1–3 个入口点。最大化每个入口点的杠杆效应。"
|
|
26
|
+
- 代理 2:"最大化灵活性——支持多种用例和扩展。"
|
|
27
|
+
- 代理 3:"针对最常见调用方优化——让默认情况变得简单。"
|
|
28
|
+
- 代理 4(如适用):"围绕端口与适配器设计跨接缝依赖。"
|
|
29
|
+
|
|
30
|
+
在概要中同时包含 [SKILL.md](SKILL.md) 词汇和 CONTEXT.md 词汇,以便每个子代理在命名时与架构语言和项目的领域语言保持一致。
|
|
31
|
+
|
|
32
|
+
每个子代理输出:
|
|
33
|
+
|
|
34
|
+
1. 接口(类型、方法、参数——加上不变量、排序、错误模式)
|
|
35
|
+
2. 使用示例,展示调用方如何使用
|
|
36
|
+
3. 实现隐藏在接缝背后的内容
|
|
37
|
+
4. 依赖策略和适配器(参见 [DEEPENING.md](DEEPENING.md))
|
|
38
|
+
5. 权衡——杠杆效应高的地方,薄弱的地方
|
|
39
|
+
|
|
40
|
+
### 3. 展示与比较
|
|
41
|
+
|
|
42
|
+
依次展示设计,以便用户逐一消化,然后用文字进行比较。通过**深度**(接口层面的杠杆效应)、**局部性**(变更集中的位置)和**接缝位置**进行对比。
|
|
43
|
+
|
|
44
|
+
比较后,给出你自己的推荐:你认为哪个设计最强以及为什么。如果来自不同设计的元素可以很好地组合,提出一个混合方案。要有明确的观点——用户想要的是一个强有力的解读,而不是一份菜单。
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codebase-design
|
|
3
|
+
description: 设计深层模块的共享词汇。适用于用户想要设计或改进模块接口、寻找深化机会、决定接缝位置、使代码更可测试或对 AI 更可导航,或其他技能需要深层模块词汇的场景。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 代码库设计
|
|
7
|
+
|
|
8
|
+
设计**深层模块**:大量行为隐藏在小型接口之后,放置在清晰的接缝处,通过该接口可测试。在任何设计或重构代码的地方使用这套语言和原则。目标是为调用者提供杠杆,为维护者提供局部性,为所有人提供可测试性。
|
|
9
|
+
|
|
10
|
+
## 词汇表
|
|
11
|
+
|
|
12
|
+
严格使用这些术语——不要替换为"组件"、"服务"、"API"或"边界"。一致的语言是全部要点。
|
|
13
|
+
|
|
14
|
+
**模块**——任何有接口和实现的东西。刻意与规模无关:一个函数、类、包或跨层切片。*避免*:单元、组件、服务。
|
|
15
|
+
|
|
16
|
+
**接口**——调用者正确使用模块必须知道的一切:类型签名,还有不变量、排序约束、错误模式、所需配置和性能特征。*避免*:API、签名(太窄——它们仅指向类型层面的表面)。
|
|
17
|
+
|
|
18
|
+
**实现**——模块内部的内容,其代码体。区别于**适配器**:一个东西可以是一个小适配器带大实现(一个 Postgres 仓库)或一个大适配器带小实现(一个内存假对象)。当接缝是主题时用"适配器";否则用"实现"。
|
|
19
|
+
|
|
20
|
+
**深度**——接口处的杠杆:调用者(或测试)每学习单位接口能运用的行为量。一个模块是**深的**,当大量行为隐藏在小型接口之后;是**浅的**,当接口几乎和实现一样复杂。
|
|
21
|
+
|
|
22
|
+
**接缝** *(Michael Feathers)*——一个可以在不编辑该处的情况下改变行为的地方;模块接口所在的*位置*。接缝放在哪里是其自身的设计决策,区别于接缝后面是什么。*避免*:边界(被 DDD 的有界上下文过载)。
|
|
23
|
+
|
|
24
|
+
**适配器**——在接缝处满足接口的具体事物。描述*角色*(它填补哪个槽位),而非实质(里面是什么)。
|
|
25
|
+
|
|
26
|
+
**杠杆**——调用者从深度中获得的东西:每学习单位接口获得更多能力。一个实现付出,在 N 个调用点和 M 个测试中获得回报。
|
|
27
|
+
|
|
28
|
+
**局部性**——维护者从深度中获得的东西:变更、bug、知识和验证集中在一处,而不是分散在调用者中。一处修复,处处修复。
|
|
29
|
+
|
|
30
|
+
## 深 vs 浅
|
|
31
|
+
|
|
32
|
+
**深层模块** = 小接口 + 大量实现:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
┌─────────────────────┐
|
|
36
|
+
│ 小型接口 │ ← 少数方法,简单参数
|
|
37
|
+
├─────────────────────┤
|
|
38
|
+
│ │
|
|
39
|
+
│ 深层实现 │ ← 复杂逻辑隐藏
|
|
40
|
+
│ │
|
|
41
|
+
└─────────────────────┘
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**浅层模块** = 大接口 + 少量实现(应避免):
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
┌─────────────────────────────────┐
|
|
48
|
+
│ 大型接口 │ ← 许多方法,复杂参数
|
|
49
|
+
├─────────────────────────────────┤
|
|
50
|
+
│ 薄实现 │ ← 只是传递
|
|
51
|
+
└─────────────────────────────────┘
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
设计接口时,问:
|
|
55
|
+
|
|
56
|
+
- 我能减少方法数量吗?
|
|
57
|
+
- 我能简化参数吗?
|
|
58
|
+
- 我能隐藏更多复杂性在内部吗?
|
|
59
|
+
|
|
60
|
+
## 原则
|
|
61
|
+
|
|
62
|
+
- **深度是接口的属性,而非实现的属性。** 一个深层模块可以在内部由小型、可 mock、可替换的部件组成——它们只是不是接口的一部分。一个模块可以有**内部接缝**(对其实现私有,由其自己的测试使用)以及其接口处的**外部接缝**。
|
|
63
|
+
- **删除测试。** 想象删除该模块。如果复杂性消失,它就是个传递。如果复杂性在 N 个调用者中重新出现,它就在赚取它的价值。
|
|
64
|
+
- **接口就是测试表面。** 调用者和测试跨越同一接缝。如果你想测试到接口*之外*,模块的形状可能不对。
|
|
65
|
+
- **一个适配器意味着假设的接缝。两个适配器意味着真实的接缝。** 除非某物确实在接缝处变化,否则不要引入接缝。
|
|
66
|
+
|
|
67
|
+
## 为可测试性设计
|
|
68
|
+
|
|
69
|
+
好的接口使测试变得自然:
|
|
70
|
+
|
|
71
|
+
1. **接受依赖,而非创建依赖。**
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// 可测试
|
|
75
|
+
function processOrder(order, paymentGateway) {}
|
|
76
|
+
|
|
77
|
+
// 难以测试
|
|
78
|
+
function processOrder(order) {
|
|
79
|
+
const gateway = new StripeGateway();
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
2. **返回结果,而非产生副作用。**
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// 可测试
|
|
87
|
+
function calculateDiscount(cart): Discount {}
|
|
88
|
+
|
|
89
|
+
// 难以测试
|
|
90
|
+
function applyDiscount(cart): void {
|
|
91
|
+
cart.total -= discount;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
3. **小表面积。** 更少的方法 = 需要更少的测试。更少的参数 = 更简单的测试设置。
|
|
96
|
+
|
|
97
|
+
## 关系
|
|
98
|
+
|
|
99
|
+
- 一个**模块**有且仅有一个**接口**(它呈现给调用者和测试的表面)。
|
|
100
|
+
- **深度**是**模块**的属性,对照其**接口**来衡量。
|
|
101
|
+
- **接缝**是模块**接口**所在之处。
|
|
102
|
+
- **适配器**位于**接缝**处并满足**接口**。
|
|
103
|
+
- **深度**为调用者产生**杠杆**,为维护者产生**局部性**。
|
|
104
|
+
|
|
105
|
+
## 拒绝的框架
|
|
106
|
+
|
|
107
|
+
- **深度为实现行数与接口行数之比**(Ousterhout):奖励填充实现。我们改用深度作为杠杆。
|
|
108
|
+
- **"接口"作为 TypeScript `interface` 关键字或类的公共方法**:太窄——这里的接口包括调用者必须知道的每个事实。
|
|
109
|
+
- **"边界"**:被 DDD 的有界上下文过载。说**接缝**或**接口**。
|
|
110
|
+
|
|
111
|
+
## 深入探索
|
|
112
|
+
|
|
113
|
+
- **给定依赖深化一个集群**——参见 [DEEPENING.md](DEEPENING.md):依赖类别、接缝规范和替换而非分层的测试。
|
|
114
|
+
- **探索替代接口**——参见 [DESIGN-IT-TWICE.md](DESIGN-IT-TWICE.md):启动并行子代理以几种截然不同的方式设计接口,然后比较深度、局部性和接缝位置。
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: resolving-merge-conflicts
|
|
3
|
+
description: "适用于需要解决进行中的 git merge/rebase 冲突的场景。"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
1. **查看当前状态**——merge/rebase 的当前状态。检查 git 历史以及冲突文件。
|
|
7
|
+
|
|
8
|
+
2. **找到每个冲突的主要来源。** 深入理解每次更改的原因以及原始意图。阅读提交消息、查看 PR、查看原始 issue/工单。
|
|
9
|
+
|
|
10
|
+
3. **解决每个冲突块。** 在可能的情况下保留两种意图。当不兼容时,选择与合并声明目标匹配的那个并注明权衡。**不要**发明新行为。始终解决;永远不要 `--abort`。
|
|
11
|
+
|
|
12
|
+
4. 发现项目的**自动化检查**并运行它们——通常是类型检查,然后是测试,然后是格式化。修复合并破坏的任何内容。
|
|
13
|
+
|
|
14
|
+
5. **完成 merge/rebase。** 暂存所有内容并提交。如果正在 rebase,继续 rebase 过程直到所有提交都被 rebase。
|
|
@@ -26,6 +26,8 @@ keywords: [dev, 开发, workflow, index, 状态]
|
|
|
26
26
|
| `dev/H` | `H-diagnose/H-diagnose.md` | hotfix / bug / 性能回退诊断,零依赖,可独立进入 |
|
|
27
27
|
| `dev/R` | `R-review/R-review.md` | Spec / Engineering / Standards 三维度 diff 审查,零依赖,可独立进入 |
|
|
28
28
|
| `dev/D` | `D-docs-sync/D-docs-sync.md` | 基于 git diff 同步 README、CHANGELOG、AGENTS 等对外文档 |
|
|
29
|
+
| `dev/M` | `M-domain-modeling/M-domain-modeling.md` | 主动领域建模:挑战术语、压测边界,沉淀 CONTEXT 通用语言与 ADR;格式单一事实源,可嵌入其他 dev workflow,也可独立进入 |
|
|
30
|
+
| `dev/A` | `A-improve-architecture/A-improve-architecture.md` | 深化机会扫描 + HTML 架构审查 + 质询,基于 `vendor/codebase-design` 词汇,零依赖,可独立进入 |
|
|
29
31
|
|
|
30
32
|
## 进入协议
|
|
31
33
|
|
|
@@ -50,8 +52,12 @@ keywords: [dev, 开发, workflow, index, 状态]
|
|
|
50
52
|
- `review`:已有 fixed point 或用户要求审查时,从 `dev/R` 开始(零依赖,无需上游工作流产物)。
|
|
51
53
|
- `finalize`:实现完成、需要完成前验证与状态收尾归档时,从 `dev/04` 开始。
|
|
52
54
|
- `docs-sync`:需要基于 git 差异刷新对外文档时,从 `dev/D` 开始。
|
|
55
|
+
- `domain-modeling`:需要主动澄清/锐化领域术语、维护 CONTEXT 与 ADR 时,从 `dev/M` 开始(零依赖;也被 `dev/01`、`dev/02`、`dev/04`、`dev/D`、`dev/A` 引用)。
|
|
56
|
+
- `improve-architecture`:需要系统性发现并落实架构深化机会时,从 `dev/A` 开始(零依赖;建立在 `vendor/codebase-design` 词汇与 `dev/M` 领域模型之上)。
|
|
53
57
|
|
|
54
|
-
> **独立入口说明:** `dev/H`、`dev/I`、`dev/R`
|
|
58
|
+
> **独立入口说明:** `dev/H`、`dev/I`、`dev/R`、`dev/M`、`dev/A` 五个横向工作流均为零硬依赖设计。用户可直接从任一入口进入,无需预先执行 `dev/01`、`dev/02` 等主线工作流。当同 change 目录下缺少上游产物时,各工作流会自行通过代码库探索(git 考古、grep 搜索、文档扫描)采集所需上下文,仅在代码库无法确定的决策点上询问用户。
|
|
59
|
+
>
|
|
60
|
+
> **横向工作流的共享底座:** `dev/M`(领域模型)拥有 CONTEXT / ADR 格式的单一事实源;`dev/A`(架构深化)与 `dev/03`(TDD)共享 `vendor/codebase-design` 的设计词汇(模块 / 接口 / 接缝 / 适配器 / 深度 / 杠杆 / 局部性)。引用方一律不复制这些规范。
|
|
55
61
|
|
|
56
62
|
## 状态汇报
|
|
57
63
|
|
|
@@ -8,7 +8,7 @@ keywords: [grill, context, adr, 术语, 决策]
|
|
|
8
8
|
|
|
9
9
|
# Grill With Docs 工作流执行指引
|
|
10
10
|
|
|
11
|
-
本工作流用于在 PRD 或实现前澄清领域语言、识别决策分支,并把已确认的上下文沉淀为当前 change
|
|
11
|
+
本工作流用于在 PRD 或实现前澄清领域语言、识别决策分支,并把已确认的上下文沉淀为当前 change 的可追踪产物。**领域建模的主动纪律(挑战术语、锐化语言、压测边界)与 CONTEXT / ADR 格式由横向工作流 `../M-domain-modeling/M-domain-modeling.md` 拥有**,本工作流引用之,专注把拷问结论落到当前 change 的 `context-map.md` 与 `decision-log.md`。
|
|
12
12
|
|
|
13
13
|
## 内置指引
|
|
14
14
|
|
|
@@ -38,7 +38,7 @@ keywords: [grill, context, adr, 术语, 决策]
|
|
|
38
38
|
|
|
39
39
|
每次只问一个问题,等待用户对当前问题的反馈后再继续。如果某个问题可以通过探索代码库来回答,就直接探索代码库。
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
需要格式约定时读取 `../M-domain-modeling/CONTEXT-FORMAT.md` 或 `../M-domain-modeling/ADR-FORMAT.md`(格式单一事实源);主动拷问的具体手法见 `../M-domain-modeling/M-domain-modeling.md`「会话期间(主动纪律)」。项目 CONTEXT 或 ADR 的创建、修改必须写入 `speculo/.speculo/.config/` 下,并符合本 workflow 的用户确认策略;未确认内容只记录到当前 change 的 `decision-log.md`。
|
|
42
42
|
|
|
43
43
|
### Worktree 隔离(条件)
|
|
44
44
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
- `speculo/.speculo/dev/<change>/context-map.md`
|
|
6
6
|
- 用户当前方案或目标
|
|
7
7
|
- 本 workflow 入口文件中的内置领域拷问指引
|
|
8
|
-
-
|
|
8
|
+
- `../M-domain-modeling/CONTEXT-FORMAT.md`、`../M-domain-modeling/ADR-FORMAT.md`(格式单一事实源);主动拷问手法见 `../M-domain-modeling/M-domain-modeling.md`
|
|
9
9
|
|
|
10
10
|
## 产物
|
|
11
11
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
## 填写引导
|
|
16
16
|
|
|
17
|
-
1. 遵循 `01-grill-with-docs.md`
|
|
17
|
+
1. 遵循 `01-grill-with-docs.md` 的内置指引,再按需读取 `../M-domain-modeling/` 的格式文档与主动拷问纪律。
|
|
18
18
|
2. 每次只问一个会改变决策树的问题,并给出推荐答案。
|
|
19
19
|
3. 对术语冲突、代码现实冲突和 ADR 候选直接指出。
|
|
20
20
|
4. 用户确认后,把决策写入 `decision-log.md`。
|
|
@@ -22,6 +22,8 @@ keywords: [prd, zoom-out, 需求, 计划]
|
|
|
22
22
|
|
|
23
23
|
当 dev workflow 已完成足够上下文探索,需要把当前对话和代码理解沉淀成 PRD 时使用。不要重复访谈已明确的信息;综合当前对话、代码库事实、领域术语、ADR、模块候选和测试目标。
|
|
24
24
|
|
|
25
|
+
PRD 综合统一使用 `speculo/.speculo/.config/context/CONTEXT.md` 的通用语言;若 PRD 引入或锐化了 CONTEXT 中尚不存在的领域术语,按横向工作流 `../M-domain-modeling/M-domain-modeling.md` 主动沉淀(用户确认后写入 `.config/context/`),不要让术语只活在 PRD 里。
|
|
26
|
+
|
|
25
27
|
PRD 只写入 `speculo/.speculo/dev/<change>/prd.md`,overview 只写入 `speculo/.speculo/dev/<change>/overview.md`。不写项目根下的任意规划文档,不默认发布外部 issue。只有 tracker 已配置且用户明确要求时,才进入外部发布动作。
|
|
26
28
|
|
|
27
29
|
(`<change>` 格式:`YYYY-MM-DD-<kebab-name>`)
|
|
@@ -8,7 +8,7 @@ keywords: [tdd, implement, red-green-refactor, 实现, 测试]
|
|
|
8
8
|
|
|
9
9
|
# TDD Implementation 工作流执行指引
|
|
10
10
|
|
|
11
|
-
本工作流用于把 PRD、issue、诊断结论或用户明确任务实现为经过验证的代码变更。TDD 红绿重构、测试、mock
|
|
11
|
+
本工作流用于把 PRD、issue、诊断结论或用户明确任务实现为经过验证的代码变更。TDD 红绿重构、测试、mock 与重构指引内置在本 workflow 目录中;**深模块、接口、接缝、适配器的设计词汇与原则统一引用 `vendor/codebase-design`,本工作流不再复制**(见下「渐进披露」)。
|
|
12
12
|
|
|
13
13
|
## 内置指引
|
|
14
14
|
|
|
@@ -24,11 +24,17 @@ keywords: [tdd, implement, red-green-refactor, 实现, 测试]
|
|
|
24
24
|
|
|
25
25
|
### 渐进披露
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- `
|
|
30
|
-
- `
|
|
31
|
-
- `refactoring.md
|
|
27
|
+
测试与重构相关指引内置在同目录:
|
|
28
|
+
|
|
29
|
+
- `tests.md`:设计测试方式(好测试 vs 坏测试)时读取。
|
|
30
|
+
- `mocking.md`:考虑 mock 边界、为可 mock 性设计接口时读取。
|
|
31
|
+
- `refactoring.md`:进入重构阶段、识别重构候选时读取。
|
|
32
|
+
|
|
33
|
+
深模块 / 接口 / 接缝 / 适配器 / 杠杆 / 局部性的设计词汇与原则统一由 `vendor/codebase-design` 承载(**单一事实源,本工作流不复制**),按需直接引用:
|
|
34
|
+
|
|
35
|
+
- `../../../vendor/codebase-design/SKILL.md`:设计深模块、判断深 vs 浅、为可测试性设计接口(接受依赖而非创建、返回结果而非副作用、小表面积)时读取——deep module 与可测试接口设计的权威来源。
|
|
36
|
+
- `../../../vendor/codebase-design/DEEPENING.md`:判定依赖类别(进程内 / 本地可替换 / 端口与适配器 / mock)与「替换而非叠加」的测试策略时读取。
|
|
37
|
+
- `../../../vendor/codebase-design/DESIGN-IT-TWICE.md`:需要为深化候选并行探索多个备选接口时读取。
|
|
32
38
|
|
|
33
39
|
### 消费 slices 切片契约
|
|
34
40
|
|
|
@@ -1,40 +1,23 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Mock 边界与可 Mock 性
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **依赖类别**(进程内 / 本地可替换 / 端口与适配器 / 真正外部)与「在接缝处注入端口、生产用真实适配器、测试用内存或 mock 适配器」的判定,是设计词汇的一部分,见单一事实源 `../../../vendor/codebase-design/DEEPENING.md`。本文只覆盖**写测试时**的 mock 取舍与 SDK 风格接口。
|
|
4
|
+
|
|
5
|
+
## 只在系统边界处 mock
|
|
4
6
|
|
|
5
7
|
- 外部 API(支付、邮件等)
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
+
- 数据库(有时——优先考虑测试数据库 / 本地可替换实现)
|
|
9
|
+
- 时间 / 随机性
|
|
8
10
|
- 文件系统(有时)
|
|
9
11
|
|
|
10
12
|
不要 mock:
|
|
11
13
|
|
|
12
|
-
-
|
|
14
|
+
- 你自己的类 / 模块
|
|
13
15
|
- 内部协作者
|
|
14
16
|
- 任何你能控制的东西
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
在系统边界处,设计易于 mock 的接口:
|
|
19
|
-
|
|
20
|
-
**1. 使用依赖注入**
|
|
21
|
-
|
|
22
|
-
将外部依赖传入,而不是在内部创建:
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
// 易于 mock
|
|
26
|
-
function processPayment(order, paymentClient) {
|
|
27
|
-
return paymentClient.charge(order.total);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// 难以 mock
|
|
31
|
-
function processPayment(order) {
|
|
32
|
-
const client = new StripeClient(process.env.STRIPE_KEY);
|
|
33
|
-
return client.charge(order.total);
|
|
34
|
-
}
|
|
35
|
-
```
|
|
18
|
+
> 依赖注入(接受依赖而非内部创建)是让边界可 mock 的前提;该原则见 `../../../vendor/codebase-design/SKILL.md`「为可测试性设计」,本文不复制。
|
|
36
19
|
|
|
37
|
-
|
|
20
|
+
## 优先 SDK 风格接口,而非通用 fetcher
|
|
38
21
|
|
|
39
22
|
为每个外部操作创建专用函数,而不是一个带条件逻辑的通用函数:
|
|
40
23
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
## 填写引导
|
|
15
15
|
|
|
16
16
|
1. 遵循 `03-tdd.md` 的内置 TDD 指引。
|
|
17
|
-
2.
|
|
17
|
+
2. 按需读取同目录 `tests.md` / `mocking.md`,以及设计词汇单一事实源 `../../../vendor/codebase-design/`(`SKILL.md` 深模块与可测试接口设计、`DEEPENING.md` 依赖类别与接缝、`DESIGN-IT-TWICE.md` 备选接口)。
|
|
18
18
|
3. 与用户确认公共接口、最重要的行为和测试覆盖优先级。
|
|
19
19
|
4. 拆出第一个 tracing slice,避免水平切片。
|
|
20
20
|
5. 探索代码库时使用项目领域术语表,确保测试名称和接口词汇与项目语言一致,并尊重触及区域的 ADR。
|
|
@@ -82,6 +82,7 @@ keywords: [finalize, verify, complete, archive, 归档, 收尾, 完成验证]
|
|
|
82
82
|
- 每条完成结论都有**本次运行**的命令与输出证据
|
|
83
83
|
- 已对照来源(PRD / issue / slices / 用户任务)逐项核对需求清单
|
|
84
84
|
- 无调试残留与推测性功能
|
|
85
|
+
- (如适用)实现期引入的新领域术语 / 架构决策已按 `../M-domain-modeling/M-domain-modeling.md` 沉淀到 CONTEXT / ADR(模型未漂移);无新术语则不适用
|
|
85
86
|
- `completion-verification.md` 无残留 `[TODO:]`
|
|
86
87
|
- `.status.json` 的 `verification_status` 为 `verified` 或 `blocked`
|
|
87
88
|
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: dev/A-improve-architecture
|
|
3
|
+
category: dev
|
|
4
|
+
name: Improve Architecture
|
|
5
|
+
description: 扫描代码库寻找深化机会,以可视化 HTML 报告呈现候选,再对选中方向深入质询并沉淀领域模型
|
|
6
|
+
keywords: [architecture, deepening, deep-module, refactor, 架构, 深化, 接缝]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Improve Architecture 工作流执行指引
|
|
10
|
+
|
|
11
|
+
本工作流是 `dev/A` 入口:浮现架构摩擦、提出**深化机会**(把浅模块转化为深模块的重构),目标是可测试性与 AI 可导航性。它**建立在共享设计词汇与项目领域模型之上**:
|
|
12
|
+
|
|
13
|
+
- 架构词汇与原则(模块 / 接口 / 深度 / 接缝 / 适配器 / 杠杆 / 局部性;删除测试、「接口就是测试表面」、「一个适配器 = 假设接缝,两个 = 真实接缝」)统一引用 `../../../vendor/codebase-design/SKILL.md`(及 `DEEPENING.md`)。在每条建议中**严格使用**这些术语——不要偏离到「组件 / 服务 / API / 边界」。
|
|
14
|
+
- 领域语言来自 `speculo/.speculo/.config/context/CONTEXT.md`(为好接缝命名);`speculo/.speculo/.config/adr/` 中的 ADR 记录本工作流**不应重新争议**的决策。领域模型的主动维护见 `../M-domain-modeling/M-domain-modeling.md`。
|
|
15
|
+
|
|
16
|
+
## 内置指引
|
|
17
|
+
|
|
18
|
+
### 何时使用
|
|
19
|
+
|
|
20
|
+
当用户想系统性发现并落实架构深化机会(让代码更可测试、对 AI 更可导航)时使用。也可由 `../H-diagnose/H-diagnose.md` 在修复后转入——当 Bug 根因涉及架构(没有好接缝、纠缠调用者、隐藏耦合)时。
|
|
21
|
+
|
|
22
|
+
### 输入
|
|
23
|
+
|
|
24
|
+
- 当前 git 仓库与待改进的代码区域
|
|
25
|
+
- `speculo/.speculo/.config/context/CONTEXT.md` 领域词汇、触及区域的 `speculo/.speculo/.config/adr/` ADR
|
|
26
|
+
- 设计词汇单一事实源 `../../../vendor/codebase-design/SKILL.md`、`DEEPENING.md`、`DESIGN-IT-TWICE.md`
|
|
27
|
+
- 当前 change 目录:`speculo/.speculo/dev/<change>/`(`<change>` 必须为 `YYYY-MM-DD-<kebab-name>`,例:`2026-06-12-deepen-order-intake`)
|
|
28
|
+
|
|
29
|
+
### 输出
|
|
30
|
+
|
|
31
|
+
- `speculo/.speculo/dev/<change>/architecture-candidates.md` —— 结构化深化候选清单
|
|
32
|
+
- `speculo/.speculo/dev/<change>/architecture-review.html` —— 可视化架构审查报告(前后对比图 + 推荐强度)
|
|
33
|
+
- `speculo/.speculo/dev/<change>/architecture-design.md` —— 选中候选经质询后的接口设计与决策
|
|
34
|
+
- 经用户确认后更新 `.config/context/`、`.config/adr/`(经 `../M-domain-modeling/`)
|
|
35
|
+
|
|
36
|
+
(`<change>` 格式:`YYYY-MM-DD-<kebab-name>`)
|
|
37
|
+
|
|
38
|
+
### 核心原则(引用 codebase-design)
|
|
39
|
+
|
|
40
|
+
- **删除测试**:对任何疑似浅的模块,想象删除它——复杂性会集中(好信号,值得深化)还是只是移动?
|
|
41
|
+
- **深度是接口的属性**:小接口 + 大量实现;深化 = 缩小接口、把复杂性吸收进实现。
|
|
42
|
+
- **接缝纪律**:一个适配器 = 假设接缝,两个 = 真实接缝;不要为单一实现凭空切接缝。
|
|
43
|
+
- 完整原则、依赖类别与「替换而非叠加」测试策略见 `../../../vendor/codebase-design/SKILL.md` 与 `DEEPENING.md`,本工作流不复制。
|
|
44
|
+
|
|
45
|
+
### 渐进披露
|
|
46
|
+
|
|
47
|
+
- `HTML-REPORT.md`:编写 `architecture-review.html` 时读取——完整 HTML 框架、图表模式与样式指南。
|
|
48
|
+
|
|
49
|
+
### 独立使用
|
|
50
|
+
|
|
51
|
+
本工作流**零硬依赖**,无需预先执行其他工作流即可独立进入(`dev/A`)。只需当前 git 仓库即可启动;缺 change 目录时按下「自初始化」创建;缺 CONTEXT / ADR 时按代码现状探索,不阻塞。
|
|
52
|
+
|
|
53
|
+
### 缺少 change 目录时的自初始化
|
|
54
|
+
|
|
55
|
+
若当前无对应 change 目录:
|
|
56
|
+
|
|
57
|
+
1. 从用户意图提取 `<kebab-name>`(如 `deepen-order-intake`)
|
|
58
|
+
2. 创建 `speculo/.speculo/dev/<YYYY-MM-DD>-<kebab-name>/`
|
|
59
|
+
3. 初始化 `.status.json`:
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"dev_entry": "dev/A",
|
|
63
|
+
"current_phase": "1. Scan",
|
|
64
|
+
"phase_history": [],
|
|
65
|
+
"change_status": "active",
|
|
66
|
+
"embedded_guides": ["improve-architecture"],
|
|
67
|
+
"candidate_count": 0,
|
|
68
|
+
"selected_candidate": null,
|
|
69
|
+
"report_path": null,
|
|
70
|
+
"architecture_status": "scanning"
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
4. 在 `speculo/.speculo/dev-status.json` 的 `active` 数组追加该 change 目录名
|
|
74
|
+
|
|
75
|
+
## 阶段
|
|
76
|
+
|
|
77
|
+
> **持久化铁律**:所有产物(含 HTML 报告)写入 `speculo/.speculo/dev/<change>/`,**禁止写入 `temp/`、系统临时目录或项目根目录**。
|
|
78
|
+
|
|
79
|
+
### 1. Scan — 探索深化候选
|
|
80
|
+
- 规范:本入口「核心原则」+ `../../../vendor/codebase-design/SKILL.md`、`../../../vendor/codebase-design/DEEPENING.md`
|
|
81
|
+
- 模板:无(候选条目结构见下「引导」第 4 步)
|
|
82
|
+
- 产物:`architecture-candidates.md`
|
|
83
|
+
- 引导:
|
|
84
|
+
1. 先读 `speculo/.speculo/.config/context/CONTEXT.md` 与触及区域的 `.config/adr/`。
|
|
85
|
+
2. 用 Agent 工具(`subagent_type=Explore`)有机地遍历代码库,注意摩擦:理解一个概念要在许多小模块间跳转?模块浅(接口几乎和实现一样复杂)?纯函数仅为可测试性而提取、真 bug 藏在其调用方式里(没有局部性)?紧耦合模块在接缝处泄漏?哪些区域难以通过当前接口测试?
|
|
86
|
+
3. 对每个疑似浅模块应用**删除测试**,保留「删除会集中复杂性」的候选。
|
|
87
|
+
4. 每个候选记录:**涉及文件**、**问题**(当前摩擦)、**解决方案**(通俗语言)、**收益**(用局部性 / 杠杆 / 测试改善表述)、**依赖类别**(进程内 / 本地可替换 / 端口与适配器 / mock)、**推荐强度**(强烈 / 值得探索 / 推测性)。
|
|
88
|
+
5. 与现有 ADR 冲突的候选,仅在摩擦真实到值得重审 ADR 时保留,并在条目中显式标注(如「与 ADR-0007 矛盾——但因……值得重新讨论」)。
|
|
89
|
+
- 完成准则:
|
|
90
|
+
- 候选均用 codebase-design 词汇命名(不散用「组件 / 服务 / 边界」)
|
|
91
|
+
- 每个候选含文件、问题、解决方案、收益、依赖类别、推荐强度
|
|
92
|
+
- `architecture-candidates.md` 无残留 `[TODO:]`
|
|
93
|
+
|
|
94
|
+
### 2. Report — 可视化架构审查报告
|
|
95
|
+
- 规范:`HTML-REPORT.md`
|
|
96
|
+
- 模板:无
|
|
97
|
+
- 产物:`architecture-review.html`
|
|
98
|
+
- 引导:
|
|
99
|
+
1. 按 `HTML-REPORT.md` 编写**自包含** HTML(Tailwind + Mermaid 走 CDN),每个候选一张卡片含**前后对比图**,结尾「首要推荐」段。
|
|
100
|
+
2. 写入 `speculo/.speculo/dev/<change>/architecture-review.html`(**不写临时目录**),用 OS 命令打开(macOS `open <path>`、Linux `xdg-open <path>`、Windows `start <path>`),并告知用户绝对路径。
|
|
101
|
+
3. 领域用 CONTEXT 词汇、架构用 codebase-design 词汇。
|
|
102
|
+
4. 此时不提接口设计;写入并打开后,询问用户:「这些候选你想探索哪一个?」
|
|
103
|
+
- 完成准则:
|
|
104
|
+
- HTML 自包含、每个候选有前后对比图与推荐强度徽章、含首要推荐段
|
|
105
|
+
- 报告写入 change 目录并已为用户打开
|
|
106
|
+
- 已请用户选择候选
|
|
107
|
+
|
|
108
|
+
### 3. Grill — 质询所选候选并沉淀
|
|
109
|
+
- 规范:`../../../skills/grill-me/SKILL.md`(逐问压测)+ `../M-domain-modeling/M-domain-modeling.md`(内联沉淀)
|
|
110
|
+
- 模板:无
|
|
111
|
+
- 产物:`architecture-design.md`;经用户确认后更新 `.config/context/`、`.config/adr/`
|
|
112
|
+
- 引导:
|
|
113
|
+
1. 用 `../../../skills/grill-me/SKILL.md` 与用户走设计树:约束、依赖、深化后模块形态、接缝后面是什么、哪些测试存活。
|
|
114
|
+
2. 决策结晶时按 `../M-domain-modeling/M-domain-modeling.md` 内联沉淀:深化模块用了 CONTEXT 没有的概念 → 加术语;锐化了模糊术语 → 更新 CONTEXT;用户以关键理由否决候选 → 按 ADR 三判据决定是否记 ADR(防止未来架构审查重复建议同一件事)。
|
|
115
|
+
3. 想探索深化模块的备选接口时,按 `../../../vendor/codebase-design/DESIGN-IT-TWICE.md` 的「设计两次」并行子代理模式。
|
|
116
|
+
- 完成准则:
|
|
117
|
+
- 选中候选的接口、依赖策略与适配器、存活测试已记入 `architecture-design.md`
|
|
118
|
+
- 决策结晶处的术语 / ADR 已按 `../M-domain-modeling/` 沉淀(经用户确认)
|
|
119
|
+
- `architecture-design.md` 无残留 `[TODO:]`
|
|
120
|
+
|
|
121
|
+
## 依赖
|
|
122
|
+
|
|
123
|
+
- 硬依赖:无(零依赖横向工作流)
|
|
124
|
+
- 软依赖:无。可独立进入;也可由 `../H-diagnose/H-diagnose.md` 修复后转入。建立在 `../../../vendor/codebase-design/`(设计词汇)与 `../M-domain-modeling/`(领域模型)之上;深化的实现落地交由 `../03-tdd/03-tdd.md`。
|
|
125
|
+
|
|
126
|
+
## 状态扩展字段
|
|
127
|
+
|
|
128
|
+
本工作流需在同 change 的 `.status.json` 追加:
|
|
129
|
+
|
|
130
|
+
- `dev_entry` (string) — 固定为 `dev/A`
|
|
131
|
+
- `embedded_guides` (array) — 包含 `improve-architecture`
|
|
132
|
+
- `candidate_count` (number) — 深化候选数量
|
|
133
|
+
- `selected_candidate` (string|null) — 用户选中的候选
|
|
134
|
+
- `report_path` (string|null) — `speculo/.speculo/dev/<change>/architecture-review.html`
|
|
135
|
+
- `architecture_status` (scanning | reported | grilling | designed | blocked) — 工作流状态
|
|
136
|
+
|
|
137
|
+
## 完成与状态更新
|
|
138
|
+
|
|
139
|
+
- 进入每个 phase 时更新 `current_phase` 和 `phase_history`。
|
|
140
|
+
- 报告生成后写入 `candidate_count`、`report_path`,置 `architecture_status: reported`。
|
|
141
|
+
- 用户选定并质询后写入 `selected_candidate`,置 `architecture_status: designed`。
|
|
142
|
+
- 写 `.config/context/` 或 `.config/adr/` 前必须经用户确认(经 `../M-domain-modeling/`)。
|
|
143
|
+
- 本工作流不自动完成 change;深化的实现交由 `../03-tdd/03-tdd.md` 落地。
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# HTML 报告格式
|
|
2
|
+
|
|
3
|
+
架构审查以单个**自包含 HTML 文件**渲染,写入 `speculo/.speculo/dev/<change>/architecture-review.html`(由入口 `A-improve-architecture.md` Phase 2 规定,**不写临时目录**)。Tailwind 和 Mermaid 均从 CDN 加载。Mermaid 可靠地处理图形状图表;手写 div 和内联 SVG 处理更具编辑性的可视化(质量图、横截面图)。两者混合使用——不要所有内容都依赖 Mermaid,否则会显得千篇一律。
|
|
4
|
+
|
|
5
|
+
## 脚手架
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<!doctype html>
|
|
9
|
+
<html lang="en">
|
|
10
|
+
<head>
|
|
11
|
+
<meta charset="utf-8" />
|
|
12
|
+
<title>Architecture review — {{repo name}}</title>
|
|
13
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
14
|
+
<script type="module">
|
|
15
|
+
import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs";
|
|
16
|
+
mermaid.initialize({ startOnLoad: true, theme: "neutral", securityLevel: "loose" });
|
|
17
|
+
</script>
|
|
18
|
+
<style>
|
|
19
|
+
/* small custom layer for things Tailwind doesn't cover cleanly:
|
|
20
|
+
dashed seam lines, hand-drawn-feeling arrow heads, etc. */
|
|
21
|
+
.seam { stroke-dasharray: 4 4; }
|
|
22
|
+
.leak { stroke: #dc2626; }
|
|
23
|
+
.deep { background: linear-gradient(135deg, #0f172a, #1e293b); }
|
|
24
|
+
</style>
|
|
25
|
+
</head>
|
|
26
|
+
<body class="bg-stone-50 text-slate-900 font-sans">
|
|
27
|
+
<main class="max-w-5xl mx-auto px-6 py-12 space-y-12">
|
|
28
|
+
<header>...</header>
|
|
29
|
+
<section id="candidates" class="space-y-10">...</section>
|
|
30
|
+
<section id="top-recommendation">...</section>
|
|
31
|
+
</main>
|
|
32
|
+
</body>
|
|
33
|
+
</html>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 页头
|
|
37
|
+
|
|
38
|
+
仓库名称、日期和紧凑图例:实线框 = 模块,虚线 = 接缝,红色箭头 = 泄漏,深色粗框 = 深层模块。没有介绍段落——直接进入候选方案。
|
|
39
|
+
|
|
40
|
+
## 候选卡片
|
|
41
|
+
|
|
42
|
+
图表承担主要信息量。文字稀疏、平实,使用 `../../../vendor/codebase-design/SKILL.md` 的术语表词汇,不铺陈。
|
|
43
|
+
|
|
44
|
+
每个候选方案为一个 `<article>`:
|
|
45
|
+
|
|
46
|
+
- **标题**——简短,命名深化操作(例如「折叠订单接收流水线」)。
|
|
47
|
+
- **徽章行**——推荐强度(`Strong` = 翡翠绿,`Worth exploring` = 琥珀色,`Speculative` = 石板灰),外加一个依赖类别标签(`in-process`、`local-substitutable`、`ports & adapters`、`mock`)。
|
|
48
|
+
- **文件**——等宽字体列表,`font-mono text-sm`。
|
|
49
|
+
- **Before / After 图表**——核心部分。两列并排。见下方模式。
|
|
50
|
+
- **问题**——一句话。痛点是什么。
|
|
51
|
+
- **解决方案**——一句话。改变了什么。
|
|
52
|
+
- **收益**——项目符号,每条 ≤6 个字。例如「测试只需命中一个接口」「定价逻辑不再泄漏」「删除 4 个浅层包装器」。
|
|
53
|
+
- **ADR 提示**(如适用)——琥珀色背景框中的一行说明。
|
|
54
|
+
|
|
55
|
+
没有解释性段落。如果图表需要一段文字才能理解,那就重绘图表。
|
|
56
|
+
|
|
57
|
+
## 图表模式
|
|
58
|
+
|
|
59
|
+
选择适合候选方案的模式。混合使用。不要让每张图表看起来都一样——多样性本身就是目的之一。
|
|
60
|
+
|
|
61
|
+
### Mermaid 图(依赖/调用流的常用工具)
|
|
62
|
+
|
|
63
|
+
当要表达「X 调用 Y 调用 Z,看看这有多乱」时,使用 Mermaid `flowchart` 或 `graph`。用 Tailwind 风格的卡片包裹它,避免显得突兀。使用 classDef 将泄漏边着色为红色,将深层模块着色为深色。时序图适合表达「Before:6 次往返;After:1 次」。
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<div class="rounded-lg border border-slate-200 bg-white p-4">
|
|
67
|
+
<pre class="mermaid">
|
|
68
|
+
flowchart LR
|
|
69
|
+
A[OrderHandler] --> B[OrderValidator]
|
|
70
|
+
B --> C[OrderRepo]
|
|
71
|
+
C -.leak.-> D[PricingClient]
|
|
72
|
+
classDef leak stroke:#dc2626,stroke-width:2px;
|
|
73
|
+
class C,D leak
|
|
74
|
+
</pre>
|
|
75
|
+
</div>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 手写框线箭头图(当 Mermaid 布局不理想时)
|
|
79
|
+
|
|
80
|
+
模块用带有边框和标签的 `<div>` 表示。箭头用绝对定位在相对容器上的内联 SVG `<line>` 或 `<path>` 元素表示。当你希望「After」图表呈现为一个粗边框的深层模块,内部变灰时,使用这种方式——Mermaid 无法渲染出正确的视觉重量。
|
|
81
|
+
|
|
82
|
+
### 横截面图(适合展示分层浅度)
|
|
83
|
+
|
|
84
|
+
堆叠水平条带(`h-12 border-l-4`)来展示调用经过的层级。Before:6 个薄层,每层几乎什么都不做。After:1 个粗条带,标注了合并后的职责。
|
|
85
|
+
|
|
86
|
+
### 质量图(适合展示「接口与实现一样宽」)
|
|
87
|
+
|
|
88
|
+
每个模块两个矩形——一个表示接口表面积,一个表示实现。Before:接口矩形几乎和实现矩形一样高(浅层)。After:接口矩形短,实现矩形高(深层)。
|
|
89
|
+
|
|
90
|
+
### 调用图折叠
|
|
91
|
+
|
|
92
|
+
Before:函数调用树,渲染为嵌套盒子。After:同一棵树折叠为一个盒子,内部现已内部化的调用在其中淡色显示。
|
|
93
|
+
|
|
94
|
+
## 样式指南
|
|
95
|
+
|
|
96
|
+
- 偏编辑风格,而非企业仪表盘风格。宽裕的留白。标题可选衬线字体(`font-serif` 与 stone/slate 配色搭配效果很好)。
|
|
97
|
+
- 颜色克制:一种强调色(翡翠绿或靛蓝)加红色表示泄漏,琥珀色表示警告。
|
|
98
|
+
- 图表高度保持在约 320px,以便 before/after 并排显示无需滚动。
|
|
99
|
+
- 图表内模块标签使用 `text-xs uppercase tracking-wider`——它们应该呈现为示意图风格,而非 UI 风格。
|
|
100
|
+
- 唯一的脚本是 Tailwind CDN 和 Mermaid ESM 导入。报告其余部分是静态的——没有应用代码,除 Mermaid 自身渲染外没有交互性。
|
|
101
|
+
|
|
102
|
+
## 首选推荐部分
|
|
103
|
+
|
|
104
|
+
一张较大的卡片。候选方案名称,一句说明原因的话,锚链接指向其卡片。仅此而已。
|
|
105
|
+
|
|
106
|
+
## 语气
|
|
107
|
+
|
|
108
|
+
平实中文,简洁——但架构名词和动词直接来自 `../../../vendor/codebase-design/SKILL.md`。简洁不是偏离术语表的借口。
|
|
109
|
+
|
|
110
|
+
**精确使用:** 模块(module)、接口(interface)、实现(implementation)、深度(depth)、深(deep)、浅(shallow)、接缝(seam)、适配器(adapter)、杠杆(leverage)、局部性(locality)。
|
|
111
|
+
|
|
112
|
+
**绝不替换:** 组件 / 服务 / 单元(表示 module)· API / 签名(表示 interface)· 边界(表示 seam)· 层 / 包装器(表示 module,当你的意思是 module 时)。
|
|
113
|
+
|
|
114
|
+
**符合风格的表述:**
|
|
115
|
+
|
|
116
|
+
- 「订单接收模块是浅的——接口几乎和实现一样复杂。」
|
|
117
|
+
- 「定价逻辑在接缝处泄漏。」
|
|
118
|
+
- 「深化:一个接口,一处可测。」
|
|
119
|
+
- 「两个适配器证明了接缝:生产用 HTTP,测试用内存。」
|
|
120
|
+
|
|
121
|
+
**收益项目符号**用术语表词汇命名收益:「局部性:bug 集中在一个模块」「杠杆:一个接口,N 个调用点」「接口缩小,实现吸收包装器」。不要写「更易维护」或「更干净的代码」——这些词不在术语表中,不应出现。
|
|
122
|
+
|
|
123
|
+
不模棱两可,不开场白,不写「值得注意的是……」。如果一句话可以变成项目符号,就变成项目符号。如果一个项目符号可以删掉,就删掉。如果一个词不在 `../../../vendor/codebase-design/SKILL.md` 术语表中,在发明新词之前先找一个术语表中有的词。
|
|
@@ -40,6 +40,8 @@ keywords: [docs-sync, changelog, readme, agents, documentation, 文档同步]
|
|
|
40
40
|
- `changelog-contract.md`:更新 CHANGELOG 类文档时读取。
|
|
41
41
|
- `state-json-schema.md`:初始化、读取或写回 docs-sync state 时读取。
|
|
42
42
|
|
|
43
|
+
> **通用语言对齐**:对外文档(README / AGENTS)中的领域术语以 `speculo/.speculo/.config/context/CONTEXT.md` 为准;同步中若发现文档与 CONTEXT 术语漂移,交由 `../M-domain-modeling/M-domain-modeling.md` 沉淀,docs-sync 本身不另立或重定义领域术语。
|
|
44
|
+
|
|
43
45
|
## 阶段
|
|
44
46
|
|
|
45
47
|
### 1. State Read — 读取同步状态
|
|
@@ -141,4 +141,4 @@
|
|
|
141
141
|
- [ ] 一次性原型已删除(或移到明确标记的调试位置)
|
|
142
142
|
- [ ] 最终正确的假设已写在 commit / PR 信息中——以便下一个调试者从中学习
|
|
143
143
|
|
|
144
|
-
**然后问:什么能预防这个 Bug?**
|
|
144
|
+
**然后问:什么能预防这个 Bug?** 如果答案涉及架构变更(没有好的测试接缝、纠缠的调用者、隐藏的耦合),将具体信息交给横向工作流 `../A-improve-architecture/A-improve-architecture.md` 处理。在修复**之后**提出建议,而不是之前——你现在比开始时拥有更多信息。
|
|
@@ -28,6 +28,7 @@ keywords: [issues, slices, vertical, AFK, HITL, 切片]
|
|
|
28
28
|
|
|
29
29
|
- `issues-slices.md` — 进行实际切片分解时读取;含有完整结构规范(8 段 slices.md)、独立进入时的深度搜索协议(三轮自采集)、存疑时的提问协议(决策树)
|
|
30
30
|
- `../_templates/issues-slices-template.md` — 写 `slices.md` 时作为骨架填写;头部 blockquote 标注了服务工作流与产物文件名,每个 `[TODO:]` 对应结构规范中的一段
|
|
31
|
+
- `../../../vendor/codebase-design/SKILL.md` — 切分跨层切片、在 §2 架构上下文命名模块与接缝时引用(**设计词汇单一事实源**):统一使用深模块设计词汇(模块 / 接口 / 接缝 / 适配器 / 深度 / 杠杆 / 局部性),不散用「组件 / 服务 / 边界」;判定某个切片是否值得引入新接缝时,应用「一个适配器 = 假设接缝,两个适配器 = 真实接缝」——不要为单一实现凭空切出接缝。
|
|
31
32
|
|
|
32
33
|
### 输入
|
|
33
34
|
|
|
@@ -78,6 +78,8 @@
|
|
|
78
78
|
- 不可逾越约束(来自 `AGENTS.md` 或 PRD 的硬性规则)
|
|
79
79
|
- 可选 ASCII 分层图,标出依赖方向(如 `src → core → src-tauri`)
|
|
80
80
|
|
|
81
|
+
> **设计词汇**:描述模块、接口与接缝时统一使用 `../../../vendor/codebase-design/SKILL.md` 的词汇(模块 / 接口 / 接缝 / 适配器 / 深度),不要散用「组件 / 服务 / 边界」。某切片是否值得切出新接缝,按「一个适配器 = 假设接缝,两个适配器 = 真实接缝」判定。
|
|
82
|
+
|
|
81
83
|
单文件修复或热点 patch 可省略本节。
|
|
82
84
|
|
|
83
85
|
### 2.5. 涉及的数据库表 —— [条件]
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# ADR 格式
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
本文是项目架构决策记录(ADR)格式与判据的**单一事实源**,由 `dev/M-domain-modeling` 拥有,`dev/01`、`dev/04`、`dev/A` 等工作流按需引用。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
默认产物写入调用方工作流的会话产物(如 `decision-log.md`、`domain-model-log.md`);只有用户明确确认时,才按本格式创建项目 ADR。
|
|
6
6
|
|
|
7
|
-
`speculo/.speculo/.config/adr/` 目录由 Speculo 初始化提供;如果目标项目缺失该目录,按需创建。
|
|
7
|
+
ADR 存放在 `speculo/.speculo/.config/adr/` 目录下,使用顺序编号:`0001-slug.md`、`0002-slug.md`,以此类推。`speculo/.speculo/.config/adr/` 目录由 Speculo 初始化提供;如果目标项目缺失该目录,按需创建。
|
|
8
8
|
|
|
9
9
|
## 模板
|
|
10
10
|
|
|
@@ -44,6 +44,6 @@ ADR 存放在 `speculo/.speculo/.config/adr/` 目录下,使用顺序编号:`
|
|
|
44
44
|
- **上下文之间的集成模式。** 「Ordering 和 Billing 通过领域事件通信,而非同步 HTTP。」
|
|
45
45
|
- **带有锁定效应的技术选型。** 数据库、消息总线、认证提供商、部署目标。不是每个库——只是那些换掉需要花一个季度的。
|
|
46
46
|
- **边界和范围决策。** 「客户数据由 Customer 上下文拥有,其他上下文只通过 ID 引用。」明确的「不做」和「要做」同样有价值。
|
|
47
|
-
- **刻意偏离显而易见的路径。** 「我们用原生 SQL 而非 ORM,因为 X
|
|
47
|
+
- **刻意偏离显而易见的路径。** 「我们用原生 SQL 而非 ORM,因为 X。」任何理性读者会假设相反做法的地方。这能防止下一个工程师去「修复」某个刻意为之的设计。
|
|
48
48
|
- **代码中看不见的约束。** 「因为合规要求,我们不能用 AWS。」「因为合作方 API 合约,响应时间必须在 200 ms 以内。」
|
|
49
49
|
- **拒绝理由不明显的替代方案。** 如果你考虑过 GraphQL 但因为某些微妙原因选了 REST,记录下来——否则六个月后会有人再次提议 GraphQL。
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# CONTEXT.md 格式
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
本文是项目术语表(通用语言)写法的**单一事实源**,由 `dev/M-domain-modeling` 拥有,`dev/01`、`dev/02`、`dev/04`、`dev/D`、`dev/A` 等工作流按需引用。
|
|
4
|
+
|
|
5
|
+
只有用户明确确认时,才按本格式创建或更新 `speculo/.speculo/.config/context/CONTEXT.md` / `speculo/.speculo/.config/context/CONTEXT-MAP.md`;未确认的术语只记录到调用方工作流的会话产物(如 `decision-log.md`、`domain-model-log.md`)。
|
|
4
6
|
|
|
5
7
|
## 结构
|
|
6
8
|
|
|
@@ -56,7 +58,7 @@ _避免使用_:Client、buyer、account
|
|
|
56
58
|
- **Ordering ↔ Billing**:共享 `CustomerId` 和 `Money` 类型
|
|
57
59
|
```
|
|
58
60
|
|
|
59
|
-
|
|
61
|
+
本工作流自动推断适用哪种结构:
|
|
60
62
|
|
|
61
63
|
- 如果 `speculo/.speculo/.config/context/CONTEXT-MAP.md` 存在,读取它以查找上下文
|
|
62
64
|
- 如果只有 `speculo/.speculo/.config/context/CONTEXT.md`,则为单上下文
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: dev/M-domain-modeling
|
|
3
|
+
category: dev
|
|
4
|
+
name: Domain Modeling
|
|
5
|
+
description: 主动构建与精炼项目领域模型——挑战术语、压测边界,并在决策结晶当下沉淀通用语言(CONTEXT)与架构决策(ADR)
|
|
6
|
+
keywords: [domain-modeling, context, adr, ubiquitous-language, 领域建模, 术语, 通用语言]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Domain Modeling 工作流执行指引
|
|
10
|
+
|
|
11
|
+
本工作流是 `dev/M` 入口,也是 dev 分类**领域模型的横向纪律与格式单一事实源**:在设计与讨论中*主动*构建、精炼项目领域模型,并在术语和决策结晶的当下立即沉淀。它既可独立进入(`dev/M`),也被 `dev/01`、`dev/02`、`dev/04`、`dev/D` 与 `dev/A` 在各自阶段中引用。
|
|
12
|
+
|
|
13
|
+
> **主动 vs 消费**:仅仅*读取* CONTEXT 取词汇**不是**本工作流——那是任何工作流都该有的一行习惯。本工作流用于你正在*改变*模型,而不仅是消费它时。
|
|
14
|
+
|
|
15
|
+
## 内置指引
|
|
16
|
+
|
|
17
|
+
### 何时使用
|
|
18
|
+
|
|
19
|
+
当 dev 工作流需要*改变*领域模型时使用——挑战或锐化术语、消解一词多义、记录难以逆转的架构决策、维护通用语言。典型触发:
|
|
20
|
+
|
|
21
|
+
- 用户用词与现有 CONTEXT 冲突,或同一概念出现多个词
|
|
22
|
+
- 讨论领域关系,需要用具体场景压测边界
|
|
23
|
+
- 出现「难以逆转 + 缺上下文会令人意外 + 真实权衡」的决策,值得记成 ADR
|
|
24
|
+
- 实现 / 重构 / PRD 中引入了 CONTEXT 里尚不存在的概念
|
|
25
|
+
|
|
26
|
+
### 输入
|
|
27
|
+
|
|
28
|
+
- 用户的计划、设计或当前讨论
|
|
29
|
+
- `speculo/.speculo/.config/context/CONTEXT.md`、`speculo/.speculo/.config/context/CONTEXT-MAP.md`、`speculo/.speculo/.config/adr/` 与相关代码
|
|
30
|
+
- 当前 change 目录:`speculo/.speculo/dev/<change>/`(`<change>` 必须为 `YYYY-MM-DD-<kebab-name>`,例:`2026-06-12-model-ordering`)
|
|
31
|
+
|
|
32
|
+
### 输出
|
|
33
|
+
|
|
34
|
+
- 会话沉淀记录:`speculo/.speculo/dev/<change>/domain-model-log.md`
|
|
35
|
+
- 经用户确认后更新 `speculo/.speculo/.config/context/CONTEXT.md`(或 `CONTEXT-MAP.md`)
|
|
36
|
+
- 经用户确认后在 `speculo/.speculo/.config/adr/` 新建 ADR
|
|
37
|
+
- 需要用户决策的术语 / 边界问题,每次只问一个
|
|
38
|
+
|
|
39
|
+
(`<change>` 格式:`YYYY-MM-DD-<kebab-name>`)
|
|
40
|
+
|
|
41
|
+
### 会话期间(主动纪律)
|
|
42
|
+
|
|
43
|
+
在讨论进行中持续执行,**不要批量**——在发生的当下捕获:
|
|
44
|
+
|
|
45
|
+
- **对照词汇表挑战**:用户用词与 CONTEXT 现有语言冲突时立即指出。「你的词汇表把『取消』定义为 X,但你似乎指 Y——到底是哪个?」
|
|
46
|
+
- **锐化模糊语言**:用户用含混或一词多义术语时,提出一个精确的规范术语。「你说『账户』——是指 Customer 还是 User?它们是不同的东西。」
|
|
47
|
+
- **用具体场景压测**:讨论领域关系时,发明探测边界的场景,迫使精确界定概念之间的边界。
|
|
48
|
+
- **与代码交叉引用**:用户陈述某事如何运作时,核对代码是否一致;矛盾即指出。「你的代码取消整个 Order,但你刚说支持部分取消——哪个对?」
|
|
49
|
+
- **内联沉淀**:术语一旦解决,立即按 `CONTEXT-FORMAT.md` 更新(用户确认后写 `.config/context/`);未确认的只记到 `domain-model-log.md`。
|
|
50
|
+
- **有节制地提供 ADR**:仅当「难以逆转 + 缺上下文会令人意外 + 真实权衡的结果」三条全部满足时,才按 `ADR-FORMAT.md` 提议创建 ADR;任一不满足则跳过。
|
|
51
|
+
|
|
52
|
+
> `CONTEXT.md` 必须完全不含实现细节——它是词汇表,不是 spec、草稿本或实现决策仓库。
|
|
53
|
+
|
|
54
|
+
### 渐进披露
|
|
55
|
+
|
|
56
|
+
- `CONTEXT-FORMAT.md`:撰写或更新项目术语表(CONTEXT / CONTEXT-MAP)时读取——**通用语言格式的单一事实源**。
|
|
57
|
+
- `ADR-FORMAT.md`:判断是否该写 ADR、以何种格式写时读取——**ADR 格式与判据的单一事实源**。
|
|
58
|
+
|
|
59
|
+
### 独立使用
|
|
60
|
+
|
|
61
|
+
本工作流**零硬依赖**,无需预先执行其他工作流即可独立进入(`dev/M`)。只需用户的领域讨论 + 当前 git 仓库即可启动;缺 change 目录时按下「自初始化」创建。
|
|
62
|
+
|
|
63
|
+
### 缺少 change 目录时的自初始化
|
|
64
|
+
|
|
65
|
+
若当前无对应 change 目录:
|
|
66
|
+
|
|
67
|
+
1. 从用户意图提取 `<kebab-name>`(如 `model-ordering-terms`)
|
|
68
|
+
2. 创建 `speculo/.speculo/dev/<YYYY-MM-DD>-<kebab-name>/`
|
|
69
|
+
3. 初始化 `.status.json`:
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"dev_entry": "dev/M",
|
|
73
|
+
"current_phase": "1. Model Session",
|
|
74
|
+
"phase_history": [],
|
|
75
|
+
"change_status": "active",
|
|
76
|
+
"embedded_guides": ["domain-modeling"],
|
|
77
|
+
"terms_resolved": [],
|
|
78
|
+
"adr_candidates": [],
|
|
79
|
+
"context_write_status": "none"
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
4. 在 `speculo/.speculo/dev-status.json` 的 `active` 数组追加该 change 目录名
|
|
83
|
+
|
|
84
|
+
## 阶段
|
|
85
|
+
|
|
86
|
+
> **惰性创建文件**——只在需要写入时才创建。`.config/context/CONTEXT.md` 与 `.config/adr/` 由 Speculo 初始化提供;若目标项目缺失,在第一个术语 / ADR 解决时按需创建。
|
|
87
|
+
|
|
88
|
+
### 1. Model Session — 词汇与决策沉淀
|
|
89
|
+
- 规范:本入口「会话期间(主动纪律)」+ 同目录 `CONTEXT-FORMAT.md`、`ADR-FORMAT.md`
|
|
90
|
+
- 模板:`../_templates/domain-model-log-template.md`
|
|
91
|
+
- 产物:`domain-model-log.md`;经用户确认后更新 `.config/context/` 与 `.config/adr/`
|
|
92
|
+
- 完成准则:
|
|
93
|
+
- 每个被挑战 / 锐化的术语都有结论(已写入 CONTEXT 或记为 `[待确认]`)
|
|
94
|
+
- 每个 ADR 候选都已按三条判据裁决(提议创建,或显式跳过并记原因)
|
|
95
|
+
- 写入 `.config/context/` 或 `.config/adr/` 的内容均经用户确认
|
|
96
|
+
- `domain-model-log.md` 无残留 `[TODO:]`
|
|
97
|
+
|
|
98
|
+
## 依赖
|
|
99
|
+
|
|
100
|
+
- 硬依赖:无
|
|
101
|
+
- 软依赖:无。可独立进入;也被 `../01-grill-with-docs/01-grill-with-docs.md`、`../02-prd/02-prd.md`、`../04-finalize/04-finalize.md`、`../D-docs-sync/D-docs-sync.md`、`../A-improve-architecture/A-improve-architecture.md` 在其阶段中引用。
|
|
102
|
+
|
|
103
|
+
## 状态扩展字段
|
|
104
|
+
|
|
105
|
+
本工作流需在同 change 的 `.status.json` 追加:
|
|
106
|
+
|
|
107
|
+
- `dev_entry` (string) — 固定为 `dev/M`
|
|
108
|
+
- `embedded_guides` (array) — 包含 `domain-modeling`
|
|
109
|
+
- `terms_resolved` (array) — 本会话解决的术语及结论
|
|
110
|
+
- `adr_candidates` (array) — ADR 候选及裁决(`created` | `skipped` + 原因)
|
|
111
|
+
- `context_write_status` (none | logged | context-updated | adr-created) — 领域模型沉淀状态
|
|
112
|
+
|
|
113
|
+
## 完成与状态更新
|
|
114
|
+
|
|
115
|
+
- 进入 phase 时更新 `current_phase` 和 `phase_history`。
|
|
116
|
+
- 术语 / 决策沉淀后更新 `terms_resolved`、`adr_candidates`、`context_write_status`。
|
|
117
|
+
- 写 `.config/context/` 或 `.config/adr/` **前必须经用户确认**(持久化写入责任表中,这两处 AI 仅在用户确认后写入)。
|
|
118
|
+
- 本工作流不自动完成 change;嵌入其他工作流时随宿主流程推进。
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
> **服务工作流:** `../M-domain-modeling/M-domain-modeling.md`
|
|
2
|
+
> **产物文件名:** `domain-model-log.md`
|
|
3
|
+
> **父目录规则:** 本模板产物写入 `YYYY-MM-DD-<kebab-name>/` change 目录内
|
|
4
|
+
|
|
5
|
+
# Domain Model Log
|
|
6
|
+
|
|
7
|
+
## 术语沉淀
|
|
8
|
+
[TODO: 逐条记录本会话挑战或锐化的术语。每条含:术语、结论(规范词 + 避免使用的别名)、是否已写入 `speculo/.speculo/.config/context/CONTEXT.md`(已写入 / `[待确认]`)。]
|
|
9
|
+
|
|
10
|
+
## 场景压测
|
|
11
|
+
[TODO: 记录用于界定边界的具体场景,以及由此确定的概念边界结论。无则写「无」。]
|
|
12
|
+
|
|
13
|
+
## 代码交叉核对
|
|
14
|
+
[TODO: 记录领域陈述与代码现实的核对结果(一致 / 矛盾及处置)。无则写「无」。]
|
|
15
|
+
|
|
16
|
+
## ADR 候选与裁决
|
|
17
|
+
[TODO: 逐条列出 ADR 候选。每条按三条判据(难以逆转 / 缺上下文会令人意外 / 真实权衡)裁决:`created`(编号 + `.config/adr/` 路径)或 `skipped`(原因)。无则写「无」。]
|
|
18
|
+
|
|
19
|
+
## 待确认
|
|
20
|
+
[TODO: 仍需用户决策的术语 / 边界 / 决策分支,每条一行。无则写「无」。]
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# 深模块
|
|
2
|
-
|
|
3
|
-
来自《A Philosophy of Software Design》:
|
|
4
|
-
|
|
5
|
-
**深模块** = 小接口 + 大量实现
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
┌─────────────────────┐
|
|
9
|
-
│ 小接口 │ ← 方法少,参数简单
|
|
10
|
-
├─────────────────────┤
|
|
11
|
-
│ │
|
|
12
|
-
│ │
|
|
13
|
-
│ 深层实现 │ ← 复杂逻辑被隐藏
|
|
14
|
-
│ │
|
|
15
|
-
│ │
|
|
16
|
-
└─────────────────────┘
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
**浅模块** = 大接口 + 很少实现(应避免)
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
┌─────────────────────────────────┐
|
|
23
|
-
│ 大接口 │ ← 方法多,参数复杂
|
|
24
|
-
├─────────────────────────────────┤
|
|
25
|
-
│ 薄实现 │ ← 只是透传
|
|
26
|
-
└─────────────────────────────────┘
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
设计接口时,问自己:
|
|
30
|
-
|
|
31
|
-
- 能否减少方法数量?
|
|
32
|
-
- 能否简化参数?
|
|
33
|
-
- 能否把更多复杂性隐藏在里面?
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# 面向可测试性的接口设计
|
|
2
|
-
|
|
3
|
-
好的接口让测试变得自然:
|
|
4
|
-
|
|
5
|
-
1. **接受依赖,而不是自己创建**
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
// 易于测试
|
|
9
|
-
function processOrder(order, paymentGateway) {}
|
|
10
|
-
|
|
11
|
-
// 难以测试
|
|
12
|
-
function processOrder(order) {
|
|
13
|
-
const gateway = new StripeGateway();
|
|
14
|
-
}
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
2. **返回结果,而不是产生副作用**
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
// 易于测试
|
|
21
|
-
function calculateDiscount(cart): Discount {}
|
|
22
|
-
|
|
23
|
-
// 难以测试
|
|
24
|
-
function applyDiscount(cart): void {
|
|
25
|
-
cart.total -= discount;
|
|
26
|
-
}
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
3. **小表面积**
|
|
30
|
-
- 方法越少 = 需要的测试越少
|
|
31
|
-
- 参数越少 = 测试准备越简单
|