cc-devflow 4.5.1 → 4.5.2
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/.claude/skills/cc-act/CHANGELOG.md +14 -0
- package/.claude/skills/cc-act/PLAYBOOK.md +26 -1
- package/.claude/skills/cc-act/SKILL.md +36 -7
- package/.claude/skills/cc-act/assets/PR_BRIEF_TEMPLATE.md +20 -0
- package/.claude/skills/cc-act/references/closure-contract.md +8 -0
- package/.claude/skills/cc-act/scripts/cc-act-common.sh +6 -1
- package/.claude/skills/cc-act/scripts/render-pr-brief.sh +99 -0
- package/.claude/skills/cc-act/scripts/verify-act-gate.sh +17 -1
- package/.claude/skills/cc-check/CHANGELOG.md +14 -0
- package/.claude/skills/cc-check/PLAYBOOK.md +101 -1
- package/.claude/skills/cc-check/SKILL.md +128 -7
- package/.claude/skills/cc-check/assets/REPORT_CARD_TEMPLATE.json +121 -1
- package/.claude/skills/cc-check/references/review-contract.md +88 -0
- package/.claude/skills/cc-check/scripts/render-report-card.js +172 -5
- package/.claude/skills/cc-check/scripts/verify-gate.sh +21 -0
- package/.claude/skills/cc-investigate/CHANGELOG.md +13 -0
- package/.claude/skills/cc-investigate/PLAYBOOK.md +105 -4
- package/.claude/skills/cc-investigate/SKILL.md +185 -8
- package/.claude/skills/cc-investigate/assets/ANALYSIS_TEMPLATE.md +77 -3
- package/.claude/skills/cc-investigate/assets/TASKS_TEMPLATE.md +10 -3
- package/.claude/skills/cc-investigate/assets/TASK_MANIFEST_TEMPLATE.json +102 -1
- package/.claude/skills/cc-investigate/references/investigation-contract.md +146 -0
- package/.claude/skills/cc-simplify/CHANGELOG.md +15 -0
- package/.claude/skills/cc-simplify/SKILL.md +255 -35
- package/CHANGELOG.md +16 -0
- package/docs/examples/example-bindings.json +3 -3
- package/docs/examples/full-design-blocked/README.md +1 -1
- package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/review/report-card.json +140 -3
- package/docs/examples/local-handoff/README.md +1 -1
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/review/report-card.json +92 -0
- package/docs/examples/pdca-loop/README.md +1 -1
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/handoff/pr-brief.md +20 -0
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/review/report-card.json +92 -0
- package/lib/skill-runtime/review.js +64 -1
- package/lib/skill-runtime/schemas.js +150 -3
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cc-check
|
|
3
|
-
version: 1.8.
|
|
3
|
+
version: 1.8.4
|
|
4
4
|
description: Use when a planned or investigated change needs fresh verification evidence, layered gate proof, review truth, and an honest pass fail blocked verdict before entering cc-act.
|
|
5
5
|
triggers:
|
|
6
6
|
- 验收这个需求
|
|
@@ -25,7 +25,7 @@ entry_gate:
|
|
|
25
25
|
- Re-run fresh commands instead of inheriting cc-do narration.
|
|
26
26
|
- If evidence is stale or missing, reset context and rebuild the verdict from canonical artifacts.
|
|
27
27
|
exit_criteria:
|
|
28
|
-
- review/report-card.json records pass, fail, or blocked using fresh evidence, plus spec alignment and sync readiness.
|
|
28
|
+
- review/report-card.json records pass, fail, or blocked using fresh evidence, review freshness, claim evidence, QA coverage and browser evidence, failure ownership, plus spec alignment and sync readiness.
|
|
29
29
|
- Task-level review and requirement-level diff review are separated clearly.
|
|
30
30
|
- 'The next step is unambiguous: cc-act, cc-do, cc-investigate, or cc-plan.'
|
|
31
31
|
reroutes:
|
|
@@ -119,6 +119,8 @@ NO PASS WITHOUT FRESH EVIDENCE
|
|
|
119
119
|
- runtime gate
|
|
120
120
|
- task-level review proof
|
|
121
121
|
- requirement-level diff review
|
|
122
|
+
- claim evidence matrix
|
|
123
|
+
- QA regression / test-quality proof
|
|
122
124
|
- spec alignment / sync readiness
|
|
123
125
|
4. **Freeze Verdict**
|
|
124
126
|
- 只允许 `pass` / `fail` / `blocked`
|
|
@@ -131,12 +133,12 @@ NO PASS WITHOUT FRESH EVIDENCE
|
|
|
131
133
|
|
|
132
134
|
- Allowed actions: rerun gates, inspect review proof, record a verdict, and route the requirement honestly.
|
|
133
135
|
- Forbidden actions: continuing development, inheriting old execution claims without fresh proof, or masking blocked work as pass.
|
|
134
|
-
- Required evidence: every passing statement must cite fresh command output, exit status, and
|
|
136
|
+
- Required evidence: every passing statement must cite fresh command output, exit status, key observation, and the claim it proves.
|
|
135
137
|
- Reroute rule: code and review fixes return to `cc-do`; root-cause drift returns to `cc-investigate`; scope or design invalidation returns to `cc-plan`.
|
|
136
138
|
|
|
137
139
|
## Verification Layers
|
|
138
140
|
|
|
139
|
-
`cc-check` 不是只看“测试是不是绿的”,而是至少看
|
|
141
|
+
`cc-check` 不是只看“测试是不是绿的”,而是至少看 9 层:
|
|
140
142
|
|
|
141
143
|
1. **Runtime Layer**
|
|
142
144
|
- 测试、lint、typecheck、build、脚本 gate
|
|
@@ -147,9 +149,61 @@ NO PASS WITHOUT FRESH EVIDENCE
|
|
|
147
149
|
- 当前改动是否真的兑现 requirement,而不是只让局部测试通过
|
|
148
150
|
4. **Spec Sync Layer**
|
|
149
151
|
- capability truth、expected spec delta、handoff readiness 是否仍然一致
|
|
152
|
+
5. **Claim Evidence Layer**
|
|
153
|
+
- 测试通过、build 成功、bug 修复、需求完成、agent 完成等声明,是否各自有对应证据
|
|
154
|
+
6. **QA Test Layer**
|
|
155
|
+
- 回归测试是否有 red/green 证据
|
|
156
|
+
- 测试是否验证真实行为,而不是 mock 或 test-only production API
|
|
157
|
+
7. **Review Freshness Layer**
|
|
158
|
+
- review 是否绑定当前 `headSha`
|
|
159
|
+
- 从 review 到当前 HEAD 是否还有新增 commit
|
|
160
|
+
- 质量分、置信度、finding 去噪是否可复盘
|
|
161
|
+
8. **QA Coverage / Browser Layer**
|
|
162
|
+
- 行为链路、错误态、边界条件是否被测试映射覆盖
|
|
163
|
+
- UI / 用户路径变更是否有浏览器证据、截图、console 结果或明确 skip 理由
|
|
164
|
+
9. **Failure Ownership Layer**
|
|
165
|
+
- 失败是本分支引入、基线已存在、环境阻塞,还是归属不明
|
|
166
|
+
- 归属不明默认不能支撑 `pass`
|
|
150
167
|
|
|
151
168
|
任何一层失真,都不能写 `pass`。
|
|
152
169
|
|
|
170
|
+
## Claim Evidence Matrix
|
|
171
|
+
|
|
172
|
+
不要把所有绿色都写成“测试过了”。`cc-check` 必须把声明拆成证据:
|
|
173
|
+
|
|
174
|
+
| Claim | Required proof | Not enough |
|
|
175
|
+
| --- | --- | --- |
|
|
176
|
+
| Tests pass | 本轮 test command、exit 0、0 failures | 旧输出、局部日志、应该会过 |
|
|
177
|
+
| Lint clean | 本轮 lint command、0 errors | 只跑 formatter、只看 touched file 且声明全仓 clean |
|
|
178
|
+
| Build succeeds | build command exit 0 | test / lint 通过 |
|
|
179
|
+
| Bug fixed | 原始症状或回归测试通过 | 代码改了、推测已修 |
|
|
180
|
+
| Regression test works | red -> green 证据 | 测试只绿过一次 |
|
|
181
|
+
| Agent completed | VCS diff / artifact 证明实际变化 | agent 自报 success |
|
|
182
|
+
| Requirements met | 逐项 plan / manifest checklist | 测试通过 |
|
|
183
|
+
|
|
184
|
+
这些事实写入 `claimEvidence[]`。缺少关键 claim 的证据时,结论至少是 `blocked`。
|
|
185
|
+
|
|
186
|
+
## QA Test Review
|
|
187
|
+
|
|
188
|
+
`cc-check` 必须区分“有测试”和“测试证明了正确行为”:
|
|
189
|
+
|
|
190
|
+
1. 回归测试必须记录 red/green 证据;red 要因为目标行为缺失而失败,不是语法、fixture 或 mock 写错。
|
|
191
|
+
2. 测试应验证真实行为;如果依赖 mock,必须说明 mock 的边界和为什么不会测试 mock 本身。
|
|
192
|
+
3. 生产代码里新增仅测试使用的 API,默认是坏味道,必须 blocking,除非有明确生产生命周期理由。
|
|
193
|
+
4. 复杂 mock setup 超过测试主体时,优先要求 integration / contract test 解释。
|
|
194
|
+
|
|
195
|
+
这些事实写入 `qa.regressionProof` 和 `qa.testQuality`。如果本需求没有行为测试空间,必须记录 `tddException` 或替代验证命令。
|
|
196
|
+
|
|
197
|
+
## QA Coverage And Browser Evidence
|
|
198
|
+
|
|
199
|
+
测试不是数量游戏。`cc-check` 必须判断测试覆盖了哪条真实路径:
|
|
200
|
+
|
|
201
|
+
1. `qa.coverageAudit` 记录 `coveragePct`、`pathMap`、`gaps`、`testsAdded`、`e2eRequired`、`evalRequired`、`qualityStars`。
|
|
202
|
+
2. UI、路由、端到端用户路径、可视状态、交互状态变化时,必须记录 `qa.browserEvidence`。
|
|
203
|
+
3. `qa.browserEvidence` 至少说明 `mode`、`affectedRoutes`、`screenshots`、`consoleErrors`、`healthScore`、`issues`、`skipReason`。
|
|
204
|
+
4. 前端变更没有浏览器证据也没有 skip reason,不能写 `pass`。
|
|
205
|
+
5. 非前端或纯内部变更可以把 `browserEvidence.status` 写成 `skipped`,但必须说明为什么不需要浏览器 QA。
|
|
206
|
+
|
|
153
207
|
## Diff Review Pipeline
|
|
154
208
|
|
|
155
209
|
`cc-check` 的 requirement-level review 不能只写“diff 看过了”。至少要形成这些事实:
|
|
@@ -161,9 +215,56 @@ NO PASS WITHOUT FRESH EVIDENCE
|
|
|
161
215
|
5. Outside-diff lookup:新增枚举值、状态、路由、artifact 类型时,必须搜索 sibling references,不能只读 diff 内文件。
|
|
162
216
|
6. Documentation staleness:代码行为、入口、命令、结构变化时,检查 README / CLAUDE / architecture docs 是否漂移。
|
|
163
217
|
7. Adversarial synthesis:如果有 codex review、subagent review、人工 review,多视角 finding 要去重并标出高置信重叠项。
|
|
218
|
+
8. Specialist facets:按实际风险记录 `testing`、`security`、`performance`、`api-contract`、`data-migration`、`design` 等 review facet;没有派发也要写 skip reason,避免 reviewer 误以为已经覆盖。
|
|
219
|
+
9. Confidence calibration:每条 finding 必须有可比较的置信度和指纹,低置信 finding 不准伪装成 blocker。
|
|
164
220
|
|
|
165
221
|
这些事实写入 `review.diffReview.details` 或 `review.findings`。`pass` 只在 scope、completion、critical pass、doc staleness 都没有 blocking finding 时成立。
|
|
166
222
|
|
|
223
|
+
## Review Packet And Triage
|
|
224
|
+
|
|
225
|
+
每次 task-level 或 requirement-level review 都必须能脱离聊天记录复盘:
|
|
226
|
+
|
|
227
|
+
1. `reviewPacket.baseSha`
|
|
228
|
+
2. `reviewPacket.headSha`
|
|
229
|
+
3. `reviewPacket.requirements`
|
|
230
|
+
4. `reviewPacket.implemented`
|
|
231
|
+
5. `reviewPacket.reviewerContext`
|
|
232
|
+
|
|
233
|
+
每次 review 还必须记录 freshness:
|
|
234
|
+
|
|
235
|
+
1. `review.freshness.status`:`fresh` / `stale` / `unknown` / `not-applicable`
|
|
236
|
+
2. `review.freshness.reviewedCommit`
|
|
237
|
+
3. `review.freshness.currentCommit`
|
|
238
|
+
4. `review.freshness.commitsSinceReview`
|
|
239
|
+
5. `review.freshness.staleReason`
|
|
240
|
+
6. `review.qualityScore`:0-10,缺失时不能当成高置信审查
|
|
241
|
+
|
|
242
|
+
每条 finding 必须有 triage:
|
|
243
|
+
|
|
244
|
+
- `accepted-fixed`:已修并有验证
|
|
245
|
+
- `rejected-with-evidence`:经代码 / 测试证明不适用
|
|
246
|
+
- `deferred-minor`:非阻塞,已写入 follow-up
|
|
247
|
+
- `clarification-needed`:不清楚,当前 verdict 不能是 `pass`
|
|
248
|
+
|
|
249
|
+
`critical` / `important` finding 未 triage 或未闭环,不能进入 `cc-act`。
|
|
250
|
+
|
|
251
|
+
每条 finding 还必须带去噪字段:
|
|
252
|
+
|
|
253
|
+
- `confidenceScore`:1-10,低于 7 的 finding 只能作为 warning 或待验证 gap
|
|
254
|
+
- `fingerprint`:稳定去重键,避免多路 review 重复报同一件事
|
|
255
|
+
- `displayTier`:`blocking` / `warning` / `info` / `suppressed`
|
|
256
|
+
- `suppressionReason`:只有 `displayTier=suppressed` 时允许非空
|
|
257
|
+
|
|
258
|
+
## Failure Ownership
|
|
259
|
+
|
|
260
|
+
失败不能只写“测试红了”。`cc-check` 必须把失败归属写入 `runtime.failureOwnership[]`:
|
|
261
|
+
|
|
262
|
+
1. `classification` 只能是 `in-branch`、`pre-existing`、`environment`、`ambiguous`。
|
|
263
|
+
2. `ambiguous` 默认按 `in-branch` 处理,除非有 base branch 复验证据。
|
|
264
|
+
3. `pre-existing` 必须有 base branch 或历史证据,不能靠猜。
|
|
265
|
+
4. `environment` 必须记录缺失依赖、权限、服务、密钥或平台约束。
|
|
266
|
+
5. `pass` 不能带未解释的 `in-branch` 或 `ambiguous` 失败。
|
|
267
|
+
|
|
167
268
|
## Entry Gate
|
|
168
269
|
|
|
169
270
|
1. 先读 `planning/design.md` 或 `planning/analysis.md`,再读 `planning/tasks.md`、`planning/task-manifest.json`。
|
|
@@ -181,6 +282,7 @@ NO PASS WITHOUT FRESH EVIDENCE
|
|
|
181
282
|
- 运行真实命令
|
|
182
283
|
- 记录 exit status
|
|
183
284
|
- 识别 failure 还是 blocked
|
|
285
|
+
- 记录 failure ownership,而不是把所有红灯混成一个失败摘要
|
|
184
286
|
3. **Compare against the contract**
|
|
185
287
|
- 对照 `planning/design.md` 或 `planning/analysis.md`
|
|
186
288
|
- 对照 `planning/tasks.md`、`planning/task-manifest.json`
|
|
@@ -265,9 +367,12 @@ NO PASS WITHOUT FRESH EVIDENCE
|
|
|
265
367
|
|
|
266
368
|
1. severity:`critical` / `important` / `info`
|
|
267
369
|
2. confidence:`high` / `medium` / `low`,低置信不要伪装成 blocker
|
|
370
|
+
- 同时写 `confidenceScore`,用 1-10 数字表达可比较置信度
|
|
268
371
|
3. source:`runtime` / `task-review` / `diff-review` / `adversarial` / `docs`
|
|
269
372
|
4. evidence:文件、命令、退出码、manifest path、或具体观察
|
|
270
373
|
5. action:`fix-now` / `reroute-cc-do` / `reroute-cc-plan` / `reroute-cc-investigate` / `document-follow-up`
|
|
374
|
+
6. fingerprint:稳定去重键
|
|
375
|
+
7. displayTier:`blocking` / `warning` / `info` / `suppressed`
|
|
271
376
|
|
|
272
377
|
不能写“可能有问题”然后让接手者猜。要么证明,要么标成待验证 gap。
|
|
273
378
|
|
|
@@ -281,15 +386,31 @@ NO PASS WITHOUT FRESH EVIDENCE
|
|
|
281
386
|
"verdict": "pass",
|
|
282
387
|
"overall": "pass",
|
|
283
388
|
"summary": "verdict=pass quick=3/3 strict=0/0 review=pass",
|
|
389
|
+
"claimEvidence": [
|
|
390
|
+
{ "claim": "tests-pass", "requiredProof": "fresh test command", "commandOrArtifact": "npm test", "exitStatus": 0, "keyObservation": "0 failures", "status": "pass" },
|
|
391
|
+
{ "claim": "requirements-met", "requiredProof": "plan checklist", "commandOrArtifact": "planning/tasks.md", "exitStatus": null, "keyObservation": "all tasks complete", "status": "pass" }
|
|
392
|
+
],
|
|
393
|
+
"runtime": { "status": "pass", "failureOwnership": [] },
|
|
394
|
+
"qa": {
|
|
395
|
+
"status": "pass",
|
|
396
|
+
"regressionProof": [],
|
|
397
|
+
"testQuality": [],
|
|
398
|
+
"coverageAudit": { "status": "pass", "coveragePct": 80, "pathMap": [], "gaps": [], "testsAdded": [], "e2eRequired": false, "evalRequired": false, "qualityStars": "★★" },
|
|
399
|
+
"browserEvidence": { "status": "skipped", "mode": "not-applicable", "affectedRoutes": [], "screenshots": [], "consoleErrors": [], "healthScore": null, "issues": [], "skipReason": "not a UI or user-path change" },
|
|
400
|
+
"tddException": null
|
|
401
|
+
},
|
|
284
402
|
"quickGates": [],
|
|
285
403
|
"strictGates": [],
|
|
286
404
|
"review": {
|
|
287
405
|
"status": "pass",
|
|
288
406
|
"summary": "Task review and diff review both passed",
|
|
289
407
|
"details": "",
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
408
|
+
"freshness": { "status": "fresh", "reviewedCommit": "example-head", "currentCommit": "example-head", "commitsSinceReview": 0, "staleReason": "" },
|
|
409
|
+
"qualityScore": 9,
|
|
410
|
+
"specialistReviews": [],
|
|
411
|
+
"taskReviews": { "status": "pass", "required": true, "summary": "all completed tasks carry spec/code proof", "reviewPacket": {}, "reviewers": [], "findings": [] },
|
|
412
|
+
"diffReview": { "status": "pass", "required": true, "summary": "plan completion clean, no scope drift, no critical diff findings", "reviewPacket": {}, "reviewers": [], "findings": [] },
|
|
413
|
+
"findings": []
|
|
293
414
|
},
|
|
294
415
|
"blockingFindings": [],
|
|
295
416
|
"reroute": "none",
|
|
@@ -9,6 +9,80 @@
|
|
|
9
9
|
"specAlignment": "blocked",
|
|
10
10
|
"specDeltaVerified": false,
|
|
11
11
|
"specSyncReady": false,
|
|
12
|
+
"runtime": {
|
|
13
|
+
"status": "blocked",
|
|
14
|
+
"failureOwnership": [
|
|
15
|
+
{
|
|
16
|
+
"failure": "missing spec review proof",
|
|
17
|
+
"classification": "in-branch",
|
|
18
|
+
"touchedByDiff": true,
|
|
19
|
+
"evidence": "planning/task-manifest.json tasks[T002].reviews.spec is empty",
|
|
20
|
+
"action": "reroute-cc-do",
|
|
21
|
+
"status": "open"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"claimEvidence": [
|
|
26
|
+
{
|
|
27
|
+
"claim": "tests-pass",
|
|
28
|
+
"requiredProof": "fresh test command with exit 0 and 0 failures",
|
|
29
|
+
"commandOrArtifact": "npm test -- src/feature/feature.test.ts",
|
|
30
|
+
"exitStatus": 0,
|
|
31
|
+
"keyObservation": "targeted tests passed in this run",
|
|
32
|
+
"status": "pass"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"claim": "requirements-met",
|
|
36
|
+
"requiredProof": "line-by-line planning/tasks.md and task-manifest.json checklist",
|
|
37
|
+
"commandOrArtifact": "planning/tasks.md + planning/task-manifest.json",
|
|
38
|
+
"exitStatus": null,
|
|
39
|
+
"keyObservation": "T002 still lacks spec review proof",
|
|
40
|
+
"status": "blocked"
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"qa": {
|
|
44
|
+
"status": "blocked",
|
|
45
|
+
"regressionProof": [
|
|
46
|
+
{
|
|
47
|
+
"behavior": "original symptom",
|
|
48
|
+
"redCommand": "",
|
|
49
|
+
"redFailure": "",
|
|
50
|
+
"greenCommand": "",
|
|
51
|
+
"greenObservation": "",
|
|
52
|
+
"restoredState": false
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"testQuality": [
|
|
56
|
+
{
|
|
57
|
+
"area": "targeted-tests",
|
|
58
|
+
"checksRealBehavior": true,
|
|
59
|
+
"mockBoundary": "none",
|
|
60
|
+
"testOnlyProductionApi": false,
|
|
61
|
+
"status": "pass"
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"coverageAudit": {
|
|
65
|
+
"status": "blocked",
|
|
66
|
+
"coveragePct": null,
|
|
67
|
+
"pathMap": ["planning/tasks.md#T002"],
|
|
68
|
+
"gaps": ["T002 has no spec review proof, so the requirement cannot be marked covered"],
|
|
69
|
+
"testsAdded": [],
|
|
70
|
+
"e2eRequired": false,
|
|
71
|
+
"evalRequired": false,
|
|
72
|
+
"qualityStars": "★"
|
|
73
|
+
},
|
|
74
|
+
"browserEvidence": {
|
|
75
|
+
"status": "skipped",
|
|
76
|
+
"mode": "not-applicable",
|
|
77
|
+
"affectedRoutes": [],
|
|
78
|
+
"screenshots": [],
|
|
79
|
+
"consoleErrors": [],
|
|
80
|
+
"healthScore": null,
|
|
81
|
+
"issues": [],
|
|
82
|
+
"skipReason": "template example is not a UI browser QA scenario"
|
|
83
|
+
},
|
|
84
|
+
"tddException": null
|
|
85
|
+
},
|
|
12
86
|
"quickGates": [
|
|
13
87
|
{
|
|
14
88
|
"name": "targeted-tests",
|
|
@@ -28,17 +102,63 @@
|
|
|
28
102
|
"status": "blocked",
|
|
29
103
|
"summary": "Task review evidence is incomplete",
|
|
30
104
|
"details": "T002 is implemented, but the requirement still lacks spec review proof required by the gate.",
|
|
105
|
+
"freshness": {
|
|
106
|
+
"status": "unknown",
|
|
107
|
+
"reviewedCommit": "",
|
|
108
|
+
"currentCommit": "",
|
|
109
|
+
"commitsSinceReview": null,
|
|
110
|
+
"staleReason": "review range is not recorded yet"
|
|
111
|
+
},
|
|
112
|
+
"qualityScore": null,
|
|
113
|
+
"specialistReviews": [
|
|
114
|
+
{
|
|
115
|
+
"name": "testing",
|
|
116
|
+
"status": "blocked",
|
|
117
|
+
"required": true,
|
|
118
|
+
"summary": "testing facet cannot pass while task review proof is missing",
|
|
119
|
+
"skipReason": "",
|
|
120
|
+
"findings": []
|
|
121
|
+
}
|
|
122
|
+
],
|
|
31
123
|
"taskReviews": {
|
|
32
124
|
"status": "blocked",
|
|
33
125
|
"required": true,
|
|
34
126
|
"summary": "T002 has no spec review record yet",
|
|
127
|
+
"reviewPacket": {
|
|
128
|
+
"baseSha": "",
|
|
129
|
+
"headSha": "",
|
|
130
|
+
"requirements": "planning/tasks.md#T002",
|
|
131
|
+
"implemented": "implementation report for T002",
|
|
132
|
+
"reviewerContext": "task spec and changed files"
|
|
133
|
+
},
|
|
35
134
|
"reviewers": [],
|
|
36
|
-
"findings": [
|
|
135
|
+
"findings": [
|
|
136
|
+
{
|
|
137
|
+
"severity": "important",
|
|
138
|
+
"confidence": "high",
|
|
139
|
+
"source": "task-review",
|
|
140
|
+
"summary": "T002 spec review proof is missing",
|
|
141
|
+
"evidence": "planning/task-manifest.json tasks[T002].reviews.spec is empty",
|
|
142
|
+
"action": "reroute-cc-do",
|
|
143
|
+
"triageStatus": "clarification-needed",
|
|
144
|
+
"confidenceScore": 9,
|
|
145
|
+
"fingerprint": "task-review:T002:missing-spec-review",
|
|
146
|
+
"displayTier": "blocking",
|
|
147
|
+
"suppressionReason": null
|
|
148
|
+
}
|
|
149
|
+
]
|
|
37
150
|
},
|
|
38
151
|
"diffReview": {
|
|
39
152
|
"status": "skipped",
|
|
40
153
|
"required": false,
|
|
41
154
|
"summary": "",
|
|
155
|
+
"reviewPacket": {
|
|
156
|
+
"baseSha": "",
|
|
157
|
+
"headSha": "",
|
|
158
|
+
"requirements": "planning/design.md",
|
|
159
|
+
"implemented": "",
|
|
160
|
+
"reviewerContext": ""
|
|
161
|
+
},
|
|
42
162
|
"reviewers": [],
|
|
43
163
|
"findings": []
|
|
44
164
|
},
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
每个 reviewer 结果至少说明:
|
|
23
23
|
|
|
24
|
+
- reviewPacket
|
|
24
25
|
- status
|
|
25
26
|
- summary
|
|
26
27
|
- evidence
|
|
@@ -30,16 +31,103 @@
|
|
|
30
31
|
|
|
31
32
|
- severity
|
|
32
33
|
- confidence
|
|
34
|
+
- confidenceScore
|
|
33
35
|
- source
|
|
34
36
|
- summary
|
|
35
37
|
- evidence
|
|
36
38
|
- action
|
|
39
|
+
- triageStatus
|
|
40
|
+
- fingerprint
|
|
41
|
+
- displayTier
|
|
42
|
+
- suppressionReason
|
|
43
|
+
|
|
44
|
+
## Review Packet
|
|
45
|
+
|
|
46
|
+
Review 不能依赖聊天记忆。每个 task-level review 和 requirement-level diff review 至少记录:
|
|
47
|
+
|
|
48
|
+
- `baseSha`:被审查范围的起点
|
|
49
|
+
- `headSha`:被审查范围的终点
|
|
50
|
+
- `requirements`:对应的 plan、task、analysis 或 spec 路径
|
|
51
|
+
- `implemented`:实现者声称完成的内容
|
|
52
|
+
- `reviewerContext`:reviewer 实际拿到的上下文摘要
|
|
53
|
+
|
|
54
|
+
缺 `baseSha` / `headSha` 时,review 只能算 `blocked` 或 `skipped`,不能支撑 `pass`。
|
|
55
|
+
|
|
56
|
+
## Review Freshness
|
|
57
|
+
|
|
58
|
+
Review 必须绑定当前被交付的 commit,而不是绑定聊天记忆。
|
|
59
|
+
|
|
60
|
+
每份 requirement-level review 至少记录:
|
|
61
|
+
|
|
62
|
+
- `review.freshness.status`:`fresh` / `stale` / `unknown` / `not-applicable`
|
|
63
|
+
- `review.freshness.reviewedCommit`
|
|
64
|
+
- `review.freshness.currentCommit`
|
|
65
|
+
- `review.freshness.commitsSinceReview`
|
|
66
|
+
- `review.freshness.staleReason`
|
|
67
|
+
- `review.qualityScore`:0-10,可空但空值不能支撑高置信 pass
|
|
68
|
+
|
|
69
|
+
`status=stale`、`status=unknown` 且没有解释,或 `commitsSinceReview > 0` 且未重审,都会阻塞 `pass`。
|
|
70
|
+
|
|
71
|
+
## Specialist Facets
|
|
72
|
+
|
|
73
|
+
`review.specialistReviews[]` 用来记录按风险覆盖的审查面,不要求每次都派发独立 reviewer,但要求边界说清:
|
|
74
|
+
|
|
75
|
+
- `testing`:负路径、边界条件、隔离性、flaky 风险、回归测试质量
|
|
76
|
+
- `security`:trust boundary、shell / SQL / secret / auth 风险
|
|
77
|
+
- `performance`:热路径、批量、缓存、N+1、资源泄漏
|
|
78
|
+
- `api-contract`:输入输出、状态枚举、兼容面、错误语义
|
|
79
|
+
- `data-migration`:schema、回滚、幂等、历史数据
|
|
80
|
+
- `design`:UI / UX / visual consistency 和可用性
|
|
81
|
+
|
|
82
|
+
没有相关风险时写 `status=skipped` 和 `skipReason`;有风险却缺 facet 时,至少是 review gap。
|
|
83
|
+
|
|
84
|
+
## Finding Triage
|
|
85
|
+
|
|
86
|
+
Review finding 不只是“发现过”,必须有处置结果:
|
|
87
|
+
|
|
88
|
+
| triageStatus | 什么时候用 |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| `accepted-fixed` | finding 正确,已修复,并有验证证据 |
|
|
91
|
+
| `rejected-with-evidence` | finding 不适用,已有代码 / 测试 / 契约证据支撑 |
|
|
92
|
+
| `deferred-minor` | minor,不阻塞本次交付,已写入 follow-up |
|
|
93
|
+
| `clarification-needed` | finding 不清楚,需要用户或 reviewer 澄清 |
|
|
94
|
+
|
|
95
|
+
`critical` / `important` finding 不能用 `deferred-minor`。任何 `clarification-needed` 都会阻塞 `pass`。
|
|
96
|
+
|
|
97
|
+
## QA Test Review Facts
|
|
98
|
+
|
|
99
|
+
Review 必须判断测试是否证明行为:
|
|
100
|
+
|
|
101
|
+
- 回归测试是否有 red/green 证据
|
|
102
|
+
- red 是否因为目标行为缺失而失败
|
|
103
|
+
- green 是否包含 targeted test 和必要的 broader gate
|
|
104
|
+
- mock 是否必要,且没有断言 mock 本身
|
|
105
|
+
- 生产代码是否新增 test-only API
|
|
106
|
+
- integration / contract test 是否比复杂 mock 更直接
|
|
107
|
+
- coverage audit 是否映射真实 codepath / user flow / error state / edge case
|
|
108
|
+
- UI 或用户路径变更是否有 browser evidence、截图、console 结果,或明确 skip reason
|
|
109
|
+
|
|
110
|
+
## Failure Ownership
|
|
111
|
+
|
|
112
|
+
失败归属必须结构化写入 `runtime.failureOwnership[]`:
|
|
113
|
+
|
|
114
|
+
- `classification=in-branch`:当前分支引入
|
|
115
|
+
- `classification=pre-existing`:base branch 也能复现,必须有证据
|
|
116
|
+
- `classification=environment`:缺依赖、权限、服务、密钥或平台条件
|
|
117
|
+
- `classification=ambiguous`:归属不明,默认不能支撑 `pass`
|
|
118
|
+
|
|
119
|
+
不要把 pre-existing failure 当成当前分支失败,也不要把 ambiguous failure 当成环境问题。
|
|
37
120
|
|
|
38
121
|
## Gate Rules
|
|
39
122
|
|
|
40
123
|
- 任务级 review 缺证据,不能绿灯
|
|
41
124
|
- 需求级 diff review 在 strict 模式下缺失,至少是 `blocked`
|
|
42
125
|
- `important` / `critical` finding 未处理前,不算通过
|
|
126
|
+
- `important` / `critical` finding 缺 triageStatus,不算通过
|
|
127
|
+
- QA test quality 缺失且本次涉及行为变化,至少是 `blocked`
|
|
128
|
+
- review freshness 缺失、过期或与当前 head 不一致,不能绿灯
|
|
129
|
+
- UI / 用户路径变更缺 browser evidence 且无 skip reason,不能绿灯
|
|
130
|
+
- `runtime.failureOwnership` 仍有 `in-branch` 或 `ambiguous` 未解释失败,不能绿灯
|
|
43
131
|
- plan item 是 `PARTIAL` / `NOT_DONE` 且影响成功标准时,不能通过
|
|
44
132
|
- scope drift 没有解释清楚时,不能通过
|
|
45
133
|
- 文档漂移如果影响 reviewer / maintainer 接手,必须阻塞到 `cc-act` doc sync 或 reroute
|