mustflow 1.18.16 → 1.31.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 (314) hide show
  1. package/README.md +28 -8
  2. package/dist/cli/commands/adapters.js +90 -0
  3. package/dist/cli/commands/classify.js +3 -4
  4. package/dist/cli/commands/contract-lint.js +26 -6
  5. package/dist/cli/commands/dashboard.js +103 -4
  6. package/dist/cli/commands/explain-verify.js +213 -0
  7. package/dist/cli/commands/explain.js +48 -4
  8. package/dist/cli/commands/handoff.js +136 -0
  9. package/dist/cli/commands/run.js +302 -168
  10. package/dist/cli/commands/update.js +91 -61
  11. package/dist/cli/commands/upgrade.js +65 -0
  12. package/dist/cli/commands/verify.js +304 -139
  13. package/dist/cli/i18n/en.js +77 -4
  14. package/dist/cli/i18n/es.js +77 -4
  15. package/dist/cli/i18n/fr.js +77 -4
  16. package/dist/cli/i18n/hi.js +77 -4
  17. package/dist/cli/i18n/ko.js +77 -4
  18. package/dist/cli/i18n/zh.js +77 -4
  19. package/dist/cli/index.js +34 -42
  20. package/dist/cli/lib/command-registry.js +15 -0
  21. package/dist/cli/lib/dashboard-export.js +775 -0
  22. package/dist/cli/lib/dashboard-html.js +1 -1
  23. package/dist/cli/lib/local-index.js +33 -14
  24. package/dist/cli/lib/reporter.js +6 -0
  25. package/dist/cli/lib/run-plan.js +239 -0
  26. package/dist/cli/lib/templates.js +18 -3
  27. package/dist/cli/lib/update-diff-preview.js +163 -0
  28. package/dist/cli/lib/validation.js +132 -1
  29. package/dist/core/adapter-compatibility.js +235 -0
  30. package/dist/core/bounded-output.js +38 -0
  31. package/dist/core/change-classification.js +14 -1
  32. package/dist/core/change-verification.js +246 -5
  33. package/dist/core/check-issues.js +10 -0
  34. package/dist/core/command-contract-validation.js +34 -0
  35. package/dist/core/command-cwd.js +18 -6
  36. package/dist/core/command-effects.js +13 -0
  37. package/dist/core/command-env.js +91 -0
  38. package/dist/core/contract-lint.js +260 -4
  39. package/dist/core/contract-models.js +172 -0
  40. package/dist/core/dashboard-verification.js +10 -0
  41. package/dist/core/doc-review-triage.js +1 -0
  42. package/dist/core/handoff-record.js +376 -0
  43. package/dist/core/public-json-contracts.js +23 -0
  44. package/dist/core/run-performance-history.js +307 -0
  45. package/dist/core/run-profile.js +87 -0
  46. package/dist/core/run-receipt.js +217 -11
  47. package/dist/core/run-write-drift.js +196 -0
  48. package/dist/core/secret-redaction.js +39 -0
  49. package/dist/core/skill-route-alignment.js +90 -0
  50. package/dist/core/source-anchors.js +3 -5
  51. package/dist/core/test-selection.js +224 -0
  52. package/dist/core/verification-decision-graph.js +290 -0
  53. package/dist/core/verification-scheduler.js +96 -2
  54. package/package.json +3 -1
  55. package/schemas/README.md +15 -4
  56. package/schemas/adapter-compatibility-report.schema.json +184 -0
  57. package/schemas/change-verification-report.schema.json +286 -4
  58. package/schemas/commands.schema.json +55 -2
  59. package/schemas/contract-lint-report.schema.json +99 -0
  60. package/schemas/dashboard-export.schema.json +273 -0
  61. package/schemas/explain-report.schema.json +267 -2
  62. package/schemas/handoff-validation-report.schema.json +68 -0
  63. package/schemas/run-receipt.schema.json +183 -1
  64. package/templates/default/common/.mustflow/config/commands.toml +3 -1
  65. package/templates/default/i18n.toml +78 -234
  66. package/templates/default/locales/en/.mustflow/skills/INDEX.md +7 -3
  67. package/templates/default/locales/en/.mustflow/skills/architecture-deepening-review/SKILL.md +154 -0
  68. package/templates/default/locales/en/.mustflow/skills/behavior-preserving-refactor/SKILL.md +8 -3
  69. package/templates/default/locales/en/.mustflow/skills/code-review/SKILL.md +9 -4
  70. package/templates/default/locales/en/.mustflow/skills/date-number-audit/SKILL.md +19 -4
  71. package/templates/default/locales/en/.mustflow/skills/diff-risk-review/SKILL.md +4 -2
  72. package/templates/default/locales/en/.mustflow/skills/external-skill-intake/SKILL.md +141 -0
  73. package/templates/default/locales/en/.mustflow/skills/release-notes-authoring/SKILL.md +143 -0
  74. package/templates/default/locales/en/.mustflow/skills/repro-first-debug/SKILL.md +22 -8
  75. package/templates/default/locales/en/.mustflow/skills/skill-authoring/SKILL.md +3 -3
  76. package/templates/default/locales/en/.mustflow/skills/source-freshness-check/SKILL.md +22 -9
  77. package/templates/default/locales/en/.mustflow/skills/ui-quality-gate/SKILL.md +21 -13
  78. package/templates/default/locales/en/.mustflow/skills/vertical-slice-tdd/SKILL.md +167 -0
  79. package/templates/default/manifest.toml +16 -1
  80. package/templates/default/locales/es/.mustflow/skills/INDEX.md +0 -75
  81. package/templates/default/locales/es/.mustflow/skills/adapter-boundary/SKILL.md +0 -193
  82. package/templates/default/locales/es/.mustflow/skills/artifact-integrity-check/SKILL.md +0 -114
  83. package/templates/default/locales/es/.mustflow/skills/behavior-preserving-refactor/SKILL.md +0 -182
  84. package/templates/default/locales/es/.mustflow/skills/code-review/SKILL.md +0 -115
  85. package/templates/default/locales/es/.mustflow/skills/codebase-orientation/SKILL.md +0 -115
  86. package/templates/default/locales/es/.mustflow/skills/command-pattern/SKILL.md +0 -247
  87. package/templates/default/locales/es/.mustflow/skills/composition-over-inheritance/SKILL.md +0 -176
  88. package/templates/default/locales/es/.mustflow/skills/contract-sync-check/SKILL.md +0 -116
  89. package/templates/default/locales/es/.mustflow/skills/database-change-safety/SKILL.md +0 -155
  90. package/templates/default/locales/es/.mustflow/skills/date-number-audit/SKILL.md +0 -116
  91. package/templates/default/locales/es/.mustflow/skills/dependency-injection/SKILL.md +0 -161
  92. package/templates/default/locales/es/.mustflow/skills/dependency-reality-check/SKILL.md +0 -115
  93. package/templates/default/locales/es/.mustflow/skills/diff-risk-review/SKILL.md +0 -136
  94. package/templates/default/locales/es/.mustflow/skills/docs-prose-review/SKILL.md +0 -119
  95. package/templates/default/locales/es/.mustflow/skills/docs-update/SKILL.md +0 -97
  96. package/templates/default/locales/es/.mustflow/skills/external-prompt-injection-defense/SKILL.md +0 -116
  97. package/templates/default/locales/es/.mustflow/skills/facade-pattern/SKILL.md +0 -210
  98. package/templates/default/locales/es/.mustflow/skills/failure-triage/SKILL.md +0 -97
  99. package/templates/default/locales/es/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +0 -118
  100. package/templates/default/locales/es/.mustflow/skills/line-ending-hygiene/SKILL.md +0 -111
  101. package/templates/default/locales/es/.mustflow/skills/migration-safety-check/SKILL.md +0 -117
  102. package/templates/default/locales/es/.mustflow/skills/multi-agent-work-coordination/SKILL.md +0 -260
  103. package/templates/default/locales/es/.mustflow/skills/null-object-pattern/SKILL.md +0 -196
  104. package/templates/default/locales/es/.mustflow/skills/pattern-scout/SKILL.md +0 -110
  105. package/templates/default/locales/es/.mustflow/skills/performance-budget-check/SKILL.md +0 -121
  106. package/templates/default/locales/es/.mustflow/skills/project-context-authoring/SKILL.md +0 -107
  107. package/templates/default/locales/es/.mustflow/skills/pure-core-imperative-shell/SKILL.md +0 -212
  108. package/templates/default/locales/es/.mustflow/skills/readme-authoring/SKILL.md +0 -115
  109. package/templates/default/locales/es/.mustflow/skills/repo-improvement-loop/SKILL.md +0 -150
  110. package/templates/default/locales/es/.mustflow/skills/repro-first-debug/SKILL.md +0 -112
  111. package/templates/default/locales/es/.mustflow/skills/requirement-regression-guard/SKILL.md +0 -152
  112. package/templates/default/locales/es/.mustflow/skills/result-option/SKILL.md +0 -186
  113. package/templates/default/locales/es/.mustflow/skills/security-privacy-review/SKILL.md +0 -116
  114. package/templates/default/locales/es/.mustflow/skills/security-regression-tests/SKILL.md +0 -131
  115. package/templates/default/locales/es/.mustflow/skills/skill-authoring/SKILL.md +0 -110
  116. package/templates/default/locales/es/.mustflow/skills/source-freshness-check/SKILL.md +0 -111
  117. package/templates/default/locales/es/.mustflow/skills/state-machine-pattern/SKILL.md +0 -214
  118. package/templates/default/locales/es/.mustflow/skills/strategy-pattern/SKILL.md +0 -215
  119. package/templates/default/locales/es/.mustflow/skills/structure-discovery-gate/SKILL.md +0 -159
  120. package/templates/default/locales/es/.mustflow/skills/test-design-guard/SKILL.md +0 -162
  121. package/templates/default/locales/es/.mustflow/skills/test-maintenance/SKILL.md +0 -122
  122. package/templates/default/locales/es/.mustflow/skills/ui-quality-gate/SKILL.md +0 -117
  123. package/templates/default/locales/es/.mustflow/skills/visual-review-artifact/SKILL.md +0 -127
  124. package/templates/default/locales/es/.mustflow/skills/visual-review-artifact/assets/review-template.html +0 -286
  125. package/templates/default/locales/es/.mustflow/skills/visual-review-artifact/resources.toml +0 -7
  126. package/templates/default/locales/es/.mustflow/skills/web-asset-optimization/SKILL.md +0 -108
  127. package/templates/default/locales/fr/.mustflow/skills/INDEX.md +0 -75
  128. package/templates/default/locales/fr/.mustflow/skills/adapter-boundary/SKILL.md +0 -193
  129. package/templates/default/locales/fr/.mustflow/skills/artifact-integrity-check/SKILL.md +0 -114
  130. package/templates/default/locales/fr/.mustflow/skills/behavior-preserving-refactor/SKILL.md +0 -182
  131. package/templates/default/locales/fr/.mustflow/skills/code-review/SKILL.md +0 -115
  132. package/templates/default/locales/fr/.mustflow/skills/codebase-orientation/SKILL.md +0 -115
  133. package/templates/default/locales/fr/.mustflow/skills/command-pattern/SKILL.md +0 -247
  134. package/templates/default/locales/fr/.mustflow/skills/composition-over-inheritance/SKILL.md +0 -176
  135. package/templates/default/locales/fr/.mustflow/skills/contract-sync-check/SKILL.md +0 -116
  136. package/templates/default/locales/fr/.mustflow/skills/database-change-safety/SKILL.md +0 -155
  137. package/templates/default/locales/fr/.mustflow/skills/date-number-audit/SKILL.md +0 -116
  138. package/templates/default/locales/fr/.mustflow/skills/dependency-injection/SKILL.md +0 -161
  139. package/templates/default/locales/fr/.mustflow/skills/dependency-reality-check/SKILL.md +0 -115
  140. package/templates/default/locales/fr/.mustflow/skills/diff-risk-review/SKILL.md +0 -136
  141. package/templates/default/locales/fr/.mustflow/skills/docs-prose-review/SKILL.md +0 -119
  142. package/templates/default/locales/fr/.mustflow/skills/docs-update/SKILL.md +0 -97
  143. package/templates/default/locales/fr/.mustflow/skills/external-prompt-injection-defense/SKILL.md +0 -116
  144. package/templates/default/locales/fr/.mustflow/skills/facade-pattern/SKILL.md +0 -210
  145. package/templates/default/locales/fr/.mustflow/skills/failure-triage/SKILL.md +0 -97
  146. package/templates/default/locales/fr/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +0 -118
  147. package/templates/default/locales/fr/.mustflow/skills/line-ending-hygiene/SKILL.md +0 -111
  148. package/templates/default/locales/fr/.mustflow/skills/migration-safety-check/SKILL.md +0 -117
  149. package/templates/default/locales/fr/.mustflow/skills/multi-agent-work-coordination/SKILL.md +0 -260
  150. package/templates/default/locales/fr/.mustflow/skills/null-object-pattern/SKILL.md +0 -196
  151. package/templates/default/locales/fr/.mustflow/skills/pattern-scout/SKILL.md +0 -110
  152. package/templates/default/locales/fr/.mustflow/skills/performance-budget-check/SKILL.md +0 -121
  153. package/templates/default/locales/fr/.mustflow/skills/project-context-authoring/SKILL.md +0 -107
  154. package/templates/default/locales/fr/.mustflow/skills/pure-core-imperative-shell/SKILL.md +0 -212
  155. package/templates/default/locales/fr/.mustflow/skills/readme-authoring/SKILL.md +0 -115
  156. package/templates/default/locales/fr/.mustflow/skills/repo-improvement-loop/SKILL.md +0 -150
  157. package/templates/default/locales/fr/.mustflow/skills/repro-first-debug/SKILL.md +0 -112
  158. package/templates/default/locales/fr/.mustflow/skills/requirement-regression-guard/SKILL.md +0 -152
  159. package/templates/default/locales/fr/.mustflow/skills/result-option/SKILL.md +0 -186
  160. package/templates/default/locales/fr/.mustflow/skills/security-privacy-review/SKILL.md +0 -116
  161. package/templates/default/locales/fr/.mustflow/skills/security-regression-tests/SKILL.md +0 -131
  162. package/templates/default/locales/fr/.mustflow/skills/skill-authoring/SKILL.md +0 -110
  163. package/templates/default/locales/fr/.mustflow/skills/source-freshness-check/SKILL.md +0 -111
  164. package/templates/default/locales/fr/.mustflow/skills/state-machine-pattern/SKILL.md +0 -214
  165. package/templates/default/locales/fr/.mustflow/skills/strategy-pattern/SKILL.md +0 -215
  166. package/templates/default/locales/fr/.mustflow/skills/structure-discovery-gate/SKILL.md +0 -159
  167. package/templates/default/locales/fr/.mustflow/skills/test-design-guard/SKILL.md +0 -162
  168. package/templates/default/locales/fr/.mustflow/skills/test-maintenance/SKILL.md +0 -122
  169. package/templates/default/locales/fr/.mustflow/skills/ui-quality-gate/SKILL.md +0 -117
  170. package/templates/default/locales/fr/.mustflow/skills/visual-review-artifact/SKILL.md +0 -127
  171. package/templates/default/locales/fr/.mustflow/skills/visual-review-artifact/assets/review-template.html +0 -286
  172. package/templates/default/locales/fr/.mustflow/skills/visual-review-artifact/resources.toml +0 -7
  173. package/templates/default/locales/fr/.mustflow/skills/web-asset-optimization/SKILL.md +0 -108
  174. package/templates/default/locales/hi/.mustflow/skills/INDEX.md +0 -75
  175. package/templates/default/locales/hi/.mustflow/skills/adapter-boundary/SKILL.md +0 -193
  176. package/templates/default/locales/hi/.mustflow/skills/artifact-integrity-check/SKILL.md +0 -114
  177. package/templates/default/locales/hi/.mustflow/skills/behavior-preserving-refactor/SKILL.md +0 -182
  178. package/templates/default/locales/hi/.mustflow/skills/code-review/SKILL.md +0 -115
  179. package/templates/default/locales/hi/.mustflow/skills/codebase-orientation/SKILL.md +0 -115
  180. package/templates/default/locales/hi/.mustflow/skills/command-pattern/SKILL.md +0 -247
  181. package/templates/default/locales/hi/.mustflow/skills/composition-over-inheritance/SKILL.md +0 -176
  182. package/templates/default/locales/hi/.mustflow/skills/contract-sync-check/SKILL.md +0 -116
  183. package/templates/default/locales/hi/.mustflow/skills/database-change-safety/SKILL.md +0 -155
  184. package/templates/default/locales/hi/.mustflow/skills/date-number-audit/SKILL.md +0 -116
  185. package/templates/default/locales/hi/.mustflow/skills/dependency-injection/SKILL.md +0 -161
  186. package/templates/default/locales/hi/.mustflow/skills/dependency-reality-check/SKILL.md +0 -115
  187. package/templates/default/locales/hi/.mustflow/skills/diff-risk-review/SKILL.md +0 -136
  188. package/templates/default/locales/hi/.mustflow/skills/docs-prose-review/SKILL.md +0 -119
  189. package/templates/default/locales/hi/.mustflow/skills/docs-update/SKILL.md +0 -97
  190. package/templates/default/locales/hi/.mustflow/skills/external-prompt-injection-defense/SKILL.md +0 -116
  191. package/templates/default/locales/hi/.mustflow/skills/facade-pattern/SKILL.md +0 -210
  192. package/templates/default/locales/hi/.mustflow/skills/failure-triage/SKILL.md +0 -97
  193. package/templates/default/locales/hi/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +0 -118
  194. package/templates/default/locales/hi/.mustflow/skills/line-ending-hygiene/SKILL.md +0 -111
  195. package/templates/default/locales/hi/.mustflow/skills/migration-safety-check/SKILL.md +0 -117
  196. package/templates/default/locales/hi/.mustflow/skills/multi-agent-work-coordination/SKILL.md +0 -260
  197. package/templates/default/locales/hi/.mustflow/skills/null-object-pattern/SKILL.md +0 -196
  198. package/templates/default/locales/hi/.mustflow/skills/pattern-scout/SKILL.md +0 -110
  199. package/templates/default/locales/hi/.mustflow/skills/performance-budget-check/SKILL.md +0 -121
  200. package/templates/default/locales/hi/.mustflow/skills/project-context-authoring/SKILL.md +0 -107
  201. package/templates/default/locales/hi/.mustflow/skills/pure-core-imperative-shell/SKILL.md +0 -212
  202. package/templates/default/locales/hi/.mustflow/skills/readme-authoring/SKILL.md +0 -115
  203. package/templates/default/locales/hi/.mustflow/skills/repo-improvement-loop/SKILL.md +0 -150
  204. package/templates/default/locales/hi/.mustflow/skills/repro-first-debug/SKILL.md +0 -112
  205. package/templates/default/locales/hi/.mustflow/skills/requirement-regression-guard/SKILL.md +0 -152
  206. package/templates/default/locales/hi/.mustflow/skills/result-option/SKILL.md +0 -186
  207. package/templates/default/locales/hi/.mustflow/skills/security-privacy-review/SKILL.md +0 -116
  208. package/templates/default/locales/hi/.mustflow/skills/security-regression-tests/SKILL.md +0 -131
  209. package/templates/default/locales/hi/.mustflow/skills/skill-authoring/SKILL.md +0 -110
  210. package/templates/default/locales/hi/.mustflow/skills/source-freshness-check/SKILL.md +0 -111
  211. package/templates/default/locales/hi/.mustflow/skills/state-machine-pattern/SKILL.md +0 -214
  212. package/templates/default/locales/hi/.mustflow/skills/strategy-pattern/SKILL.md +0 -215
  213. package/templates/default/locales/hi/.mustflow/skills/structure-discovery-gate/SKILL.md +0 -159
  214. package/templates/default/locales/hi/.mustflow/skills/test-design-guard/SKILL.md +0 -162
  215. package/templates/default/locales/hi/.mustflow/skills/test-maintenance/SKILL.md +0 -122
  216. package/templates/default/locales/hi/.mustflow/skills/ui-quality-gate/SKILL.md +0 -117
  217. package/templates/default/locales/hi/.mustflow/skills/visual-review-artifact/SKILL.md +0 -127
  218. package/templates/default/locales/hi/.mustflow/skills/visual-review-artifact/assets/review-template.html +0 -286
  219. package/templates/default/locales/hi/.mustflow/skills/visual-review-artifact/resources.toml +0 -7
  220. package/templates/default/locales/hi/.mustflow/skills/web-asset-optimization/SKILL.md +0 -108
  221. package/templates/default/locales/ko/.mustflow/skills/INDEX.md +0 -80
  222. package/templates/default/locales/ko/.mustflow/skills/adapter-boundary/SKILL.md +0 -193
  223. package/templates/default/locales/ko/.mustflow/skills/artifact-integrity-check/SKILL.md +0 -114
  224. package/templates/default/locales/ko/.mustflow/skills/behavior-preserving-refactor/SKILL.md +0 -182
  225. package/templates/default/locales/ko/.mustflow/skills/code-review/SKILL.md +0 -118
  226. package/templates/default/locales/ko/.mustflow/skills/codebase-orientation/SKILL.md +0 -115
  227. package/templates/default/locales/ko/.mustflow/skills/command-pattern/SKILL.md +0 -247
  228. package/templates/default/locales/ko/.mustflow/skills/composition-over-inheritance/SKILL.md +0 -176
  229. package/templates/default/locales/ko/.mustflow/skills/contract-sync-check/SKILL.md +0 -116
  230. package/templates/default/locales/ko/.mustflow/skills/database-change-safety/SKILL.md +0 -155
  231. package/templates/default/locales/ko/.mustflow/skills/date-number-audit/SKILL.md +0 -116
  232. package/templates/default/locales/ko/.mustflow/skills/dependency-injection/SKILL.md +0 -161
  233. package/templates/default/locales/ko/.mustflow/skills/dependency-reality-check/SKILL.md +0 -115
  234. package/templates/default/locales/ko/.mustflow/skills/diff-risk-review/SKILL.md +0 -136
  235. package/templates/default/locales/ko/.mustflow/skills/docs-prose-review/SKILL.md +0 -119
  236. package/templates/default/locales/ko/.mustflow/skills/docs-update/SKILL.md +0 -107
  237. package/templates/default/locales/ko/.mustflow/skills/external-prompt-injection-defense/SKILL.md +0 -116
  238. package/templates/default/locales/ko/.mustflow/skills/facade-pattern/SKILL.md +0 -210
  239. package/templates/default/locales/ko/.mustflow/skills/failure-triage/SKILL.md +0 -119
  240. package/templates/default/locales/ko/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +0 -118
  241. package/templates/default/locales/ko/.mustflow/skills/line-ending-hygiene/SKILL.md +0 -111
  242. package/templates/default/locales/ko/.mustflow/skills/migration-safety-check/SKILL.md +0 -117
  243. package/templates/default/locales/ko/.mustflow/skills/multi-agent-work-coordination/SKILL.md +0 -259
  244. package/templates/default/locales/ko/.mustflow/skills/null-object-pattern/SKILL.md +0 -196
  245. package/templates/default/locales/ko/.mustflow/skills/pattern-scout/SKILL.md +0 -110
  246. package/templates/default/locales/ko/.mustflow/skills/performance-budget-check/SKILL.md +0 -121
  247. package/templates/default/locales/ko/.mustflow/skills/project-context-authoring/SKILL.md +0 -107
  248. package/templates/default/locales/ko/.mustflow/skills/pure-core-imperative-shell/SKILL.md +0 -212
  249. package/templates/default/locales/ko/.mustflow/skills/readme-authoring/SKILL.md +0 -115
  250. package/templates/default/locales/ko/.mustflow/skills/repo-improvement-loop/SKILL.md +0 -150
  251. package/templates/default/locales/ko/.mustflow/skills/repro-first-debug/SKILL.md +0 -112
  252. package/templates/default/locales/ko/.mustflow/skills/requirement-regression-guard/SKILL.md +0 -152
  253. package/templates/default/locales/ko/.mustflow/skills/result-option/SKILL.md +0 -186
  254. package/templates/default/locales/ko/.mustflow/skills/security-privacy-review/SKILL.md +0 -116
  255. package/templates/default/locales/ko/.mustflow/skills/security-regression-tests/SKILL.md +0 -131
  256. package/templates/default/locales/ko/.mustflow/skills/skill-authoring/SKILL.md +0 -110
  257. package/templates/default/locales/ko/.mustflow/skills/source-freshness-check/SKILL.md +0 -111
  258. package/templates/default/locales/ko/.mustflow/skills/state-machine-pattern/SKILL.md +0 -214
  259. package/templates/default/locales/ko/.mustflow/skills/strategy-pattern/SKILL.md +0 -215
  260. package/templates/default/locales/ko/.mustflow/skills/structure-discovery-gate/SKILL.md +0 -159
  261. package/templates/default/locales/ko/.mustflow/skills/test-design-guard/SKILL.md +0 -162
  262. package/templates/default/locales/ko/.mustflow/skills/test-maintenance/SKILL.md +0 -130
  263. package/templates/default/locales/ko/.mustflow/skills/ui-quality-gate/SKILL.md +0 -117
  264. package/templates/default/locales/ko/.mustflow/skills/visual-review-artifact/SKILL.md +0 -127
  265. package/templates/default/locales/ko/.mustflow/skills/visual-review-artifact/assets/review-template.html +0 -286
  266. package/templates/default/locales/ko/.mustflow/skills/visual-review-artifact/resources.toml +0 -7
  267. package/templates/default/locales/ko/.mustflow/skills/web-asset-optimization/SKILL.md +0 -108
  268. package/templates/default/locales/zh/.mustflow/skills/INDEX.md +0 -74
  269. package/templates/default/locales/zh/.mustflow/skills/adapter-boundary/SKILL.md +0 -193
  270. package/templates/default/locales/zh/.mustflow/skills/artifact-integrity-check/SKILL.md +0 -114
  271. package/templates/default/locales/zh/.mustflow/skills/behavior-preserving-refactor/SKILL.md +0 -182
  272. package/templates/default/locales/zh/.mustflow/skills/code-review/SKILL.md +0 -115
  273. package/templates/default/locales/zh/.mustflow/skills/codebase-orientation/SKILL.md +0 -115
  274. package/templates/default/locales/zh/.mustflow/skills/command-pattern/SKILL.md +0 -247
  275. package/templates/default/locales/zh/.mustflow/skills/composition-over-inheritance/SKILL.md +0 -176
  276. package/templates/default/locales/zh/.mustflow/skills/contract-sync-check/SKILL.md +0 -116
  277. package/templates/default/locales/zh/.mustflow/skills/database-change-safety/SKILL.md +0 -155
  278. package/templates/default/locales/zh/.mustflow/skills/date-number-audit/SKILL.md +0 -116
  279. package/templates/default/locales/zh/.mustflow/skills/dependency-injection/SKILL.md +0 -161
  280. package/templates/default/locales/zh/.mustflow/skills/dependency-reality-check/SKILL.md +0 -115
  281. package/templates/default/locales/zh/.mustflow/skills/diff-risk-review/SKILL.md +0 -136
  282. package/templates/default/locales/zh/.mustflow/skills/docs-prose-review/SKILL.md +0 -119
  283. package/templates/default/locales/zh/.mustflow/skills/docs-update/SKILL.md +0 -97
  284. package/templates/default/locales/zh/.mustflow/skills/external-prompt-injection-defense/SKILL.md +0 -116
  285. package/templates/default/locales/zh/.mustflow/skills/facade-pattern/SKILL.md +0 -210
  286. package/templates/default/locales/zh/.mustflow/skills/failure-triage/SKILL.md +0 -96
  287. package/templates/default/locales/zh/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +0 -118
  288. package/templates/default/locales/zh/.mustflow/skills/line-ending-hygiene/SKILL.md +0 -111
  289. package/templates/default/locales/zh/.mustflow/skills/migration-safety-check/SKILL.md +0 -117
  290. package/templates/default/locales/zh/.mustflow/skills/multi-agent-work-coordination/SKILL.md +0 -260
  291. package/templates/default/locales/zh/.mustflow/skills/null-object-pattern/SKILL.md +0 -196
  292. package/templates/default/locales/zh/.mustflow/skills/pattern-scout/SKILL.md +0 -110
  293. package/templates/default/locales/zh/.mustflow/skills/performance-budget-check/SKILL.md +0 -121
  294. package/templates/default/locales/zh/.mustflow/skills/project-context-authoring/SKILL.md +0 -107
  295. package/templates/default/locales/zh/.mustflow/skills/pure-core-imperative-shell/SKILL.md +0 -212
  296. package/templates/default/locales/zh/.mustflow/skills/readme-authoring/SKILL.md +0 -115
  297. package/templates/default/locales/zh/.mustflow/skills/repo-improvement-loop/SKILL.md +0 -150
  298. package/templates/default/locales/zh/.mustflow/skills/repro-first-debug/SKILL.md +0 -112
  299. package/templates/default/locales/zh/.mustflow/skills/requirement-regression-guard/SKILL.md +0 -152
  300. package/templates/default/locales/zh/.mustflow/skills/result-option/SKILL.md +0 -186
  301. package/templates/default/locales/zh/.mustflow/skills/security-privacy-review/SKILL.md +0 -116
  302. package/templates/default/locales/zh/.mustflow/skills/security-regression-tests/SKILL.md +0 -131
  303. package/templates/default/locales/zh/.mustflow/skills/skill-authoring/SKILL.md +0 -110
  304. package/templates/default/locales/zh/.mustflow/skills/source-freshness-check/SKILL.md +0 -111
  305. package/templates/default/locales/zh/.mustflow/skills/state-machine-pattern/SKILL.md +0 -214
  306. package/templates/default/locales/zh/.mustflow/skills/strategy-pattern/SKILL.md +0 -215
  307. package/templates/default/locales/zh/.mustflow/skills/structure-discovery-gate/SKILL.md +0 -159
  308. package/templates/default/locales/zh/.mustflow/skills/test-design-guard/SKILL.md +0 -162
  309. package/templates/default/locales/zh/.mustflow/skills/test-maintenance/SKILL.md +0 -122
  310. package/templates/default/locales/zh/.mustflow/skills/ui-quality-gate/SKILL.md +0 -117
  311. package/templates/default/locales/zh/.mustflow/skills/visual-review-artifact/SKILL.md +0 -127
  312. package/templates/default/locales/zh/.mustflow/skills/visual-review-artifact/assets/review-template.html +0 -286
  313. package/templates/default/locales/zh/.mustflow/skills/visual-review-artifact/resources.toml +0 -7
  314. package/templates/default/locales/zh/.mustflow/skills/web-asset-optimization/SKILL.md +0 -108
@@ -1,14 +1,16 @@
1
- import { readFileSync } from 'node:fs';
1
+ import { mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
2
2
  import path from 'node:path';
3
+ import { createClassifyOutput } from './classify.js';
3
4
  import { runRun } from './run.js';
4
5
  import { createChangeVerificationReport, } from '../../core/change-verification.js';
5
- import { createVerificationPlan } from '../../core/verification-plan.js';
6
6
  import { readCommandContract } from '../../core/config-loading.js';
7
7
  import { printUsageError, renderHelp } from '../lib/cli-output.js';
8
8
  import { t } from '../lib/i18n.js';
9
9
  import { readLocalCommandEffectGraph, readLocalPathSurfaces, } from '../lib/local-index.js';
10
10
  import { resolveMustflowRoot } from '../lib/project-root.js';
11
11
  const VERIFY_SCHEMA_VERSION = '1';
12
+ const VERIFY_RUN_DIR = path.join('.mustflow', 'state', 'runs', 'verify-latest');
13
+ const LATEST_RUN_RECEIPT_PATH = path.join('.mustflow', 'state', 'runs', 'latest.json');
12
14
  function createBufferedOutput() {
13
15
  const stdout = [];
14
16
  const stderr = [];
@@ -31,11 +33,13 @@ function createBufferedOutput() {
31
33
  }
32
34
  export function getVerifyHelp(lang = 'en') {
33
35
  return renderHelp({
34
- usage: 'mf verify --reason <event> [options] | mf verify --from-plan <path> [options]',
36
+ usage: 'mf verify --reason <event> [options] | mf verify --from-plan <path> [options] | mf verify --changed [options]',
35
37
  summary: t(lang, 'verify.help.summary'),
36
38
  options: [
37
39
  { label: '--reason <event>', description: t(lang, 'verify.help.option.reason') },
38
40
  { label: '--from-plan <path>', description: t(lang, 'verify.help.option.fromPlan') },
41
+ { label: '--changed', description: t(lang, 'verify.help.option.changed') },
42
+ { label: '--write-plan <path>', description: t(lang, 'verify.help.option.writePlan') },
39
43
  { label: '--plan-only', description: t(lang, 'verify.help.option.planOnly') },
40
44
  { label: '--json', description: t(lang, 'cli.option.json') },
41
45
  { label: '-h, --help', description: t(lang, 'cli.option.help') },
@@ -45,6 +49,8 @@ export function getVerifyHelp(lang = 'en') {
45
49
  'mf verify --reason docs_change --json',
46
50
  'mf verify --reason docs_change --plan-only --json',
47
51
  'mf verify --from-plan verify-plan.json --json',
52
+ 'mf verify --changed --plan-only --json',
53
+ 'mf verify --changed --write-plan .mustflow/state/change-plan.json --json',
48
54
  'mf verify --reason mustflow_docs_change',
49
55
  ],
50
56
  exitCodes: [
@@ -56,8 +62,10 @@ export function getVerifyHelp(lang = 'en') {
56
62
  function parseVerifyArgs(args) {
57
63
  let reason;
58
64
  let fromPlan;
65
+ let writePlan;
59
66
  let json = false;
60
67
  let planOnly = false;
68
+ let changed = false;
61
69
  for (let index = 0; index < args.length; index += 1) {
62
70
  const arg = args[index];
63
71
  if (arg === '--json') {
@@ -68,10 +76,14 @@ function parseVerifyArgs(args) {
68
76
  planOnly = true;
69
77
  continue;
70
78
  }
79
+ if (arg === '--changed') {
80
+ changed = true;
81
+ continue;
82
+ }
71
83
  if (arg === '--reason') {
72
84
  const value = args[index + 1];
73
85
  if (!value || value.startsWith('-')) {
74
- return { json, planOnly, reason, error: 'missing_reason_value' };
86
+ return { json, planOnly, changed, reason, error: 'missing_reason_value' };
75
87
  }
76
88
  reason = value;
77
89
  index += 1;
@@ -80,16 +92,25 @@ function parseVerifyArgs(args) {
80
92
  if (arg === '--from-plan') {
81
93
  const value = args[index + 1];
82
94
  if (!value || value.startsWith('-')) {
83
- return { json, planOnly, reason, fromPlan, error: 'missing_from_plan_value' };
95
+ return { json, planOnly, changed, reason, fromPlan, error: 'missing_from_plan_value' };
84
96
  }
85
97
  fromPlan = value;
86
98
  index += 1;
87
99
  continue;
88
100
  }
101
+ if (arg === '--write-plan') {
102
+ const value = args[index + 1];
103
+ if (!value || value.startsWith('-')) {
104
+ return { json, planOnly, changed, reason, fromPlan, writePlan, error: 'missing_write_plan_value' };
105
+ }
106
+ writePlan = value;
107
+ index += 1;
108
+ continue;
109
+ }
89
110
  if (arg.startsWith('--reason=')) {
90
111
  const value = arg.slice('--reason='.length);
91
112
  if (value.length === 0) {
92
- return { json, planOnly, reason, error: 'missing_reason_value' };
113
+ return { json, planOnly, changed, reason, error: 'missing_reason_value' };
93
114
  }
94
115
  reason = value;
95
116
  continue;
@@ -97,35 +118,152 @@ function parseVerifyArgs(args) {
97
118
  if (arg.startsWith('--from-plan=')) {
98
119
  const value = arg.slice('--from-plan='.length);
99
120
  if (value.length === 0) {
100
- return { json, planOnly, reason, fromPlan, error: 'missing_from_plan_value' };
121
+ return { json, planOnly, changed, reason, fromPlan, error: 'missing_from_plan_value' };
101
122
  }
102
123
  fromPlan = value;
103
124
  continue;
104
125
  }
126
+ if (arg.startsWith('--write-plan=')) {
127
+ const value = arg.slice('--write-plan='.length);
128
+ if (value.length === 0) {
129
+ return { json, planOnly, changed, reason, fromPlan, writePlan, error: 'missing_write_plan_value' };
130
+ }
131
+ writePlan = value;
132
+ continue;
133
+ }
105
134
  if (arg.startsWith('-')) {
106
- return { json, planOnly, reason, error: arg };
135
+ return { json, planOnly, changed, reason, fromPlan, writePlan, error: arg };
107
136
  }
108
- return { json, planOnly, reason, error: `unexpected:${arg}` };
137
+ return { json, planOnly, changed, reason, fromPlan, writePlan, error: `unexpected:${arg}` };
109
138
  }
110
- return { json, planOnly, reason, fromPlan };
139
+ return { json, planOnly, changed, reason, fromPlan, writePlan };
111
140
  }
112
141
  function uniqueStrings(values) {
113
142
  return [...new Set(values.map((value) => value.trim()).filter((value) => value.length > 0))];
114
143
  }
144
+ function toPosixPath(value) {
145
+ return value.split(path.sep).join('/');
146
+ }
147
+ function sanitizeIntentFilePart(value) {
148
+ const sanitized = value.replace(/[^A-Za-z0-9._-]+/g, '_').replace(/^_+|_+$/g, '');
149
+ return sanitized.length > 0 ? sanitized.slice(0, 80) : 'intent';
150
+ }
115
151
  function readStringArray(value) {
116
152
  if (!Array.isArray(value)) {
117
153
  return [];
118
154
  }
119
155
  return value.filter((item) => typeof item === 'string');
120
156
  }
121
- function readNumber(value) {
122
- return Number.isInteger(value) && Number(value) >= 0 ? Number(value) : null;
157
+ function isStringArray(value) {
158
+ return Array.isArray(value) && value.every((item) => typeof item === 'string');
123
159
  }
124
- function readUpdatePolicies(value) {
125
- return readStringArray(value).filter((item) => item === 'update' || item === 'update_or_mark_stale' || item === 'not_applicable');
160
+ function isPlainRecord(value) {
161
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
126
162
  }
127
- function readChangeSource(value) {
128
- return value === 'changed' || value === 'paths' ? value : 'paths';
163
+ function isUpdatePolicy(value) {
164
+ return value === 'update' || value === 'update_or_mark_stale' || value === 'not_applicable';
165
+ }
166
+ function isUpdatePolicyArray(value) {
167
+ return Array.isArray(value) && value.every((item) => isUpdatePolicy(item));
168
+ }
169
+ function readPlanRoot(value) {
170
+ if (!isPlainRecord(value)) {
171
+ return null;
172
+ }
173
+ const root = value.mustflow_root;
174
+ return typeof root === 'string' && root.length > 0 ? root : null;
175
+ }
176
+ function readStrictClassificationSummary(value) {
177
+ if (!isPlainRecord(value)) {
178
+ return null;
179
+ }
180
+ if (!Number.isInteger(value.fileCount) ||
181
+ Number(value.fileCount) < 0 ||
182
+ !Number.isInteger(value.publicSurfaceCount) ||
183
+ Number(value.publicSurfaceCount) < 0 ||
184
+ !isStringArray(value.changeKinds) ||
185
+ !isStringArray(value.validationReasons) ||
186
+ !isUpdatePolicyArray(value.updatePolicies) ||
187
+ !isStringArray(value.driftChecks) ||
188
+ !isStringArray(value.affectedContracts)) {
189
+ return null;
190
+ }
191
+ return {
192
+ fileCount: Number(value.fileCount),
193
+ publicSurfaceCount: Number(value.publicSurfaceCount),
194
+ changeKinds: [...value.changeKinds],
195
+ validationReasons: uniqueStrings(value.validationReasons),
196
+ updatePolicies: [...value.updatePolicies],
197
+ driftChecks: [...value.driftChecks],
198
+ affectedContracts: [...value.affectedContracts],
199
+ };
200
+ }
201
+ function readStrictClassification(value) {
202
+ if (!isPlainRecord(value) || typeof value.path !== 'string' || !isStringArray(value.changeKinds)) {
203
+ return null;
204
+ }
205
+ const surface = value.surface;
206
+ if (!isPlainRecord(surface)) {
207
+ return null;
208
+ }
209
+ if (typeof surface.kind !== 'string' ||
210
+ typeof surface.category !== 'string' ||
211
+ typeof surface.isPublicSurface !== 'boolean' ||
212
+ !isStringArray(surface.validationReasons) ||
213
+ !isStringArray(surface.affectedContracts) ||
214
+ !isUpdatePolicy(surface.updatePolicy) ||
215
+ !isStringArray(surface.driftChecks)) {
216
+ return null;
217
+ }
218
+ return {
219
+ path: value.path,
220
+ changeKinds: [...value.changeKinds],
221
+ surface: {
222
+ kind: surface.kind,
223
+ category: surface.category,
224
+ isPublicSurface: surface.isPublicSurface,
225
+ validationReasons: [...surface.validationReasons],
226
+ affectedContracts: [...surface.affectedContracts],
227
+ updatePolicy: surface.updatePolicy,
228
+ driftChecks: [...surface.driftChecks],
229
+ },
230
+ };
231
+ }
232
+ function readStrictClassifications(value) {
233
+ if (!Array.isArray(value)) {
234
+ return null;
235
+ }
236
+ const classifications = value.map(readStrictClassification);
237
+ return classifications.every((classification) => classification !== null)
238
+ ? classifications
239
+ : null;
240
+ }
241
+ function readStrictClassifyPlan(projectRoot, plan) {
242
+ if (!isPlainRecord(plan)) {
243
+ throw new Error('unsupported_plan_source');
244
+ }
245
+ if (plan.schema_version !== '1' || plan.command !== 'classify') {
246
+ throw new Error('unsupported_plan_source');
247
+ }
248
+ if (readPlanRoot(plan) !== projectRoot) {
249
+ throw new Error('plan_root_mismatch');
250
+ }
251
+ const source = plan.source;
252
+ const files = plan.files;
253
+ const classifications = readStrictClassifications(plan.classifications);
254
+ const summary = readStrictClassificationSummary(plan.summary);
255
+ if ((source !== 'changed' && source !== 'paths') || !isStringArray(files) || !classifications || !summary) {
256
+ throw new Error('invalid_plan_file');
257
+ }
258
+ if (summary.validationReasons.length === 0) {
259
+ throw new Error('missing_plan_reasons');
260
+ }
261
+ return {
262
+ source,
263
+ files: [...files],
264
+ classifications,
265
+ summary,
266
+ };
129
267
  }
130
268
  function emptyClassificationSummary(validationReasons) {
131
269
  return {
@@ -138,51 +276,6 @@ function emptyClassificationSummary(validationReasons) {
138
276
  affectedContracts: [],
139
277
  };
140
278
  }
141
- function readClassificationSummary(value, fallbackReasons) {
142
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
143
- return emptyClassificationSummary(fallbackReasons);
144
- }
145
- const record = value;
146
- const validationReasons = uniqueStrings([...fallbackReasons, ...readStringArray(record.validationReasons)]);
147
- return {
148
- fileCount: readNumber(record.fileCount) ?? 0,
149
- publicSurfaceCount: readNumber(record.publicSurfaceCount) ?? 0,
150
- changeKinds: readStringArray(record.changeKinds),
151
- validationReasons,
152
- updatePolicies: readUpdatePolicies(record.updatePolicies),
153
- driftChecks: readStringArray(record.driftChecks),
154
- affectedContracts: readStringArray(record.affectedContracts),
155
- };
156
- }
157
- function readClassifications(value) {
158
- if (!Array.isArray(value)) {
159
- return [];
160
- }
161
- return value.filter((item) => {
162
- if (!item || typeof item !== 'object' || Array.isArray(item)) {
163
- return false;
164
- }
165
- const record = item;
166
- const surface = record.surface;
167
- const surfaceRecord = surface;
168
- return (typeof record.path === 'string' &&
169
- Array.isArray(record.changeKinds) &&
170
- readStringArray(record.changeKinds).length === record.changeKinds.length &&
171
- surface !== null &&
172
- typeof surface === 'object' &&
173
- !Array.isArray(surface) &&
174
- typeof surfaceRecord.kind === 'string' &&
175
- typeof surfaceRecord.category === 'string' &&
176
- typeof surfaceRecord.isPublicSurface === 'boolean' &&
177
- Array.isArray(surfaceRecord.validationReasons) &&
178
- readStringArray(surfaceRecord.validationReasons).length === surfaceRecord.validationReasons.length &&
179
- Array.isArray(surfaceRecord.affectedContracts) &&
180
- readStringArray(surfaceRecord.affectedContracts).length === surfaceRecord.affectedContracts.length &&
181
- readUpdatePolicies([surfaceRecord.updatePolicy]).length === 1 &&
182
- Array.isArray(surfaceRecord.driftChecks) &&
183
- readStringArray(surfaceRecord.driftChecks).length === surfaceRecord.driftChecks.length);
184
- });
185
- }
186
279
  function createSyntheticClassificationReport(reasons, source = 'paths', files = []) {
187
280
  return {
188
281
  source,
@@ -191,45 +284,6 @@ function createSyntheticClassificationReport(reasons, source = 'paths', files =
191
284
  summary: emptyClassificationSummary(reasons),
192
285
  };
193
286
  }
194
- function readClassificationReport(plan, fallbackReasons) {
195
- if (!plan || typeof plan !== 'object' || Array.isArray(plan)) {
196
- return createSyntheticClassificationReport(fallbackReasons);
197
- }
198
- const record = plan;
199
- const summary = readClassificationSummary(record.classification_summary ?? record.summary, fallbackReasons);
200
- const files = readStringArray(record.files);
201
- const classifications = readClassifications(record.classifications);
202
- return {
203
- source: readChangeSource(record.source),
204
- files,
205
- classifications,
206
- summary,
207
- };
208
- }
209
- function readPlanReasons(plan) {
210
- if (!plan || typeof plan !== 'object' || Array.isArray(plan)) {
211
- return [];
212
- }
213
- const record = plan;
214
- const summary = record.summary;
215
- const classificationSummary = record.classification_summary;
216
- const verification = record.verification;
217
- const reasons = [
218
- typeof record.reason === 'string' ? record.reason : '',
219
- ...readStringArray(record.reasons),
220
- ...readStringArray(record.validationReasons),
221
- ...(summary && typeof summary === 'object' && !Array.isArray(summary)
222
- ? readStringArray(summary.validationReasons)
223
- : []),
224
- ...(classificationSummary && typeof classificationSummary === 'object' && !Array.isArray(classificationSummary)
225
- ? readStringArray(classificationSummary.validationReasons)
226
- : []),
227
- ...(verification && typeof verification === 'object' && !Array.isArray(verification)
228
- ? readStringArray(verification.reasons)
229
- : []),
230
- ];
231
- return uniqueStrings(reasons);
232
- }
233
287
  function resolvePlanPath(projectRoot, inputPath) {
234
288
  const resolved = path.resolve(projectRoot, inputPath);
235
289
  const relative = path.relative(projectRoot, resolved);
@@ -238,7 +292,7 @@ function resolvePlanPath(projectRoot, inputPath) {
238
292
  }
239
293
  return resolved;
240
294
  }
241
- function readInputFromPlan(projectRoot, inputPath) {
295
+ export function readInputFromPlan(projectRoot, inputPath) {
242
296
  let parsed;
243
297
  const planPath = resolvePlanPath(projectRoot, inputPath);
244
298
  try {
@@ -247,21 +301,37 @@ function readInputFromPlan(projectRoot, inputPath) {
247
301
  catch {
248
302
  throw new Error('invalid_plan_file');
249
303
  }
250
- const reasons = readPlanReasons(parsed);
251
- if (reasons.length === 0) {
252
- throw new Error('missing_plan_reasons');
253
- }
304
+ const classificationReport = readStrictClassifyPlan(projectRoot, parsed);
254
305
  return {
255
- reasons,
256
- classificationReport: readClassificationReport(parsed, reasons),
306
+ reasons: classificationReport.summary.validationReasons,
307
+ classificationReport,
257
308
  };
258
309
  }
259
- function planErrorMessageKey(code) {
310
+ function createInputFromChanged(projectRoot) {
311
+ const plan = createClassifyOutput(projectRoot, 'changed', []);
312
+ return {
313
+ plan,
314
+ input: {
315
+ reasons: plan.summary.validationReasons,
316
+ classificationReport: plan,
317
+ },
318
+ };
319
+ }
320
+ function writeChangedPlan(projectRoot, inputPath, plan) {
321
+ const planPath = resolvePlanPath(projectRoot, inputPath);
322
+ mkdirSync(path.dirname(planPath), { recursive: true });
323
+ writeFileSync(planPath, `${JSON.stringify(plan, null, 2)}\n`, 'utf8');
324
+ }
325
+ export function planErrorMessageKey(code) {
260
326
  switch (code) {
261
327
  case 'plan_path_outside_root':
262
328
  return 'verify.error.plan_path_outside_root';
263
329
  case 'missing_plan_reasons':
264
330
  return 'verify.error.missing_plan_reasons';
331
+ case 'unsupported_plan_source':
332
+ return 'verify.error.unsupported_plan_source';
333
+ case 'plan_root_mismatch':
334
+ return 'verify.error.plan_root_mismatch';
265
335
  default:
266
336
  return 'verify.error.invalid_plan_file';
267
337
  }
@@ -277,9 +347,48 @@ function skippedResult(candidate) {
277
347
  receipt: null,
278
348
  };
279
349
  }
280
- async function runVerificationIntent(intent, lang) {
350
+ function candidateResultKey(candidate) {
351
+ return candidate.intent
352
+ ? `intent:${candidate.intent}`
353
+ : `missing:${candidate.reason}:${candidate.skipReason ?? ''}:${candidate.detail ?? ''}`;
354
+ }
355
+ function createSkippedResults(candidates, scheduledIntents, gaps) {
356
+ const seen = new Set();
357
+ const results = [];
358
+ const activeGapReasons = new Set(gaps.map((gap) => gap.reason));
359
+ for (const candidate of candidates) {
360
+ if (candidate.status === 'runnable' || (candidate.intent && scheduledIntents.has(candidate.intent))) {
361
+ continue;
362
+ }
363
+ if (candidate.candidateState === 'gap' && !activeGapReasons.has(candidate.reason)) {
364
+ continue;
365
+ }
366
+ const key = candidateResultKey(candidate);
367
+ if (seen.has(key)) {
368
+ continue;
369
+ }
370
+ seen.add(key);
371
+ results.push(skippedResult({
372
+ intent: candidate.intent ?? '',
373
+ reason: candidate.skipReason,
374
+ detail: candidate.detail,
375
+ }));
376
+ }
377
+ return results;
378
+ }
379
+ function testTargetsByScheduledIntent(report) {
380
+ return new Map(report.test_selection.selected
381
+ .filter((candidate) => candidate.status === 'runnable' &&
382
+ candidate.testTargetsApplied &&
383
+ candidate.appliedTestTargets.length > 0)
384
+ .map((candidate) => [candidate.intent, candidate.appliedTestTargets]));
385
+ }
386
+ async function runVerificationIntent(intent, lang, testTargets = []) {
281
387
  const output = createBufferedOutput();
282
- const exitCode = await runRun([intent, '--json'], output.reporter, lang);
388
+ const exitCode = await runRun([intent, '--json'], output.reporter, lang, {
389
+ writeLatestReceipt: false,
390
+ testTargets,
391
+ });
283
392
  const rawStdout = output.stdout().trim();
284
393
  let receipt = null;
285
394
  let status = exitCode === 0 ? 'passed' : 'failed';
@@ -333,39 +442,76 @@ function getVerificationStatus(summary) {
333
442
  }
334
443
  return 'passed';
335
444
  }
336
- async function createVerifyOutput(reasons, planSource, projectRoot, lang) {
337
- const contract = readCommandContract(projectRoot);
338
- const candidatesByIntent = new Map();
339
- const unmatchedCandidates = [];
340
- for (const reason of reasons) {
341
- const plan = createVerificationPlan(contract, reason);
342
- for (const candidate of plan.candidates) {
343
- if (!candidate.intent) {
344
- unmatchedCandidates.push(candidate);
345
- continue;
346
- }
347
- if (!candidatesByIntent.has(candidate.intent)) {
348
- candidatesByIntent.set(candidate.intent, candidate);
349
- }
445
+ function writeVerifyRunReceipts(projectRoot, output) {
446
+ const runDir = path.join(projectRoot, VERIFY_RUN_DIR);
447
+ const intentDir = path.join(runDir, 'intents');
448
+ const receipts = [];
449
+ rmSync(runDir, { recursive: true, force: true });
450
+ mkdirSync(intentDir, { recursive: true });
451
+ for (const [index, result] of output.results.entries()) {
452
+ let receiptPath = null;
453
+ if (result.intent && result.receipt) {
454
+ const fileName = `${String(index + 1).padStart(3, '0')}-${sanitizeIntentFilePart(result.intent)}.json`;
455
+ const absoluteReceiptPath = path.join(intentDir, fileName);
456
+ receiptPath = toPosixPath(path.join(VERIFY_RUN_DIR, 'intents', fileName));
457
+ writeFileSync(absoluteReceiptPath, `${JSON.stringify({ ...result.receipt, receipt_path: receiptPath }, null, 2)}\n`, 'utf8');
350
458
  }
459
+ receipts.push({
460
+ intent: result.intent,
461
+ status: result.status,
462
+ skipped: result.skipped,
463
+ receipt_path: receiptPath,
464
+ });
351
465
  }
352
- const candidates = [...candidatesByIntent.values(), ...unmatchedCandidates].sort((left, right) => left.intent.localeCompare(right.intent));
466
+ const manifest = {
467
+ schema_version: '1',
468
+ command: 'verify',
469
+ reason: output.reason,
470
+ reasons: output.reasons,
471
+ plan_source: output.plan_source,
472
+ status: output.status,
473
+ summary: output.summary,
474
+ receipts,
475
+ };
476
+ writeFileSync(path.join(runDir, 'manifest.json'), `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
477
+ const latest = {
478
+ schema_version: '1',
479
+ command: 'verify',
480
+ kind: 'verify_run_summary',
481
+ reason: output.reason,
482
+ reasons: output.reasons,
483
+ plan_source: output.plan_source,
484
+ status: output.status,
485
+ summary: output.summary,
486
+ run_dir: toPosixPath(VERIFY_RUN_DIR),
487
+ manifest_path: toPosixPath(path.join(VERIFY_RUN_DIR, 'manifest.json')),
488
+ };
489
+ writeFileSync(path.join(projectRoot, LATEST_RUN_RECEIPT_PATH), `${JSON.stringify(latest, null, 2)}\n`, 'utf8');
490
+ }
491
+ async function createVerifyOutput(input, planSource, projectRoot, lang) {
492
+ const contract = readCommandContract(projectRoot);
493
+ const report = createChangeVerificationReport(input.classificationReport, contract, projectRoot);
494
+ const scheduledIntents = new Set(report.schedule.entries.map((entry) => entry.intent));
495
+ const scheduledTestTargets = testTargetsByScheduledIntent(report);
353
496
  const results = [];
354
- for (const candidate of candidates) {
355
- results.push(candidate.status === 'runnable' ? await runVerificationIntent(candidate.intent, lang) : skippedResult(candidate));
497
+ for (const entry of report.schedule.entries) {
498
+ results.push(await runVerificationIntent(entry.intent, lang, scheduledTestTargets.get(entry.intent) ?? []));
356
499
  }
500
+ results.push(...createSkippedResults(report.candidates, scheduledIntents, report.gaps));
357
501
  const summary = summarizeResults(results);
358
- return {
502
+ const output = {
359
503
  schema_version: VERIFY_SCHEMA_VERSION,
360
504
  command: 'verify',
361
505
  mustflow_root: projectRoot,
362
- reason: reasons.join(', '),
363
- reasons,
506
+ reason: input.reasons.join(', '),
507
+ reasons: input.reasons,
364
508
  plan_source: planSource,
365
509
  status: getVerificationStatus(summary),
366
510
  summary,
367
511
  results,
368
512
  };
513
+ writeVerifyRunReceipts(projectRoot, output);
514
+ return output;
369
515
  }
370
516
  async function createPlanOnlyOutput(input, projectRoot) {
371
517
  const contract = readCommandContract(projectRoot);
@@ -435,33 +581,52 @@ export async function runVerify(args, reporter, lang = 'en') {
435
581
  ? t(lang, 'cli.error.missingValue', { option: '--reason' })
436
582
  : parsed.error === 'missing_from_plan_value'
437
583
  ? t(lang, 'cli.error.missingValue', { option: '--from-plan' })
438
- : parsed.error.startsWith('unexpected:')
439
- ? t(lang, 'cli.error.unexpectedArgument', { argument: parsed.error.slice('unexpected:'.length) })
440
- : t(lang, 'cli.error.unknownOption', { option: parsed.error });
584
+ : parsed.error === 'missing_write_plan_value'
585
+ ? t(lang, 'cli.error.missingValue', { option: '--write-plan' })
586
+ : parsed.error.startsWith('unexpected:')
587
+ ? t(lang, 'cli.error.unexpectedArgument', { argument: parsed.error.slice('unexpected:'.length) })
588
+ : t(lang, 'cli.error.unknownOption', { option: parsed.error });
441
589
  printUsageError(reporter, message, 'mf verify --help', getVerifyHelp(lang), lang);
442
590
  return 1;
443
591
  }
444
- if (parsed.reason && parsed.fromPlan) {
592
+ const selectedInputCount = [parsed.reason, parsed.fromPlan, parsed.changed ? 'changed' : undefined].filter(Boolean).length;
593
+ if (selectedInputCount > 1) {
445
594
  printUsageError(reporter, t(lang, 'verify.error.conflictingInputs'), 'mf verify --help', getVerifyHelp(lang), lang);
446
595
  return 1;
447
596
  }
448
- if (!parsed.reason && !parsed.fromPlan) {
597
+ if (selectedInputCount === 0) {
449
598
  printUsageError(reporter, t(lang, 'verify.error.missingReason'), 'mf verify --help', getVerifyHelp(lang), lang);
450
599
  return 1;
451
600
  }
601
+ if (parsed.writePlan && !parsed.changed) {
602
+ printUsageError(reporter, t(lang, 'verify.error.writePlanRequiresChanged'), 'mf verify --help', getVerifyHelp(lang), lang);
603
+ return 1;
604
+ }
452
605
  if (parsed.planOnly && !parsed.json) {
453
606
  printUsageError(reporter, t(lang, 'verify.error.planOnlyJson'), 'mf verify --help', getVerifyHelp(lang), lang);
454
607
  return 1;
455
608
  }
456
609
  const projectRoot = resolveMustflowRoot();
457
610
  let input;
611
+ let changedPlan = null;
458
612
  try {
459
- input = parsed.fromPlan
460
- ? readInputFromPlan(projectRoot, parsed.fromPlan)
461
- : {
613
+ if (parsed.changed) {
614
+ const changedInput = createInputFromChanged(projectRoot);
615
+ input = changedInput.input;
616
+ changedPlan = changedInput.plan;
617
+ }
618
+ else if (parsed.fromPlan) {
619
+ input = readInputFromPlan(projectRoot, parsed.fromPlan);
620
+ }
621
+ else {
622
+ input = {
462
623
  reasons: [parsed.reason],
463
624
  classificationReport: createSyntheticClassificationReport([parsed.reason]),
464
625
  };
626
+ }
627
+ if (parsed.writePlan && changedPlan) {
628
+ writeChangedPlan(projectRoot, parsed.writePlan, changedPlan);
629
+ }
465
630
  }
466
631
  catch (error) {
467
632
  const code = error instanceof Error ? error.message : 'invalid_plan_file';
@@ -472,7 +637,7 @@ export async function runVerify(args, reporter, lang = 'en') {
472
637
  reporter.stdout(JSON.stringify(await createPlanOnlyOutput(input, projectRoot), null, 2));
473
638
  return 0;
474
639
  }
475
- const output = await createVerifyOutput(input.reasons, parsed.fromPlan ?? null, projectRoot, lang);
640
+ const output = await createVerifyOutput(input, parsed.fromPlan ?? (parsed.changed ? 'changed' : null), projectRoot, lang);
476
641
  if (parsed.json) {
477
642
  reporter.stdout(JSON.stringify(output, null, 2));
478
643
  }