scrum-skills 0.3.2 → 0.3.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 (384) hide show
  1. package/.agents/skills/diagram-design/LICENSE +4 -0
  2. package/.agents/skills/diagram-design/SKILL.md +413 -0
  3. package/.agents/skills/diagram-design/UPSTREAM.json +76 -0
  4. package/.agents/skills/diagram-design/UPSTREAM.md +23 -0
  5. package/.agents/skills/diagram-design/assets/example-architecture-containment.html +205 -0
  6. package/.agents/skills/diagram-design/assets/example-architecture-delta.html +193 -0
  7. package/.agents/skills/diagram-design/assets/example-architecture.html +183 -0
  8. package/.agents/skills/diagram-design/assets/example-axonometric-plan-campus.html +108 -0
  9. package/.agents/skills/diagram-design/assets/example-axonometric-plan-coffee-shop.html +121 -0
  10. package/.agents/skills/diagram-design/assets/example-axonometric-plan-warehouse.html +127 -0
  11. package/.agents/skills/diagram-design/assets/example-axonometric-plan.html +114 -0
  12. package/.agents/skills/diagram-design/assets/example-bar.html +129 -0
  13. package/.agents/skills/diagram-design/assets/example-beeswarm.html +384 -0
  14. package/.agents/skills/diagram-design/assets/example-box-plot.html +127 -0
  15. package/.agents/skills/diagram-design/assets/example-bubble.html +147 -0
  16. package/.agents/skills/diagram-design/assets/example-bump.html +142 -0
  17. package/.agents/skills/diagram-design/assets/example-data-flow.html +143 -0
  18. package/.agents/skills/diagram-design/assets/example-datalake.html +269 -0
  19. package/.agents/skills/diagram-design/assets/example-db-schema.html +302 -0
  20. package/.agents/skills/diagram-design/assets/example-dependency.html +224 -0
  21. package/.agents/skills/diagram-design/assets/example-deployment.html +190 -0
  22. package/.agents/skills/diagram-design/assets/example-dp-integration.html +81 -0
  23. package/.agents/skills/diagram-design/assets/example-dp-security-matrix.html +88 -0
  24. package/.agents/skills/diagram-design/assets/example-er.html +202 -0
  25. package/.agents/skills/diagram-design/assets/example-exploded-ai-stack.html +85 -0
  26. package/.agents/skills/diagram-design/assets/example-exploded-keyboard.html +84 -0
  27. package/.agents/skills/diagram-design/assets/example-exploded-phone.html +83 -0
  28. package/.agents/skills/diagram-design/assets/example-exploded-unboxing.html +84 -0
  29. package/.agents/skills/diagram-design/assets/example-exploded.html +83 -0
  30. package/.agents/skills/diagram-design/assets/example-fishbone.html +152 -0
  31. package/.agents/skills/diagram-design/assets/example-flowchart.html +163 -0
  32. package/.agents/skills/diagram-design/assets/example-gantt.html +137 -0
  33. package/.agents/skills/diagram-design/assets/example-heatmap.html +224 -0
  34. package/.agents/skills/diagram-design/assets/example-high-level-vertical.html +325 -0
  35. package/.agents/skills/diagram-design/assets/example-high-level.html +301 -0
  36. package/.agents/skills/diagram-design/assets/example-import-drawio.html +185 -0
  37. package/.agents/skills/diagram-design/assets/example-import-excalidraw.html +70 -0
  38. package/.agents/skills/diagram-design/assets/example-import-mermaid.html +70 -0
  39. package/.agents/skills/diagram-design/assets/example-it-state.html +128 -0
  40. package/.agents/skills/diagram-design/assets/example-journey.html +148 -0
  41. package/.agents/skills/diagram-design/assets/example-kanban.html +174 -0
  42. package/.agents/skills/diagram-design/assets/example-layers.html +123 -0
  43. package/.agents/skills/diagram-design/assets/example-line.html +111 -0
  44. package/.agents/skills/diagram-design/assets/example-loop.html +100 -0
  45. package/.agents/skills/diagram-design/assets/example-marimekko.html +148 -0
  46. package/.agents/skills/diagram-design/assets/example-medallion.html +159 -0
  47. package/.agents/skills/diagram-design/assets/example-nested.html +136 -0
  48. package/.agents/skills/diagram-design/assets/example-org-chart.html +45 -0
  49. package/.agents/skills/diagram-design/assets/example-polar.html +116 -0
  50. package/.agents/skills/diagram-design/assets/example-process.html +64 -0
  51. package/.agents/skills/diagram-design/assets/example-pyramid.html +119 -0
  52. package/.agents/skills/diagram-design/assets/example-quadrant-consultant.html +166 -0
  53. package/.agents/skills/diagram-design/assets/example-quadrant.html +135 -0
  54. package/.agents/skills/diagram-design/assets/example-radar.html +139 -0
  55. package/.agents/skills/diagram-design/assets/example-ridgeline.html +104 -0
  56. package/.agents/skills/diagram-design/assets/example-sankey.html +150 -0
  57. package/.agents/skills/diagram-design/assets/example-scatter.html +141 -0
  58. package/.agents/skills/diagram-design/assets/example-sequence-oauth.html +227 -0
  59. package/.agents/skills/diagram-design/assets/example-sequence.html +222 -0
  60. package/.agents/skills/diagram-design/assets/example-service-blueprint.html +185 -0
  61. package/.agents/skills/diagram-design/assets/example-slopegraph.html +119 -0
  62. package/.agents/skills/diagram-design/assets/example-state-lifecycle.html +92 -0
  63. package/.agents/skills/diagram-design/assets/example-state.html +147 -0
  64. package/.agents/skills/diagram-design/assets/example-story-map.html +184 -0
  65. package/.agents/skills/diagram-design/assets/example-streamgraph.html +99 -0
  66. package/.agents/skills/diagram-design/assets/example-swimlane.html +172 -0
  67. package/.agents/skills/diagram-design/assets/example-timeline.html +135 -0
  68. package/.agents/skills/diagram-design/assets/example-tree-block-decomposition.html +151 -0
  69. package/.agents/skills/diagram-design/assets/example-tree.html +173 -0
  70. package/.agents/skills/diagram-design/assets/example-treemap.html +107 -0
  71. package/.agents/skills/diagram-design/assets/example-uml-class.html +188 -0
  72. package/.agents/skills/diagram-design/assets/example-venn.html +110 -0
  73. package/.agents/skills/diagram-design/assets/example-wardley.html +153 -0
  74. package/.agents/skills/diagram-design/assets/example-waterfall.html +129 -0
  75. package/.agents/skills/diagram-design/assets/template-dark.html +99 -0
  76. package/.agents/skills/diagram-design/assets/template-full.html +421 -0
  77. package/.agents/skills/diagram-design/assets/template-motion.html +448 -0
  78. package/.agents/skills/diagram-design/assets/template-terminal.html +188 -0
  79. package/.agents/skills/diagram-design/assets/template.html +100 -0
  80. package/.agents/skills/diagram-design/references/animation.md +143 -0
  81. package/.agents/skills/diagram-design/references/export-registry.md +78 -0
  82. package/.agents/skills/diagram-design/references/export.md +376 -0
  83. package/.agents/skills/diagram-design/references/import-drawio.md +181 -0
  84. package/.agents/skills/diagram-design/references/import-excalidraw.md +130 -0
  85. package/.agents/skills/diagram-design/references/import-mermaid.md +137 -0
  86. package/.agents/skills/diagram-design/references/layout-budget.md +97 -0
  87. package/.agents/skills/diagram-design/references/onboarding.md +368 -0
  88. package/.agents/skills/diagram-design/references/output-spec.md +277 -0
  89. package/.agents/skills/diagram-design/references/primitive-annotation.md +36 -0
  90. package/.agents/skills/diagram-design/references/primitive-icons.md +827 -0
  91. package/.agents/skills/diagram-design/references/primitive-sketchy.md +43 -0
  92. package/.agents/skills/diagram-design/references/primitive-terminal.md +76 -0
  93. package/.agents/skills/diagram-design/references/primitives-core.md +146 -0
  94. package/.agents/skills/diagram-design/references/profiles.md +183 -0
  95. package/.agents/skills/diagram-design/references/semantic-patterns.md +154 -0
  96. package/.agents/skills/diagram-design/references/style-guide.md +236 -0
  97. package/.agents/skills/diagram-design/references/style-vivid.md +148 -0
  98. package/.agents/skills/diagram-design/references/type-architecture-delta.md +143 -0
  99. package/.agents/skills/diagram-design/references/type-architecture.md +117 -0
  100. package/.agents/skills/diagram-design/references/type-axonometric-plan.md +83 -0
  101. package/.agents/skills/diagram-design/references/type-bar.md +108 -0
  102. package/.agents/skills/diagram-design/references/type-data-flow.md +371 -0
  103. package/.agents/skills/diagram-design/references/type-db-schema.md +48 -0
  104. package/.agents/skills/diagram-design/references/type-dependency.md +44 -0
  105. package/.agents/skills/diagram-design/references/type-deployment.md +45 -0
  106. package/.agents/skills/diagram-design/references/type-dp-integration.md +407 -0
  107. package/.agents/skills/diagram-design/references/type-dp-security-matrix.md +379 -0
  108. package/.agents/skills/diagram-design/references/type-er.md +25 -0
  109. package/.agents/skills/diagram-design/references/type-exploded.md +115 -0
  110. package/.agents/skills/diagram-design/references/type-fishbone.md +75 -0
  111. package/.agents/skills/diagram-design/references/type-flowchart.md +23 -0
  112. package/.agents/skills/diagram-design/references/type-gantt.md +45 -0
  113. package/.agents/skills/diagram-design/references/type-heatmap.md +80 -0
  114. package/.agents/skills/diagram-design/references/type-high-level.md +470 -0
  115. package/.agents/skills/diagram-design/references/type-it-state.md +468 -0
  116. package/.agents/skills/diagram-design/references/type-journey.md +55 -0
  117. package/.agents/skills/diagram-design/references/type-kanban.md +49 -0
  118. package/.agents/skills/diagram-design/references/type-layers.md +26 -0
  119. package/.agents/skills/diagram-design/references/type-line.md +337 -0
  120. package/.agents/skills/diagram-design/references/type-loop.md +223 -0
  121. package/.agents/skills/diagram-design/references/type-medallion.md +356 -0
  122. package/.agents/skills/diagram-design/references/type-nested.md +22 -0
  123. package/.agents/skills/diagram-design/references/type-org-chart.md +44 -0
  124. package/.agents/skills/diagram-design/references/type-polar.md +136 -0
  125. package/.agents/skills/diagram-design/references/type-process.md +490 -0
  126. package/.agents/skills/diagram-design/references/type-pyramid.md +33 -0
  127. package/.agents/skills/diagram-design/references/type-quadrant.md +81 -0
  128. package/.agents/skills/diagram-design/references/type-radar.md +82 -0
  129. package/.agents/skills/diagram-design/references/type-sankey.md +75 -0
  130. package/.agents/skills/diagram-design/references/type-scatter.md +276 -0
  131. package/.agents/skills/diagram-design/references/type-sequence.md +130 -0
  132. package/.agents/skills/diagram-design/references/type-service-blueprint.md +103 -0
  133. package/.agents/skills/diagram-design/references/type-state.md +30 -0
  134. package/.agents/skills/diagram-design/references/type-story-map.md +46 -0
  135. package/.agents/skills/diagram-design/references/type-swimlane.md +22 -0
  136. package/.agents/skills/diagram-design/references/type-timeline.md +20 -0
  137. package/.agents/skills/diagram-design/references/type-tree.md +24 -0
  138. package/.agents/skills/diagram-design/references/type-treemap.md +137 -0
  139. package/.agents/skills/diagram-design/references/type-uml-class.md +65 -0
  140. package/.agents/skills/diagram-design/references/type-venn.md +26 -0
  141. package/.agents/skills/diagram-design/references/type-wardley.md +39 -0
  142. package/.agents/skills/diagram-design/references/type-waterfall.md +75 -0
  143. package/.agents/skills/scrum-meta/SKILL.md +36 -36
  144. package/.agents/skills/scrum-planning/SKILL.md +61 -61
  145. package/.agents/skills/scrum-planning/references/schema.md +384 -336
  146. package/.agents/skills/scrum-report/SKILL.md +42 -42
  147. package/.agents/skills/scrum-sprint/SKILL.md +49 -49
  148. package/.agents/skills/scrum-tdd/SKILL.md +140 -127
  149. package/README.md +224 -201
  150. package/assets/board/200.html +1 -1
  151. package/assets/board/404.html +1 -1
  152. package/assets/board/_nuxt/1XlYaCp9.js +1 -0
  153. package/assets/board/_nuxt/4gQF_HS3.js +1 -0
  154. package/assets/board/_nuxt/5okfNy5D.js +1 -0
  155. package/assets/board/_nuxt/{Bb3Limos.js → B0C2jsdk.js} +1 -1
  156. package/assets/board/_nuxt/B1j6UC4U.js +1 -0
  157. package/assets/board/_nuxt/B3LKy6o2.js +1 -0
  158. package/assets/board/_nuxt/BAQQngAq.js +13 -0
  159. package/assets/board/_nuxt/BE6t7Q2m.js +1 -0
  160. package/assets/board/_nuxt/BLvbupFS.js +1 -0
  161. package/assets/board/_nuxt/BQgzP7ur.js +1 -0
  162. package/assets/board/_nuxt/BRZIF_wo.js +1 -0
  163. package/assets/board/_nuxt/BW3xJdEx.js +1 -0
  164. package/assets/board/_nuxt/{Cm9lkUvP.js → BY36DFyj.js} +1 -1
  165. package/assets/board/_nuxt/BZlZD94i.js +1 -0
  166. package/assets/board/_nuxt/BZvXNwev.js +3 -0
  167. package/assets/board/_nuxt/BbxmvdIF.js +1 -0
  168. package/assets/board/_nuxt/BiWrMOsL.js +1 -0
  169. package/assets/board/_nuxt/BizDeOK5.js +1 -0
  170. package/assets/board/_nuxt/BkcaOYQ_.js +95 -0
  171. package/assets/board/_nuxt/BkoKCNUY.js +1 -0
  172. package/assets/board/_nuxt/BlKmZhhF.js +1 -0
  173. package/assets/board/_nuxt/BmBpmU73.js +1 -0
  174. package/assets/board/_nuxt/BrWE0up6.js +1 -0
  175. package/assets/board/_nuxt/Bs52qkgk.js +1 -0
  176. package/assets/board/_nuxt/BtzUbHO_.js +1 -0
  177. package/assets/board/_nuxt/BuBzMkFZ.js +1 -0
  178. package/assets/board/_nuxt/Bubk0xn-.js +1 -0
  179. package/assets/board/_nuxt/BxuBMtk_.js +3 -0
  180. package/assets/board/_nuxt/By1KXXLR.js +1 -0
  181. package/assets/board/_nuxt/BygIGL69.js +2 -0
  182. package/assets/board/_nuxt/C1iO5KH3.js +1 -0
  183. package/assets/board/_nuxt/C2YPmTzt.js +1 -0
  184. package/assets/board/_nuxt/C3SpAhCW.js +1 -0
  185. package/assets/board/_nuxt/C3ZRWz5L.js +1 -0
  186. package/assets/board/_nuxt/C4WdPP6K.js +1 -0
  187. package/assets/board/_nuxt/C6o03JHe.js +1 -0
  188. package/assets/board/_nuxt/C8qB5llI.js +1 -0
  189. package/assets/board/_nuxt/C9MgRdhu.js +1 -0
  190. package/assets/board/_nuxt/CCA81-4P.js +1 -0
  191. package/assets/board/_nuxt/{D2O8Q8x9.js → CFCM18fF.js} +1 -1
  192. package/assets/board/_nuxt/CGXljzd_.js +1 -0
  193. package/assets/board/_nuxt/CI0scS-N.js +1 -0
  194. package/assets/board/_nuxt/CJs9B42o.js +1 -0
  195. package/assets/board/_nuxt/COecDWbb.js +1 -0
  196. package/assets/board/_nuxt/COmtTtfB.js +1 -0
  197. package/assets/board/_nuxt/CPYm4J_K.js +1 -0
  198. package/assets/board/_nuxt/CReA4TEB.js +3 -0
  199. package/assets/board/_nuxt/CXG7GZes.js +1 -0
  200. package/assets/board/_nuxt/CYGiZn-X.js +1 -0
  201. package/assets/board/_nuxt/CaE8VlUp.js +1 -0
  202. package/assets/board/_nuxt/CcGiNUgA.js +1 -0
  203. package/assets/board/_nuxt/Ccgv3lDj.js +1 -0
  204. package/assets/board/_nuxt/CdPGFZyy.js +1 -0
  205. package/assets/board/_nuxt/{DfR3IZN_.js → Cdf_T8Xa.js} +1 -1
  206. package/assets/board/_nuxt/CgQ30j_6.js +1 -0
  207. package/assets/board/_nuxt/ChUHb39z.js +1 -0
  208. package/assets/board/_nuxt/Ck0-FqVI.js +1 -0
  209. package/assets/board/_nuxt/CkWKLtjO.js +1 -0
  210. package/assets/board/_nuxt/Cq7hsCKB.js +1 -0
  211. package/assets/board/_nuxt/CtFknnHZ.js +1 -0
  212. package/assets/board/_nuxt/D166WVUG.js +1 -0
  213. package/assets/board/_nuxt/D4Dpzo9e.js +1 -0
  214. package/assets/board/_nuxt/D5i92OZO.js +1 -0
  215. package/assets/board/_nuxt/D6dUp4Nm.js +9 -0
  216. package/assets/board/_nuxt/DFQDFspC.js +1 -0
  217. package/assets/board/_nuxt/DHX2tw9J.js +1 -0
  218. package/assets/board/_nuxt/DJM7u8P3.js +1 -0
  219. package/assets/board/_nuxt/{BPTrRhcw.js → DLr85ebo.js} +1 -1
  220. package/assets/board/_nuxt/DOMM1wfl.js +1 -0
  221. package/assets/board/_nuxt/DU6ArlUN.js +1 -0
  222. package/assets/board/_nuxt/{B_SlFcWp.js → DUgGsde6.js} +1 -1
  223. package/assets/board/_nuxt/DV4ti-Pq.js +1 -0
  224. package/assets/board/_nuxt/DZ--fXuU.js +1 -0
  225. package/assets/board/_nuxt/D_ct-Stz.js +2 -0
  226. package/assets/board/_nuxt/DbWAComO.js +1 -0
  227. package/assets/board/_nuxt/DbwlcHAt.js +1 -0
  228. package/assets/board/_nuxt/DjzLR9Bl.js +1 -0
  229. package/assets/board/_nuxt/Dki9VkAL.js +3 -0
  230. package/assets/board/_nuxt/DlNJhOoc.js +1 -0
  231. package/assets/board/_nuxt/DqG7CtD4.js +1 -0
  232. package/assets/board/_nuxt/DqUSsCJ2.js +1 -0
  233. package/assets/board/_nuxt/Du2F4WXh.js +1 -0
  234. package/assets/board/_nuxt/DuRiEXn4.js +1 -0
  235. package/assets/board/_nuxt/DxBwVNyP.js +2 -0
  236. package/assets/board/_nuxt/DzmVW5-D.js +1 -0
  237. package/assets/board/_nuxt/I-sGtDIB.js +6 -0
  238. package/assets/board/_nuxt/JU9-x68N.js +1 -0
  239. package/assets/board/_nuxt/Lozm7hhE.js +1 -0
  240. package/assets/board/_nuxt/MMsTMkcB.js +1 -0
  241. package/assets/board/_nuxt/MS7CGmCB.js +1 -0
  242. package/assets/board/_nuxt/OKKaKILz.js +1 -0
  243. package/assets/board/_nuxt/{Csqgy925.js → P6qlvBHA.js} +1 -1
  244. package/assets/board/_nuxt/SrNUvNwO.js +1 -0
  245. package/assets/board/_nuxt/{DSaWoFHS.js → SywdkA98.js} +1 -1
  246. package/assets/board/_nuxt/TBIRpVLG.js +1 -0
  247. package/assets/board/_nuxt/TlTrMIMm.js +1 -0
  248. package/assets/board/_nuxt/Zv9-SOQF.js +1 -0
  249. package/assets/board/_nuxt/_id_.ItzoSaBL.css +1 -0
  250. package/assets/board/_nuxt/builds/latest.json +1 -1
  251. package/assets/board/_nuxt/builds/meta/2218461a-f45b-41d6-ae44-b0d2332a9511.json +1 -0
  252. package/assets/board/_nuxt/burndown.CT8fx1Ge.css +1 -0
  253. package/assets/board/_nuxt/diagrams.D1ybqBem.css +1 -0
  254. package/assets/board/_nuxt/{entry.CKHePurH.css → entry.BCuHiFgF.css} +1 -1
  255. package/assets/board/_nuxt/epics.CUeDIEa0.css +1 -0
  256. package/assets/board/_nuxt/error-404.Y9imKiDC.css +1 -0
  257. package/assets/board/_nuxt/error-500.DufSBGVC.css +1 -0
  258. package/assets/board/_nuxt/gantt.CiC2Ts1t.css +1 -0
  259. package/assets/board/_nuxt/jbri6q1p.js +1 -0
  260. package/assets/board/_nuxt/last-change.C05Vc3BF.css +1 -0
  261. package/assets/board/_nuxt/milestones.Civ3sMiQ.css +1 -0
  262. package/assets/board/_nuxt/oSJF4yHw.js +1 -0
  263. package/assets/board/_nuxt/pages.BshWbOyo.css +1 -0
  264. package/assets/board/_nuxt/q_8bxRMt.js +1 -0
  265. package/assets/board/_nuxt/tests.Ci9fBCka.css +1 -0
  266. package/assets/board/burndown/index.html +1 -1
  267. package/assets/board/diagrams/index.html +1 -0
  268. package/assets/board/epics/index.html +1 -1
  269. package/assets/board/favicon.svg +16 -16
  270. package/assets/board/gantt/index.html +1 -1
  271. package/assets/board/index.html +1 -1
  272. package/assets/board/last-change/index.html +1 -1
  273. package/assets/board/milestones/index.html +1 -1
  274. package/assets/board/tests/index.html +1 -1
  275. package/bin/scrum-skills.mjs +204 -191
  276. package/docs/ai-assistant-guide.md +1008 -1008
  277. package/package.json +42 -41
  278. package/templates/AGENTS.md +84 -74
  279. package/tools/agile-tools.mjs +510 -510
  280. package/tools/ai.mjs +464 -464
  281. package/tools/diagram-import.mjs +238 -0
  282. package/tools/diagram-lint.mjs +518 -0
  283. package/tools/diagram.mjs +299 -0
  284. package/tools/git-commit.mjs +216 -216
  285. package/tools/last-change.mjs +326 -326
  286. package/tools/projects.mjs +240 -215
  287. package/tools/serve.mjs +180 -154
  288. package/tools/validate.mjs +781 -664
  289. package/assets/board/_nuxt/1eqboJxR.js +0 -1
  290. package/assets/board/_nuxt/2K7ag6ES.js +0 -1
  291. package/assets/board/_nuxt/51OWHj8c.js +0 -2
  292. package/assets/board/_nuxt/6gFtTBwm.js +0 -1
  293. package/assets/board/_nuxt/B3jkABw9.js +0 -1
  294. package/assets/board/_nuxt/B5n2_jZN.js +0 -1
  295. package/assets/board/_nuxt/BDK2Hj7B.js +0 -1
  296. package/assets/board/_nuxt/BDcnzXHq.js +0 -1
  297. package/assets/board/_nuxt/BaG8y0Wt.js +0 -1
  298. package/assets/board/_nuxt/BbwJq5pb.js +0 -1
  299. package/assets/board/_nuxt/BgLeKwx0.js +0 -1
  300. package/assets/board/_nuxt/Bi9Axj3V.js +0 -1
  301. package/assets/board/_nuxt/BmxvtaMq.js +0 -1
  302. package/assets/board/_nuxt/BodFvto3.js +0 -1
  303. package/assets/board/_nuxt/BpWeHLuN.js +0 -1
  304. package/assets/board/_nuxt/BuOKDFiJ.js +0 -1
  305. package/assets/board/_nuxt/C40iTe-x.js +0 -1
  306. package/assets/board/_nuxt/C7K0R7F-.js +0 -2
  307. package/assets/board/_nuxt/C8vL692X.js +0 -1
  308. package/assets/board/_nuxt/C9StZL3D.js +0 -3
  309. package/assets/board/_nuxt/CGI_ZV79.js +0 -1
  310. package/assets/board/_nuxt/CJ2mz0WY.js +0 -1
  311. package/assets/board/_nuxt/CJMBJQuf.js +0 -1
  312. package/assets/board/_nuxt/CK-lOYG9.js +0 -1
  313. package/assets/board/_nuxt/CK9_veoz.js +0 -1
  314. package/assets/board/_nuxt/CLBcBrYf.js +0 -1
  315. package/assets/board/_nuxt/CMUi2-Lj.js +0 -1
  316. package/assets/board/_nuxt/COf6E6h4.js +0 -1
  317. package/assets/board/_nuxt/CPCUMJnF.js +0 -1
  318. package/assets/board/_nuxt/CPcKlmSm.js +0 -1
  319. package/assets/board/_nuxt/CQTvWh4i.js +0 -1
  320. package/assets/board/_nuxt/CSEEUF8S.js +0 -1
  321. package/assets/board/_nuxt/CSSb154I.js +0 -13
  322. package/assets/board/_nuxt/CgDTd7jS.js +0 -1
  323. package/assets/board/_nuxt/ChG76uh9.js +0 -1
  324. package/assets/board/_nuxt/Ci0qbkgh.js +0 -1
  325. package/assets/board/_nuxt/CqoQ__I_.js +0 -1
  326. package/assets/board/_nuxt/CuJUHLl8.js +0 -1
  327. package/assets/board/_nuxt/CvLiA4_O.js +0 -1
  328. package/assets/board/_nuxt/Cvs12oA0.js +0 -3
  329. package/assets/board/_nuxt/CyEXFe3V.js +0 -1
  330. package/assets/board/_nuxt/Cz6rZcLK.js +0 -1
  331. package/assets/board/_nuxt/D2FhHl1o.js +0 -1
  332. package/assets/board/_nuxt/D3YCAmfu.js +0 -1
  333. package/assets/board/_nuxt/D5CE81jK.js +0 -1
  334. package/assets/board/_nuxt/D75vbfSb.js +0 -1
  335. package/assets/board/_nuxt/D99LbGfb.js +0 -9
  336. package/assets/board/_nuxt/DEfLc7p3.js +0 -6
  337. package/assets/board/_nuxt/DF-nsa1Z.js +0 -1
  338. package/assets/board/_nuxt/DIc8yx98.js +0 -1
  339. package/assets/board/_nuxt/DLkAKotw.js +0 -1
  340. package/assets/board/_nuxt/DRPlYvb3.js +0 -1
  341. package/assets/board/_nuxt/DRlQgul3.js +0 -1
  342. package/assets/board/_nuxt/DSLbmoWa.js +0 -1
  343. package/assets/board/_nuxt/DWO9c9yp.js +0 -1
  344. package/assets/board/_nuxt/DZo3dYLJ.js +0 -3
  345. package/assets/board/_nuxt/D_S6N7_b.js +0 -1
  346. package/assets/board/_nuxt/DajA-Tkt.js +0 -1
  347. package/assets/board/_nuxt/DbHiyab-.js +0 -1
  348. package/assets/board/_nuxt/Dc7Ql6eE.js +0 -1
  349. package/assets/board/_nuxt/Dd9ZukPU.js +0 -1
  350. package/assets/board/_nuxt/Dg2LiqmN.js +0 -1
  351. package/assets/board/_nuxt/DhuleNnm.js +0 -1
  352. package/assets/board/_nuxt/DkI1Qxpp.js +0 -95
  353. package/assets/board/_nuxt/DnDHGSYI.js +0 -1
  354. package/assets/board/_nuxt/DpXJ_tCU.js +0 -1
  355. package/assets/board/_nuxt/DqZgF3hU.js +0 -1
  356. package/assets/board/_nuxt/DqcxvfbD.js +0 -1
  357. package/assets/board/_nuxt/DsA2lVci.js +0 -1
  358. package/assets/board/_nuxt/Dtsa-1NS.js +0 -1
  359. package/assets/board/_nuxt/Du91iq0p.js +0 -1
  360. package/assets/board/_nuxt/Dx1wcYFo.js +0 -1
  361. package/assets/board/_nuxt/EYTShbt4.js +0 -1
  362. package/assets/board/_nuxt/MaXJprwN.js +0 -1
  363. package/assets/board/_nuxt/P9x67aq2.js +0 -1
  364. package/assets/board/_nuxt/S08nFESZ.js +0 -3
  365. package/assets/board/_nuxt/V0uynWE2.js +0 -1
  366. package/assets/board/_nuxt/Vo4wMbnS.js +0 -1
  367. package/assets/board/_nuxt/ZVTqot-_.js +0 -1
  368. package/assets/board/_nuxt/ZngEd3HB.js +0 -1
  369. package/assets/board/_nuxt/_id_.B2NDKSlX.css +0 -1
  370. package/assets/board/_nuxt/assMu_Wn.js +0 -1
  371. package/assets/board/_nuxt/builds/meta/8e23aec9-5b67-4569-b8bf-d4f07e50ffdf.json +0 -1
  372. package/assets/board/_nuxt/burndown.Do6IbM6o.css +0 -1
  373. package/assets/board/_nuxt/epics.Dmessplu.css +0 -1
  374. package/assets/board/_nuxt/error-404.BFmXOnCT.css +0 -1
  375. package/assets/board/_nuxt/error-500.BZ-DdjQ6.css +0 -1
  376. package/assets/board/_nuxt/gantt.Dmp00GUo.css +0 -1
  377. package/assets/board/_nuxt/last-change.1Su4GrCN.css +0 -1
  378. package/assets/board/_nuxt/milestones.U0xKCsEo.css +0 -1
  379. package/assets/board/_nuxt/pages.Dbj2IVk8.css +0 -1
  380. package/assets/board/_nuxt/rlePnzpc.js +0 -1
  381. package/assets/board/_nuxt/tests.dXlUX16A.css +0 -1
  382. package/assets/board/_nuxt/uKzCKCTq.js +0 -1
  383. package/assets/board/_nuxt/vwxaNGfc.js +0 -1
  384. package/assets/board/_nuxt/yh6sf_D5.js +0 -1
@@ -1,336 +1,384 @@
1
- # 敏捷数据 Schema(v3 · 三常驻 + 两可选)
2
-
3
- `agile/` 下**三个常驻数据文件 + 两个可选文件**(测试资产、交付说明),全部 UTF-8 JSON、2 空格缩进、末尾换行。
4
-
5
- | 文件 | 装什么 |
6
- |---|---|
7
- | `agile/backlog.json` | 史诗 epics(含量化目标 keyResults)+ 用户故事 stories(内联 tasks) |
8
- | `agile/sprints.json` | 迭代 sprints + 里程碑 milestones(MVP 节点是里程碑的一种) |
9
- | `agile/journal.json` | TDD 实施日志 journals(一个 task 一条,内联 entries) |
10
- | `agile/tests.json` | 测试资产:suites(层 × 级别 → cases)+ runs(执行记录与代码覆盖率),见第 5 节 |
11
- | `agile/last-change.json` | 最近一次交付的汇报(可选;已提交才覆盖,未提交则合并,见第 4 节) |
12
-
13
- > 所有数据文件都必须带 `"schemaVersion": 3`(含可选的 `tests.json` / `last-change.json`)。v2 及更早的散文件结构不再兼容,校验器发现 `agile/backlog/epics/`、`agile/backlog/stories/`、`agile/sprints/`、`agile/journal/` 里还有 JSON 会直接报错。
14
-
15
- ## 1. backlog.json
16
-
17
- ```json
18
- {
19
- "schemaVersion": 3,
20
- "epics": [
21
- {
22
- "id": "E-001",
23
- "title": "用户认证与工作空间",
24
- "goal": "一句话说明这个史诗完成后用户获得了什么",
25
- "status": "draft | active | done | cancelled",
26
- "keyResults": [
27
- { "id": "E-001-KR1", "text": "新成员从收到邀请到能登录用时", "unit": "分钟", "target": 2, "current": 1.5 }
28
- ],
29
- "stories": ["S-001", "S-002"],
30
- "created": "2026-08-24"
31
- }
32
- ],
33
- "stories": [
34
- {
35
- "id": "S-001",
36
- "epicId": "E-001",
37
- "title": "邮箱密码登录",
38
- "narrative": "作为<角色>,我想要<能力>,以便<价值>",
39
- "type": "feature | bug | debt | spike",
40
- "priority": "P0 | P1 | P2 | P3",
41
- "value": 13,
42
- "bug": {
43
- "severity": "blocker | major | minor | trivial",
44
- "environment": "Chrome 120 / Windows 11,看板页四列布局",
45
- "steps": "1. …;2. …;3. …"
46
- },
47
- "acceptance": [
48
- { "given": "已注册用户", "when": "输入正确邮箱密码提交", "then": "下发会话 cookie 并跳转首页", "verifyBy": ["S-001-T1"] }
49
- ],
50
- "points": 5,
51
- "status": "draft | ready | in-progress | review | done | cancelled",
52
- "sprintId": "R1-S1",
53
- "created": "2026-08-24",
54
- "schedule": { "start": "2026-08-31", "end": "2026-09-08" },
55
- "dependsOn": ["S-004"],
56
- "blocked": { "reason": "等产品确认是否要留审计日志", "since": "2026-10-21" },
57
- "scopeChange": { "kind": "added-mid-sprint | split | expanded", "at": "2026-10-15", "reason": "客户临时插需求" },
58
- "tasks": [
59
- {
60
- "id": "S-001-T1",
61
- "title": "为登录接口写失败测试",
62
- "type": "test | impl | refactor | chore",
63
- "status": "todo | red | green | refactored | done",
64
- "files": ["tests/auth/login.spec.ts"]
65
- }
66
- ]
67
- }
68
- ]
69
- }
70
- ```
71
-
72
- 字段说明:
73
-
74
- - **`type`**:`feature` 功能 / `bug` 缺陷 / `debt` 技术债 / `spike` 调研。`bug` 必须同时给 `bug` 详情三件套(severity / environment / steps),否则校验报错。
75
- - **`priority`**:P0 最高。数组顺序即 backlog 排序(rank),看板可再按优先级或 WSJF 重排。
76
- - **`value` + `points`** → WSJF = value / points,用来决定「先做谁」;点数仍是成本口径,两者别混。
77
- - **`acceptance[].verifyBy`**:这条验收由哪个 task 的测试覆盖(task id)。非 `draft` 状态没写只给 WARN,但它是「验收不是口号」的唯一凭据,建议必填。
78
- - **`dependsOn`**:故事级依赖,必须存在、不能自依赖、**不能成环**(校验器做 DFS 检测)。
79
- - **`blocked`**:当前阻塞的事实(原因 + 起始日期)。已 `done` 的故事不许带 `blocked`;处于迭代里还被阻塞会 WARN(站会必须处理)。
80
- - **`scopeChange`**:范围变更标记。`added-mid-sprint` 迭代中途插入、`split` 拆分产生、`expanded` 范围扩大。有了它,燃尽图上那段平台期才不会被误读成「拖延」。
81
- - **`schedule`** 可选,只给甘特图用(计划区间);实际区间由 `journal.json` 的记录日期推出来,不用手填。
82
- - task 的 `id` 必须是 `<storyId>-T<n>`;日志集中在 `journal.json`,用 `taskId` 关联。
83
-
84
- ## 2. sprints.json
85
-
86
- ```json
87
- {
88
- "schemaVersion": 3,
89
- "sprints": [
90
- {
91
- "id": "R1-S1",
92
- "name": "第 1 个迭代(登录与邀请)",
93
- "goal": "本迭代要交付什么",
94
- "start": "2026-08-31",
95
- "end": "2026-09-13",
96
- "stories": ["S-001", "S-002"],
97
- "capacity": 12
98
- }
99
- ],
100
- "milestones": [
101
- {
102
- "id": "M-001",
103
- "title": "MVP · 内测可登录",
104
- "kind": "mvp | release | checkpoint",
105
- "due": "2026-09-13",
106
- "status": "planned | at-risk | reached | missed",
107
- "sprintId": "R1-S1",
108
- "criteria": "达成口径:怎样算这个节点到了",
109
- "stories": ["S-001", "S-002"]
110
- }
111
- ]
112
- }
113
- ```
114
-
115
- - **MVP 节点就是 `kind: "mvp"` 的里程碑**,不另设实体。
116
- - `status: "reached"` 时挂的故事必须全部 `done/cancelled`,否则校验报错。
117
- - `due` 早于今天但状态仍是 `planned` → WARN。
118
-
119
- ### 迭代编号规则(`sprints[].id`)
120
-
121
- 格式:`R<发布周期>-S<期内冲刺号>`,例如 `R1-S1`、`R1-S2`、`R2-S1`。
122
-
123
- - **`S<期内冲刺号>`** 是 Sprint 本体 —— Scrum 里的 Sprint(冲刺/迭代)就是它,在一个发布周期内从 1 开始连号、不跳号。
124
- - **`R<发布周期>`** 是引用Release(发布周期/版本)这一层的分组:若干个冲刺归到一个发布窗口,和 `milestones`(尤其 `kind: "release"`)对齐。当前约定**一个发布周期 = 4 周 = 2 个两周冲刺**。
125
- 它不是 Scrum 术语(Scrum 只有 Sprint),业界最接近的是 Release 或 SAFe 的 PI(Program Increment,通常 8~12 周、含 4 个开发冲刺 + 1 个 IP 冲刺)。**既然叫 Release 就按 4 周一个周期排,别套 PI 的节奏。**
126
- - 周期号按时间递增(`R1`、`R2`…,不带前导零);同一周期内冲刺号不得重复;**一个周期建议不超过 2 个冲刺**。
127
- - 小团队不需要发布周期这一层时,可以只用 `S-01`、`S-02` 纯序号(整段省略 `R` 前缀),但**同一个项目里不许两种风格混用**。
128
- - **id 被 `story.sprintId`、`milestones[].sprintId` 引用,定了就别改**;确需重命名时两处引用同步改,改完跑 `validate`(引用完整性会兜住漏改)。
129
-
130
- 以上规则由 `tools/validate.mjs` 强制:id 必须匹配 `R<n>-S<n>` 或 `S-<n>`、不许混用风格、同一周期内冲刺号必须从 1 连续、周期号与起始日期顺序要一致(后两条分别报错与警告)。
131
-
132
- ## 3. journal.json
133
-
134
- ```json
135
- {
136
- "schemaVersion": 3,
137
- "journals": [
138
- {
139
- "taskId": "S-001-T1",
140
- "storyId": "S-001",
141
- "entries": [
142
- {
143
- "phase": "red | green | refactor",
144
- "date": "2026-08-31",
145
- "note": "这一步做了什么、为什么",
146
- "files": ["tests/auth/login.spec.ts"],
147
- "testCommand": "pnpm test auth/login",
148
- "result": "fail: 3 failed, 0 passed — 404 Not Found"
149
- }
150
- ]
151
- }
152
- ]
153
- }
154
- ```
155
-
156
- ## 4. last-change.json(最后更新 / 交付说明)
157
-
158
- `agile/last-change.json` 是**可选**文件:还没交付过东西时不存在,校验器不报错。看板 `/last-change` 页读的就是它。
159
-
160
- ### 写之前先查 git:已提交才覆盖,未提交就合并
161
-
162
- 只留最近一次交付的前提是**上一次已经进了版本库**。文件如果还有没提交的改动,直接覆盖就把那次记录冲掉了,所以写入策略分两种:
163
-
164
- | 文件在 git 里的状态 | 写法 | 结果 |
165
- |---|---|---|
166
- | 已提交、工作区干净 | 整份覆盖 | 文件里只有本次交付 |
167
- | 有未提交改动 / 已暂存未提交 / 未跟踪 / 不是 git 仓库 | 合并 | 本次结果并进旧记录,旧的一条不丢 |
168
-
169
- 用工具判断并写入,不要手写覆盖:
170
-
171
- ```bash
172
- node tools/last-change.mjs check # 退出码 0 = 可覆盖,2 = 必须先合并
173
- node tools/last-change.mjs write <记录.json> # 按状态自动覆盖或合并,写后校验,失败回滚
174
- node tools/last-change.mjs write <记录.json> --replace # 确认旧记录不要了才强制覆盖
175
- ```
176
-
177
- 合并的取舍(`write` 自动完成,手动合并也要照这个来):
178
-
179
- - `changes` 按 `kind:id`、`scenarios` 按 `id`(没有就按 `title`)去重:**新的覆盖旧的**,没被提到的旧条目原样保留,顺序按「旧的在前、新增的追加」;
180
- - `extras` 按 `title`、`verification` 按 `what`、`preparation` 按 `step` 去重,规则同上;
181
- - `notes` / `open` 字符串去重后拼接;`access.urls` 按 `url`、`access.accounts` 按 `username` 合并;
182
- - `title` / `at` / `summary` 取本次的(缺了才沿用旧的);
183
- - 合并后自动带上 `"merged": true` 与 `"mergedFrom"`(被并进来的那几次交付),看板据此标「合并记录」。
184
-
185
- ```json
186
- {
187
- "schemaVersion": 3,
188
- "lastChange": {
189
- "title": "登录接口收尾",
190
- "at": "2026-10-27 14:35:12",
191
- "summary": "一句话说清这次交付做成了什么",
192
- "changes": [
193
- {
194
- "kind": "story",
195
- "id": "S-001",
196
- "title": "邮箱密码登录",
197
- "action": "added | updated | removed",
198
- "from": "in-progress",
199
- "to": "review",
200
- "note": "变更内容:补了两条验收、状态推进到评审",
201
- "files": ["agile/backlog.json", "src/auth/login.ts"]
202
- }
203
- ],
204
- "extras": [{ "title": "顺手把校验错误信息改成中文", "detail": "为什么做、做到什么程度", "files": ["tools/validate.mjs"] }],
205
- "verification": [{ "what": "pnpm test", "result": "pass | fail | partial | skipped", "detail": "32 passed" }],
206
- "access": {
207
- "urls": [{ "label": "看板", "url": "http://localhost:4173", "note": "先起 serve" }],
208
- "accounts": [{ "role": "管理员", "username": "admin@example.com", "password": "Passw0rd!", "note": "仅本地环境" }]
209
- },
210
- "preparation": [{ "step": "装依赖", "command": "pnpm install", "note": "Node ≥ 18" }],
211
- "scenarios": [
212
- {
213
- "id": "TC-01",
214
- "title": "正确密码能登录",
215
- "storyIds": ["S-001"],
216
- "steps": ["打开 /login", "填表提交"],
217
- "expect": "跳转首页并下发会话 cookie",
218
- "acceptance": "对应验收第 1 条"
219
- }
220
- ],
221
- "merged": true,
222
- "mergedFrom": [{ "title": "上一次还没提交的交付", "at": "2026-10-26 18:02:41" }],
223
- "notes": ["使用说明、口径解释"],
224
- "open": ["还没做的、已知限制"]
225
- }
226
- }
227
- ```
228
-
229
- 字段说明:
230
-
231
- - **`title` / `at` 必填**:`at` 是本次交付时间,**写到秒**:`YYYY-MM-DD HH:mm:ss`(ISO 的 `T` 分隔也认)。只写 `YYYY-MM-DD` 仍然合法,但校验器会给 WARN、看板上也只能看到「哪天」,看不出「几点几分交付的」。`node tools/last-change.mjs write` 发现缺 `at` 会自动补当前时间。
232
- - **`merged` / `mergedFrom` 由工具写,不要手填**:只有「并进未提交旧记录」时才出现,`mergedFrom` 每条要有 `title`(`at` 可选)。`merged: true` 却没有 `mergedFrom` 会被校验器提醒。
233
- - **`changes[]`**:故事与任务的变更清单,看板表格一行一条。`kind` 只认 `story` / `task`,`id` 必须是 backlg 里真实存在的 id;`action` 是 `added`(新增)/ `updated`(状态或内容变更)/ `removed`(删除);状态变更填 `from` → `to`,`files` 是这次动过的文件。
234
- - **其余分区都可选**,没有就省略,**不许为了填满而编**:项目没有账号体系就不写 `accounts`,没有前端入口就不写 `urls`。
235
- - `verification[].result` 与 `scenarios[].expect` 是「验收不是口号」的凭据:场景必须写清步骤与验收标准,验证结果只认 `pass/fail/partial/skipped`。
236
- - 校验器会查:`schemaVersion`、`at` 格式、`kind`/`action`/`result` 枚举、`changes[].id` 是否真实存在、`scenarios[].steps` 与 `expect` 是否齐备、`access.urls[].url` 是否为 `http(s)` 完整地址。缺 `title`、`what`、`expect`、`step` 报错;缺 `changes[].title`、场景 id、url label 只给 WARN。
237
-
238
- ## 5. tests.json(测试资产与覆盖率)
239
-
240
- `agile/tests.json` 是**可选**文件:不存在时校验器不报错、看板 `/tests` 页显示空状态。它由 Coding Agent 在**每个 task 推到 `done`、story 送进 `review` 之前**维护(见 `scrum-tdd` 的交工汇报第 1 步),不是事后补的报表。
241
-
242
- ```json
243
- {
244
- "schemaVersion": 3,
245
- "suites": [
246
- {
247
- "id": "TS-BE-01",
248
- "name": "登录接口",
249
- "layer": "frontend | backend | e2e",
250
- "level": "unit | integration | e2e",
251
- "runner": "vitest",
252
- "files": ["tests/auth/login.spec.ts"],
253
- "cases": [
254
- {
255
- "id": "TC-BE-001",
256
- "title": "正确密码登录返回 200 并下发 httpOnly cookie",
257
- "automated": true,
258
- "taskId": "S-001-T1",
259
- "covers": ["S-001-A1"],
260
- "expect": "200;set-cookie 含 sid;HttpOnly",
261
- "code": "tests/auth/login.spec.ts::正确密码登录",
262
- "status": "pass | fail | skipped | blocked | not-run",
263
- "lastRun": "2026-10-29",
264
- "durationMs": 42,
265
- "note": "失败原因写在这里"
266
- }
267
- ]
268
- }
269
- ],
270
- "runs": [
271
- {
272
- "id": "RUN-20261029-2110",
273
- "at": "2026-10-29 21:10:00",
274
- "env": "local",
275
- "command": "pnpm test",
276
- "totals": { "total": 159, "pass": 158, "fail": 1, "skipped": 0, "durationMs": 24300 },
277
- "failedCases": ["TC-BE-001"],
278
- "coverage": {
279
- "frontend": { "tool": "vitest", "lines": 72.4, "branches": 61.5, "functions": 66.0, "report": "coverage/frontend/lcov.info" },
280
- "backend": { "tool": "vitest", "lines": 84.1, "branches": 70.2, "functions": 80.5, "report": "coverage/backend/lcov.info" }
281
- }
282
- }
283
- ]
284
- }
285
- ```
286
-
287
- 字段说明:
288
-
289
- - **`suites[]`** 按模块 / 测试文件分组,承载**两个正交维度**:`layer`(`frontend` / `backend` / `e2e`,QA 主视图的三条泳道)与 `level`(`unit` / `integration` / `e2e`)。`files` 只用于定位,可省。
290
- - **`cases[]`** 一条用例 = 一次能判定成败的验证:
291
- - `automated` 区分自动化 / 手工;**手工用例也要登记**,`steps` 一步一条,这是交接给 QA 的正文;
292
- - `covers` 是覆盖的验收,写法 `S-001-A1`(故事 id + 第几条验收,**1 基**);改验收顺序要同步改它,一条 E2E 用例可以覆盖多个故事;
293
- - `expect` 必填(只有标题的用例不算交付物);`taskId` 指向产出它的 TDD 任务(可省);`code` 是自动化用例的定位串 `文件::用例名`,导入器靠它回写状态;
294
- - `status` 只认 `pass / fail / skipped / blocked / not-run`;`not-run` 不要求 `lastRun`,其余必须写。
295
- - **`runs[]`** 每次执行一条,**按时间正序**(最后一条 = 最近一次):`at` 到秒、`command`、`env`、`totals`、`failedCases`,有覆盖率报告就填 `coverage`。
296
- - `coverage` 按层给 `lines / branches / functions / statements` 与 `tool`:**前端、后端各报各的,绝不做加权平均**,E2E 一般不报行覆盖。
297
-
298
- 覆盖率的三个口径(页面按这个算,禁止合成一个「覆盖率」):
299
-
300
- | 口径 | 分母 | 分子 |
301
- |---|---|---|
302
- | 需求覆盖 | 非 `draft` / `cancelled` 故事的验收条数 | 被至少一条用例 `covers` 命中的条数;其中最近一次 `pass` 的另算「验证通过」 |
303
- | 用例通过率 | 最近一次执行的 `total - skipped` | `pass` |
304
- | 代码覆盖 | 测试工具报告 | `lines` / `branches`,前端、后端分开 |
305
-
306
- 校验器强制:枚举合法;用例 / 套件 id 与其它记录共用一个命名空间;`covers` 指向的验收必须存在且序号不越界;`taskId` 必须存在且属于 `covers` 里的故事;`runs` 时间正序;`通过+失败+跳过 ≤ 总数`;最新一次 `failedCases` 必须对应 `status: fail`;覆盖率在 0~100 之间。
307
-
308
- 收口纪律(**只查登记过用例的故事**,避免老项目一升级就满屏报错):
309
-
310
- - 该 story 下每个 `done` 的 `type: test` task 至少一条用例 → 否则**报错**;
311
- - story 到 `review` / `done` 时每条验收都被覆盖 → 否则**报错**(未到 review 只给 WARN);
312
- - 用例 `lastRun` 早于 task 最后一次 `pass` → WARN(结果过期了);
313
- - 最近一次执行条数多于已登记用例 → WARN(还有测试没登记)。
314
-
315
- ## 状态机(校验器强制)
316
-
317
- - story: `draft → ready → in-progress → review → done`;不做了直接进 `cancelled`(已取消)终态(可回退,不可跳级;`done` 与 `cancelled` 都是终态)
318
- - task: `todo → red → green → refactored → done`(只能前进;test 型可 `todo → green`)
319
- - epic: 无强制流转,但 `done` 要求其下所有 story 均 `done/cancelled`
320
- - milestone: `planned → at-risk → reached / missed`
321
-
322
- ## 硬约束(校验器强制 / 警告)
323
-
324
- 1. ID 全局唯一(epic / story / task / sprint / milestone / suite / case 共用命名空间),task 命名 `<storyId>-T<n>`
325
- 2. **双向引用一致**:`epic.stories` ↔ `story.epicId`、`sprint.stories` ↔ `story.sprintId`、`journal.taskId` ↔ task
326
- 3. `ready` / `in-progress` / `review` / `done` 必须有验收标准;进 sprint 的故事必须有验收标准(`cancelled` 两样都不要求)
327
- 4. 验收标准的 `verifyBy` 必须指向**同一 story 的** task
328
- 5. task 到 `green/refactored/done` 时,journal 必须存在且首条 `red` 的 result 以 `fail` 开头、`green` 以 `pass` 开头
329
- 6. task 为 `done` 时,journal 末条 entry 的 `result` 必须 `pass`
330
- 7. story 为 `done` 时,其所有 task 必须 `done`,且不许仍标着 `blocked`
331
- 8. 同时只能有一个活跃 sprint(`start ≤ 今天 ≤ end`)
332
- 9. `dependsOn` 必须存在、不能自依赖、不能成环
333
- 10. `schedule.start ≤ schedule.end`;计划区间超出所属迭代只给 WARN
334
- 11. sprint 承诺点数超过 `capacity` → WARN
335
- 12. epic 没有 `keyResults` → WARN(史诗要有量化目标)
336
- 13. `cancelled` 是终态:不要求验收、不要求 task 全部 `done`;但仍标着 `blocked` 报错;还留在某个 sprint 里只给 WARN —— 它的点数不计入承诺容量,看板的燃尽图与里程碑完成度同样把它扣掉
1
+ # 敏捷数据 Schema(v3 · 三常驻 + 三可选)
2
+
3
+ `agile/` 下**三个常驻数据文件 + 三个可选文件**(测试资产、交付说明、架构图例),全部 UTF-8 JSON、2 空格缩进、末尾换行。
4
+
5
+ | 文件 | 装什么 |
6
+ |---|---|
7
+ | `agile/backlog.json` | 史诗 epics(含量化目标 keyResults)+ 用户故事 stories(内联 tasks) |
8
+ | `agile/sprints.json` | 迭代 sprints + 里程碑 milestones(MVP 节点是里程碑的一种) |
9
+ | `agile/journal.json` | TDD 实施日志 journals(一个 task 一条,内联 entries) |
10
+ | `agile/tests.json` | 测试资产:suites(层 × 级别 → cases)+ runs(执行记录与代码覆盖率),见第 5 节 |
11
+ | `agile/last-change.json` | 最近一次交付的汇报(可选;已提交才覆盖,未提交则合并,见第 4 节) |
12
+ | `agile/diagrams.json` | 架构图例索引(可选;产物 HTML 在 `agile/diagrams/` 下),见第 6 节 |
13
+
14
+ > 所有数据文件都必须带 `"schemaVersion": 3`(含可选的 `tests.json` / `last-change.json` / `diagrams.json`)。v2 及更早的散文件结构不再兼容,校验器发现 `agile/backlog/epics/`、`agile/backlog/stories/`、`agile/sprints/`、`agile/journal/` 里还有 JSON 会直接报错。
15
+
16
+ ## 1. backlog.json
17
+
18
+ ```json
19
+ {
20
+ "schemaVersion": 3,
21
+ "epics": [
22
+ {
23
+ "id": "E-001",
24
+ "title": "用户认证与工作空间",
25
+ "goal": "一句话说明这个史诗完成后用户获得了什么",
26
+ "status": "draft | active | done | cancelled",
27
+ "keyResults": [
28
+ { "id": "E-001-KR1", "text": "新成员从收到邀请到能登录用时", "unit": "分钟", "target": 2, "current": 1.5 }
29
+ ],
30
+ "stories": ["S-001", "S-002"],
31
+ "created": "2026-08-24"
32
+ }
33
+ ],
34
+ "stories": [
35
+ {
36
+ "id": "S-001",
37
+ "epicId": "E-001",
38
+ "title": "邮箱密码登录",
39
+ "narrative": "作为<角色>,我想要<能力>,以便<价值>",
40
+ "type": "feature | bug | debt | spike",
41
+ "priority": "P0 | P1 | P2 | P3",
42
+ "value": 13,
43
+ "bug": {
44
+ "severity": "blocker | major | minor | trivial",
45
+ "environment": "Chrome 120 / Windows 11,看板页四列布局",
46
+ "steps": "1. …;2. …;3. …"
47
+ },
48
+ "acceptance": [
49
+ { "given": "已注册用户", "when": "输入正确邮箱密码提交", "then": "下发会话 cookie 并跳转首页", "verifyBy": ["S-001-T1"] }
50
+ ],
51
+ "points": 5,
52
+ "status": "draft | ready | in-progress | review | done | cancelled",
53
+ "sprintId": "R1-S1",
54
+ "created": "2026-08-24",
55
+ "schedule": { "start": "2026-08-31", "end": "2026-09-08" },
56
+ "dependsOn": ["S-004"],
57
+ "blocked": { "reason": "等产品确认是否要留审计日志", "since": "2026-10-21" },
58
+ "scopeChange": { "kind": "added-mid-sprint | split | expanded", "at": "2026-10-15", "reason": "客户临时插需求" },
59
+ "tasks": [
60
+ {
61
+ "id": "S-001-T1",
62
+ "title": "为登录接口写失败测试",
63
+ "type": "test | impl | refactor | chore",
64
+ "status": "todo | red | green | refactored | done",
65
+ "files": ["tests/auth/login.spec.ts"]
66
+ }
67
+ ]
68
+ }
69
+ ]
70
+ }
71
+ ```
72
+
73
+ 字段说明:
74
+
75
+ - **`type`**:`feature` 功能 / `bug` 缺陷 / `debt` 技术债 / `spike` 调研。`bug` 必须同时给 `bug` 详情三件套(severity / environment / steps),否则校验报错。
76
+ - **`priority`**:P0 最高。数组顺序即 backlog 排序(rank),看板可再按优先级或 WSJF 重排。
77
+ - **`value` + `points`** → WSJF = value / points,用来决定「先做谁」;点数仍是成本口径,两者别混。
78
+ - **`acceptance[].verifyBy`**:这条验收由哪个 task 的测试覆盖(task id)。非 `draft` 状态没写只给 WARN,但它是「验收不是口号」的唯一凭据,建议必填。
79
+ - **`dependsOn`**:故事级依赖,必须存在、不能自依赖、**不能成环**(校验器做 DFS 检测)。
80
+ - **`blocked`**:当前阻塞的事实(原因 + 起始日期)。已 `done` 的故事不许带 `blocked`;处于迭代里还被阻塞会 WARN(站会必须处理)。
81
+ - **`scopeChange`**:范围变更标记。`added-mid-sprint` 迭代中途插入、`split` 拆分产生、`expanded` 范围扩大。有了它,燃尽图上那段平台期才不会被误读成「拖延」。
82
+ - **`schedule`** 可选,只给甘特图用(计划区间);实际区间由 `journal.json` 的记录日期推出来,不用手填。
83
+ - task 的 `id` 必须是 `<storyId>-T<n>`;日志集中在 `journal.json`,用 `taskId` 关联。
84
+
85
+ ## 2. sprints.json
86
+
87
+ ```json
88
+ {
89
+ "schemaVersion": 3,
90
+ "sprints": [
91
+ {
92
+ "id": "R1-S1",
93
+ "name": "第 1 个迭代(登录与邀请)",
94
+ "goal": "本迭代要交付什么",
95
+ "start": "2026-08-31",
96
+ "end": "2026-09-13",
97
+ "stories": ["S-001", "S-002"],
98
+ "capacity": 12
99
+ }
100
+ ],
101
+ "milestones": [
102
+ {
103
+ "id": "M-001",
104
+ "title": "MVP · 内测可登录",
105
+ "kind": "mvp | release | checkpoint",
106
+ "due": "2026-09-13",
107
+ "status": "planned | at-risk | reached | missed",
108
+ "sprintId": "R1-S1",
109
+ "criteria": "达成口径:怎样算这个节点到了",
110
+ "stories": ["S-001", "S-002"]
111
+ }
112
+ ]
113
+ }
114
+ ```
115
+
116
+ - **MVP 节点就是 `kind: "mvp"` 的里程碑**,不另设实体。
117
+ - `status: "reached"` 时挂的故事必须全部 `done/cancelled`,否则校验报错。
118
+ - `due` 早于今天但状态仍是 `planned` → WARN。
119
+
120
+ ### 迭代编号规则(`sprints[].id`)
121
+
122
+ 格式:`R<发布周期>-S<期内冲刺号>`,例如 `R1-S1`、`R1-S2`、`R2-S1`。
123
+
124
+ - **`S<期内冲刺号>`** 是 Sprint 本体 —— Scrum 里的 Sprint(冲刺/迭代)就是它,在一个发布周期内从 1 开始连号、不跳号。
125
+ - **`R<发布周期>`** 是引用Release(发布周期/版本)这一层的分组:若干个冲刺归到一个发布窗口,和 `milestones`(尤其 `kind: "release"`)对齐。当前约定**一个发布周期 = 4 周 = 2 个两周冲刺**。
126
+ 它不是 Scrum 术语(Scrum 只有 Sprint),业界最接近的是 Release 或 SAFe 的 PI(Program Increment,通常 8~12 周、含 4 个开发冲刺 + 1 个 IP 冲刺)。**既然叫 Release 就按 4 周一个周期排,别套 PI 的节奏。**
127
+ - 周期号按时间递增(`R1`、`R2`…,不带前导零);同一周期内冲刺号不得重复;**一个周期建议不超过 2 个冲刺**。
128
+ - 小团队不需要发布周期这一层时,可以只用 `S-01`、`S-02` 纯序号(整段省略 `R` 前缀),但**同一个项目里不许两种风格混用**。
129
+ - **id 被 `story.sprintId`、`milestones[].sprintId` 引用,定了就别改**;确需重命名时两处引用同步改,改完跑 `validate`(引用完整性会兜住漏改)。
130
+
131
+ 以上规则由 `tools/validate.mjs` 强制:id 必须匹配 `R<n>-S<n>` 或 `S-<n>`、不许混用风格、同一周期内冲刺号必须从 1 连续、周期号与起始日期顺序要一致(后两条分别报错与警告)。
132
+
133
+ ## 3. journal.json
134
+
135
+ ```json
136
+ {
137
+ "schemaVersion": 3,
138
+ "journals": [
139
+ {
140
+ "taskId": "S-001-T1",
141
+ "storyId": "S-001",
142
+ "entries": [
143
+ {
144
+ "phase": "red | green | refactor",
145
+ "date": "2026-08-31",
146
+ "note": "这一步做了什么、为什么",
147
+ "files": ["tests/auth/login.spec.ts"],
148
+ "testCommand": "pnpm test auth/login",
149
+ "result": "fail: 3 failed, 0 passed — 404 Not Found"
150
+ }
151
+ ]
152
+ }
153
+ ]
154
+ }
155
+ ```
156
+
157
+ ## 4. last-change.json(最后更新 / 交付说明)
158
+
159
+ `agile/last-change.json` 是**可选**文件:还没交付过东西时不存在,校验器不报错。看板 `/last-change` 页读的就是它。
160
+
161
+ ### 写之前先查 git:已提交才覆盖,未提交就合并
162
+
163
+ 只留最近一次交付的前提是**上一次已经进了版本库**。文件如果还有没提交的改动,直接覆盖就把那次记录冲掉了,所以写入策略分两种:
164
+
165
+ | 文件在 git 里的状态 | 写法 | 结果 |
166
+ |---|---|---|
167
+ | 已提交、工作区干净 | 整份覆盖 | 文件里只有本次交付 |
168
+ | 有未提交改动 / 已暂存未提交 / 未跟踪 / 不是 git 仓库 | 合并 | 本次结果并进旧记录,旧的一条不丢 |
169
+
170
+ 用工具判断并写入,不要手写覆盖:
171
+
172
+ ```bash
173
+ node tools/last-change.mjs check # 退出码 0 = 可覆盖,2 = 必须先合并
174
+ node tools/last-change.mjs write <记录.json> # 按状态自动覆盖或合并,写后校验,失败回滚
175
+ node tools/last-change.mjs write <记录.json> --replace # 确认旧记录不要了才强制覆盖
176
+ ```
177
+
178
+ 合并的取舍(`write` 自动完成,手动合并也要照这个来):
179
+
180
+ - `changes` 按 `kind:id`、`scenarios` 按 `id`(没有就按 `title`)去重:**新的覆盖旧的**,没被提到的旧条目原样保留,顺序按「旧的在前、新增的追加」;
181
+ - `extras` 按 `title`、`verification` 按 `what`、`preparation` 按 `step` 去重,规则同上;
182
+ - `notes` / `open` 字符串去重后拼接;`access.urls` 按 `url`、`access.accounts` 按 `username` 合并;
183
+ - `title` / `at` / `summary` 取本次的(缺了才沿用旧的);
184
+ - 合并后自动带上 `"merged": true` 与 `"mergedFrom"`(被并进来的那几次交付),看板据此标「合并记录」。
185
+
186
+ ```json
187
+ {
188
+ "schemaVersion": 3,
189
+ "lastChange": {
190
+ "title": "登录接口收尾",
191
+ "at": "2026-10-27 14:35:12",
192
+ "summary": "一句话说清这次交付做成了什么",
193
+ "changes": [
194
+ {
195
+ "kind": "story",
196
+ "id": "S-001",
197
+ "title": "邮箱密码登录",
198
+ "action": "added | updated | removed",
199
+ "from": "in-progress",
200
+ "to": "review",
201
+ "note": "变更内容:补了两条验收、状态推进到评审",
202
+ "files": ["agile/backlog.json", "src/auth/login.ts"]
203
+ }
204
+ ],
205
+ "extras": [{ "title": "顺手把校验错误信息改成中文", "detail": "为什么做、做到什么程度", "files": ["tools/validate.mjs"] }],
206
+ "verification": [{ "what": "pnpm test", "result": "pass | fail | partial | skipped", "detail": "32 passed" }],
207
+ "access": {
208
+ "urls": [{ "label": "看板", "url": "http://localhost:4173", "note": "先起 serve" }],
209
+ "accounts": [{ "role": "管理员", "username": "admin@example.com", "password": "Passw0rd!", "note": "仅本地环境" }]
210
+ },
211
+ "preparation": [{ "step": "装依赖", "command": "pnpm install", "note": "Node ≥ 18" }],
212
+ "scenarios": [
213
+ {
214
+ "id": "TC-01",
215
+ "title": "正确密码能登录",
216
+ "storyIds": ["S-001"],
217
+ "steps": ["打开 /login", "填表提交"],
218
+ "expect": "跳转首页并下发会话 cookie",
219
+ "acceptance": "对应验收第 1 条"
220
+ }
221
+ ],
222
+ "merged": true,
223
+ "mergedFrom": [{ "title": "上一次还没提交的交付", "at": "2026-10-26 18:02:41" }],
224
+ "notes": ["使用说明、口径解释"],
225
+ "open": ["还没做的、已知限制"]
226
+ }
227
+ }
228
+ ```
229
+
230
+ 字段说明:
231
+
232
+ - **`title` / `at` 必填**:`at` 是本次交付时间,**写到秒**:`YYYY-MM-DD HH:mm:ss`(ISO 的 `T` 分隔也认)。只写 `YYYY-MM-DD` 仍然合法,但校验器会给 WARN、看板上也只能看到「哪天」,看不出「几点几分交付的」。`node tools/last-change.mjs write` 发现缺 `at` 会自动补当前时间。
233
+ - **`merged` / `mergedFrom` 由工具写,不要手填**:只有「并进未提交旧记录」时才出现,`mergedFrom` 每条要有 `title`(`at` 可选)。`merged: true` 却没有 `mergedFrom` 会被校验器提醒。
234
+ - **`changes[]`**:故事与任务的变更清单,看板表格一行一条。`kind` 只认 `story` / `task`,`id` 必须是 backlg 里真实存在的 id;`action` 是 `added`(新增)/ `updated`(状态或内容变更)/ `removed`(删除);状态变更填 `from` → `to`,`files` 是这次动过的文件。
235
+ - **其余分区都可选**,没有就省略,**不许为了填满而编**:项目没有账号体系就不写 `accounts`,没有前端入口就不写 `urls`。
236
+ - `verification[].result` 与 `scenarios[].expect` 是「验收不是口号」的凭据:场景必须写清步骤与验收标准,验证结果只认 `pass/fail/partial/skipped`。
237
+ - 校验器会查:`schemaVersion`、`at` 格式、`kind`/`action`/`result` 枚举、`changes[].id` 是否真实存在、`scenarios[].steps` 与 `expect` 是否齐备、`access.urls[].url` 是否为 `http(s)` 完整地址。缺 `title`、`what`、`expect`、`step` 报错;缺 `changes[].title`、场景 id、url label 只给 WARN。
238
+
239
+ ## 5. tests.json(测试资产与覆盖率)
240
+
241
+ `agile/tests.json` 是**可选**文件:不存在时校验器不报错、看板 `/tests` 页显示空状态。它由 Coding Agent 在**每个 task 推到 `done`、story 送进 `review` 之前**维护(见 `scrum-tdd` 的交工汇报第 1 步),不是事后补的报表。
242
+
243
+ ```json
244
+ {
245
+ "schemaVersion": 3,
246
+ "suites": [
247
+ {
248
+ "id": "TS-BE-01",
249
+ "name": "登录接口",
250
+ "layer": "frontend | backend | e2e",
251
+ "level": "unit | integration | e2e",
252
+ "runner": "vitest",
253
+ "files": ["tests/auth/login.spec.ts"],
254
+ "cases": [
255
+ {
256
+ "id": "TC-BE-001",
257
+ "title": "正确密码登录返回 200 并下发 httpOnly cookie",
258
+ "automated": true,
259
+ "taskId": "S-001-T1",
260
+ "covers": ["S-001-A1"],
261
+ "expect": "200;set-cookie 含 sid;HttpOnly",
262
+ "code": "tests/auth/login.spec.ts::正确密码登录",
263
+ "status": "pass | fail | skipped | blocked | not-run",
264
+ "lastRun": "2026-10-29",
265
+ "durationMs": 42,
266
+ "note": "失败原因写在这里"
267
+ }
268
+ ]
269
+ }
270
+ ],
271
+ "runs": [
272
+ {
273
+ "id": "RUN-20261029-2110",
274
+ "at": "2026-10-29 21:10:00",
275
+ "env": "local",
276
+ "command": "pnpm test",
277
+ "totals": { "total": 159, "pass": 158, "fail": 1, "skipped": 0, "durationMs": 24300 },
278
+ "failedCases": ["TC-BE-001"],
279
+ "coverage": {
280
+ "frontend": { "tool": "vitest", "lines": 72.4, "branches": 61.5, "functions": 66.0, "report": "coverage/frontend/lcov.info" },
281
+ "backend": { "tool": "vitest", "lines": 84.1, "branches": 70.2, "functions": 80.5, "report": "coverage/backend/lcov.info" }
282
+ }
283
+ }
284
+ ]
285
+ }
286
+ ```
287
+
288
+ 字段说明:
289
+
290
+ - **`suites[]`** 按模块 / 测试文件分组,承载**两个正交维度**:`layer`(`frontend` / `backend` / `e2e`,QA 主视图的三条泳道)与 `level`(`unit` / `integration` / `e2e`)。`files` 只用于定位,可省。
291
+ - **`cases[]`** 一条用例 = 一次能判定成败的验证:
292
+ - `automated` 区分自动化 / 手工;**手工用例也要登记**,`steps` 一步一条,这是交接给 QA 的正文;
293
+ - `covers` 是覆盖的验收,写法 `S-001-A1`(故事 id + 第几条验收,**1 基**);改验收顺序要同步改它,一条 E2E 用例可以覆盖多个故事;
294
+ - `expect` 必填(只有标题的用例不算交付物);`taskId` 指向产出它的 TDD 任务(可省);`code` 是自动化用例的定位串 `文件::用例名`,导入器靠它回写状态;
295
+ - `status` 只认 `pass / fail / skipped / blocked / not-run`;`not-run` 不要求 `lastRun`,其余必须写。
296
+ - **`runs[]`** 每次执行一条,**按时间正序**(最后一条 = 最近一次):`at` 到秒、`command`、`env`、`totals`、`failedCases`,有覆盖率报告就填 `coverage`。
297
+ - `coverage` 按层给 `lines / branches / functions / statements` 与 `tool`:**前端、后端各报各的,绝不做加权平均**,E2E 一般不报行覆盖。
298
+
299
+ 覆盖率的三个口径(页面按这个算,禁止合成一个「覆盖率」):
300
+
301
+ | 口径 | 分母 | 分子 |
302
+ |---|---|---|
303
+ | 需求覆盖 | 非 `draft` / `cancelled` 故事的验收条数 | 被至少一条用例 `covers` 命中的条数;其中最近一次 `pass` 的另算「验证通过」 |
304
+ | 用例通过率 | 最近一次执行的 `total - skipped` | `pass` |
305
+ | 代码覆盖 | 测试工具报告 | `lines` / `branches`,前端、后端分开 |
306
+
307
+ 校验器强制:枚举合法;用例 / 套件 id 与其它记录共用一个命名空间;`covers` 指向的验收必须存在且序号不越界;`taskId` 必须存在且属于 `covers` 里的故事;`runs` 时间正序;`通过+失败+跳过 ≤ 总数`;最新一次 `failedCases` 必须对应 `status: fail`;覆盖率在 0~100 之间。
308
+
309
+ 收口纪律(**只查登记过用例的故事**,避免老项目一升级就满屏报错):
310
+
311
+ - 该 story 下每个 `done` 的 `type: test` task 至少一条用例 → 否则**报错**;
312
+ - story 到 `review` / `done` 时每条验收都被覆盖 → 否则**报错**(未到 review 只给 WARN);
313
+ - 用例 `lastRun` 早于 task 最后一次 `pass` → WARN(结果过期了);
314
+ - 最近一次执行条数多于已登记用例 → WARN(还有测试没登记)。
315
+
316
+ ## 6. diagrams.json(架构图例)
317
+
318
+ `agile/diagrams.json` 是**可选**文件:不存在时校验器不报错、看板 `/diagrams` 页显示空状态。
319
+
320
+ 它是**索引**,不是图本身:产物是一份自包含 HTML(内联 SVG),放在 `agile/diagrams/` 下。分开存是硬要求——一张图动辄几十 KB,塞进 JSON 会让 `/api/agile` 的快照变大好几倍,而且没法单独打开、单独 diff。
321
+
322
+ ```json
323
+ {
324
+ "schemaVersion": 3,
325
+ "diagrams": [
326
+ {
327
+ "id": "DG-001",
328
+ "title": "登录时序",
329
+ "kind": "sequence",
330
+ "catalog": "sequence",
331
+ "storyIds": ["S-001"],
332
+ "taskId": "S-001-T2",
333
+ "summary": "浏览器 → 网关 → 认证服务 → Redis:会话建立、刷新与登出",
334
+ "file": "agile/diagrams/DG-001.html",
335
+ "svg": "agile/diagrams/DG-001.svg",
336
+ "aspect": "16:9",
337
+ "source": "diagram-design",
338
+ "lint": "pass",
339
+ "createdAt": "2026-10-31",
340
+ "updatedAt": "2026-10-31",
341
+ "supersedes": null
342
+ }
343
+ ]
344
+ }
345
+ ```
346
+
347
+ 字段说明:
348
+
349
+ - **`kind`** 是我们自己的筛选维度,只认 7 类:`architecture`(架构)/ `sequence`(时序)/ `flow`(流程)/ `erd`(ER 关系)/ `state`(状态)/ `deploy`(部署)/ `other`。
350
+ - **`catalog`** 存 diagram-design 的原始图型名(如 `sequence`、`high-level`、`sankey`)。上游图型会从 42 种涨到 45 种、还会继续涨,所以这里**不做枚举校验**,写字符串即可。
351
+ - **`storyIds`** 指向这张图服务的需求,可多挂(跨故事的端到端图很常见)。**单向引用**:故事那边不写 `diagrams` 字段,反向列表由页面派生。
352
+ - **`taskId`** 可选,指向产出它的 TDD 任务;填了就必须属于 `storyIds` 里的故事。
353
+ - **`file` / `svg`** 必须是 `agile/diagrams/` 下的**相对路径**,不许绝对路径、不许 `..`;`file` 必须真实存在。
354
+ - **`lint`**:`pass`(过质检)/ `skipped`(明确 `--no-lint` 跳过)。图例入库走 `node tools/diagram.mjs add`,它会先跑 `node tools/diagram-lint.mjs` 再登记,不要手改 JSON。
355
+ - **`supersedes`**:指向被本图取代的旧版,用来保留演进痕迹;不许自引用、不许成环。
356
+
357
+ 校验器强制:`schemaVersion`、id 形如 `DG-001` 且全局唯一、`title` / `kind` / `file` / 日期齐备、`file` 路径合法且存在、`storyIds` 与 `taskId` 引用真实存在且互相一致、`supersedes` 可解析且无环。
358
+
359
+ 校验器提醒(WARN):`agile/diagrams/*.html` 存在但索引里没有(孤儿文件);`updatedAt` 早于所挂故事最后一次 `pass` 的日志日期(图可能画的是改之前的版本)。
360
+
361
+ 收口纪律:改动涉及**模块边界 / 鉴权 / 支付 / 数据模型 / 外部集成**时,交工前用内置的 `diagram-design` skill 出图或重画,再 `node tools/diagram.mjs add` 登记;纯样式、文案、测试改动不需要画。
362
+
363
+ ## 状态机(校验器强制)
364
+
365
+ - story: `draft → ready → in-progress → review → done`;不做了直接进 `cancelled`(已取消)终态(可回退,不可跳级;`done` 与 `cancelled` 都是终态)
366
+ - task: `todo → red → green → refactored → done`(只能前进;test 型可 `todo → green`)
367
+ - epic: 无强制流转,但 `done` 要求其下所有 story 均 `done/cancelled`
368
+ - milestone: `planned → at-risk → reached / missed`
369
+
370
+ ## 硬约束(校验器强制 / 警告)
371
+
372
+ 1. ID 全局唯一(epic / story / task / sprint / milestone / suite / case 共用命名空间),task 命名 `<storyId>-T<n>`
373
+ 2. **双向引用一致**:`epic.stories` ↔ `story.epicId`、`sprint.stories` ↔ `story.sprintId`、`journal.taskId` ↔ task
374
+ 3. `ready` / `in-progress` / `review` / `done` 必须有验收标准;进 sprint 的故事必须有验收标准(`cancelled` 两样都不要求)
375
+ 4. 验收标准的 `verifyBy` 必须指向**同一 story 的** task
376
+ 5. task 到 `green/refactored/done` 时,journal 必须存在且首条 `red` 的 result 以 `fail` 开头、`green` 以 `pass` 开头
377
+ 6. task 为 `done` 时,journal 末条 entry 的 `result` 必须 `pass`
378
+ 7. story 为 `done` 时,其所有 task 必须 `done`,且不许仍标着 `blocked`
379
+ 8. 同时只能有一个活跃 sprint(`start ≤ 今天 ≤ end`)
380
+ 9. `dependsOn` 必须存在、不能自依赖、不能成环
381
+ 10. `schedule.start ≤ schedule.end`;计划区间超出所属迭代只给 WARN
382
+ 11. sprint 承诺点数超过 `capacity` → WARN
383
+ 12. epic 没有 `keyResults` → WARN(史诗要有量化目标)
384
+ 13. `cancelled` 是终态:不要求验收、不要求 task 全部 `done`;但仍标着 `blocked` 报错;还留在某个 sprint 里只给 WARN —— 它的点数不计入承诺容量,看板的燃尽图与里程碑完成度同样把它扣掉