@namewta/speculo 0.1.0 → 0.1.1

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.
Files changed (24) hide show
  1. package/package.json +1 -1
  2. package/speculo/skills/worktree-isolation/SKILL.md +59 -0
  3. package/speculo/skills/worktree-isolation/references/audit-branch-tree.md +32 -0
  4. package/speculo/skills/worktree-isolation/references/create-worktree.md +39 -0
  5. package/speculo/skills/worktree-isolation/references/merge-and-cleanup.md +43 -0
  6. package/speculo/workflows/dev/00-INDEX.md +6 -2
  7. package/speculo/workflows/dev/01-grill-with-docs/01-grill-with-docs.md +26 -0
  8. package/speculo/workflows/dev/04-finalize/04-finalize.md +133 -0
  9. package/speculo/workflows/dev/04-finalize/completion-gate.md +40 -0
  10. package/speculo/workflows/dev/04-finalize/finalize-archive.md +55 -0
  11. package/speculo/workflows/dev/R-review/R-review.md +60 -26
  12. package/speculo/workflows/dev/R-review/code-quality-checklist.md +118 -0
  13. package/speculo/workflows/dev/R-review/removal-checklist.md +53 -0
  14. package/speculo/workflows/dev/R-review/review-axes.md +57 -0
  15. package/speculo/workflows/dev/R-review/review-setup.md +16 -8
  16. package/speculo/workflows/dev/R-review/review-verdict.md +40 -0
  17. package/speculo/workflows/dev/R-review/security-checklist.md +126 -0
  18. package/speculo/workflows/dev/R-review/solid-checklist.md +73 -0
  19. package/speculo/workflows/dev/_templates/completion-summary-template.md +24 -0
  20. package/speculo/workflows/dev/_templates/completion-verification-template.md +28 -0
  21. package/speculo/workflows/dev/_templates/review-report-template.md +19 -6
  22. package/speculo/workflows/dev/_templates/review-sources-template.md +11 -3
  23. package/speculo/workflows/dev/_templates/review-verdict-template.md +32 -0
  24. package/speculo/workflows/dev/R-review/review-two-axis.md +0 -33
@@ -0,0 +1,118 @@
1
+ # 代码质量清单
2
+
3
+ 服务 `R-review.md` 的 **Engineering 维度**。审查 diff 的错误处理、性能与边界条件时读取本文。重点标记会导致**静默失败**或**生产事故**的问题,并按下方"严重度提示"定级。
4
+
5
+ ## 错误处理
6
+
7
+ ### 需要标记的反模式
8
+
9
+ - **吞掉异常**:空 catch,或只打日志的 catch
10
+ ```javascript
11
+ try { ... } catch (e) { } // 静默失败
12
+ try { ... } catch (e) { console.log(e) } // 打了日志就不管
13
+ ```
14
+ - **过宽的 catch**:捕获 `Exception` / `Error` 基类而非具体类型
15
+ - **错误信息泄露**:把堆栈或内部细节暴露给用户
16
+ - **缺少错误处理**:可失败操作(I/O、网络、解析)周围没有 try-catch
17
+ - **异步错误处理**:未处理的 promise rejection、缺 `.catch()`、无 error boundary
18
+
19
+ ### 应核对的最佳实践
20
+
21
+ - [ ] 错误在恰当的边界被捕获
22
+ - [ ] 错误信息对用户友好(不暴露内部细节)
23
+ - [ ] 错误带足够上下文记录,便于调试
24
+ - [ ] 异步错误被正确传播或处理
25
+ - [ ] 可恢复错误有定义好的兜底行为
26
+ - [ ] 关键错误触发告警 / 监控
27
+
28
+ ### 追问
29
+ - "这个操作失败时会发生什么?"
30
+ - "调用方会知道出错了吗?"
31
+ - "有足够上下文调试这个错误吗?"
32
+
33
+ ## 性能与缓存
34
+
35
+ ### CPU 密集操作
36
+ - **热路径上的昂贵操作**:循环中编译正则、解析 JSON、做加密
37
+ - **阻塞主线程**:同步 I/O、无 worker / async 的重计算
38
+ - **重复计算**:同一计算被多次执行
39
+ - **缺少记忆化**:相同输入反复调用的纯函数
40
+
41
+ ### 数据库与 I/O
42
+ - **N+1 查询**:循环里每个元素查一次,而非批量
43
+ ```javascript
44
+ // 差:N+1
45
+ for (const id of ids) {
46
+ const user = await db.query(`SELECT * FROM users WHERE id = ?`, id)
47
+ }
48
+ // 好:批量
49
+ const users = await db.query(`SELECT * FROM users WHERE id IN (?)`, ids)
50
+ ```
51
+ - **缺索引**:在未建索引的列上查询
52
+ - **过度取数**:只需几列却 SELECT *
53
+ - **无分页**:把整个数据集加载进内存
54
+
55
+ ### 缓存问题
56
+ - **昂贵操作缺缓存**:重复的 API 调用、DB 查询、计算
57
+ - **缓存无 TTL**:脏数据被无限期返回
58
+ - **缓存无失效策略**:数据更新了但缓存没清
59
+ - **缓存键碰撞**:键唯一性不足
60
+ - **把用户私有数据全局缓存**:安全 / 隐私问题
61
+
62
+ ### 内存
63
+ - **无界集合**:不断增长的数组 / map
64
+ - **大对象滞留**:持有引用阻止 GC
65
+ - **循环中字符串拼接**:应改用 StringBuilder / join
66
+ - **整文件加载**:应改用流式
67
+
68
+ ### 追问
69
+ - "这个操作的时间复杂度是多少?"
70
+ - "数据量 10 倍 / 100 倍时行为如何?"
71
+ - "结果可缓存吗?该缓存吗?"
72
+ - "能批量代替逐条吗?"
73
+
74
+ ## 边界条件
75
+
76
+ ### Null / Undefined 处理
77
+ - **缺空值检查**:在可能为 null 的对象上访问属性
78
+ - **truthy / falsy 混淆**:`if (value)` 而 `0` 或 `""` 是合法值
79
+ - **过度可选链**:`a?.b?.c?.d` 掩盖了结构性问题
80
+ - **null 与 undefined 不一致**:混用且无明确约定
81
+
82
+ ### 空集合
83
+ - **未处理空数组**:代码假设数组非空
84
+ - **空对象边界**:在空对象上 `for...in` 或 `Object.keys`
85
+ - **首 / 末元素访问**:`arr[0]` 或 `arr[arr.length-1]` 未先判空
86
+
87
+ ### 数值边界
88
+ - **除零**:除法前缺检查
89
+ - **整数溢出**:超出安全整数范围的大数
90
+ - **浮点比较**:用 `===` 而非 epsilon 比较
91
+ - **负值**:本不该为负的索引或计数
92
+ - **off-by-one**:循环边界、数组切片、分页
93
+
94
+ ### 字符串边界
95
+ - **空字符串**:未作为边界处理
96
+ - **纯空白字符串**:通过 truthy 检查但实际为空
97
+ - **超长字符串**:无长度上限导致内存 / 展示问题
98
+ - **Unicode 边界**:emoji、RTL 文本、组合字符
99
+
100
+ ### 需要标记的危险模式
101
+ ```javascript
102
+ const name = user.profile.name // 危险:无空值检查
103
+ const first = items[0] // 危险:数组访问未判空
104
+ const avg = total / count // 危险:除法未判零
105
+ if (value) { ... } // 危险:truthy 检查排除了 0、""、false
106
+ ```
107
+
108
+ ### 追问
109
+ - "如果它是 null / undefined 会怎样?"
110
+ - "如果集合为空会怎样?"
111
+ - "这个数的合法范围是什么?"
112
+ - "边界值(0、-1、MAX_INT)处会怎样?"
113
+
114
+ ## 严重度提示
115
+
116
+ - 会导致正确性 bug、数据损坏或生产事故的静默失败 → **P0 / P1**
117
+ - 性能回退、可维护性隐患、未覆盖的边界 → **P1 / P2**
118
+ - 局部健壮性改进 → **P3**
@@ -0,0 +1,53 @@
1
+ # 删除候选与迭代计划清单
2
+
3
+ 服务 `R-review.md` 的 **Engineering 维度**。审查 diff 引入或暴露的死代码、冗余、关停特性时读取本文。区分**现在可安全删除**与**需计划后再删**,审查阶段只给出候选与计划,**不在审查中直接删除代码**。
4
+
5
+ ## 优先级
6
+
7
+ - [ ] **P0**:需立即删除(安全风险、显著成本、阻塞其他工作)
8
+ - [ ] **P1**:本迭代删除
9
+ - [ ] **P2**:进 backlog / 下个迭代
10
+
11
+ ## 现在可安全删除
12
+
13
+ ### 候选项:[名称 / 描述]
14
+
15
+ | 字段 | 内容 |
16
+ |------|------|
17
+ | **位置** | `path/to/file.ts:line` |
18
+ | **理由** | 为什么应该删除 |
19
+ | **证据** | 无引用、死特性开关、已废弃 API |
20
+ | **影响** | 无 / 低 —— 无活跃消费者 |
21
+ | **删除步骤** | 1. 删代码 2. 删测试 3. 删配置 |
22
+ | **验证** | 跑测试、确认无运行时错误、观察日志 |
23
+
24
+ ## 推迟删除(需计划)
25
+
26
+ ### 候选项:[名称 / 描述]
27
+
28
+ | 字段 | 内容 |
29
+ |------|------|
30
+ | **位置** | `path/to/file.ts:line` |
31
+ | **为何推迟** | 有活跃消费者、需迁移、需干系人签字 |
32
+ | **前置条件** | 特性开关关闭 2 周、遥测显示 0 使用 |
33
+ | **破坏性变更** | 列出 API / 契约变更 |
34
+ | **迁移计划** | 消费者迁移步骤 |
35
+ | **时间线** | 目标日期或迭代 |
36
+ | **负责人** | 责任人 / 团队 |
37
+ | **验证** | 确认可安全删除的指标(错误率、使用计数) |
38
+ | **回滚计划** | 出问题时如何恢复 |
39
+
40
+ ## 删除前核对
41
+
42
+ - [ ] 全代码库搜索过所有引用(`rg`、`grep`)
43
+ - [ ] 检查过动态 / 反射式调用
44
+ - [ ] 确认无外部消费者(API、SDK、文档)
45
+ - [ ] 复核过特性开关遥测(如适用)
46
+ - [ ] 测试已更新 / 删除
47
+ - [ ] 文档已更新
48
+ - [ ] 已通知团队(如为共享代码)
49
+
50
+ ## 严重度提示
51
+
52
+ - 引入的死代码 / 冗余本身一般是 **P3**;但当它**掩盖了正确性或安全风险**,或带来显著维护 / 成本负担时升级到 **P2 / P1**。
53
+ - 审查只产出删除候选与计划;实际删除交由后续 `../03-tdd/03-tdd.md` 或专门的清理任务执行。
@@ -0,0 +1,57 @@
1
+ # Multi-Axis Review Phase
2
+
3
+ ## 输入
4
+
5
+ - `.speculo/dev/<change>/review-sources.md`
6
+ - `git diff <fixed-point>...HEAD`
7
+ - spec 来源文件或 `no spec available`
8
+ - standards 来源文件或覆盖空白说明
9
+ - Engineering 深度清单:同目录 `solid-checklist.md`、`security-checklist.md`、`code-quality-checklist.md`、`removal-checklist.md`
10
+
11
+ ## 产物
12
+
13
+ - `.speculo/dev/<change>/review-report.md`,由 `../_templates/review-report-template.md` 填写
14
+
15
+ ## 填写引导
16
+
17
+ 三个维度各自独立成区,每条 finding 都要带**严重度(P0–P3)**、**文件/行或 hunk 依据**、**引用来源**,并尽量给出**可执行的修复建议**。
18
+
19
+ ### Spec 维度(做对了吗)
20
+
21
+ 1. 先读 spec,再读 diff。
22
+ 2. 报告:缺失需求、范围蔓延(spec 外的实现)、看似实现但有问题的需求。
23
+ 3. 每条引用 spec 原文。缺少 spec 时整区写 `no spec available`。
24
+
25
+ ### Engineering 维度(做好了吗)
26
+
27
+ 按需读取四份清单,逐项扫描 diff:
28
+
29
+ 1. **SOLID 与架构**(`solid-checklist.md`):SRP/OCP/LSP/ISP/DIP 违背、代码异味;提重构时说明为何改善内聚 / 降低耦合,非平凡重构给增量计划。
30
+ 2. **安全与可靠性**(`security-checklist.md`):注入 / XSS / SSRF / 路径穿越、认证授权、密钥泄露、竞态(TOCTOU、共享状态、DB 并发)、密码学、运行时风险;每条说明可利用性与影响。
31
+ 3. **代码质量**(`code-quality-checklist.md`):错误处理(吞异常、异步错误)、性能(N+1、热路径昂贵操作、缓存)、边界条件(null、空集合、数值 / 字符串边界、off-by-one)。
32
+ 4. **删除候选**(`removal-checklist.md`):死代码、冗余、关停特性;区分可安全删除与需计划,只产出候选与计划,不在审查中删代码。
33
+
34
+ ### Standards 维度(合规吗)
35
+
36
+ 1. 先读已记录标准(RULES、ADR、CONTRIBUTING、配置),再读 diff。
37
+ 2. 报告违反**已成文**标准的位置,引用标准来源。
38
+ 3. 工具已机器强制的项不重复人工检查;无成文标准时说明覆盖空白。
39
+
40
+ ### 并行与隔离
41
+
42
+ - 如果可用,使用三个并行子代理分别审查 Spec、Engineering、Standards。
43
+ - 如果没有子代理,分三个独立小节顺序执行,不让任一维度的结论影响另一维度。
44
+ - 最终报告在 `## Spec`、`## Engineering`、`## Standards` 下并排呈现,可轻微清理措辞,但不要合并或重排 findings。
45
+
46
+ ## 边界
47
+
48
+ - 不修复代码(review-first)。
49
+ - 不把三个维度混成一个优先级列表。
50
+ - 缺少 spec 时跳过 Spec 维度并明确写 `no spec available`;Engineering 维度始终执行。
51
+ - 严重度按各清单的"严重度提示"判定,不凭印象拔高或压低。
52
+
53
+ ## 完成准则
54
+
55
+ - `review-report.md` 已按 Spec / Engineering / Standards 三区呈现
56
+ - 每条 finding 有严重度、明确依据和来源引用
57
+ - `.status.json` 写入 `severity_summary`,`review_status: judged`
@@ -12,28 +12,36 @@
12
12
 
13
13
  ## 填写引导
14
14
 
15
- 1. 沿用用户提供的 fixed point,不自行替换为其他分支。
15
+ 1. 沿用用户提供的 fixed point,不自行替换为其他分支。**Worktree 模式**(`.status.json` 的 `worktree_enabled` 为真)下,若用户未另行指定,fixed point 默认取 `base_branch`,并按 `../../../skills/worktree-isolation/SKILL.md` 的 `references/audit-branch-tree.md` 用 `git log <base_branch>..<change_branch> --oneline` 记录 change 分支树**全部 commit**、`git diff <base_branch>...<change_branch>` 取全量 diff,确保审查覆盖每个 commit。
16
16
  2. 记录 `git diff <fixed-point>...HEAD` 和 `git log <fixed-point>..HEAD --oneline`。
17
- 3. 寻找 spec 来源,顺序为:
17
+ 3. `git diff <fixed-point>...HEAD --stat` 评估 diff 规模并定分批策略:
18
+ - **无变更**:`git diff` 为空时,告知用户并询问是否改审 staged 变更或某个 commit 区间,拿到前不继续。
19
+ - **大 diff(> 500 行)**:先按文件 / 模块汇总,再按模块或功能分批审查。
20
+ - **混合关注点**:按逻辑功能分组,不只按文件顺序。
21
+ 4. 标识关键路径:auth / 授权、支付 / 金额、数据写入、网络 / 外部调用、并发 —— 这些区域在 Engineering 维度需重点审查。
22
+ 5. 寻找 spec 来源,顺序为:
18
23
  - commit message 中的 issue / PR 引用
19
24
  - 用户作为参数传入的路径
20
25
  - `.speculo/dev/<change>/prd.md`、`slices.md`、`decision-log.md`
21
26
  - 仓库中与分支名或功能匹配的规格文档
22
- 4. 寻找 standards 来源,常见路径包括:
27
+ 6. 寻找 standards 来源,常见路径包括:
23
28
  - `.speculo/.config/RULES.md`
24
29
  - `.speculo/.config/context/`
25
30
  - `.speculo/.config/adr/`
26
31
  - `AGENTS.md`、`CONTRIBUTING.md`
27
32
  - `.editorconfig`、`eslint.config.*`、`biome.json`、`prettier.config.*`、`tsconfig.json`
28
- 5. 机器强制的标准只记录来源,不重复检查工具已覆盖的内容。
33
+ 7. 机器强制的标准只记录来源,不重复检查工具已覆盖的内容。
34
+ 8. Engineering 维度不需要外部来源,但记录将依据同目录的 `solid-checklist.md`、`security-checklist.md`、`code-quality-checklist.md`、`removal-checklist.md`。
29
35
 
30
36
  ## 边界
31
37
 
32
- - 不开始主观审查,先完成来源收集。
38
+ - 不开始主观审查,先完成来源与范围收集。
33
39
  - 找不到 spec 时不要编造;记录 `no spec available`。
40
+ - 找不到成文标准时记录覆盖空白,不把缺失当作"无问题"。
34
41
 
35
42
  ## 完成准则
36
43
 
37
- - fixed point、diff 命令、commit 列表已记录
38
- - standards spec 来源已记录
39
- - `.status.json` review setup 字段已更新
44
+ - fixed point、diff 命令、commit 列表、diff 规模与分批策略已记录
45
+ - worktree 模式下已记录 change 分支树 `base_branch..change_branch` 的全部 commit
46
+ - standards 来源、spec 来源、关键路径已记录
47
+ - `.status.json` 写入 `review_fixed_point`、`review_diff_command`、`review_axes`、`standards_sources`、`spec_sources`,`review_status: collecting`
@@ -0,0 +1,40 @@
1
+ # Verdict & Next Steps Phase
2
+
3
+ ## 输入
4
+
5
+ - `.speculo/dev/<change>/review-report.md`(三维度 findings)
6
+ - `.status.json` 的 `severity_summary`
7
+
8
+ ## 产物
9
+
10
+ - `.speculo/dev/<change>/review-verdict.md`,由 `../_templates/review-verdict-template.md` 填写
11
+
12
+ ## 填写引导
13
+
14
+ 1. **严重度汇总**:统计三维度合计的 P0 / P1 / P2 / P3 计数。
15
+ 2. **整体裁决**,依据汇总给出其一:
16
+ - `REQUEST_CHANGES`:存在任何 P0,或存在合并前应修复的 P1
17
+ - `COMMENT`:无 P0/P1,但有值得跟进的 P2/P3
18
+ - `APPROVE`:无阻断项,至多少量 P3
19
+ 3. **Clean-review 诚实声明**(无论是否发现问题都必须写):
20
+ - **检查了什么**:覆盖到的文件 / 模块 / 维度(worktree 模式下须确认已覆盖 `base_branch..change_branch` 的每个 commit)
21
+ - **未覆盖什么**:未审的区域及原因(如 "未验证数据库迁移"、"大 diff 仅抽样审查了 X 模块")
22
+ - **残留风险**:建议补充的测试或后续验证
23
+ 4. **后续选项**:向用户给出明确选项并等待选择,未经确认不实施修复:
24
+ 1. 修复全部
25
+ 2. 仅修复 P0 / P1
26
+ 3. 修复指定项(由用户点名)
27
+ 4. 不改动,审查到此为止
28
+ 5. 用户选择修复时,移交 `../03-tdd/03-tdd.md` 的红绿重构循环执行,并在该 change 内继续维护状态。
29
+
30
+ ## 边界
31
+
32
+ - 不修复代码;本阶段只裁决与确认。
33
+ - 不夸大或弱化裁决;裁决必须与 `severity_summary` 一致。
34
+ - 不把"未覆盖"伪装成"无问题"。
35
+
36
+ ## 完成准则
37
+
38
+ - `review-verdict.md` 含整体裁决、严重度汇总、clean-review 三项声明、后续选项
39
+ - `review-verdict.md` 无残留 `[TODO:]`
40
+ - `.status.json` 写入 `review_verdict`,`review_status: completed`
@@ -0,0 +1,126 @@
1
+ # 安全与可靠性清单
2
+
3
+ 服务 `R-review.md` 的 **Engineering 维度**。审查 diff 是否引入安全漏洞或运行时风险时读取本文。每条命中都要同时说明**可利用性(exploitability)**与**影响(impact)**,并按下方"严重度提示"定级。
4
+
5
+ ## 输入 / 输出安全
6
+
7
+ - **XSS**:不安全的 HTML 注入、`dangerouslySetInnerHTML`、未转义模板、`innerHTML` 赋值
8
+ - **注入**:通过字符串拼接或模板串构造的 SQL / NoSQL / 命令 / GraphQL 注入
9
+ - **SSRF**:用户可控 URL 在无 allowlist 校验下访问内部服务
10
+ - **路径穿越**:用户输入未经清洗进入文件路径(`../` 攻击)
11
+ - **原型污染**:JavaScript 中用用户输入做不安全的对象合并(`Object.assign`、带用户输入的展开)
12
+
13
+ ## 认证 / 授权(AuthN/AuthZ)
14
+
15
+ - 读写操作缺少租户或归属(ownership)校验
16
+ - 新端点没有 auth guard 或 RBAC 约束
17
+ - 信任客户端传入的 role / flag / ID
18
+ - 越权访问(IDOR —— 不安全的直接对象引用)
19
+ - 会话固定或弱会话管理
20
+
21
+ ## JWT 与令牌安全
22
+
23
+ - 算法混淆攻击(期望 `RS256` 却接受 `none` 或 `HS256`)
24
+ - 弱密钥或硬编码密钥
25
+ - 缺少 `exp` 过期或未校验
26
+ - 敏感数据放进 JWT payload(token 是 base64,不是加密)
27
+ - 不校验 `iss`(签发者)或 `aud`(受众)
28
+
29
+ ## 密钥与 PII
30
+
31
+ - API key、token、凭据出现在代码 / 配置 / 日志
32
+ - 密钥进入 git 历史,或环境变量暴露给客户端
33
+ - 过度记录 PII 或敏感载荷
34
+ - 错误信息缺少数据脱敏
35
+
36
+ ## 供应链与依赖
37
+
38
+ - 未锁版本的依赖,允许恶意更新
39
+ - 依赖混淆(私有包名冲突)
40
+ - 从不可信源或 CDN 引入且无完整性校验
41
+ - 含已知 CVE 的过期依赖
42
+
43
+ ## CORS 与响应头
44
+
45
+ - 过宽的 CORS(带 credentials 时 `Access-Control-Allow-Origin: *`)
46
+ - 缺少安全响应头(CSP、X-Frame-Options、X-Content-Type-Options)
47
+ - 暴露内部头或堆栈信息
48
+
49
+ ## 运行时风险
50
+
51
+ - 无界循环、递归调用或大块内存缓冲
52
+ - 外部调用缺少超时、重试或限流
53
+ - 请求路径上的阻塞操作(async 上下文中的同步 I/O)
54
+ - 资源耗尽(文件句柄、连接、内存)
55
+ - ReDoS(正则表达式拒绝服务)
56
+
57
+ ## 密码学
58
+
59
+ - 弱算法(用于安全目的的 MD5、SHA1)
60
+ - 硬编码 IV 或 salt
61
+ - 只加密不认证(ECB 模式、无 HMAC)
62
+ - 密钥长度不足
63
+
64
+ ## 竞态条件(Race Conditions)
65
+
66
+ 竞态是引发间歇性故障和安全漏洞的隐蔽缺陷,重点关注:
67
+
68
+ ### 共享状态访问
69
+ - 多线程 / 协程 / 异步任务无同步地访问共享变量
70
+ - 并发修改全局状态或单例
71
+ - 无正确加锁的惰性初始化(double-checked locking 问题)
72
+ - 在并发上下文使用非线程安全集合
73
+
74
+ ### 先检查后行动(TOCTOU)
75
+ - `if (exists) then use` 无原子操作
76
+ - `if (authorized) then perform`,而授权可能变化
77
+ - 文件存在性检查后再做文件操作
78
+ - 余额检查后扣减(金融操作)
79
+ - 库存检查后下单
80
+
81
+ ### 数据库并发
82
+ - 缺少乐观锁(`version` 列、`updated_at` 校验)
83
+ - 缺少悲观锁(`SELECT FOR UPDATE`)
84
+ - 无事务隔离的 read-modify-write
85
+ - 非原子的计数器自增(应用 `UPDATE SET count = count + 1`)
86
+ - 并发插入触发唯一约束冲突
87
+
88
+ ### 分布式系统
89
+ - 共享资源缺少分布式锁
90
+ - 领导选举竞态
91
+ - 缓存失效竞态(写后读到脏数据)
92
+ - 缺少正确排序的事件顺序依赖
93
+ - 集群操作的脑裂
94
+
95
+ ### 需要标记的危险模式
96
+ ```
97
+ # 危险模式:
98
+ if not exists(key): # TOCTOU
99
+ create(key)
100
+
101
+ value = get(key) # read-modify-write
102
+ value += 1
103
+ set(key, value)
104
+
105
+ if user.balance >= amount: # 先检查后行动
106
+ user.balance -= amount
107
+ ```
108
+
109
+ ### 追问
110
+ - "两个请求同时进入这段代码会怎样?"
111
+ - "这个操作是原子的,还是可被打断?"
112
+ - "这段代码访问了哪些共享状态?"
113
+ - "高并发下它的行为如何?"
114
+
115
+ ## 数据完整性
116
+
117
+ - 缺少事务、部分写入或状态更新不一致
118
+ - 持久化前校验薄弱(类型强转问题)
119
+ - 可重试操作缺少幂等性
120
+ - 并发修改导致的丢失更新(lost update)
121
+
122
+ ## 严重度提示
123
+
124
+ - 可被利用的安全漏洞、数据丢失风险、敏感信息泄露 → **P0**(阻断合并)
125
+ - 需特定条件触发但影响显著的安全 / 可靠性缺陷 → **P1**
126
+ - 纵深防御缺口、低影响硬化项 → **P2**
@@ -0,0 +1,73 @@
1
+ # SOLID 与架构异味清单
2
+
3
+ 服务 `R-review.md` 的 **Engineering 维度**。在审查 diff 的设计质量时读取本文,按 SOLID 与常见代码异味定位结构性问题,并对照下方"严重度提示"给出 P0–P3。
4
+
5
+ ## SOLID 异味提示
6
+
7
+ ### SRP(单一职责)
8
+
9
+ - 一个文件承担互不相关的关注点(如 HTTP + DB + 领域规则混在一起)
10
+ - 大类 / 大模块内聚低,存在多个变更原因
11
+ - 函数编排了大量互不相关的步骤
12
+ - 知道太多系统细节的 God Object
13
+ - **追问**:"这个模块只因为哪一个原因而改变?"
14
+
15
+ ### OCP(开闭)
16
+
17
+ - 新增一种行为要修改多个 switch / if 分支
18
+ - 功能增长需要改核心逻辑,而不是扩展点
19
+ - 没有 plugin / strategy / hook 等变化点
20
+ - **追问**:"不动现有代码能加一个新变体吗?"
21
+
22
+ ### LSP(里氏替换)
23
+
24
+ - 子类检查具体类型,或对基类方法抛异常
25
+ - 重写方法弱化了前置条件、强化了后置条件
26
+ - 子类忽略或空实现父类行为
27
+ - **追问**:"调用方无感知地替换任意子类能成立吗?"
28
+
29
+ ### ISP(接口隔离)
30
+
31
+ - 接口方法很多,实现者大多用不到
32
+ - 调用方为很窄的需求依赖很宽的接口
33
+ - 接口方法出现空 / 桩实现
34
+ - **追问**:"每个实现者都用到了全部方法吗?"
35
+
36
+ ### DIP(依赖倒置)
37
+
38
+ - 高层逻辑直接依赖具体 IO、存储或网络类型
39
+ - 硬编码实现,而不是抽象或注入
40
+ - import 链把业务逻辑耦合到基础设施
41
+ - **追问**:"不改业务逻辑能换掉实现吗?"
42
+
43
+ ## 常见代码异味(SOLID 之外)
44
+
45
+ | 异味 | 信号 |
46
+ |------|------|
47
+ | **Long method** | 函数 > 30 行,多层嵌套 |
48
+ | **Feature envy** | 方法用别的类的数据多过用自己的 |
49
+ | **Data clumps** | 同一组参数反复一起传递 |
50
+ | **Primitive obsession** | 用 string / number 代替领域类型 |
51
+ | **Shotgun surgery** | 一处改动要散落地改多个文件 |
52
+ | **Divergent change** | 一个文件因多个无关原因反复改 |
53
+ | **Dead code** | 不可达或从不被调用的代码(详见 `removal-checklist.md`) |
54
+ | **Speculative generality** | 为假想的未来需求做的抽象 |
55
+ | **Magic numbers/strings** | 没有命名常量的硬编码值 |
56
+
57
+ ## 重构启发式
58
+
59
+ 1. **按职责拆,而不是按体积拆** —— 小文件也可能违反 SRP
60
+ 2. **需要时才引入抽象** —— 等到第二个用例再抽
61
+ 3. **重构保持增量** —— 先隔离行为再搬移
62
+ 4. **先保行为** —— 重构前先有测试兜底
63
+ 5. **按意图命名** —— 命名困难往往说明抽象有问题
64
+ 6. **组合优于继承** —— 继承带来强耦合
65
+ 7. **让非法状态不可表达** —— 用类型固化不变量
66
+
67
+ ## 严重度提示
68
+
69
+ - 导致正确性问题或架构性返工的结构缺陷 → **P1**
70
+ - 明显但局部的 SOLID 违背、可维护性隐患 → **P2**
71
+ - 命名、轻微异味、可选改进 → **P3**
72
+
73
+ > 提出重构时,必须说明它**为什么**改善内聚 / 降低耦合,并给出最小、安全的拆分;非平凡重构给增量计划,不给大重写。
@@ -0,0 +1,24 @@
1
+ > **服务工作流:** `../04-finalize/04-finalize.md`
2
+ > **产物文件名:** `completion-summary.md`
3
+
4
+ # Completion Summary
5
+
6
+ ## 交付边界
7
+
8
+ [TODO: 本 change 交付了什么、不含什么。]
9
+
10
+ ## 关键变更
11
+
12
+ [TODO: 用 3-6 条概括主要变更。]
13
+
14
+ ## 验证证据
15
+
16
+ [TODO: 指向 `completion-verification.md` 的关键结论与命令证据。]
17
+
18
+ ## 遗留事项
19
+
20
+ [TODO: 已知遗留、后续建议或转交的工作;无则写"无"。]
21
+
22
+ ## 归档记录
23
+
24
+ [TODO: 归档时间、源路径 → `.speculo/archive/dev/<YYYY-MM>/<change>/`、用户确认记录。]
@@ -0,0 +1,28 @@
1
+ > **服务工作流:** `../04-finalize/04-finalize.md`
2
+ > **产物文件名:** `completion-verification.md`
3
+
4
+ # Completion Verification
5
+
6
+ ## 已运行命令(含证据)
7
+
8
+ [TODO: 逐条记录本次运行的验证命令、退出码、通过/失败计数;无证据不得声称通过。]
9
+
10
+ ## 未运行命令
11
+
12
+ [TODO: 列出相关但未运行的命令及原因;对应结论不得声称通过。]
13
+
14
+ ## 需求逐项核对
15
+
16
+ [TODO: 重读来源,逐项列出需求 + satisfied/missing/partial + 来源引用。]
17
+
18
+ ## 回归证据(如适用)
19
+
20
+ [TODO: 记录红-绿循环验证;无 bug 修复可写 N/A。]
21
+
22
+ ## 调试残留检查
23
+
24
+ [TODO: 临时日志、DEBUG 标记、一次性脚本、推测性功能的清理结果。]
25
+
26
+ ## 验证结论
27
+
28
+ [TODO: verified 或 blocked;blocked 时写明实际状态与缺口。]
@@ -3,14 +3,27 @@
3
3
 
4
4
  # Review Report
5
5
 
6
- ## Standards
7
-
8
- [TODO: 按 Standards 维度列出 findings;引用文件/行或 hunk,以及对应标准来源。]
6
+ > 每条 finding 格式:`[严重度] [file:line 或 hunk] 标题` + 问题描述 + 修复建议 + 来源引用。
7
+ > 严重度取值 P0 / P1 / P2 / P3,见 `../R-review/R-review.md` 的严重度模型。
9
8
 
10
9
  ## Spec
11
10
 
12
- [TODO: 按 Spec 维度列出 findings;引用 spec 来源。若缺失 spec,写 `no spec available`。]
11
+ [TODO: 按 Spec 维度列出 findings(缺失需求、范围蔓延、看似实现但有问题的需求),引用 spec 原文。缺失 spec 时写 `no spec available`。]
12
+
13
+ ## Engineering
14
+
15
+ ### SOLID 与架构
16
+ [TODO: 依据 `../R-review/solid-checklist.md` 列出 findings。]
13
17
 
14
- ## Summary
18
+ ### 安全与可靠性
19
+ [TODO: 依据 `../R-review/security-checklist.md` 列出 findings,含可利用性与影响。]
20
+
21
+ ### 代码质量
22
+ [TODO: 依据 `../R-review/code-quality-checklist.md` 列出 findings。]
23
+
24
+ ### 删除候选
25
+ [TODO: 依据 `../R-review/removal-checklist.md` 列出死代码 / 删除候选与计划。]
26
+
27
+ ## Standards
15
28
 
16
- [TODO: 一行总结每个维度 findings 数量和最严重单个问题。]
29
+ [TODO: Standards 维度列出违反已记录标准的 findings,引用标准来源;无成文标准时记录覆盖空白。]
@@ -15,10 +15,18 @@
15
15
 
16
16
  [TODO: 粘贴或摘要 `git log <fixed-point>..HEAD --oneline`。]
17
17
 
18
- ## Standards Sources
18
+ ## Scope
19
+
20
+ [TODO: 记录 `--stat` 规模、是否大 diff、分批策略;无变更时记录处理方式。]
21
+
22
+ ## Critical Paths
19
23
 
20
- [TODO: 列出已发现的规则、上下文、ADR、贡献指南或配置文件。]
24
+ [TODO: 列出 diff 触及的关键路径:auth / 支付 / 数据写入 / 网络 / 并发。]
21
25
 
22
26
  ## Spec Sources
23
27
 
24
- [TODO: 列出 PRD、issue、slices、用户路径或 `no spec available`。]
28
+ [TODO: 列出 PRD、issue、slices、用户路径;缺失写 `no spec available`。]
29
+
30
+ ## Standards Sources
31
+
32
+ [TODO: 列出已发现的规则、上下文、ADR、贡献指南或配置文件;无成文标准时记录覆盖空白。]
@@ -0,0 +1,32 @@
1
+ > **服务工作流:** `../R-review/R-review.md`
2
+ > **产物文件名:** `review-verdict.md`
3
+
4
+ # Review Verdict
5
+
6
+ ## 整体裁决
7
+
8
+ [TODO: APPROVE / REQUEST_CHANGES / COMMENT,并一句话说明依据。]
9
+
10
+ ## 严重度汇总
11
+
12
+ | 严重度 | 数量 |
13
+ |--------|------|
14
+ | P0 | [TODO] |
15
+ | P1 | [TODO] |
16
+ | P2 | [TODO] |
17
+ | P3 | [TODO] |
18
+
19
+ ## Clean Review 声明
20
+
21
+ ### 检查了什么
22
+ [TODO: 覆盖到的文件 / 模块 / 维度。]
23
+
24
+ ### 未覆盖什么
25
+ [TODO: 未审区域及原因,如未验证迁移、大 diff 抽样审查。]
26
+
27
+ ### 残留风险
28
+ [TODO: 建议补充的测试或后续验证。]
29
+
30
+ ## 后续选项
31
+
32
+ [TODO: 记录向用户给出的选项(修复全部 / 仅 P0·P1 / 指定项 / 不改动)及用户选择;未确认前不实施修复。]