cc-devflow 4.5.1 → 4.5.3

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 (81) hide show
  1. package/.claude/skills/cc-act/CHANGELOG.md +27 -0
  2. package/.claude/skills/cc-act/PLAYBOOK.md +32 -1
  3. package/.claude/skills/cc-act/SKILL.md +53 -7
  4. package/.claude/skills/cc-act/assets/PR_BRIEF_TEMPLATE.md +35 -1
  5. package/.claude/skills/cc-act/assets/RELEASE_NOTE_TEMPLATE.md +10 -1
  6. package/.claude/skills/cc-act/references/closure-contract.md +11 -0
  7. package/.claude/skills/cc-act/scripts/cc-act-common.sh +32 -1
  8. package/.claude/skills/cc-act/scripts/render-pr-brief.sh +130 -0
  9. package/.claude/skills/cc-act/scripts/verify-act-gate.sh +23 -1
  10. package/.claude/skills/cc-check/CHANGELOG.md +26 -0
  11. package/.claude/skills/cc-check/PLAYBOOK.md +128 -1
  12. package/.claude/skills/cc-check/SKILL.md +147 -7
  13. package/.claude/skills/cc-check/assets/REPORT_CARD_TEMPLATE.json +164 -1
  14. package/.claude/skills/cc-check/references/gate-contract.md +11 -0
  15. package/.claude/skills/cc-check/references/review-contract.md +104 -0
  16. package/.claude/skills/cc-check/scripts/render-report-card.js +209 -5
  17. package/.claude/skills/cc-check/scripts/verify-gate.sh +28 -0
  18. package/.claude/skills/cc-do/CHANGELOG.md +12 -0
  19. package/.claude/skills/cc-do/PLAYBOOK.md +14 -9
  20. package/.claude/skills/cc-do/SKILL.md +24 -13
  21. package/.claude/skills/cc-do/references/execution-recovery.md +16 -5
  22. package/.claude/skills/cc-do/scripts/verify-task-gates.sh +19 -6
  23. package/.claude/skills/cc-do/scripts/write-task-checkpoint.sh +14 -2
  24. package/.claude/skills/cc-investigate/CHANGELOG.md +31 -0
  25. package/.claude/skills/cc-investigate/PLAYBOOK.md +124 -8
  26. package/.claude/skills/cc-investigate/SKILL.md +252 -17
  27. package/.claude/skills/cc-investigate/assets/ANALYSIS_TEMPLATE.md +112 -3
  28. package/.claude/skills/cc-investigate/assets/TASKS_TEMPLATE.md +17 -5
  29. package/.claude/skills/cc-investigate/assets/TASK_MANIFEST_TEMPLATE.json +141 -1
  30. package/.claude/skills/cc-investigate/references/investigation-contract.md +192 -0
  31. package/.claude/skills/cc-plan/CHANGELOG.md +26 -0
  32. package/.claude/skills/cc-plan/PLAYBOOK.md +18 -6
  33. package/.claude/skills/cc-plan/SKILL.md +72 -34
  34. package/.claude/skills/cc-plan/assets/DESIGN_TEMPLATE.md +30 -3
  35. package/.claude/skills/cc-plan/assets/TASKS_TEMPLATE.md +28 -0
  36. package/.claude/skills/cc-plan/assets/TASK_MANIFEST_TEMPLATE.json +46 -1
  37. package/.claude/skills/cc-plan/assets/TINY_DESIGN_TEMPLATE.md +24 -0
  38. package/.claude/skills/cc-plan/references/planning-contract.md +18 -4
  39. package/.claude/skills/cc-roadmap/CHANGELOG.md +14 -0
  40. package/.claude/skills/cc-roadmap/PLAYBOOK.md +10 -7
  41. package/.claude/skills/cc-roadmap/SKILL.md +43 -23
  42. package/.claude/skills/cc-roadmap/assets/BACKLOG_TEMPLATE.md +10 -0
  43. package/.claude/skills/cc-roadmap/assets/ROADMAP_TEMPLATE.md +15 -0
  44. package/.claude/skills/cc-roadmap/assets/TRACKING_TEMPLATE.json +1 -1
  45. package/.claude/skills/cc-roadmap/references/roadmap-dialogue.md +11 -7
  46. package/.claude/skills/cc-simplify/CHANGELOG.md +21 -0
  47. package/.claude/skills/cc-simplify/SKILL.md +264 -35
  48. package/.claude/skills/cc-spec-init/CHANGELOG.md +6 -0
  49. package/.claude/skills/cc-spec-init/SKILL.md +14 -1
  50. package/CHANGELOG.md +37 -0
  51. package/README.md +10 -2
  52. package/README.zh-CN.md +10 -2
  53. package/docs/examples/example-bindings.json +7 -7
  54. package/docs/examples/full-design-blocked/BACKLOG.md +1 -1
  55. package/docs/examples/full-design-blocked/README.md +1 -1
  56. package/docs/examples/full-design-blocked/ROADMAP.md +1 -1
  57. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/design.md +1 -1
  58. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/tasks.md +1 -1
  59. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/review/report-card.json +140 -3
  60. package/docs/examples/full-design-blocked/roadmap-tracking.json +1 -1
  61. package/docs/examples/local-handoff/BACKLOG.md +1 -1
  62. package/docs/examples/local-handoff/README.md +1 -1
  63. package/docs/examples/local-handoff/ROADMAP.md +1 -1
  64. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/design.md +1 -1
  65. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/tasks.md +1 -1
  66. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/review/report-card.json +92 -0
  67. package/docs/examples/local-handoff/roadmap-tracking.json +1 -1
  68. package/docs/examples/pdca-loop/BACKLOG.md +1 -1
  69. package/docs/examples/pdca-loop/README.md +1 -1
  70. package/docs/examples/pdca-loop/ROADMAP.md +1 -1
  71. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/handoff/pr-brief.md +20 -0
  72. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/design.md +1 -1
  73. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json +2 -2
  74. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/tasks.md +1 -1
  75. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/review/report-card.json +92 -0
  76. package/docs/examples/pdca-loop/roadmap-tracking.json +1 -1
  77. package/docs/skill-strategy-audit.md +48 -0
  78. package/lib/skill-runtime/__tests__/runtime.integration.test.js +19 -1
  79. package/lib/skill-runtime/review.js +64 -1
  80. package/lib/skill-runtime/schemas.js +161 -4
  81. package/package.json +1 -1
@@ -9,7 +9,7 @@
9
9
  "sourceRoadmap": {
10
10
  "itemId": "RM-001",
11
11
  "roadmapVersion": "roadmap.v1",
12
- "roadmapSkillVersion": "4.3.4",
12
+ "roadmapSkillVersion": "4.4.1",
13
13
  "sourceStage": "Stage 1",
14
14
  "successSignal": "Users can copy the invite link with one click",
15
15
  "killSignal": "The patch requires backend or permission changes",
@@ -22,7 +22,7 @@
22
22
  ]
23
23
  },
24
24
  "planningMeta": {
25
- "reqPlanSkillVersion": "3.5.6",
25
+ "reqPlanSkillVersion": "3.7.0",
26
26
  "designVersion": "design.v1",
27
27
  "approvedAt": "2026-04-15T10:05:00.000Z",
28
28
  "approvedBy": "user",
@@ -4,7 +4,7 @@
4
4
 
5
5
  - Requirement version: `REQ-001.v1`
6
6
  - Design version: `design.v1`
7
- - CC-Plan skill version: `3.5.6`
7
+ - CC-Plan skill version: `3.7.0`
8
8
  - Source roadmap item: `RM-001`
9
9
  - Source roadmap version: `roadmap.v1`
10
10
 
@@ -3,6 +3,65 @@
3
3
  "verdict": "pass",
4
4
  "overall": "pass",
5
5
  "summary": "verdict=pass quick=2/2 strict=0/0 review=pass",
6
+ "specAlignment": "pass",
7
+ "specDeltaVerified": true,
8
+ "specSyncReady": true,
9
+ "runtime": {
10
+ "status": "pass",
11
+ "failureOwnership": []
12
+ },
13
+ "claimEvidence": [
14
+ {
15
+ "claim": "tests-pass",
16
+ "requiredProof": "fresh targeted test command with exit 0",
17
+ "commandOrArtifact": "npm test -- src/features/share/ShareDialog.test.tsx",
18
+ "exitStatus": 0,
19
+ "keyObservation": "share dialog targeted tests passed",
20
+ "status": "pass"
21
+ },
22
+ {
23
+ "claim": "requirements-met",
24
+ "requiredProof": "line-by-line planning/tasks.md and task-manifest.json checklist",
25
+ "commandOrArtifact": "planning/tasks.md + planning/task-manifest.json",
26
+ "exitStatus": null,
27
+ "keyObservation": "T001-T003 complete with spec/code review proof",
28
+ "status": "pass"
29
+ }
30
+ ],
31
+ "qa": {
32
+ "status": "pass",
33
+ "regressionProof": [],
34
+ "testQuality": [
35
+ {
36
+ "area": "share-dialog",
37
+ "checksRealBehavior": true,
38
+ "mockBoundary": "none",
39
+ "testOnlyProductionApi": false,
40
+ "status": "pass"
41
+ }
42
+ ],
43
+ "coverageAudit": {
44
+ "status": "pass",
45
+ "coveragePct": 80,
46
+ "pathMap": ["copy invite link success path", "clipboard fallback error path"],
47
+ "gaps": [],
48
+ "testsAdded": ["src/features/share/ShareDialog.test.tsx"],
49
+ "e2eRequired": false,
50
+ "evalRequired": false,
51
+ "qualityStars": "★★"
52
+ },
53
+ "browserEvidence": {
54
+ "status": "skipped",
55
+ "mode": "not-applicable",
56
+ "affectedRoutes": [],
57
+ "screenshots": [],
58
+ "consoleErrors": [],
59
+ "healthScore": null,
60
+ "issues": [],
61
+ "skipReason": "example fixture uses targeted component evidence instead of a live browser"
62
+ },
63
+ "tddException": null
64
+ },
6
65
  "quickGates": [
7
66
  {
8
67
  "name": "targeted-tests",
@@ -22,10 +81,35 @@
22
81
  "status": "pass",
23
82
  "summary": "Task review proof and requirement-level diff review both passed",
24
83
  "details": "T001-T003 have matching spec/code review proof and the diff stays inside the approved tiny-design boundary.",
84
+ "freshness": {
85
+ "status": "fresh",
86
+ "reviewedCommit": "example-head",
87
+ "currentCommit": "example-head",
88
+ "commitsSinceReview": 0,
89
+ "staleReason": ""
90
+ },
91
+ "qualityScore": 9,
92
+ "specialistReviews": [
93
+ {
94
+ "name": "testing",
95
+ "status": "pass",
96
+ "required": true,
97
+ "summary": "targeted tests cover the share dialog behavior for this example",
98
+ "skipReason": "",
99
+ "findings": []
100
+ }
101
+ ],
25
102
  "taskReviews": {
26
103
  "status": "pass",
27
104
  "required": true,
28
105
  "summary": "All completed tasks carry spec/code proof",
106
+ "reviewPacket": {
107
+ "baseSha": "example-base",
108
+ "headSha": "example-head",
109
+ "requirements": "planning/tasks.md#T001-T003",
110
+ "implemented": "copy invite link workflow",
111
+ "reviewerContext": "task manifest plus changed share dialog files"
112
+ },
29
113
  "reviewers": [],
30
114
  "findings": []
31
115
  },
@@ -33,12 +117,20 @@
33
117
  "status": "pass",
34
118
  "required": false,
35
119
  "summary": "No blocking requirement-level findings",
120
+ "reviewPacket": {
121
+ "baseSha": "example-base",
122
+ "headSha": "example-head",
123
+ "requirements": "planning/design.md",
124
+ "implemented": "copy invite link workflow",
125
+ "reviewerContext": "requirement diff, plan completion, scope drift, docs staleness"
126
+ },
36
127
  "reviewers": [],
37
128
  "findings": []
38
129
  },
39
130
  "findings": []
40
131
  },
41
132
  "blockingFindings": [],
133
+ "gaps": [],
42
134
  "reroute": "none",
43
135
  "timestamp": "2026-04-15T11:20:00.000Z"
44
136
  }
@@ -3,7 +3,7 @@
3
3
  "lastSyncedAt": "2026-04-19",
4
4
  "backlogMeta": {
5
5
  "roadmapVersion": "roadmap.v1",
6
- "skillVersion": "4.3.4",
6
+ "skillVersion": "4.4.1",
7
7
  "currentFocusStage": "Stage 1"
8
8
  },
9
9
  "dependencyHandoff": {
@@ -0,0 +1,48 @@
1
+ # External Skill Strategy Audit
2
+
3
+ 本审计覆盖 `/Users/dimon/001Area/80-CodeWorld/003-project/skills` 下的 22 个
4
+ `SKILL.md`。目标不是复制外部 skill,而是抽取能让 cc-devflow 原生 workflow
5
+ 更稳的策略,并把不适合迁移的部分明确跳过。
6
+
7
+ ## Migration Summary
8
+
9
+ | Source skill | Good strategy | cc-devflow target | Decision |
10
+ | --- | --- | --- | --- |
11
+ | `deprecated/design-an-interface` | "design it twice",用不同接口形态比较 depth、易用错点和隐藏复杂度 | `cc-plan` | 迁移为接口备选比较 gate,不迁移 parallel subagent 强制要求 |
12
+ | `deprecated/qa` | 用户视角 issue、轻量澄清、按可独立验证行为拆分 | `cc-act` / `cc-plan` | 迁移为 follow-up / issue handoff 的行为化规则 |
13
+ | `deprecated/request-refactor-plan` | 重构计划拆成 tiny commits,每步保持可运行 | `cc-plan` / `cc-act` | 迁移为 refactor slicing 和 bisectable commit 规则 |
14
+ | `deprecated/triage-issue` | 先查根因,再写 TDD fix plan,issue 不绑定易腐烂文件行号 | `cc-investigate` / `cc-plan` | 迁移为 repair contract 和 durable issue brief 规则 |
15
+ | `deprecated/ubiquitous-language` | canonical terms、aliases to avoid、ambiguity flag | `cc-spec-init` / `cc-plan` | 迁移为 capability/domain language glossary gate |
16
+ | `engineering/diagnose` | 反馈回路优先级、提高 flaky 复现率、假设必须可证伪、debug tag cleanup | `cc-investigate` | 已有大部分;补强 loop sharpening 和 postmortem handoff |
17
+ | `engineering/github-triage` | label state machine、needs-info 保留已确认事实、resume triage notes | `cc-act` | 迁移为远端 issue/PR closeout 的状态一致性规则 |
18
+ | `engineering/grill-with-docs` | 术语冲突立即叫停、具体场景压测、ADR 只记难逆/意外/真实取舍 | `cc-plan` | 已有大部分;补强 glossary update 和 ADR sparsity |
19
+ | `engineering/improve-codebase-architecture` | deep module、deletion test、one adapter vs two adapters、locality/leverage | `cc-simplify` / `cc-plan` | 迁移为架构坏味道确认清单 |
20
+ | `engineering/tdd` | 禁止水平切片,使用 tracer bullet 垂直 Red/Green 循环 | `cc-do` / `cc-plan` | 已有 planning 规则;补强执行阶段逐条 task 的 tracer bullet guard |
21
+ | `engineering/to-issues` | 独立可领的 vertical slices,HITL/AFK 标注,依赖顺序创建 | `cc-plan` / `cc-act` | 迁移为 task / follow-up 切片规则 |
22
+ | `engineering/to-prd` | 从现有上下文合成 PRD,测试决策只写行为和模块,不写短期文件路径 | `cc-plan` | 迁移为 design durable output 规则,不迁移 GitHub issue 自动创建 |
23
+ | `engineering/zoom-out` | 不熟悉区域时先上升一层,画模块和调用方地图 | `cc-roadmap` / `cc-plan` | 已被 context sweep 覆盖;仅作为审计备注 |
24
+ | `misc/git-guardrails-claude-code` | 阻断危险 git 动作,保留用户确认边界 | `cc-act` | 迁移为 destructive / publish action guard,不迁移 Claude hook 实现 |
25
+ | `misc/migrate-to-shoehorn` | 测试里的 partial fixture 要显式表达,不用不透明 cast 掩盖类型事实 | `cc-do` / `cc-check` | 迁移为通用 test fixture discipline,不绑定 shoehorn 依赖 |
26
+ | `misc/scaffold-exercises` | 生成目录后必须跑专用 lint,移动用 `git mv` 保留历史 | `cc-act` | 仅迁移验证/移动原则;课程目录规则不迁移 |
27
+ | `misc/setup-pre-commit` | 根据实际包管理器和已有 scripts 装配 hook,最后用真实 hook smoke | `cc-act` | 仅作为工具链变更验证参考,不迁移 Husky 方案 |
28
+ | `personal/edit-article` | 文档结构按依赖顺序组织,段落短、信息先后可追踪 | `docs-sync` | 迁移为 docs-sync 叙事顺序规则 |
29
+ | `personal/obsidian-vault` | index note、wikilink、反向查找的知识图谱维护 | none | 个人知识库规则,不迁移到 cc-devflow |
30
+ | `productivity/caveman` | 压缩沟通但保留精确技术事实,复杂步骤暂时恢复完整表达 | `cc-act` / output style | 作为输出风格参考,不写进 workflow 合约 |
31
+ | `productivity/grill-me` | 一次一个问题;能查代码就别问用户 | `cc-plan` | 已有规则;审计确认不重复迁移 |
32
+ | `productivity/write-a-skill` | description 是触发真相源;SKILL.md 要短,复杂内容下沉到 references/scripts | `docs-sync` | 迁移为 skill contract quality gate |
33
+
34
+ ## Implementation Order
35
+
36
+ 1. `cc-plan`: 吸收接口备选、领域语言、垂直切片和 durable design 输出规则。
37
+ 2. `cc-investigate`: 补强 feedback loop sharpening、flaky rate、postmortem handoff。
38
+ 3. `cc-do`: 补强 tracer bullet 执行和 test fixture discipline。
39
+ 4. `cc-simplify`: 增加 deep module / deletion test / adapter reality 检查。
40
+ 5. `cc-act`: 增加 issue/PR 状态、危险 git 动作、工具链验证和 durable follow-up 规则。
41
+ 6. `docs-sync`: 增加 skill 合约质量 gate 和文档依赖顺序检查。
42
+
43
+ ## Skip Rules
44
+
45
+ - 不迁移个人路径、个人 vault、课程目录命名、具体第三方测试依赖。
46
+ - 不把 deprecated skill 的 GitHub issue 自动创建行为搬进主流程;cc-devflow 仍以
47
+ durable local artifact 和可选 remote handoff 为主。
48
+ - 不新增一套平行 skill;所有迁移必须落回现有 `cc-*` workflow 语义。
@@ -204,7 +204,22 @@ describe('Skill runtime', () => {
204
204
  '--status',
205
205
  'passed',
206
206
  '--summary',
207
- 'task finished'
207
+ 'task finished',
208
+ '--tdd-json',
209
+ JSON.stringify({
210
+ red: {
211
+ testSeam: 'public helper command',
212
+ behaviorAsserted: 'checkpoint is written under execution/tasks',
213
+ allowedMocks: [],
214
+ implementationDetailRisk: 'low'
215
+ },
216
+ testQuality: {
217
+ usesPublicInterface: true,
218
+ describesBehavior: true,
219
+ survivesInternalRefactor: true,
220
+ mocksOnlySystemBoundaries: true
221
+ }
222
+ })
208
223
  ], { encoding: 'utf8' });
209
224
  expect(checkpoint.status).toBe(0);
210
225
 
@@ -245,6 +260,9 @@ describe('Skill runtime', () => {
245
260
  expect(verify.status).toBe(0);
246
261
 
247
262
  expect(fs.existsSync(path.join(change.tasksDir, 'T001', 'checkpoint.json'))).toBe(true);
263
+ const checkpointJson = JSON.parse(fs.readFileSync(path.join(change.tasksDir, 'T001', 'checkpoint.json'), 'utf8'));
264
+ expect(checkpointJson.tdd.red.testSeam).toBe('public helper command');
265
+ expect(checkpointJson.tdd.testQuality.usesPublicInterface).toBe(true);
248
266
  expect(fs.existsSync(path.join(repoRoot, '.harness', 'runtime', changeId))).toBe(false);
249
267
  expect(fs.existsSync(path.join(change.tasksDir, 'T001', 'checkpoint.md'))).toBe(false);
250
268
  expect(fs.existsSync(path.join(change.tasksDir, 'T001', 'review-spec.md'))).toBe(false);
@@ -79,6 +79,7 @@ function makeFinding({
79
79
  status = 'open',
80
80
  fingerprint
81
81
  }) {
82
+ const confidenceScore = severityRank(severity) >= severityRank('important') ? 8 : 6;
82
83
  return {
83
84
  id,
84
85
  source,
@@ -91,7 +92,12 @@ function makeFinding({
91
92
  ...(typeof line === 'number' ? { line } : {}),
92
93
  action,
93
94
  status,
94
- ...(fingerprint ? { fingerprint } : {})
95
+ confidenceScore,
96
+ fingerprint: fingerprint || `${source}:${category}:${id}`,
97
+ displayTier: status === 'informational'
98
+ ? 'info'
99
+ : (severityRank(severity) >= severityRank('important') ? 'blocking' : 'warning'),
100
+ suppressionReason: null
95
101
  };
96
102
  }
97
103
 
@@ -231,6 +237,14 @@ async function detectBaseRef(repoRoot) {
231
237
  return 'HEAD~1';
232
238
  }
233
239
 
240
+ async function detectCurrentCommit(repoRoot) {
241
+ const result = await runCommand('git rev-parse --short HEAD', { cwd: repoRoot });
242
+ if (result.code === 0 && result.stdout.trim()) {
243
+ return result.stdout.trim();
244
+ }
245
+ return 'working-tree';
246
+ }
247
+
234
248
  async function runCodexStructuredReview({ repoRoot, baseRef }) {
235
249
  const command = [
236
250
  'codex review',
@@ -530,6 +544,7 @@ async function runReviewSuite({ repoRoot, changeId, manifest, strict, skipReview
530
544
  const diffReview = await runDiffReviewSection({ repoRoot, strict, skipReview });
531
545
  const findings = flattenFindings(taskReviews, diffReview);
532
546
  const status = deriveReviewStatus(taskReviews, diffReview);
547
+ const currentCommit = await detectCurrentCommit(repoRoot);
533
548
  const details = [
534
549
  taskReviews.summary,
535
550
  diffReview.summary
@@ -539,6 +554,54 @@ async function runReviewSuite({ repoRoot, changeId, manifest, strict, skipReview
539
554
  status,
540
555
  summary: `Task review: ${taskReviews.status}. Diff review: ${diffReview.status}.`,
541
556
  details,
557
+ freshness: {
558
+ status: 'fresh',
559
+ reviewedCommit: currentCommit,
560
+ currentCommit,
561
+ commitsSinceReview: 0,
562
+ staleReason: ''
563
+ },
564
+ qualityScore: status === 'pass' ? 9 : (status === 'blocked' ? 5 : 3),
565
+ specialistReviews: [
566
+ {
567
+ name: 'testing',
568
+ status: taskReviews.status,
569
+ required: true,
570
+ summary: taskReviews.summary,
571
+ skipReason: '',
572
+ findings: []
573
+ }
574
+ ],
575
+ runtime: {
576
+ status: status === 'pass' ? 'pass' : (status === 'fail' ? 'fail' : 'blocked'),
577
+ failureOwnership: []
578
+ },
579
+ qa: {
580
+ status: 'pass',
581
+ regressionProof: [],
582
+ testQuality: [],
583
+ coverageAudit: {
584
+ status: 'pass',
585
+ coveragePct: null,
586
+ pathMap: [],
587
+ gaps: [],
588
+ testsAdded: [],
589
+ e2eRequired: false,
590
+ evalRequired: false,
591
+ qualityStars: ''
592
+ },
593
+ browserEvidence: {
594
+ status: 'skipped',
595
+ mode: 'not-applicable',
596
+ affectedRoutes: [],
597
+ screenshots: [],
598
+ consoleErrors: [],
599
+ healthScore: null,
600
+ issues: [],
601
+ skipReason: 'runtime verify did not identify a UI browser QA target'
602
+ },
603
+ tddException: null
604
+ },
542
605
  taskReviews,
543
606
  diffReview,
544
607
  findings
@@ -247,6 +247,14 @@ const ManifestSchema = z.object({
247
247
  }
248
248
  });
249
249
 
250
+ const TddCheckpointEvidenceSchema = z.object({
251
+ red: z.record(z.any()).optional(),
252
+ green: z.record(z.any()).optional(),
253
+ refactor: z.record(z.any()).optional(),
254
+ feedbackLoop: z.record(z.any()).optional(),
255
+ testQuality: z.record(z.any()).optional()
256
+ }).passthrough();
257
+
250
258
  const CheckpointSchema = z.object({
251
259
  changeId: ChangeIdSchema,
252
260
  taskId: z.string().regex(TASK_ID_PATTERN),
@@ -257,7 +265,9 @@ const CheckpointSchema = z.object({
257
265
  error: z.string().default(''),
258
266
  outputExcerpt: z.string().default(''),
259
267
  timestamp: z.string().datetime(),
260
- attempt: z.number().int().min(0).default(0)
268
+ attempt: z.number().int().min(0).default(0),
269
+ tdd: TddCheckpointEvidenceSchema.optional(),
270
+ tddException: z.record(z.any()).optional()
261
271
  });
262
272
 
263
273
  const GateResultSchema = z.object({
@@ -269,8 +279,26 @@ const GateResultSchema = z.object({
269
279
  });
270
280
 
271
281
  const ReviewSeveritySchema = z.enum(['critical', 'important', 'minor', 'info']);
272
- const ReviewActionSchema = z.enum(['fix_now', 'follow_up', 'cc-investigate', 'none']);
273
- const ReviewFindingStatusSchema = z.enum(['open', 'resolved', 'accepted', 'informational']);
282
+ const ReviewActionSchema = z.enum([
283
+ 'fix_now',
284
+ 'follow_up',
285
+ 'cc-investigate',
286
+ 'reroute-cc-do',
287
+ 'reroute-cc-plan',
288
+ 'reroute-cc-investigate',
289
+ 'document-follow-up',
290
+ 'none'
291
+ ]);
292
+ const ReviewFindingStatusSchema = z.enum([
293
+ 'open',
294
+ 'resolved',
295
+ 'accepted',
296
+ 'informational',
297
+ 'accepted-fixed',
298
+ 'rejected-with-evidence',
299
+ 'deferred-minor',
300
+ 'clarification-needed'
301
+ ]);
274
302
 
275
303
  const ReviewEvidenceSchema = z.object({
276
304
  kind: z.enum(['command', 'file', 'note']),
@@ -291,7 +319,11 @@ const ReviewFindingSchema = z.object({
291
319
  line: z.number().int().min(1).optional(),
292
320
  action: ReviewActionSchema.default('none'),
293
321
  status: ReviewFindingStatusSchema.default('open'),
294
- fingerprint: z.string().optional()
322
+ fingerprint: z.string().optional(),
323
+ confidence: z.enum(['high', 'medium', 'low']).optional(),
324
+ confidenceScore: z.number().min(1).max(10).optional(),
325
+ displayTier: z.enum(['blocking', 'warning', 'info', 'suppressed']).optional(),
326
+ suppressionReason: z.string().nullable().optional()
295
327
  });
296
328
 
297
329
  const ReviewerResultSchema = z.object({
@@ -317,6 +349,28 @@ const ReportReviewSchema = z.object({
317
349
  status: ReviewDecisionStatusSchema.default('skipped'),
318
350
  summary: z.string().default(''),
319
351
  details: z.string().default(''),
352
+ freshness: z.object({
353
+ status: z.enum(['fresh', 'stale', 'unknown', 'not-applicable']).default('unknown'),
354
+ reviewedCommit: z.string().default(''),
355
+ currentCommit: z.string().default(''),
356
+ commitsSinceReview: z.number().int().min(0).nullable().default(null),
357
+ staleReason: z.string().default('')
358
+ }).default({
359
+ status: 'unknown',
360
+ reviewedCommit: '',
361
+ currentCommit: '',
362
+ commitsSinceReview: null,
363
+ staleReason: ''
364
+ }),
365
+ qualityScore: z.number().min(0).max(10).nullable().default(null),
366
+ specialistReviews: z.array(z.object({
367
+ name: z.string().min(1),
368
+ status: ReviewDecisionStatusSchema,
369
+ required: z.boolean().default(false),
370
+ summary: z.string().default(''),
371
+ skipReason: z.string().default(''),
372
+ findings: z.array(ReviewFindingSchema).default([])
373
+ })).default([]),
320
374
  taskReviews: ReviewSectionSchema.default({
321
375
  status: 'skipped',
322
376
  required: false,
@@ -334,15 +388,118 @@ const ReportReviewSchema = z.object({
334
388
  findings: z.array(ReviewFindingSchema).default([])
335
389
  });
336
390
 
391
+ const ClaimEvidenceSchema = z.object({
392
+ claim: z.string().min(1),
393
+ requiredProof: z.string().min(1),
394
+ commandOrArtifact: z.string().min(1),
395
+ exitStatus: z.number().int().nullable().optional(),
396
+ keyObservation: z.string().default(''),
397
+ status: ReviewDecisionStatusSchema
398
+ });
399
+
400
+ const RuntimeFailureOwnershipSchema = z.object({
401
+ failure: z.string().min(1),
402
+ classification: z.enum(['in-branch', 'pre-existing', 'environment', 'ambiguous']),
403
+ touchedByDiff: z.boolean().optional(),
404
+ evidence: z.string().default(''),
405
+ action: z.string().default(''),
406
+ status: z.string().default('open')
407
+ });
408
+
409
+ const ReportRuntimeSchema = z.object({
410
+ status: ReviewDecisionStatusSchema.default('skipped'),
411
+ failureOwnership: z.array(RuntimeFailureOwnershipSchema).default([])
412
+ }).default({
413
+ status: 'skipped',
414
+ failureOwnership: []
415
+ });
416
+
417
+ const QaSchema = z.object({
418
+ status: ReviewDecisionStatusSchema.default('skipped'),
419
+ regressionProof: z.array(z.record(z.any())).default([]),
420
+ testQuality: z.array(z.record(z.any())).default([]),
421
+ coverageAudit: z.object({
422
+ status: ReviewDecisionStatusSchema.default('skipped'),
423
+ coveragePct: z.number().nullable().default(null),
424
+ pathMap: z.array(z.string()).default([]),
425
+ gaps: z.array(z.string()).default([]),
426
+ testsAdded: z.array(z.string()).default([]),
427
+ e2eRequired: z.boolean().default(false),
428
+ evalRequired: z.boolean().default(false),
429
+ qualityStars: z.string().default('')
430
+ }).default({
431
+ status: 'skipped',
432
+ coveragePct: null,
433
+ pathMap: [],
434
+ gaps: [],
435
+ testsAdded: [],
436
+ e2eRequired: false,
437
+ evalRequired: false,
438
+ qualityStars: ''
439
+ }),
440
+ browserEvidence: z.object({
441
+ status: ReviewDecisionStatusSchema.default('skipped'),
442
+ mode: z.string().default('not-applicable'),
443
+ affectedRoutes: z.array(z.string()).default([]),
444
+ screenshots: z.array(z.string()).default([]),
445
+ consoleErrors: z.array(z.string()).default([]),
446
+ healthScore: z.number().nullable().default(null),
447
+ issues: z.array(z.record(z.any())).default([]),
448
+ skipReason: z.string().default('')
449
+ }).default({
450
+ status: 'skipped',
451
+ mode: 'not-applicable',
452
+ affectedRoutes: [],
453
+ screenshots: [],
454
+ consoleErrors: [],
455
+ healthScore: null,
456
+ issues: [],
457
+ skipReason: ''
458
+ }),
459
+ tddException: z.string().nullable().default(null)
460
+ }).default({
461
+ status: 'skipped',
462
+ regressionProof: [],
463
+ testQuality: [],
464
+ coverageAudit: {
465
+ status: 'skipped',
466
+ coveragePct: null,
467
+ pathMap: [],
468
+ gaps: [],
469
+ testsAdded: [],
470
+ e2eRequired: false,
471
+ evalRequired: false,
472
+ qualityStars: ''
473
+ },
474
+ browserEvidence: {
475
+ status: 'skipped',
476
+ mode: 'not-applicable',
477
+ affectedRoutes: [],
478
+ screenshots: [],
479
+ consoleErrors: [],
480
+ healthScore: null,
481
+ issues: [],
482
+ skipReason: ''
483
+ },
484
+ tddException: null
485
+ });
486
+
337
487
  const ReportCardSchema = z.object({
338
488
  changeId: ChangeIdSchema,
339
489
  verdict: z.enum(['pass', 'fail', 'blocked']).optional(),
340
490
  overall: z.enum(['pass', 'fail']),
341
491
  summary: z.string().default(''),
492
+ specAlignment: z.enum(['pass', 'fail', 'blocked']).default('blocked'),
493
+ specDeltaVerified: z.boolean().default(false),
494
+ specSyncReady: z.boolean().default(false),
495
+ runtime: ReportRuntimeSchema,
496
+ claimEvidence: z.array(ClaimEvidenceSchema).default([]),
497
+ qa: QaSchema,
342
498
  quickGates: z.array(GateResultSchema),
343
499
  strictGates: z.array(GateResultSchema),
344
500
  review: ReportReviewSchema,
345
501
  blockingFindings: z.array(z.string()),
502
+ gaps: z.array(z.string()).default([]),
346
503
  reroute: z.enum(['none', 'cc-do', 'cc-investigate', 'cc-plan']).default('none'),
347
504
  timestamp: z.string().datetime()
348
505
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-devflow",
3
- "version": "4.5.1",
3
+ "version": "4.5.3",
4
4
  "description": "Multi-platform CLI and skill pack for agent coding",
5
5
  "main": "bin/cc-devflow.js",
6
6
  "bin": {