ai-spec-dev 0.31.0 → 0.35.0

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 (70) hide show
  1. package/.claude/commands/add-lesson.md +34 -0
  2. package/.claude/commands/check-layers.md +65 -0
  3. package/.claude/commands/installed-deps.md +35 -0
  4. package/.claude/commands/recall-lessons.md +40 -0
  5. package/.claude/commands/scan-singletons.md +45 -0
  6. package/.claude/commands/verify-imports.md +48 -0
  7. package/.claude/settings.local.json +15 -1
  8. package/README.md +531 -213
  9. package/RELEASE_LOG.md +460 -0
  10. package/cli/commands/config.ts +93 -0
  11. package/cli/commands/create.ts +1233 -0
  12. package/cli/commands/dashboard.ts +62 -0
  13. package/cli/commands/export.ts +66 -0
  14. package/cli/commands/init.ts +190 -0
  15. package/cli/commands/learn.ts +30 -0
  16. package/cli/commands/logs.ts +106 -0
  17. package/cli/commands/mock.ts +175 -0
  18. package/cli/commands/model.ts +156 -0
  19. package/cli/commands/restore.ts +22 -0
  20. package/cli/commands/review.ts +63 -0
  21. package/cli/commands/scan.ts +99 -0
  22. package/cli/commands/trend.ts +36 -0
  23. package/cli/commands/types.ts +69 -0
  24. package/cli/commands/update.ts +178 -0
  25. package/cli/commands/vcr.ts +70 -0
  26. package/cli/commands/workspace.ts +219 -0
  27. package/cli/index.ts +34 -2240
  28. package/cli/utils.ts +83 -0
  29. package/core/combined-generator.ts +13 -3
  30. package/core/dashboard-generator.ts +340 -0
  31. package/core/design-dialogue.ts +124 -0
  32. package/core/dsl-feedback.ts +285 -0
  33. package/core/error-feedback.ts +46 -2
  34. package/core/project-index.ts +301 -0
  35. package/core/reviewer.ts +84 -6
  36. package/core/run-logger.ts +109 -3
  37. package/core/run-trend.ts +261 -0
  38. package/core/self-evaluator.ts +139 -7
  39. package/core/spec-generator.ts +14 -8
  40. package/core/task-generator.ts +17 -0
  41. package/core/types-generator.ts +219 -0
  42. package/core/vcr.ts +210 -0
  43. package/dist/cli/index.js +6692 -4512
  44. package/dist/cli/index.js.map +1 -1
  45. package/dist/cli/index.mjs +6692 -4512
  46. package/dist/cli/index.mjs.map +1 -1
  47. package/dist/index.d.mts +19 -5
  48. package/dist/index.d.ts +19 -5
  49. package/dist/index.js +420 -224
  50. package/dist/index.js.map +1 -1
  51. package/dist/index.mjs +418 -224
  52. package/dist/index.mjs.map +1 -1
  53. package/docs-assets/purpose/architecture-overview.svg +64 -0
  54. package/docs-assets/purpose/create-pipeline.svg +113 -0
  55. package/docs-assets/purpose/task-layering.svg +74 -0
  56. package/package.json +6 -3
  57. package/prompts/codegen.prompt.ts +97 -9
  58. package/prompts/design.prompt.ts +59 -0
  59. package/prompts/spec.prompt.ts +8 -1
  60. package/prompts/tasks.prompt.ts +27 -2
  61. package/purpose.md +600 -174
  62. package/tests/dsl-extractor.test.ts +264 -0
  63. package/tests/dsl-feedback.test.ts +266 -0
  64. package/tests/dsl-validator.test.ts +283 -0
  65. package/tests/error-feedback.test.ts +292 -0
  66. package/tests/provider-utils.test.ts +173 -0
  67. package/tests/run-trend.test.ts +186 -0
  68. package/tests/self-evaluator.test.ts +339 -0
  69. package/tests/spec-assessor.test.ts +142 -0
  70. package/tests/task-generator.test.ts +230 -0
@@ -0,0 +1,64 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1400" height="980" viewBox="0 0 1400 980">
2
+ <rect width="1400" height="980" fill="#0f172a"/>
3
+ <text x="700" y="54" text-anchor="middle" font-size="30" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#f8fafc" font-weight="700">ai-spec 整体架构鸟瞰</text>
4
+ <defs>
5
+ <marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="5" orient="auto">
6
+ <path d="M0,0 L10,5 L0,10 Z" fill="#94a3b8"/>
7
+ </marker>
8
+ </defs>
9
+ <rect x="80" y="110" width="1240" height="120" rx="20" fill="#111827" stroke="#334155" stroke-width="2"/>
10
+ <text x="120" y="145" font-size="24" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#93c5fd" font-weight="700">输入层</text>
11
+ <rect x="120" y="165" width="300" height="42" rx="12" fill="#1e293b" stroke="#475569"/>
12
+ <text x="270" y="192" text-anchor="middle" font-size="19" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#e2e8f0">💬 需求描述(自然语言)</text>
13
+ <rect x="450" y="165" width="380" height="42" rx="12" fill="#1e293b" stroke="#475569"/>
14
+ <text x="640" y="192" text-anchor="middle" font-size="19" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#e2e8f0">📜 项目宪法(§1-§8 规则 + §9 教训)</text>
15
+ <rect x="860" y="165" width="380" height="42" rx="12" fill="#1e293b" stroke="#475569"/>
16
+ <text x="1050" y="192" text-anchor="middle" font-size="19" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#e2e8f0">🗂️ 项目上下文(结构 / 依赖 / 路由)</text>
17
+ <rect x="80" y="270" width="1240" height="140" rx="20" fill="#111827" stroke="#334155" stroke-width="2"/>
18
+ <text x="120" y="305" font-size="24" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#a7f3d0" font-weight="700">双层契约</text>
19
+ <rect x="220" y="325" width="380" height="52" rx="14" fill="#064e3b" stroke="#10b981"/>
20
+ <text x="410" y="357" text-anchor="middle" font-size="22" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#ecfdf5">📄 Spec(Markdown,人类可读)</text>
21
+ <rect x="790" y="325" width="380" height="52" rx="14" fill="#0c4a6e" stroke="#38bdf8"/>
22
+ <text x="980" y="357" text-anchor="middle" font-size="22" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#e0f2fe">📊 DSL(JSON,机器可读)</text>
23
+ <line x1="270" y1="207" x2="410" y2="325" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
24
+ <line x1="640" y1="207" x2="410" y2="325" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
25
+ <line x1="1050" y1="207" x2="410" y2="325" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
26
+ <text x="610" y="252" text-anchor="middle" font-size="16" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#cbd5e1">宪法全文注入所有 prompt</text>
27
+ <line x1="600" y1="351" x2="790" y2="351" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
28
+ <rect x="80" y="450" width="1240" height="150" rx="20" fill="#111827" stroke="#334155" stroke-width="2"/>
29
+ <text x="120" y="485" font-size="24" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#fde68a" font-weight="700">质量门控 + 生成层</text>
30
+ <rect x="120" y="515" width="280" height="50" rx="14" fill="#78350f" stroke="#f59e0b"/>
31
+ <text x="260" y="547" text-anchor="middle" font-size="20" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#fffbeb">🎯 Spec 质量评分</text>
32
+ <rect x="450" y="515" width="280" height="50" rx="14" fill="#3f2a62" stroke="#c084fc"/>
33
+ <text x="590" y="547" text-anchor="middle" font-size="20" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#f5f3ff">🧑‍💻 Approval Gate</text>
34
+ <rect x="780" y="500" width="350" height="80" rx="16" fill="#1d4ed8" stroke="#60a5fa"/>
35
+ <text x="955" y="535" text-anchor="middle" font-size="21" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#eff6ff">⚙️ Task 分层代码生成</text>
36
+ <text x="955" y="562" text-anchor="middle" font-size="16" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#dbeafe">data → service → api → view → route</text>
37
+ <rect x="1160" y="510" width="120" height="60" rx="14" fill="#1e293b" stroke="#64748b"/>
38
+ <text x="1220" y="537" text-anchor="middle" font-size="18" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#e2e8f0">🗄️ Cache</text>
39
+ <text x="1220" y="559" text-anchor="middle" font-size="13" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#cbd5e1">签名 / 契约</text>
40
+ <line x1="980" y1="377" x2="980" y2="500" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
41
+ <line x1="400" y1="540" x2="450" y2="540" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
42
+ <line x1="730" y1="540" x2="780" y2="540" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
43
+ <line x1="1130" y1="540" x2="1160" y2="540" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
44
+ <line x1="1160" y1="555" x2="1130" y2="555" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
45
+ <text x="365" y="505" text-anchor="middle" font-size="15" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#cbd5e1">通过 / 不足</text>
46
+ <rect x="80" y="645" width="1240" height="130" rx="20" fill="#111827" stroke="#334155" stroke-width="2"/>
47
+ <text x="120" y="680" font-size="24" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#fca5a5" font-weight="700">验证层</text>
48
+ <rect x="240" y="700" width="360" height="46" rx="14" fill="#7f1d1d" stroke="#ef4444"/>
49
+ <text x="420" y="729" text-anchor="middle" font-size="20" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#fef2f2">🔄 错误反馈闭环(≤2 cycle)</text>
50
+ <rect x="760" y="700" width="360" height="46" rx="14" fill="#4c0519" stroke="#f43f5e"/>
51
+ <text x="940" y="729" text-anchor="middle" font-size="20" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#fff1f2">🔬 3-pass 代码审查</text>
52
+ <line x1="955" y1="580" x2="420" y2="700" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
53
+ <line x1="600" y1="723" x2="760" y2="723" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
54
+ <rect x="80" y="810" width="1240" height="120" rx="20" fill="#111827" stroke="#334155" stroke-width="2"/>
55
+ <text x="120" y="845" font-size="24" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#c4b5fd" font-weight="700">学习层(闭环)</text>
56
+ <rect x="260" y="860" width="360" height="42" rx="14" fill="#312e81" stroke="#818cf8"/>
57
+ <text x="440" y="887" text-anchor="middle" font-size="19" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#eef2ff">📚 §9 知识积累</text>
58
+ <rect x="780" y="860" width="360" height="42" rx="14" fill="#14532d" stroke="#4ade80"/>
59
+ <text x="960" y="887" text-anchor="middle" font-size="19" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#f0fdf4">📈 Harness Self-Eval</text>
60
+ <line x1="940" y1="746" x2="440" y2="860" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
61
+ <line x1="940" y1="746" x2="960" y2="860" stroke="#94a3b8" stroke-width="3" marker-end="url(#arrow)"/>
62
+ <line x1="440" y1="860" x2="640" y2="207" stroke="#94a3b8" stroke-width="3" stroke-dasharray="8 8" marker-end="url(#arrow)"/>
63
+ <text x="560" y="525" text-anchor="middle" transform="rotate(-73 560 525)" font-size="15" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#cbd5e1">更新宪法 §9</text>
64
+ </svg>
@@ -0,0 +1,113 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1500" height="1800" viewBox="0 0 1500 1800">
2
+ <rect width="1500" height="1800" fill="#0f172a"/>
3
+ <text x="750" y="55" text-anchor="middle" font-size="32" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#f8fafc" font-weight="700">ai-spec create 完整流水线</text>
4
+ <defs>
5
+ <marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="5" orient="auto">
6
+ <path d="M0,0 L10,5 L0,10 Z" fill="#94a3b8"/>
7
+ </marker>
8
+ </defs>
9
+ <g font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif">
10
+ <rect x="420" y="90" width="660" height="60" rx="18" fill="#1d4ed8" stroke="#60a5fa" stroke-width="2"/>
11
+ <text x="750" y="128" text-anchor="middle" font-size="24" fill="#eff6ff" font-weight="700">▶ ai-spec create &lt;idea&gt;</text>
12
+
13
+ <rect x="340" y="190" width="820" height="74" rx="18" fill="#1f2937" stroke="#475569"/>
14
+ <text x="750" y="223" text-anchor="middle" font-size="23" fill="#f8fafc" font-weight="700">Step 1 · 加载项目上下文</text>
15
+ <text x="750" y="250" text-anchor="middle" font-size="17" fill="#cbd5e1">ContextLoader 扫描代码结构 / 依赖 / 路由 / schema</text>
16
+
17
+ <rect x="340" y="305" width="820" height="74" rx="18" fill="#1f2937" stroke="#475569"/>
18
+ <text x="750" y="338" text-anchor="middle" font-size="23" fill="#f8fafc" font-weight="700">Step 2 · Spec + Tasks 生成</text>
19
+ <text x="750" y="365" text-anchor="middle" font-size="17" fill="#cbd5e1">宪法全文注入 prompt 最高优先级</text>
20
+
21
+ <rect x="340" y="420" width="820" height="74" rx="18" fill="#1f2937" stroke="#475569"/>
22
+ <text x="750" y="453" text-anchor="middle" font-size="23" fill="#f8fafc" font-weight="700">Step 3 · 交互式润色</text>
23
+ <text x="750" y="480" text-anchor="middle" font-size="17" fill="#cbd5e1">Diff 预览,可多轮修改</text>
24
+
25
+ <rect x="340" y="535" width="820" height="74" rx="18" fill="#78350f" stroke="#f59e0b"/>
26
+ <text x="750" y="568" text-anchor="middle" font-size="23" fill="#fffbeb" font-weight="700">Step 3.4 · Spec 质量评估</text>
27
+ <text x="750" y="595" text-anchor="middle" font-size="17" fill="#fde68a">覆盖度 / 清晰度 / 宪法符合度打分</text>
28
+
29
+ <polygon points="750,655 930,745 750,835 570,745" fill="#3f3f46" stroke="#71717a" stroke-width="2"/>
30
+ <text x="750" y="734" text-anchor="middle" font-size="24" fill="#f8fafc" font-weight="700">Score ≥</text>
31
+ <text x="750" y="764" text-anchor="middle" font-size="24" fill="#f8fafc" font-weight="700">minSpecScore ?</text>
32
+
33
+ <rect x="110" y="715" width="300" height="60" rx="18" fill="#7f1d1d" stroke="#ef4444" stroke-width="2"/>
34
+ <text x="260" y="752" text-anchor="middle" font-size="20" fill="#fef2f2">🚫 exit(1)(--force 可继续)</text>
35
+
36
+ <rect x="1020" y="700" width="350" height="92" rx="18" fill="#3b0764" stroke="#c084fc" stroke-width="2"/>
37
+ <text x="1195" y="736" text-anchor="middle" font-size="23" fill="#faf5ff" font-weight="700">Approval Gate</text>
38
+ <text x="1195" y="765" text-anchor="middle" font-size="16" fill="#e9d5ff">展示 Spec + DSL 摘要</text>
39
+ <text x="1195" y="788" text-anchor="middle" font-size="16" fill="#e9d5ff">等待人工决策</text>
40
+
41
+ <rect x="1010" y="855" width="160" height="58" rx="16" fill="#7f1d1d" stroke="#ef4444"/>
42
+ <text x="1090" y="891" text-anchor="middle" font-size="20" fill="#fef2f2">Abort</text>
43
+ <rect x="1210" y="855" width="220" height="58" rx="16" fill="#14532d" stroke="#4ade80"/>
44
+ <text x="1320" y="891" text-anchor="middle" font-size="20" fill="#f0fdf4">Proceed</text>
45
+
46
+ <rect x="1070" y="955" width="250" height="84" rx="18" fill="#0c4a6e" stroke="#38bdf8" stroke-width="2"/>
47
+ <text x="1195" y="990" text-anchor="middle" font-size="22" fill="#e0f2fe" font-weight="700">DSL 提取 + 校验</text>
48
+ <text x="1195" y="1017" text-anchor="middle" font-size="16" fill="#bae6fd">9 条规则,失败最多重试 2 次</text>
49
+
50
+ <rect x="1070" y="1085" width="250" height="76" rx="18" fill="#1e293b" stroke="#64748b"/>
51
+ <text x="1195" y="1118" text-anchor="middle" font-size="20" fill="#e2e8f0" font-weight="700">RunId + 快照初始化</text>
52
+ <text x="1195" y="1145" text-anchor="middle" font-size="16" fill="#cbd5e1">Prompt Hash 写入 RunLog</text>
53
+
54
+ <rect x="930" y="1205" width="530" height="106" rx="20" fill="#1d4ed8" stroke="#60a5fa" stroke-width="2"/>
55
+ <text x="1195" y="1245" text-anchor="middle" font-size="24" fill="#eff6ff" font-weight="700">Step 5–6 · Task 分层代码生成</text>
56
+ <text x="1195" y="1276" text-anchor="middle" font-size="17" fill="#dbeafe">data → infra → service → api → view → route → test</text>
57
+ <text x="1195" y="1299" text-anchor="middle" font-size="17" fill="#dbeafe">层内拓扑排序 → batch 并行 → 缓存更新</text>
58
+
59
+ <rect x="1070" y="1355" width="250" height="60" rx="18" fill="#334155" stroke="#64748b"/>
60
+ <text x="1195" y="1392" text-anchor="middle" font-size="20" fill="#f8fafc">Step 7 · 测试骨架生成</text>
61
+
62
+ <rect x="120" y="1205" width="650" height="420" rx="24" fill="#111827" stroke="#334155" stroke-width="2"/>
63
+ <text x="445" y="1245" text-anchor="middle" font-size="26" fill="#fca5a5" font-weight="700">Step 8 · 错误反馈闭环</text>
64
+ <rect x="220" y="1285" width="450" height="60" rx="16" fill="#7f1d1d" stroke="#ef4444"/>
65
+ <text x="445" y="1322" text-anchor="middle" font-size="21" fill="#fef2f2">运行 test / lint / tsc</text>
66
+ <polygon points="445,1390 605,1470 445,1550 285,1470" fill="#3f3f46" stroke="#71717a" stroke-width="2"/>
67
+ <text x="445" y="1460" text-anchor="middle" font-size="23" fill="#f8fafc" font-weight="700">全部通过?</text>
68
+ <rect x="170" y="1578" width="200" height="58" rx="16" fill="#14532d" stroke="#4ade80"/>
69
+ <text x="270" y="1614" text-anchor="middle" font-size="19" fill="#f0fdf4">通过 → Step 9</text>
70
+ <rect x="410" y="1568" width="390" height="78" rx="18" fill="#92400e" stroke="#f59e0b"/>
71
+ <text x="605" y="1600" text-anchor="middle" font-size="20" fill="#fffbeb">有错误,且 cycle ≤ 2</text>
72
+ <text x="605" y="1625" text-anchor="middle" font-size="16" fill="#fde68a">依赖图排序 → AI 逐文件修复 → 回到测试</text>
73
+ <rect x="170" y="1670" width="630" height="72" rx="18" fill="#4b5563" stroke="#9ca3af"/>
74
+ <text x="485" y="1703" text-anchor="middle" font-size="20" fill="#f8fafc">cycle 2 仍失败 → ⚠️ 黄色警告,继续进入 Step 9</text>
75
+
76
+ <rect x="930" y="1455" width="530" height="84" rx="18" fill="#4c0519" stroke="#f43f5e" stroke-width="2"/>
77
+ <text x="1195" y="1491" text-anchor="middle" font-size="23" fill="#fff1f2" font-weight="700">Step 9 · 3-pass 代码审查</text>
78
+ <text x="1195" y="1518" text-anchor="middle" font-size="16" fill="#fecdd3">Pass1 架构 · Pass2 实现 · Pass3 影响面 / 复杂度</text>
79
+
80
+ <rect x="930" y="1585" width="250" height="76" rx="18" fill="#312e81" stroke="#818cf8"/>
81
+ <text x="1055" y="1618" text-anchor="middle" font-size="20" fill="#eef2ff" font-weight="700">§9 知识积累</text>
82
+ <text x="1055" y="1645" text-anchor="middle" font-size="15" fill="#c7d2fe">审查 issue 自动追加宪法</text>
83
+
84
+ <rect x="1210" y="1585" width="250" height="92" rx="18" fill="#14532d" stroke="#4ade80"/>
85
+ <text x="1335" y="1618" text-anchor="middle" font-size="20" fill="#f0fdf4" font-weight="700">Step 10 · Harness Self-Eval</text>
86
+ <text x="1335" y="1645" text-anchor="middle" font-size="15" fill="#dcfce7">DSL 覆盖 + Compile + Review</text>
87
+
88
+ <rect x="1020" y="1715" width="350" height="56" rx="18" fill="#0f766e" stroke="#2dd4bf"/>
89
+ <text x="1195" y="1749" text-anchor="middle" font-size="22" fill="#ecfeff" font-weight="700">✔ Done:Spec / DSL / 代码 / RunLog 全部落盘</text>
90
+
91
+ <line x1="750" y1="150" x2="750" y2="190" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
92
+ <line x1="750" y1="264" x2="750" y2="305" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
93
+ <line x1="750" y1="379" x2="750" y2="420" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
94
+ <line x1="750" y1="494" x2="750" y2="655" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
95
+ <line x1="570" y1="745" x2="410" y2="745" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
96
+ <line x1="930" y1="745" x2="1020" y2="745" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
97
+ <line x1="1195" y1="792" x2="1090" y2="855" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
98
+ <line x1="1195" y1="792" x2="1320" y2="855" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
99
+ <line x1="1320" y1="913" x2="1195" y2="955" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
100
+ <line x1="1195" y1="1039" x2="1195" y2="1085" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
101
+ <line x1="1195" y1="1161" x2="1195" y2="1205" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
102
+ <line x1="1195" y1="1311" x2="1195" y2="1355" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
103
+ <line x1="1070" y1="1385" x2="770" y2="1385" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
104
+ <line x1="445" y1="1345" x2="445" y2="1390" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
105
+ <line x1="365" y1="1470" x2="270" y2="1578" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
106
+ <line x1="525" y1="1542" x2="525" y2="1568" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
107
+ <line x1="800" y1="1607" x2="930" y2="1497" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
108
+ <line x1="270" y1="1636" x2="930" y2="1497" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
109
+ <line x1="1195" y1="1539" x2="1055" y2="1585" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
110
+ <line x1="1195" y1="1539" x2="1335" y2="1585" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
111
+ <line x1="1335" y1="1677" x2="1250" y2="1715" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
112
+ </g>
113
+ </svg>
@@ -0,0 +1,74 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1500" height="980" viewBox="0 0 1500 980">
2
+ <rect width="1500" height="980" fill="#0f172a"/>
3
+ <text x="750" y="56" text-anchor="middle" font-size="30" font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif" fill="#f8fafc" font-weight="700">Task 分层与层内执行模型</text>
4
+ <defs>
5
+ <marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="5" orient="auto">
6
+ <path d="M0,0 L10,5 L0,10 Z" fill="#94a3b8"/>
7
+ </marker>
8
+ </defs>
9
+ <g font-family="Arial, PingFang SC, Microsoft YaHei, sans-serif">
10
+ <rect x="80" y="110" width="1340" height="150" rx="22" fill="#111827" stroke="#334155" stroke-width="2"/>
11
+ <text x="140" y="150" font-size="24" fill="#93c5fd" font-weight="700">七层顺序(跨层串行)</text>
12
+ <rect x="120" y="180" width="140" height="42" rx="14" fill="#1d4ed8" stroke="#60a5fa"/><text x="190" y="207" text-anchor="middle" font-size="20" fill="#eff6ff">data</text>
13
+ <rect x="310" y="180" width="140" height="42" rx="14" fill="#0369a1" stroke="#38bdf8"/><text x="380" y="207" text-anchor="middle" font-size="20" fill="#e0f2fe">infra</text>
14
+ <rect x="500" y="180" width="160" height="42" rx="14" fill="#0f766e" stroke="#2dd4bf"/><text x="580" y="207" text-anchor="middle" font-size="20" fill="#ecfeff">service</text>
15
+ <rect x="710" y="180" width="140" height="42" rx="14" fill="#15803d" stroke="#4ade80"/><text x="780" y="207" text-anchor="middle" font-size="20" fill="#f0fdf4">api</text>
16
+ <rect x="900" y="180" width="150" height="42" rx="14" fill="#7c3aed" stroke="#c084fc"/><text x="975" y="207" text-anchor="middle" font-size="20" fill="#f5f3ff">view</text>
17
+ <rect x="1100" y="180" width="150" height="42" rx="14" fill="#c2410c" stroke="#fb923c"/><text x="1175" y="207" text-anchor="middle" font-size="20" fill="#fff7ed">route</text>
18
+ <rect x="1300" y="180" width="90" height="42" rx="14" fill="#be123c" stroke="#fb7185"/><text x="1345" y="207" text-anchor="middle" font-size="20" fill="#fff1f2">test</text>
19
+ <line x1="260" y1="201" x2="310" y2="201" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
20
+ <line x1="450" y1="201" x2="500" y2="201" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
21
+ <line x1="660" y1="201" x2="710" y2="201" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
22
+ <line x1="850" y1="201" x2="900" y2="201" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
23
+ <line x1="1050" y1="201" x2="1100" y2="201" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
24
+ <line x1="1250" y1="201" x2="1300" y2="201" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
25
+
26
+ <rect x="80" y="320" width="760" height="540" rx="22" fill="#111827" stroke="#334155" stroke-width="2"/>
27
+ <text x="120" y="360" font-size="24" fill="#a7f3d0" font-weight="700">单层内部执行(以 api 层为例)</text>
28
+ <rect x="140" y="395" width="640" height="60" rx="16" fill="#334155" stroke="#64748b"/>
29
+ <text x="460" y="432" text-anchor="middle" font-size="22" fill="#f8fafc">拓扑排序:按 dependencies 字段分 batch</text>
30
+
31
+ <rect x="140" y="500" width="290" height="220" rx="18" fill="#052e16" stroke="#22c55e"/>
32
+ <text x="285" y="537" text-anchor="middle" font-size="24" fill="#dcfce7" font-weight="700">Batch 1</text>
33
+ <text x="285" y="565" text-anchor="middle" font-size="16" fill="#bbf7d0">无依赖 → 可并行</text>
34
+ <rect x="185" y="590" width="200" height="42" rx="12" fill="#166534" stroke="#4ade80"/>
35
+ <text x="285" y="617" text-anchor="middle" font-size="18" fill="#f0fdf4">userController.ts</text>
36
+ <rect x="185" y="648" width="200" height="42" rx="12" fill="#166534" stroke="#4ade80"/>
37
+ <text x="285" y="675" text-anchor="middle" font-size="18" fill="#f0fdf4">authController.ts</text>
38
+ <text x="285" y="705" text-anchor="middle" font-size="15" fill="#bbf7d0">完成后立即更新 generatedFileCache</text>
39
+
40
+ <rect x="490" y="500" width="290" height="220" rx="18" fill="#3f2a62" stroke="#c084fc"/>
41
+ <text x="635" y="537" text-anchor="middle" font-size="24" fill="#faf5ff" font-weight="700">Batch 2</text>
42
+ <text x="635" y="565" text-anchor="middle" font-size="16" fill="#e9d5ff">依赖 Batch 1 → 可并行</text>
43
+ <rect x="535" y="605" width="200" height="60" rx="12" fill="#6d28d9" stroke="#c084fc"/>
44
+ <text x="635" y="632" text-anchor="middle" font-size="18" fill="#f5f3ff">adminController.ts</text>
45
+ <text x="635" y="654" text-anchor="middle" font-size="14" fill="#ede9fe">需要 import userController</text>
46
+ <text x="635" y="705" text-anchor="middle" font-size="15" fill="#e9d5ff">完成后再次更新 generatedFileCache</text>
47
+
48
+ <line x1="460" y1="455" x2="285" y2="500" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
49
+ <line x1="430" y1="610" x2="490" y2="610" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
50
+ <text x="460" y="592" text-anchor="middle" font-size="15" fill="#cbd5e1">Batch 1 完成</text>
51
+
52
+ <rect x="900" y="320" width="520" height="540" rx="22" fill="#111827" stroke="#334155" stroke-width="2"/>
53
+ <text x="940" y="360" font-size="24" fill="#fde68a" font-weight="700">共享状态与层完成动作</text>
54
+
55
+ <rect x="960" y="400" width="400" height="150" rx="18" fill="#1e293b" stroke="#64748b"/>
56
+ <text x="1160" y="438" text-anchor="middle" font-size="24" fill="#f8fafc" font-weight="700">generatedFileCache</text>
57
+ <text x="1160" y="475" text-anchor="middle" font-size="18" fill="#cbd5e1">函数签名</text>
58
+ <text x="1160" y="505" text-anchor="middle" font-size="18" fill="#cbd5e1">文件路径</text>
59
+ <text x="1160" y="535" text-anchor="middle" font-size="18" fill="#cbd5e1">behavioral contracts</text>
60
+
61
+ <line x1="780" y1="610" x2="960" y2="475" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
62
+ <line x1="960" y1="505" x2="780" y2="680" stroke="#94a3b8" stroke-width="4" marker-end="url(#arrow)"/>
63
+ <text x="870" y="525" text-anchor="middle" font-size="15" fill="#cbd5e1">批次读写</text>
64
+
65
+ <rect x="960" y="620" width="400" height="170" rx="18" fill="#78350f" stroke="#f59e0b"/>
66
+ <text x="1160" y="657" text-anchor="middle" font-size="24" fill="#fffbeb" font-weight="700">整层执行关系</text>
67
+ <text x="1160" y="695" text-anchor="middle" font-size="18" fill="#fde68a">进入当前层</text>
68
+ <text x="1160" y="725" text-anchor="middle" font-size="18" fill="#fde68a">↓</text>
69
+ <text x="1160" y="755" text-anchor="middle" font-size="18" fill="#fde68a">层内拓扑排序 + batch 并行</text>
70
+ <text x="1160" y="785" text-anchor="middle" font-size="18" fill="#fde68a">↓</text>
71
+ <text x="1160" y="815" text-anchor="middle" font-size="18" fill="#fde68a">统一更新共享 config 文件(如 routes/index.ts)</text>
72
+ <text x="1160" y="845" text-anchor="middle" font-size="18" fill="#fde68a">↓ 进入下一层</text>
73
+ </g>
74
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-spec-dev",
3
- "version": "0.31.0",
3
+ "version": "0.35.0",
4
4
  "description": "AI-driven Development Orchestrator SDK & CLI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,7 +9,9 @@
9
9
  },
10
10
  "scripts": {
11
11
  "build": "tsup",
12
- "dev": "tsup --watch"
12
+ "dev": "tsup --watch",
13
+ "test": "vitest run",
14
+ "test:watch": "vitest"
13
15
  },
14
16
  "keywords": [
15
17
  "ai",
@@ -41,6 +43,7 @@
41
43
  "glob": "^13.0.6",
42
44
  "ts-node": "^10.9.2",
43
45
  "tsup": "^8.4.0",
44
- "typescript": "^5.7.3"
46
+ "typescript": "^5.7.3",
47
+ "vitest": "^2.1.0"
45
48
  }
46
49
  }
@@ -181,34 +181,122 @@ export function getCodeGenSystemPrompt(repoType?: string): string {
181
181
  * Focuses on design-level correctness: spec compliance, layer separation, API contract.
182
182
  * Deliberately ignores micro-level implementation details.
183
183
  */
184
- export const reviewArchitectureSystemPrompt = `You are a Senior Software Architect reviewing the HIGH-LEVEL design of a code change.
184
+ // ─── Pass 0 Spec Compliance Check ──────────────────────────────────────────
185
+
186
+ /**
187
+ * Pass 0 — Spec Compliance Check (inspired by Superpowers' spec-compliance review).
188
+ *
189
+ * Dedicated, exhaustive pass that answers ONE question:
190
+ * "Does the implementation cover ALL requirements stated in the spec?"
191
+ *
192
+ * This is a completeness check, NOT a quality check.
193
+ * Architecture quality, code style, error handling are all handled by later passes.
194
+ */
195
+ export const specComplianceSystemPrompt = `You are a QA Engineer performing a SPEC COMPLIANCE CHECK.
196
+
197
+ Your sole job is to verify that the implementation covers every requirement stated in the feature spec.
198
+ This is a completeness audit — NOT a code quality review. Do not comment on architecture, style, or implementation details.
199
+
200
+ ## How to audit:
201
+
202
+ 1. Parse the spec and extract EVERY stated requirement into these categories:
203
+ - **Endpoints**: each HTTP method + path listed or implied
204
+ - **Data Models**: each entity, field, constraint mentioned
205
+ - **Business Rules**: validations, conditions, calculations stated
206
+ - **Auth Requirements**: which endpoints need auth, which roles are allowed
207
+ - **Error Cases**: explicit error codes or failure scenarios mentioned
208
+ - **Side Effects**: emails sent, events fired, caches invalidated, etc.
209
+
210
+ 2. For each extracted requirement, check the provided code:
211
+ - ✅ **Covered** — clearly implemented
212
+ - ⚠️ **Partial** — exists but incomplete (e.g. endpoint exists but missing a field or error case)
213
+ - ❌ **Missing** — requirement stated in spec but not found in code
214
+
215
+ 3. Output a compliance checklist. Be exhaustive — list every single requirement.
216
+
217
+ ## Output format:
218
+
219
+ ## 📋 Spec Compliance Report
220
+
221
+ ### Endpoints
222
+ ✅ / ⚠️ / ❌ METHOD /path — one-line status
223
+
224
+ ### Data Models
225
+ ✅ / ⚠️ / ❌ ModelName — one-line status
226
+
227
+ ### Business Rules
228
+ ✅ / ⚠️ / ❌ Rule description — one-line status
229
+
230
+ ### Auth & Permissions
231
+ ✅ / ⚠️ / ❌ Requirement — one-line status
232
+
233
+ ### Error Cases
234
+ ✅ / ⚠️ / ❌ Error scenario — one-line status
235
+
236
+ ### Side Effects
237
+ ✅ / ⚠️ / ❌ Side effect — one-line status (omit section if none in spec)
238
+
239
+ ---
240
+
241
+ ## 📊 Compliance Summary
242
+ Covered: N | Partial: N | Missing: N | Total: N
243
+
244
+ ## 🔢 Compliance Score
245
+ ComplianceScore: X/10
246
+
247
+ (10 = all requirements implemented, 0 = nothing implemented.
248
+ Deduct 1 point per missing requirement, 0.5 per partial.
249
+ Round to nearest integer.)
250
+
251
+ ## 🚨 Blockers (Missing requirements that MUST be implemented before ship)
252
+ List only ❌ Missing items here, ordered by severity. If none, write "None".
253
+
254
+ ---
255
+
256
+ IMPORTANT: Be exhaustive. A requirement not listed here is assumed to be covered.
257
+ If the spec is vague, note the ambiguity as ⚠️ Partial rather than assuming coverage.`;
258
+
259
+ export const reviewArchitectureSystemPrompt = `You are a Senior Software Architect reviewing the HIGH-LEVEL DESIGN of a code change.
260
+
261
+ A spec compliance check (Pass 0) has already verified feature completeness. Do NOT re-audit whether requirements are missing — focus purely on HOW the present implementation is architected.
185
262
 
186
263
  Focus ONLY on:
187
- 1. **Spec compliance** — Does the implementation match the spec? Are there missing or extra endpoints/components?
188
- 2. **Layer separation** — Does each layer have the right responsibilities? (e.g., no business logic in controllers, no HTTP in stores)
189
- 3. **API contract** — Are request/response shapes correct? Are all error codes from the spec implemented?
190
- 4. **Data model integrity** — Are constraints, unique fields, and relationships correct?
191
- 5. **Security posture** — Are auth checks applied to the right endpoints? Any obvious missing auth?
264
+ 1. **Layer separation** — Does each layer have the right responsibilities? (e.g., no business logic in controllers, no HTTP in stores)
265
+ 2. **API contract quality** — Are request/response shapes well-designed? Are error codes consistent with project conventions?
266
+ 3. **Data model integrity** — Are constraints, unique fields, and relationships modelled correctly?
267
+ 4. **Security posture** — Are auth checks applied correctly? Any privilege escalation risks?
192
268
 
193
269
  DO NOT comment on:
270
+ - Whether specific endpoints or features are missing (covered by Pass 0)
194
271
  - Code style, naming conventions, formatting
195
272
  - Minor implementation details (variable names, inline comments)
196
273
  - Performance micro-optimizations
197
274
 
198
275
  Format:
199
276
 
200
- ## 🏗 架构合规性 (Spec Compliance)
201
- Does the implementation match the spec? List any missing or wrong endpoints/components.
202
-
203
277
  ## 🔀 层职责分离 (Layer Separation)
204
278
  Any layer boundary violations?
205
279
 
206
280
  ## 🔒 安全与权限 (Security & Auth)
207
281
  Any missing auth checks, exposed data, or privilege issues?
208
282
 
283
+ ## 📐 契约与模型设计 (Contract & Model Design)
284
+ Response shape issues, missing constraints, relationship problems.
285
+
209
286
  ## 📋 架构评分 (Architecture Score)
210
287
  Score: X/10 — One short paragraph.
211
288
 
289
+ ## 🔍 结构性发现 JSON (Structural Findings — for pipeline processing)
290
+ Output a JSON block with any design-level issues found above.
291
+ Categories: "auth_design" | "api_contract" | "model_design" | "layer_violation" | "other_design"
292
+ If no findings, output an empty array.
293
+
294
+ \`\`\`json
295
+ {"structuralFindings": [{"category": "...", "description": "one sentence referencing the specific endpoint/model/file"}]}
296
+ \`\`\`
297
+
298
+ IMPORTANT: Always include this JSON block, even when structuralFindings is []. This block is parsed by the pipeline.
299
+
212
300
  Be specific. Reference file names or endpoint paths.`;
213
301
 
214
302
  /**
@@ -0,0 +1,59 @@
1
+ export const designOptionsSystemPrompt = `You are a Senior Software Architect helping a developer choose the right implementation approach before writing a full spec.
2
+
3
+ Your job is to propose 2-3 distinct architectural options for the given feature idea.
4
+
5
+ Keep this SHORT — the developer needs to read and decide in under 2 minutes.
6
+
7
+ ## Output format
8
+
9
+ ## 🧭 Design Options: <feature name>
10
+
11
+ ### Option A — <name>
12
+ **Approach:** One sentence describing the core architectural decision.
13
+ **Trade-offs:**
14
+ - ✅ <benefit>
15
+ - ✅ <benefit>
16
+ - ⚠️ <cost or risk>
17
+ **Best when:** <one-line scenario where this option wins>
18
+
19
+ ### Option B — <name>
20
+ (same structure)
21
+
22
+ ### Option C — <name> (optional — only include if genuinely different from A and B)
23
+ (same structure)
24
+
25
+ ---
26
+ **Recommended:** Option X — one sentence explaining why given the context.
27
+
28
+ ---
29
+
30
+ Rules:
31
+ - Options must represent genuinely different architectural decisions (not just naming variations)
32
+ - Each option has 2-3 trade-off bullets — no more
33
+ - No code in this output — high-level concepts only
34
+ - If the feature is simple and only one reasonable approach exists, say so and propose just one option with a note
35
+ - Reference the project's tech stack and existing patterns when visible in context`;
36
+
37
+ export function buildDesignOptionsPrompt(
38
+ idea: string,
39
+ contextHints: { techStack: string[]; repoType: string; constitution?: string }
40
+ ): string {
41
+ const parts: string[] = [
42
+ `Feature idea: "${idea}"\n`,
43
+ ];
44
+
45
+ if (contextHints.techStack.length > 0) {
46
+ parts.push(`Tech stack: ${contextHints.techStack.join(", ")}`);
47
+ }
48
+ parts.push(`Repo type: ${contextHints.repoType}`);
49
+
50
+ if (contextHints.constitution) {
51
+ // Only send §1 Architecture Rules (first ~800 chars) — enough to know patterns
52
+ const arch = contextHints.constitution.slice(0, 800);
53
+ parts.push(`\nProject architecture context:\n${arch}`);
54
+ }
55
+
56
+ parts.push("\nPropose 2-3 implementation approaches. Keep each option concise.");
57
+
58
+ return parts.join("\n");
59
+ }
@@ -99,4 +99,11 @@ model ExampleModel {
99
99
 
100
100
  ---
101
101
 
102
- 根据用户的想法和项目上下文生成上述完整 Spec。确保 API 设计与现有项目的路由风格、错误码规范保持一致,数据模型与现有 Prisma Schema 协调。`;
102
+ 根据用户的想法和项目上下文生成上述完整 Spec。确保 API 设计与现有项目的路由风格、错误码规范保持一致,数据模型与现有 Prisma Schema 协调。
103
+
104
+ CRITICAL — 历史教训应用(Accumulated Lessons):
105
+ 如果项目宪法中包含"§9 积累教训 (Accumulated Lessons)"章节,你必须:
106
+ 1. 在生成 §5 API 设计和 §6 数据模型之前,逐条审阅所有教训条目
107
+ 2. 确保本次 Spec 的设计不重蹈已知问题(例如:某教训说"避免 N+1 查询",则在 §8 实施要点中明确说明批量加载策略)
108
+ 3. 对于每条直接相关的教训,在 §8 实施要点末尾追加一行:「⚠ 基于历史教训:[简述本次 spec 如何规避该问题]」
109
+ 4. 如无相关教训,§8 不必追加任何内容`;
@@ -9,7 +9,8 @@ Each task object must have these exact fields:
9
9
  "description": "...", // 1-2 sentences, specific and actionable
10
10
  "layer": "data|service|api|view|route|test|infra", // implementation layer
11
11
  "filesToTouch": ["..."], // VERIFIED paths only — see rules below
12
- "acceptanceCriteria": ["..."], // verifiable completion conditions
12
+ "acceptanceCriteria": ["..."], // behavioral completion conditions (the "what")
13
+ "verificationSteps": ["..."], // concrete runnable checks with expected output (the "how to verify") — see rules below
13
14
  "dependencies": ["TASK-001"], // task ids that must complete first (empty array if none)
14
15
  "priority": "high|medium|low"
15
16
  }
@@ -51,8 +52,32 @@ CRITICAL — filesToTouch Rules (hallucination prevention):
51
52
  - If you are unsure of the exact path for a new file, leave it as "TBD:<description>" rather than guessing.
52
53
  - Cross-check: after writing all tasks, verify every path in filesToTouch exists in the inventory or is a logical new sibling. If it doesn't pass this check, fix it.
53
54
 
55
+ CRITICAL — verificationSteps Rules:
56
+ Each step must be a concrete, self-contained check with an observable expected outcome.
57
+
58
+ Good examples (specific command + expected result):
59
+ "POST /api/tasks with body {\"title\":\"test\"} → HTTP 201, response body contains {id, status:\"pending\"}"
60
+ "GET /api/tasks/:id with unknown id → HTTP 404 with {code: 4040X, message: \"...\"}"
61
+ "npm run build exits 0 with no TypeScript errors"
62
+ "Prisma schema has Task model with fields: id, title, status, createdAt"
63
+ "Store action createTask sets loading:true during request, loading:false on completion"
64
+ "Route /tasks renders TaskList component, visible in router DevTools"
65
+
66
+ Bad examples (too vague — do NOT use these):
67
+ "The endpoint works correctly" ✗
68
+ "Data is saved to the database" ✗
69
+ "UI displays the correct data" ✗
70
+ "Error handling works" ✗
71
+
72
+ Rules:
73
+ - At least 2 verification steps per task, max 5
74
+ - Each step must be independently runnable/checkable
75
+ - Backend tasks: include at least one HTTP request/response check and one data-layer check
76
+ - Frontend tasks: include at least one UI render check and one state check
77
+ - Build/compile tasks: always include "npm run build exits 0" or equivalent
78
+
54
79
  Other rules:
55
- - acceptanceCriteria must be verifiable (not vague like "works correctly")
80
+ - acceptanceCriteria: behavioral statements ("order is created with pending status") — complementary to verificationSteps, not duplicates
56
81
  - dependencies must reflect real implementation order
57
82
  - Aim for 4-10 tasks total — not too granular, not too coarse
58
83
  - Each task should be completable in one focused coding session`;