@chenguangyao/devflow-kit 0.1.43
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/CHANGELOG.md +232 -0
- package/LICENSE +21 -0
- package/README.md +539 -0
- package/bin/devflow.js +9 -0
- package/docs/RFC-001-devflow-kit.md +617 -0
- package/docs/RFC-002-workflow-kernel.md +134 -0
- package/docs/enterprise-integration-supplement.md +274 -0
- package/docs/internal-gitlab-setup.md +426 -0
- package/docs/marketplace-skills.md +231 -0
- package/docs/migration-from-arb.md +232 -0
- package/docs/tooling-overview.md +774 -0
- package/docs/workflow-orchestration.md +695 -0
- package/docs/workflow-ui-prototype.html +271 -0
- package/package.json +52 -0
- package/schemas/config.schema.json +51 -0
- package/schemas/delta.schema.json +22 -0
- package/schemas/state.schema.json +130 -0
- package/schemas/status-surface.schema.json +197 -0
- package/schemas/workflow-confirmation-surface.schema.json +70 -0
- package/schemas/workflow-picker.schema.json +94 -0
- package/scripts/postinstall.js +101 -0
- package/scripts/render-workflow-ui-prototype.js +271 -0
- package/skills/apply/SKILL.md +313 -0
- package/skills/apply/references/discipline-checklist.md +145 -0
- package/skills/apply/references/subagent-implementer-prompt.md +113 -0
- package/skills/apply/references/subagent-orchestration.md +150 -0
- package/skills/apply/references/subagent-reviewer-prompt.md +180 -0
- package/skills/apply/references/tdd-loop.md +287 -0
- package/skills/apply/references/when-plan-is-wrong.md +279 -0
- package/skills/apply/references/worktree-swarm.md +292 -0
- package/skills/archive/SKILL.md +229 -0
- package/skills/archive/references/conflict-resolution.md +336 -0
- package/skills/archive/references/knowledge-deposit.md +381 -0
- package/skills/archive/references/spec-merge.md +365 -0
- package/skills/brainstorm/SKILL.md +123 -0
- package/skills/brainstorm/references/proposal-template.md +244 -0
- package/skills/brainstorm/references/question-catalog.md +168 -0
- package/skills/brainstorm/references/session-template.md +184 -0
- package/skills/ci-fix/SKILL.md +63 -0
- package/skills/ci-fix/references/loop.md +25 -0
- package/skills/code-review/SKILL.md +279 -0
- package/skills/code-review/references/escalation-playbook.md +192 -0
- package/skills/code-review/references/language-cheatsheets/go.md +175 -0
- package/skills/code-review/references/language-cheatsheets/java-spring-mybatis.md +246 -0
- package/skills/code-review/references/language-cheatsheets/python.md +170 -0
- package/skills/code-review/references/language-cheatsheets/vue.md +199 -0
- package/skills/code-review/references/output-template.md +275 -0
- package/skills/code-review/references/review-checklist.md +251 -0
- package/skills/complexity-grading/SKILL.md +259 -0
- package/skills/deliver/SKILL.md +271 -0
- package/skills/deliver/references/delivery-modes.md +299 -0
- package/skills/deliver/references/notify.md +359 -0
- package/skills/deliver/references/pr-description.md +319 -0
- package/skills/dependency-upgrade/SKILL.md +57 -0
- package/skills/dependency-upgrade/references/risk-matrix.md +38 -0
- package/skills/df-orchestrator/SKILL.md +407 -0
- package/skills/df-orchestrator/references/complexity-grading.md +177 -0
- package/skills/df-orchestrator/references/escalation-matrix.md +191 -0
- package/skills/df-orchestrator/references/routing-rules.md +290 -0
- package/skills/df-orchestrator/references/workflow-state-machine.md +208 -0
- package/skills/frontend-quality/SKILL.md +61 -0
- package/skills/frontend-quality/references/checklist.md +35 -0
- package/skills/handoff-resume/SKILL.md +59 -0
- package/skills/handoff-resume/references/handoff-template.md +54 -0
- package/skills/plan/SKILL.md +166 -0
- package/skills/plan/references/task-breakdown.md +207 -0
- package/skills/plan/references/task-sequencing.md +143 -0
- package/skills/plan/references/task-template.md +248 -0
- package/skills/requirement-analysis/SKILL.md +499 -0
- package/skills/requirement-analysis/references/acceptance-criteria.md +183 -0
- package/skills/requirement-analysis/references/code-recon.md +151 -0
- package/skills/requirement-analysis/references/edge-case-catalog.md +164 -0
- package/skills/requirement-analysis/references/requirement-template.md +339 -0
- package/skills/requirement-analysis/references/scope-negotiation.md +162 -0
- package/skills/security-hardening/SKILL.md +60 -0
- package/skills/security-hardening/references/checklist.md +42 -0
- package/skills/tech-spec/SKILL.md +388 -0
- package/skills/tech-spec/references/api-contract-design.md +172 -0
- package/skills/tech-spec/references/decision-records.md +110 -0
- package/skills/tech-spec/references/design-template.md +301 -0
- package/skills/tech-spec/references/rollout-and-rollback.md +203 -0
- package/skills/tech-spec/references/spec-delta-conventions.md +250 -0
- package/skills/tech-spec/references/transaction-patterns.md +212 -0
- package/skills/test-spec/SKILL.md +219 -0
- package/skills/test-spec/references/coverage-strategy.md +218 -0
- package/skills/test-spec/references/edge-case-to-test.md +143 -0
- package/skills/test-spec/references/test-case-template.md +276 -0
- package/skills/verify/SKILL.md +232 -0
- package/skills/verify/references/nfr-verification.md +292 -0
- package/skills/verify/references/report-templates.md +510 -0
- package/skills/verify/references/self-test-guide.md +240 -0
- package/skills/verify/references/verify-rollback-map.md +247 -0
- package/src/cli/commands/_helpers.js +108 -0
- package/src/cli/commands/_submit.js +718 -0
- package/src/cli/commands/apply.js +198 -0
- package/src/cli/commands/archive.js +180 -0
- package/src/cli/commands/checkpoint.js +113 -0
- package/src/cli/commands/deliver.js +377 -0
- package/src/cli/commands/deploy.js +504 -0
- package/src/cli/commands/design.js +158 -0
- package/src/cli/commands/disable.js +21 -0
- package/src/cli/commands/doctor.js +178 -0
- package/src/cli/commands/enable.js +21 -0
- package/src/cli/commands/flow.js +645 -0
- package/src/cli/commands/help.js +93 -0
- package/src/cli/commands/ingest.js +602 -0
- package/src/cli/commands/init.js +341 -0
- package/src/cli/commands/knowledge.js +523 -0
- package/src/cli/commands/logs.js +43 -0
- package/src/cli/commands/new.js +202 -0
- package/src/cli/commands/plan.js +49 -0
- package/src/cli/commands/propose.js +27 -0
- package/src/cli/commands/provider.js +698 -0
- package/src/cli/commands/report.js +143 -0
- package/src/cli/commands/requirement.js +227 -0
- package/src/cli/commands/review.js +301 -0
- package/src/cli/commands/skills.js +457 -0
- package/src/cli/commands/status.js +925 -0
- package/src/cli/commands/switch.js +27 -0
- package/src/cli/commands/sync.js +47 -0
- package/src/cli/commands/test.js +366 -0
- package/src/cli/commands/uninstall.js +32 -0
- package/src/cli/commands/update.js +74 -0
- package/src/cli/commands/verify.js +354 -0
- package/src/cli/commands/worktree.js +78 -0
- package/src/cli/index.js +72 -0
- package/src/cli/parse-args.js +102 -0
- package/src/core/autodetect.js +271 -0
- package/src/core/change.js +208 -0
- package/src/core/checkpoint.js +217 -0
- package/src/core/config.js +60 -0
- package/src/core/delta.js +290 -0
- package/src/core/markers.js +59 -0
- package/src/core/paths.js +173 -0
- package/src/core/plan-tasks.js +36 -0
- package/src/core/project-routing.js +285 -0
- package/src/core/projects.js +200 -0
- package/src/core/state.js +200 -0
- package/src/core/workflow-check.js +177 -0
- package/src/core/workflow-init.js +34 -0
- package/src/core/workflow-picker.js +154 -0
- package/src/core/workflow-policy.js +119 -0
- package/src/core/workflow-suggest.js +181 -0
- package/src/core/workflow-verify.js +88 -0
- package/src/core/workflow.js +433 -0
- package/src/core/worktree.js +241 -0
- package/src/knowledge/categories.js +107 -0
- package/src/knowledge/classify.js +125 -0
- package/src/knowledge/deposit.js +414 -0
- package/src/knowledge/migrate.js +149 -0
- package/src/knowledge/mr.js +219 -0
- package/src/knowledge/query.js +131 -0
- package/src/knowledge/registry.js +151 -0
- package/src/knowledge/sync.js +179 -0
- package/src/providers/base.js +74 -0
- package/src/providers/drivers/api-yapi.js +78 -0
- package/src/providers/drivers/ci-jenkins.js +109 -0
- package/src/providers/drivers/intake-confluence.js +544 -0
- package/src/providers/drivers/kb-git.js +549 -0
- package/src/providers/drivers/kb-weknora.js +472 -0
- package/src/providers/drivers/notify-smtp.js +515 -0
- package/src/providers/drivers/observability-oss.js +43 -0
- package/src/providers/drivers/observability-sls.js +50 -0
- package/src/providers/lifecycle.js +135 -0
- package/src/providers/loader.js +132 -0
- package/src/providers/local.js +190 -0
- package/src/providers/userconfig.js +283 -0
- package/src/reports/aggregate.js +185 -0
- package/src/reports/coverage.js +163 -0
- package/src/reports/detect.js +143 -0
- package/src/reports/parse.js +236 -0
- package/src/templates/files/ci/github.yml +38 -0
- package/src/templates/files/ci/gitlab.yml +27 -0
- package/src/templates/files/design.md +63 -0
- package/src/templates/files/ide/devflow-workflow.md +58 -0
- package/src/templates/files/ide/project-overview-reference.md +1 -0
- package/src/templates/files/ide/project-overview.md +27 -0
- package/src/templates/files/knowledge-index.json +17 -0
- package/src/templates/files/knowledge.md +28 -0
- package/src/templates/files/meta.json +8 -0
- package/src/templates/files/plan.md +38 -0
- package/src/templates/files/proposal.md +33 -0
- package/src/templates/files/reports/contract-test.md +40 -0
- package/src/templates/files/reports/e2e-test.md +30 -0
- package/src/templates/files/reports/integration-test.md +36 -0
- package/src/templates/files/reports/joint-test.md +58 -0
- package/src/templates/files/reports/perf.md +24 -0
- package/src/templates/files/reports/regression.md +20 -0
- package/src/templates/files/reports/remote-test.md +55 -0
- package/src/templates/files/reports/self-test.md +43 -0
- package/src/templates/files/reports/smoke-test.md +22 -0
- package/src/templates/files/reports/unit-test.md +36 -0
- package/src/templates/files/requirement.md +51 -0
- package/src/templates/files/review.md +38 -0
- package/src/templates/files/tests.md +36 -0
- package/src/templates/files/verify.md +32 -0
- package/src/templates/index.js +21 -0
- package/src/utils/log.js +37 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# apply / tdd-loop
|
|
2
|
+
|
|
3
|
+
TDD 每步该做什么 / 不该做什么,常见偏离的识别。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## TDD 一轮的 6 步
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
1. 读 task 5 要素 (30 秒)
|
|
11
|
+
2. 写失败测试(RED) (10-15 分钟)
|
|
12
|
+
3. 最小实现让测试通过(GREEN) (10-20 分钟)
|
|
13
|
+
4. 运行所有相关测试(防回归) (1-2 分钟)
|
|
14
|
+
5. 重构(可选,测试为护栏) (5-10 分钟)
|
|
15
|
+
6. commit + --done (1 分钟)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Step 1:读 task 5 要素
|
|
21
|
+
|
|
22
|
+
**动作**:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
cat devflow/changes/<slug>/plan.md | awk '/^### T-<ID>/,/^### T-<next>/'
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
把 Files / Behavior / Test / Implementation / Commit 5 行读清。确认:
|
|
29
|
+
|
|
30
|
+
- [ ] Files 列表的每个文件存在?(new 的确认要在哪里新建;modified 的读一遍当前)
|
|
31
|
+
- [ ] Test 里引用的 TC 在 tests.md 真的定义了?(以防 plan 引用错 TC)
|
|
32
|
+
- [ ] Behavior 有没有歧义?(有 → 别开始,回问)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Step 2:写失败测试(RED)
|
|
37
|
+
|
|
38
|
+
**关键纪律**:
|
|
39
|
+
|
|
40
|
+
1. **先跑一次确认失败**:新测试 commit 前,确认它真的失败而不是误报
|
|
41
|
+
2. **失败原因正确**:失败必须是"被测对象的期望行为不对",不是"NPE""未编译""找不到类"
|
|
42
|
+
3. **断言具体**:不要 `assertTrue(result != null)`,要 `assertEquals(990, result.grantedCount)`
|
|
43
|
+
|
|
44
|
+
### Go 测试文件落点
|
|
45
|
+
|
|
46
|
+
Go 项目默认不要在业务源码目录旁边随手生成 `*_test.go`。优先把自动新增的黑盒 / 接口 / 联调 / 回归测试放到项目根目录 `test/` 下,例如:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
test/
|
|
50
|
+
├── member_upgrade_test.go
|
|
51
|
+
├── api/
|
|
52
|
+
│ └── member_upgrade_api_test.go
|
|
53
|
+
└── fixtures/
|
|
54
|
+
└── member_upgrade.json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
推荐写成外部包测试,通过 module path import 被测包:
|
|
58
|
+
|
|
59
|
+
```go
|
|
60
|
+
package test
|
|
61
|
+
|
|
62
|
+
import (
|
|
63
|
+
"testing"
|
|
64
|
+
|
|
65
|
+
member "code.example.com/health/go_member/internal/services/member"
|
|
66
|
+
)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
只有下面情况才允许在业务源码同目录新增 `*_test.go`,并且必须在 plan.md 的 Files / Test 中写明理由:
|
|
70
|
+
|
|
71
|
+
- 包内白盒测试:必须访问未导出的函数 / 类型 / 变量,且通过公开 API 无法可靠覆盖
|
|
72
|
+
- Go 编译限制:被测对象位于 `internal` 包且根 `test/` 无法合法 import
|
|
73
|
+
- 现有项目已有明确约定:该 package 已经有大量同目录测试,本次只是补同 package 表驱动 case
|
|
74
|
+
|
|
75
|
+
即使允许同目录测试,fixture / golden / 大样本仍优先放根目录 `test/fixtures/` 或 package 自己的 `testdata/`,不要散落到业务代码目录。
|
|
76
|
+
|
|
77
|
+
**模板**(用项目的测试框架):
|
|
78
|
+
|
|
79
|
+
```java
|
|
80
|
+
@Test
|
|
81
|
+
void batchGrant_allSuccess_returnsGrantedCount() {
|
|
82
|
+
// Arrange
|
|
83
|
+
List<String> userIds = fixtures.batch1k();
|
|
84
|
+
when(riskService.check(any(), any())).thenReturn(RiskResult.PASS);
|
|
85
|
+
|
|
86
|
+
// Act
|
|
87
|
+
BatchResult result = grantService.batchGrant(userIds, "ct_ok", "b_test");
|
|
88
|
+
|
|
89
|
+
// Assert
|
|
90
|
+
assertEquals(1000, result.getGrantedCount());
|
|
91
|
+
assertEquals(0, result.getFailedCount());
|
|
92
|
+
verify(dao, times(1000)).insertGrantLog(any());
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**常见偏离**:
|
|
97
|
+
|
|
98
|
+
| 偏离 | 对策 |
|
|
99
|
+
| --- | --- |
|
|
100
|
+
| 假装"先写实现,反正最后有测试" | 强制:`git diff` 必须先有 test 文件,再有实现文件 |
|
|
101
|
+
| 写了断言很弱的测试("doesn't throw") | 改写具体断言,覆盖 behavior 描述 |
|
|
102
|
+
| 测试依赖多个复杂 mock,逻辑复杂 | 简化 mock;mock 过复杂说明设计有问题 |
|
|
103
|
+
| 测试名像 `test1`(没描述) | 测试名必须描述"输入 → 期望",如 `batchGrant_emptyUserIds_returns400` |
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Step 3:最小实现(GREEN)
|
|
108
|
+
|
|
109
|
+
**关键纪律**:
|
|
110
|
+
|
|
111
|
+
1. **刚好让测试通过**,不多做事
|
|
112
|
+
2. **不顺手重构**其他代码(除非 task 就是重构)
|
|
113
|
+
3. **不添加没测到的代码路径**:如果你写了 branch,没测它,review 会要求补测
|
|
114
|
+
4. **不"顺便"优化性能**(除非 task 就是性能):优化属于独立 task
|
|
115
|
+
|
|
116
|
+
**常见偏离**:
|
|
117
|
+
|
|
118
|
+
| 偏离 | 识别 |
|
|
119
|
+
| --- | --- |
|
|
120
|
+
| "既然已经在这里了,顺便把 X 也做了" | 违反 scope;X 如有价值开新 task |
|
|
121
|
+
| 实现比测试要求的多 | 回头扫实现,问"这行代码对应哪条断言?无对应 → 删 或 补测" |
|
|
122
|
+
| 使用全局 / static 状态 | 测试会 flaky;改构造注入 |
|
|
123
|
+
| 硬编码(magic number / string) | 起码抽常量;避免 review 时被 NIT |
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Step 4:运行所有相关测试
|
|
128
|
+
|
|
129
|
+
**不仅**跑新加的测试。至少跑:
|
|
130
|
+
|
|
131
|
+
- 修改文件所在 module / package 的全部 test
|
|
132
|
+
- CI 必跑的 smoke 层
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Java
|
|
136
|
+
mvn -pl <entry-module> -am test
|
|
137
|
+
# Java DDD 多模块:如果只想先编译受影响链路
|
|
138
|
+
mvn -pl <entry-module> -am -DskipTests compile
|
|
139
|
+
|
|
140
|
+
# Go
|
|
141
|
+
go test ./test/... ./coupon/...
|
|
142
|
+
|
|
143
|
+
# Python
|
|
144
|
+
pytest tests/coupon/
|
|
145
|
+
|
|
146
|
+
# Node
|
|
147
|
+
npm test -- coupon
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Baseline Attribution / 验证阶梯
|
|
151
|
+
|
|
152
|
+
在老项目、DDD 多模块或编译环境不稳定时,先把"项目原本就坏"和"本轮 diff 改坏"拆开。改代码前做一次最小基线探测,改完后走验证阶梯。
|
|
153
|
+
|
|
154
|
+
**改代码前**:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
mvn -version
|
|
158
|
+
mvn -pl <entry-module> -am -DskipTests compile
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
如果失败,记录到 `baselineKnownFailures`:命令、错误摘要、是否涉及计划 Files / 本轮 diff、是否属于环境或历史红点。不要立刻改业务代码来迁就基线错误。
|
|
162
|
+
|
|
163
|
+
**改完后按从快到慢验证**:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
git diff --check
|
|
167
|
+
mvn -pl <entry-module> -am -Dtest=<TestClass> test
|
|
168
|
+
mvn -pl <entry-module> -am -DskipTests compile
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
- 命中新改文件 / 新增测试 / 本轮 diff 依赖链路的错误:当前 task 内修。
|
|
172
|
+
- 与改代码前一致、且不触碰本轮 diff 的错误:作为 `baselineKnownFailures` 上报。
|
|
173
|
+
- 单条 compile/test 的时间预算建议 3-5 分钟;超过 5 分钟不要换一串全量命令盲跑,先输出阻塞/风险和下一步卡片。
|
|
174
|
+
- 已确认的基线失败不能无限重试;最多复核一次,之后用 `DONE_WITH_CONCERNS` 或 `BLOCKED` 表达风险。
|
|
175
|
+
|
|
176
|
+
### Java DDD / 多模块 Maven 验证
|
|
177
|
+
|
|
178
|
+
DDD 多模块项目不要把"单个源码目录"或"单个 leaf module"当成最终验证单位。domain / app / adapter / infrastructure 经常依赖 annotation processor、聚合 root、DTO/BO 转换和 reactor 顺序,单模块或裸 classpath 很容易误报。
|
|
179
|
+
|
|
180
|
+
**验证前先确认实际构建 JDK**:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
mvn -version
|
|
184
|
+
rg 'maven-toolchains-plugin|toolchain|maven.compiler.release|maven.compiler.source|maven.compiler.target|<java.version>|maven-compiler-plugin|lombok' pom.xml **/pom.xml
|
|
185
|
+
ls .java-version .sdkmanrc .tool-versions 2>/dev/null
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
- `java -version` 只能说明当前 shell 的默认 Java,不等于项目编译实际使用的 Java。
|
|
189
|
+
- Maven 实际运行 JDK 以 `mvn -version` 的 `Java version` / `Java home` 为准。
|
|
190
|
+
- 如果项目使用 `maven-toolchains-plugin`,还要检查 `~/.m2/toolchains.xml` 和 Maven 日志里最终选择的 toolchain。
|
|
191
|
+
- 项目声明版本来自 `maven.compiler.release` / `source` / `target` / `<java.version>`;它只是声明,必须和 Maven 实际运行 JDK / toolchain 对照。
|
|
192
|
+
- 遇到 `Unsupported class file major version`、`IllegalAccessError`、`NoSuchFieldError`、Lombok annotation processor 报错时,先诊断 JDK / Maven / toolchain / Lombok 版本,不要先改业务代码。
|
|
193
|
+
|
|
194
|
+
**推荐策略**:
|
|
195
|
+
|
|
196
|
+
- 开发中先跑最小可编译 reactor slice:`mvn -pl <entry-module> -am -DskipTests compile`
|
|
197
|
+
- 跑相关测试也用 reactor slice:`mvn -pl <entry-module> -am -Dtest=<TestClass> test`
|
|
198
|
+
- `<entry-module>` 选真实入口模块:改 domain 但使用入口在 app,就优先选 app;改 adapter/mapper 就选承载该链路的 app/boot 模块。
|
|
199
|
+
- 公共 domain / DTO / mapper / interface 契约被多模块复用时,task 完成前再跑全量 `mvn -DskipTests compile` 或项目 CI 等价命令。
|
|
200
|
+
|
|
201
|
+
**禁止把 `javac --proc:none` 当作最终验证**:
|
|
202
|
+
|
|
203
|
+
- `javac --proc:none` 不跑 Lombok / MapStruct / QueryDSL 等 annotation processor,只能做临时语法探针。
|
|
204
|
+
- 不能因为裸 `javac` 下 Lombok getter/setter 不生成,就给 BO/DTO/Domain 补显式 getter/setter。
|
|
205
|
+
- 如果 Maven reactor 编译和裸 `javac` 结果冲突,以 Maven reactor / CI 为准。
|
|
206
|
+
|
|
207
|
+
**如果回归挂了**:
|
|
208
|
+
|
|
209
|
+
1. 第一反应:是不是我改动引起的?
|
|
210
|
+
2. 如果是 → 修(不是新 task,是当前 task 的一部分)
|
|
211
|
+
3. 如果不是(偶发 / 环境)→ quarantine 老 flaky,记 issue,继续(不要吞)
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Step 5:重构(可选)
|
|
216
|
+
|
|
217
|
+
测试通过后,在测试护栏下重构:
|
|
218
|
+
|
|
219
|
+
- 抽方法 / 拆 if-else
|
|
220
|
+
- 去重复
|
|
221
|
+
- 改命名
|
|
222
|
+
|
|
223
|
+
**前提**:测试必须先通过。重构中**只改结构不改行为**,每一小步后重跑测试。
|
|
224
|
+
|
|
225
|
+
**不要**:
|
|
226
|
+
|
|
227
|
+
- 改测试("测试和实现一起改") → 失去护栏
|
|
228
|
+
- 跨 task 重构(超出 Files 范围)
|
|
229
|
+
- 大改结构(独立开 task)
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Step 6:commit + --done
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
git add .
|
|
237
|
+
git commit -m "feat(coupon): T-01 add batch-grant controller skeleton + input validation"
|
|
238
|
+
|
|
239
|
+
# 回到 devflow-kit 工作目录执行 df(不在 worktree 里):
|
|
240
|
+
devflow apply --task 1 --done --note="commit $(git -C .devflow-worktrees/<slug>/task-1 rev-parse HEAD)"
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**硬规则**:
|
|
244
|
+
|
|
245
|
+
- commit message **严格按 plan.md** 里的格式
|
|
246
|
+
- `--done` 的 `--note` 要含 commit sha,方便 review 溯源
|
|
247
|
+
- 如果 task 分了多个 commit,note 含最后一个 sha(或所有 sha)
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## TDD 的常见误区
|
|
252
|
+
|
|
253
|
+
### "TDD 拖慢我"
|
|
254
|
+
|
|
255
|
+
事实:TDD 前期慢 15%,但整体项目减少 40-70% 的 bug 返工时间(业界研究)。
|
|
256
|
+
|
|
257
|
+
快感的 illusion:没写测试 → 跑快了 → 后面 review + verify + bug 追尾时间是 10x 回来。
|
|
258
|
+
|
|
259
|
+
### "我知道要写什么,先写实现最快"
|
|
260
|
+
|
|
261
|
+
结果:实现完你"记得"去写测试,但测试变成"为实现服务",断言往往会迁就实现的行为,而不是反向驱动正确的行为。review 会扫这种 test 叫 "implementation-driven test",严重度 SHOULD。
|
|
262
|
+
|
|
263
|
+
### "这个 bug 太明显,不用写测试"
|
|
264
|
+
|
|
265
|
+
事实:没测试的 fix 会在 3 周后由别的 commit 复活。所有 bug fix 都应该有一个 reproducing test → fix → test pass。
|
|
266
|
+
|
|
267
|
+
### "单元测试覆盖不全,我直接集成测试"
|
|
268
|
+
|
|
269
|
+
混合策略 OK,但:
|
|
270
|
+
|
|
271
|
+
- 纯逻辑分支应该在 unit 测(快、稳)
|
|
272
|
+
- 集成测试补充"真实依赖下整合对不对",不代替 unit
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## TDD 的循环小技巧
|
|
277
|
+
|
|
278
|
+
- **命名测试 → 想清行为**:写测试名时往往就想清楚 "要测什么";想不清就别写,说明 task behavior 没想清
|
|
279
|
+
- **断言写前半**:先 `assertEquals(X, ...)`,再填实现去算 X;防止 "实现出啥我断啥" 的反向 flavor
|
|
280
|
+
- **failing state 先 commit**(可选):先 `git commit -m "T-01 RED: add failing test"`,再 GREEN,再 `git rebase -i` squash;把思路流程也留下来
|
|
281
|
+
- **测试不通过了别着急看实现**:先看测试代码是不是正确表达了 behavior;测试错了 / 不对会把 debug 带向错误方向
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## 本文与 SKILL.md 的关系
|
|
286
|
+
|
|
287
|
+
SKILL.md 给了 4 步硬规则。本文给每步该做 / 不该做、常见偏离、修正、TDD 心法。apply 阶段每做一个 task 都应对照本文节奏。
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# apply / when-plan-is-wrong
|
|
2
|
+
|
|
3
|
+
发现 plan / design / requirement 不对时的决策树与审计格式。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 核心原则
|
|
8
|
+
|
|
9
|
+
apply 是**执行**,不是**决策**。当前上游产出有问题时:
|
|
10
|
+
|
|
11
|
+
1. **停**:停止编码,不在 apply 里暗改
|
|
12
|
+
2. **定位**:问题在哪个 phase(plan / tech-spec / requirement-analysis)
|
|
13
|
+
3. **回退**:跳回对应 phase 修正
|
|
14
|
+
4. **审计**:产物里记录"第 N 次返工"的原因和改动
|
|
15
|
+
5. **恢复**:回到 apply,继续当前或下一 task
|
|
16
|
+
|
|
17
|
+
最大的错误是**在 apply 里暗自调整**——代码和 design / plan 对不上,review 会炸,archive 的 spec delta 也乱。
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 决策树:回退到哪?
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
发现问题
|
|
25
|
+
↓
|
|
26
|
+
问题本质?
|
|
27
|
+
├─ "我按 task 描述做,但 test 过不了" → design 有缺陷
|
|
28
|
+
│ → 回退 tech-spec
|
|
29
|
+
│
|
|
30
|
+
├─ "task 描述不清,两种实现都说得通" → plan 颗粒度不够
|
|
31
|
+
│ → 回退 plan
|
|
32
|
+
│
|
|
33
|
+
├─ "我发现这种情况 AC 没定义应该怎么办" → 需求边界漏掉
|
|
34
|
+
│ → 回退 requirement-analysis(Round 2 追加 Q)
|
|
35
|
+
│
|
|
36
|
+
├─ "前 N 个 task 写完,才发现整体架构有问题" → design 级缺陷
|
|
37
|
+
│ → 回退 tech-spec(严重时回退 requirement-analysis)
|
|
38
|
+
│
|
|
39
|
+
├─ "依赖的外部服务接口和 design 的假设不符" → 假设错误
|
|
40
|
+
│ → 回退 tech-spec(可能 requirement)
|
|
41
|
+
│
|
|
42
|
+
├─ "性能测试发现 X 不满足 AC" → 设计没考虑
|
|
43
|
+
│ → 回退 tech-spec
|
|
44
|
+
│
|
|
45
|
+
├─ "task 做着做着发现能拆成 3 个更独立的子 task" → 颗粒度
|
|
46
|
+
│ → 回退 plan(小改,不是大回退)
|
|
47
|
+
│
|
|
48
|
+
└─ "AC 本身写错了 / 含糊" → 需求缺陷
|
|
49
|
+
→ 回退 requirement-analysis
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 回退流程
|
|
55
|
+
|
|
56
|
+
### 第 1 步:暂停当前 task
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
devflow apply --task N --pause --reason="<具体描述>"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
会:
|
|
63
|
+
|
|
64
|
+
- 把 task 状态从 in_progress 标为 paused
|
|
65
|
+
- 记录 reason 到 state.json
|
|
66
|
+
- 提示要回到 devflow-kit 工作目录处理(不在 worktree 里)
|
|
67
|
+
|
|
68
|
+
**不要**直接跳过或 abandon——要留痕。
|
|
69
|
+
|
|
70
|
+
### 第 2 步:进入对应 phase 修正
|
|
71
|
+
|
|
72
|
+
#### 回退到 plan
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
devflow plan --edit --reason="task T-07 描述有歧义"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
在 plan.md 里:
|
|
79
|
+
|
|
80
|
+
- 找到有问题的 task
|
|
81
|
+
- 修正 5 要素描述
|
|
82
|
+
- 如果是颗粒度问题:拆分 / 合并
|
|
83
|
+
- 更新依赖 DAG(如果有影响)
|
|
84
|
+
- 保留一段"# 返工记录"
|
|
85
|
+
|
|
86
|
+
然后硬闸:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
devflow plan --check
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### 回退到 tech-spec
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
devflow tech-spec --revise --reason="事务边界在并发场景下不安全"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
在 design.md:
|
|
99
|
+
|
|
100
|
+
- 改动受影响的"技术方案"/"关键决策"部分
|
|
101
|
+
- 更新或新增 ADR(记录为什么改)
|
|
102
|
+
- 如有 spec delta 变化 → 更新 `delta/<capability>.md`
|
|
103
|
+
- 留下修订说明
|
|
104
|
+
|
|
105
|
+
然后必然要回到 plan 重新核对:design 变了,plan 的 task 可能也要调整。
|
|
106
|
+
|
|
107
|
+
#### 回退到 requirement-analysis
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
devflow requirement-analysis --round-3 --reason="发现批量失败时的处理 AC 未定义"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
- 新开一轮 Q&A 补清楚
|
|
114
|
+
- 更新 requirement.md 的"功能需求"/"边界与异常"
|
|
115
|
+
- 新增 / 修改 F-ID 的 AC
|
|
116
|
+
|
|
117
|
+
然后所有下游(design / plan / tests)都要跟着核对,是否需要 revise。
|
|
118
|
+
|
|
119
|
+
### 第 3 步:审计记录
|
|
120
|
+
|
|
121
|
+
每次回退都在对应产物里留一段(附录或末尾):
|
|
122
|
+
|
|
123
|
+
```markdown
|
|
124
|
+
## 修订历史
|
|
125
|
+
|
|
126
|
+
### v1.2 (返工 #1, 2026-04-24)
|
|
127
|
+
- **触发**:apply 阶段 T-07 发现事务边界在并发超 100 时死锁
|
|
128
|
+
- **调整**:
|
|
129
|
+
- 设计:由 `@Transactional` 包整个 service method,改为拆分为 "校验(无事务)+ 核销(短事务)+ 记录(独立事务)"
|
|
130
|
+
- Spec delta:新增 `delta/coupon-batch-grant.md` "MODIFIED: 事务策略"
|
|
131
|
+
- **影响下游**:
|
|
132
|
+
- plan.md T-07 Files 新增 `TransactionConfig.java`
|
|
133
|
+
- plan.md T-08 被拆成 T-08a / T-08b
|
|
134
|
+
- **作者**:@eng-a(executor)+ @arch-b(tech-spec reviewer)
|
|
135
|
+
- **审批**:roll back approved
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 第 4 步:恢复 apply
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
devflow apply --task N --resume
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
- 当前 task 状态从 paused → in_progress
|
|
145
|
+
- 重新读 plan.md / tests.md / design.md
|
|
146
|
+
- 按新 plan 重新做(可能需要 revert 部分已写代码)
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 已完成 task 受到影响怎么办?
|
|
151
|
+
|
|
152
|
+
### 场景:做 T-05 时发现 design 有问题,回退 tech-spec 后,T-01~T-04 受影响
|
|
153
|
+
|
|
154
|
+
对策:
|
|
155
|
+
|
|
156
|
+
1. **逐个评估**:T-01 ~ T-04 的 Behavior / Implementation 是否受新 design 影响
|
|
157
|
+
2. **受影响的 task**:
|
|
158
|
+
- 重置状态为 todo:`devflow apply --task 3 --reset --reason="design revised in #1"`
|
|
159
|
+
- 重新做(可能能复用部分代码 / 测试)
|
|
160
|
+
3. **不受影响的 task**:状态保持 done,但在 state.json 记录 "verified against revise #1"
|
|
161
|
+
4. **更新 plan.md**:反映 task 重置信息
|
|
162
|
+
|
|
163
|
+
### 场景:已经 push 到远端的代码受影响
|
|
164
|
+
|
|
165
|
+
不能 revert 历史(多人协作)。做法:
|
|
166
|
+
|
|
167
|
+
- 新开 task 修正(不是回退)
|
|
168
|
+
- plan.md 里新加 task T-Nx 或 T-N+1
|
|
169
|
+
- 走正常 apply 流程
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 什么情况下**不**回退,继续 apply
|
|
174
|
+
|
|
175
|
+
有些发现不够到 "回退" 级别,只是 "noting":
|
|
176
|
+
|
|
177
|
+
| 发现 | 对策 |
|
|
178
|
+
| --- | --- |
|
|
179
|
+
| 变量命名更好的写法 | 记 NIT,当前 task 内修正即可 |
|
|
180
|
+
| 代码里可以抽一个 util | 当前 task 内抽(若 scope 合适)或 TODO + 新 task |
|
|
181
|
+
| 测试覆盖率可以更高 | 当前 task 补测试(review 前自查) |
|
|
182
|
+
| design.md 的一个小拼写错误 | apply 结束后一起修,不回退 |
|
|
183
|
+
| 发现一个 code review 风格问题 | 按 cheatsheet 自改,不回退 |
|
|
184
|
+
| 临时找到更优性能写法 | 看是否 AC 要求;不要求 → 记 TODO,新 task 讨论 |
|
|
185
|
+
|
|
186
|
+
**判断标准**:回退是"行为 / 契约 / AC 级"的;小改不是。
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 返工的审计字段
|
|
191
|
+
|
|
192
|
+
state.json 里为每次返工加一条:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"iterations": [
|
|
197
|
+
{
|
|
198
|
+
"id": 1,
|
|
199
|
+
"triggeredAt": "apply:T-07",
|
|
200
|
+
"rollbackTo": "tech-spec",
|
|
201
|
+
"reason": "事务边界在并发超 100 时死锁",
|
|
202
|
+
"durationMinutes": 120,
|
|
203
|
+
"affectedTasks": ["T-01","T-02","T-03","T-05","T-06","T-07","T-08"],
|
|
204
|
+
"impactSummary": "design revised: 事务拆分;plan revised: T-08 拆分",
|
|
205
|
+
"resolvedAt": "2026-04-24T14:30:00Z"
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
这份数据在 archive 阶段会汇总进 retrospective.md(如有),也在 `devflow doctor` / `devflow metrics` 里统计"平均返工率"。
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 常见的错误应对
|
|
216
|
+
|
|
217
|
+
### 错:在 apply 里偷改 design
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
# code 里实现了 design 没说的并发控制
|
|
221
|
+
# design.md 没更新
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
后果:
|
|
225
|
+
|
|
226
|
+
- review 看不懂代码("为什么这里有锁?design 没说啊")
|
|
227
|
+
- archive 时 spec delta 对不上代码
|
|
228
|
+
|
|
229
|
+
正确:停 → 回退 tech-spec → 更新 design + delta → 再回来 apply。
|
|
230
|
+
|
|
231
|
+
### 错:在 apply 里直接改 plan.md
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
# 把 Files 列表加了一个文件
|
|
235
|
+
# 没记录 revise 原因
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
后果:下次 review 找不到"为什么要加这个文件",可能会质疑合理性。
|
|
239
|
+
|
|
240
|
+
正确:`devflow plan --edit --reason=...` 走流程,留审计。
|
|
241
|
+
|
|
242
|
+
### 错:绕过回退,"临时"写个补丁
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
# code 里加了 @SuppressWarnings
|
|
246
|
+
# 或者硬编码 workaround
|
|
247
|
+
# 想 "先过 CI 再说"
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
后果:review 会挂,即使不挂也是技术债。
|
|
251
|
+
|
|
252
|
+
正确:回退对应 phase 彻底解决;实在紧急 → 开 ADR 明确 "临时方案" + 还债 task。
|
|
253
|
+
|
|
254
|
+
### 错:返工时漏了下游同步
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
# 改了 tech-spec
|
|
258
|
+
# 没更新 plan
|
|
259
|
+
# apply 时按老 plan 做 → 和新 design 对不上
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
正确:返工后必须按顺序检查下游:requirement → spec → plan → tests → apply。每一层都要"对齐"了才继续。
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## 返工次数的预警
|
|
267
|
+
|
|
268
|
+
| 单个 slug 返工次数 | 说明 | 建议 |
|
|
269
|
+
| --- | --- | --- |
|
|
270
|
+
| 0 次 | 一次过 | 健康(但要警惕:是不是真的想清楚了?) |
|
|
271
|
+
| 1-2 次 | 正常 | L2/L3 常见,复杂系统难免 |
|
|
272
|
+
| 3-4 次 | 警告 | 上游清晰度不够,要反思 |
|
|
273
|
+
| ≥ 5 次 | 问题 | 大概率需求 / 设计没想清,建议暂停并重新 framing |
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## 本文与 SKILL.md 的关系
|
|
278
|
+
|
|
279
|
+
SKILL.md 说了"回退优先级 + 表"。本文详解决策树 / 审计格式 / 受影响 task 处置 / 常见错误。发现问题时对照本文操作。
|