@polymorphism-tech/morph-spec 8.47.0 → 9.1.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 (377) hide show
  1. package/CLAUDE.md +51 -43
  2. package/README.md +39 -38
  3. package/bin/morph-spec.js +41 -113
  4. package/bin/validate.js +1 -147
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +1 -1
  7. package/docs/QUICKSTART.md +1 -1
  8. package/framework/CLAUDE.md +41 -101
  9. package/framework/MORPH.md +95 -252
  10. package/framework/agents.json +86 -21
  11. package/framework/commands/morph-apply.md +5 -28
  12. package/framework/commands/morph-archive.md +1 -1
  13. package/framework/commands/morph-hotfix.md +8 -8
  14. package/framework/commands/morph-infra.md +1 -1
  15. package/framework/commands/morph-preflight.md +2 -3
  16. package/framework/commands/morph-status.md +4 -4
  17. package/framework/docs/CLI.md +574 -286
  18. package/framework/evals/review-checklist.md +82 -41
  19. package/framework/hooks/README.md +10 -11
  20. package/framework/hooks/claude-code/core/block-destructive-worktree-removal.js +6 -49
  21. package/framework/hooks/claude-code/core/block-raw-worktree-add.js +2 -35
  22. package/framework/hooks/claude-code/core/chain.js +4 -65
  23. package/framework/hooks/claude-code/core/comment-guard.js +3 -17
  24. package/framework/hooks/claude-code/core/denylist.json +33 -3
  25. package/framework/hooks/claude-code/core/enforce-phase-writes.js +15 -63
  26. package/framework/hooks/claude-code/core/gate-guard.js +9 -78
  27. package/framework/hooks/claude-code/core/graph-refresh-kick.js +3 -24
  28. package/framework/hooks/claude-code/core/heavy-gate.js +3 -21
  29. package/framework/hooks/claude-code/core/heavy-release.js +2 -13
  30. package/framework/hooks/claude-code/core/loop-detect.js +2 -31
  31. package/framework/hooks/claude-code/core/pre-bash-denylist.js +36 -2
  32. package/framework/hooks/claude-code/core/protect-spec-files.js +25 -297
  33. package/framework/hooks/claude-code/core/state-sync.js +15 -85
  34. package/framework/hooks/claude-code/core/telemetry-log.js +15 -96
  35. package/framework/hooks/claude-code/core/validate-completion.js +37 -147
  36. package/framework/hooks/claude-code/core/warn-bash-source-write.js +23 -0
  37. package/framework/hooks/claude-code/core/worktree-context.js +15 -114
  38. package/framework/hooks/claude-code/core/worktree-create.js +6 -70
  39. package/framework/hooks/claude-code/core/worktree-env-inject.js +5 -56
  40. package/framework/hooks/claude-code/core/worktree-remove.js +5 -31
  41. package/framework/hooks/claude-code/statusline.py +55 -41
  42. package/framework/hooks/package.json +3 -0
  43. package/framework/hooks/shared/activity-logger.js +9 -89
  44. package/framework/hooks/shared/agent-reap.js +2 -17
  45. package/framework/hooks/shared/build-check.js +11 -76
  46. package/framework/hooks/shared/claim-registry.js +9 -119
  47. package/framework/hooks/shared/command-tokens.js +168 -44
  48. package/framework/hooks/shared/comment-rules.js +5 -20
  49. package/framework/hooks/shared/comment-scanner.js +11 -43
  50. package/framework/hooks/shared/comment-stripper.js +11 -85
  51. package/framework/hooks/shared/e2e-check.js +0 -0
  52. package/framework/hooks/shared/errata.js +59 -0
  53. package/framework/hooks/shared/feature-locator.js +11 -95
  54. package/framework/hooks/shared/frontend-locations.js +4 -0
  55. package/framework/hooks/shared/gate-question.js +12 -0
  56. package/framework/hooks/shared/git-exclude.js +3 -20
  57. package/framework/hooks/shared/git-paths.js +8 -104
  58. package/framework/hooks/shared/graph-freshness.js +22 -166
  59. package/framework/hooks/shared/graph-refresh.js +21 -149
  60. package/framework/hooks/shared/heavy-command.js +4 -12
  61. package/framework/hooks/shared/hook-response.js +8 -83
  62. package/framework/hooks/shared/morph-cli.js +8 -52
  63. package/framework/hooks/shared/payload-utils.js +10 -132
  64. package/framework/hooks/shared/phase-utils.js +14 -72
  65. package/framework/hooks/shared/redact-secrets.js +4 -15
  66. package/framework/hooks/shared/reparse-scan.js +6 -66
  67. package/framework/hooks/shared/slice-progress.js +99 -0
  68. package/framework/hooks/shared/source-files.js +4 -17
  69. package/framework/hooks/shared/spawn-command.js +23 -0
  70. package/framework/hooks/shared/state-reader.js +51 -247
  71. package/framework/hooks/shared/state-writer.js +9 -54
  72. package/framework/hooks/shared/stdin-reader.js +1 -11
  73. package/framework/hooks/shared/telemetry-logger.js +7 -67
  74. package/framework/hooks/shared/transcript-usage.js +7 -29
  75. package/framework/hooks/shared/worktree-root.js +7 -29
  76. package/framework/mcp/registry.json +3 -4
  77. package/framework/phases.json +23 -39
  78. package/framework/rules/csharp-standards.md +1 -1
  79. package/framework/rules/frontend-standards.md +1 -0
  80. package/framework/rules/hangfire-standards.md +1 -1
  81. package/framework/rules/neon-standards.md +1 -1
  82. package/framework/schemas/config.schema.json +14 -9
  83. package/framework/schemas/feature.schema.json +15 -50
  84. package/framework/skills/README.md +3 -4
  85. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  86. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  87. package/framework/skills/core/morph-apply/SKILL.md +149 -222
  88. package/framework/skills/core/morph-hotfix/SKILL.md +33 -42
  89. package/framework/skills/core/morph-machine/SKILL.md +2 -2
  90. package/framework/skills/core/morph-media/SKILL.md +1 -1
  91. package/framework/skills/core/morph-plan/SKILL.md +137 -299
  92. package/framework/skills/core/morph-review/SKILL.md +111 -136
  93. package/framework/skills/core/morph-standards/SKILL.md +27 -39
  94. package/framework/skills/core/morph-uiux/SKILL.md +94 -152
  95. package/framework/standards/STANDARDS.json +109 -1219
  96. package/framework/standards/STANDARDS.meta.json +1319 -0
  97. package/framework/standards/ai-agents/agent-archetypes.md +2 -2
  98. package/framework/standards/ai-agents/agent-session.md +1 -1
  99. package/framework/standards/ai-agents/conversational-agent-with-phases.md +4 -4
  100. package/framework/standards/ai-agents/durable-workflows-hitl.md +3 -3
  101. package/framework/standards/ai-agents/evals-with-cache.md +1 -2
  102. package/framework/standards/ai-agents/guardrails.md +1 -1
  103. package/framework/standards/ai-agents/multi-agent-patterns.md +2 -2
  104. package/framework/standards/ai-agents/observability-patterns.md +1 -1
  105. package/framework/standards/ai-agents/production.md +1 -1
  106. package/framework/standards/ai-agents/prompt-sources.md +2 -2
  107. package/framework/standards/ai-agents/providers/model-registry.md +1 -1
  108. package/framework/standards/ai-agents/rag-custom-pgvector.md +2 -2
  109. package/framework/standards/ai-agents/setup.md +3 -3
  110. package/framework/standards/ai-agents/sweet-spot.md +2 -2
  111. package/framework/standards/ai-agents/tool-adapters.md +0 -2
  112. package/framework/standards/ai-agents/vector-data-extensions.md +4 -4
  113. package/framework/standards/ai-agents/workflows.md +1 -1
  114. package/framework/standards/architecture/code-comments.md +7 -7
  115. package/framework/standards/architecture/vertical-slice/vertical-slice.md +1 -1
  116. package/framework/standards/backend/api/validation.md +1 -1
  117. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +5 -5
  118. package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +1 -1
  119. package/framework/standards/backend/integrations/neon-auth/neon-auth.md +2 -2
  120. package/framework/standards/data/nosql/cache/redis.md +1 -1
  121. package/framework/standards/data/nosql/cosmos-db.md +3 -3
  122. package/framework/standards/frontend/admin-app/forms.md +1 -1
  123. package/framework/standards/frontend/design-system/art-direction.md +88 -0
  124. package/framework/standards/frontend/design-system/premium-finish.md +77 -2
  125. package/framework/standards/infrastructure/neon/neon-pgvector.md +5 -5
  126. package/framework/standards/integration/mcp/mcp-tools.md +7 -7
  127. package/framework/templates/CLAUDE.md.core.template +3 -3
  128. package/framework/templates/README.md +2 -3
  129. package/framework/templates/REGISTRY.json +15 -179
  130. package/framework/templates/docs/plan.md +72 -0
  131. package/framework/templates/docs/ui-mockups.md +4 -0
  132. package/framework/templates/dotnet/ai-kit/README.md +1 -9
  133. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +0 -10
  134. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -1
  135. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +1 -1
  136. package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +1 -1
  137. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +3 -4
  138. package/package.json +1 -1
  139. package/src/commands/context/context-refresh.js +0 -16
  140. package/src/commands/dashboard/dashboard.js +2 -8
  141. package/src/commands/e2e/e2e.js +18 -105
  142. package/src/commands/graph/affected.js +0 -14
  143. package/src/commands/graph/build.js +11 -50
  144. package/src/commands/graph/explain.js +0 -16
  145. package/src/commands/graph/status.js +1 -12
  146. package/src/commands/mcp/mcp-setup.js +4 -62
  147. package/src/commands/observability/cost.js +17 -111
  148. package/src/commands/observability/telemetry.js +1 -14
  149. package/src/commands/project/branch.js +4 -45
  150. package/src/commands/project/claim.js +4 -48
  151. package/src/commands/project/doctor-procs.js +1 -1
  152. package/src/commands/project/doctor.js +53 -307
  153. package/src/commands/project/env.js +1 -27
  154. package/src/commands/project/fleet.js +6 -35
  155. package/src/commands/project/heavy.js +3 -3
  156. package/src/commands/project/init.js +8 -68
  157. package/src/commands/project/install-plugin-cmd.js +0 -1
  158. package/src/commands/project/setup-infra-cmd.js +2 -1
  159. package/src/commands/project/stack-scan.js +58 -0
  160. package/src/commands/project/standards.js +65 -72
  161. package/src/commands/project/status.js +28 -121
  162. package/src/commands/project/update.js +31 -223
  163. package/src/commands/project/worktree.js +109 -883
  164. package/src/commands/scaffold/scaffold.js +0 -25
  165. package/src/commands/state/advance.js +65 -120
  166. package/src/commands/state/approve.js +87 -229
  167. package/src/commands/state/archive.js +23 -139
  168. package/src/commands/state/auto-approval.js +65 -0
  169. package/src/commands/state/create.js +49 -109
  170. package/src/commands/state/delete.js +11 -63
  171. package/src/commands/state/finish.js +105 -494
  172. package/src/commands/state/gate-check.js +74 -183
  173. package/src/commands/state/gate-decision.js +8 -42
  174. package/src/commands/state/handoff.js +4 -31
  175. package/src/commands/state/list.js +21 -91
  176. package/src/commands/state/report-check.js +134 -338
  177. package/src/commands/state/retype.js +12 -28
  178. package/src/commands/validation/index.js +0 -3
  179. package/src/commands/validation/mutate.js +79 -19
  180. package/src/commands/validation/plan-check.js +81 -0
  181. package/src/commands/validation/validate-feature.js +52 -216
  182. package/src/commands/validation/verify.js +45 -160
  183. package/src/core/paths/output-schema.js +9 -155
  184. package/src/core/state/feature-identity.js +1 -25
  185. package/src/core/state/gate-order.js +2 -30
  186. package/src/core/state/lifecycle-audit.js +8 -100
  187. package/src/core/state/state-manager.js +32 -395
  188. package/src/core/templates/template-registry.js +2 -97
  189. package/src/core/templates/template-renderer.js +13 -93
  190. package/src/core/templates/template-seed.js +21 -0
  191. package/src/core/work-types.js +10 -45
  192. package/src/dashboard/app/App.jsx +1 -8
  193. package/src/dashboard/app/components/ActivityFeed.jsx +2 -8
  194. package/src/dashboard/app/components/CommandPalette.jsx +4 -11
  195. package/src/dashboard/app/components/DetailPanel.jsx +1 -5
  196. package/src/dashboard/app/components/EntityLink.jsx +0 -12
  197. package/src/dashboard/app/components/ErrorBoundary.jsx +1 -8
  198. package/src/dashboard/app/components/KnowledgeMarkdown.jsx +0 -11
  199. package/src/dashboard/app/components/Markdown.jsx +0 -9
  200. package/src/dashboard/app/components/PhaseRail.jsx +0 -11
  201. package/src/dashboard/app/components/SearchFilter.jsx +0 -4
  202. package/src/dashboard/app/components/Sidebar.jsx +0 -5
  203. package/src/dashboard/app/hooks/useMorphQuery.js +1 -11
  204. package/src/dashboard/app/hooks/usePref.js +1 -5
  205. package/src/dashboard/app/lib/format.js +0 -2
  206. package/src/dashboard/app/lib/phases.js +3 -9
  207. package/src/dashboard/app/lib/project.js +0 -12
  208. package/src/dashboard/app/pages/Activity.jsx +1 -1
  209. package/src/dashboard/app/pages/AgentMap.jsx +1 -8
  210. package/src/dashboard/app/pages/FeatureDetail.jsx +139 -133
  211. package/src/dashboard/app/pages/Features.jsx +9 -16
  212. package/src/dashboard/app/pages/Guide.jsx +2 -3
  213. package/src/dashboard/app/pages/HookInspector.jsx +2 -23
  214. package/src/dashboard/app/pages/PhasePipeline.jsx +3 -7
  215. package/src/dashboard/app/pages/Portfolio.jsx +0 -1
  216. package/src/dashboard/app/pages/RulesMap.jsx +1 -16
  217. package/src/dashboard/app/pages/SkillsLibrary.jsx +1 -16
  218. package/src/dashboard/app/pages/Standards.jsx +2 -17
  219. package/src/dashboard/scanner/activity-scanner.js +14 -83
  220. package/src/dashboard/scanner/agents-scanner.js +1 -23
  221. package/src/dashboard/scanner/docs-scanner.js +1 -7
  222. package/src/dashboard/scanner/feature-status.js +2 -5
  223. package/src/dashboard/scanner/features-scanner.js +92 -113
  224. package/src/dashboard/scanner/hooks-scanner.js +5 -28
  225. package/src/dashboard/scanner/index.js +0 -4
  226. package/src/dashboard/scanner/portfolio.js +5 -29
  227. package/src/dashboard/scanner/project-api.js +8 -54
  228. package/src/dashboard/scanner/rules-scanner.js +1 -2
  229. package/src/dashboard/scanner/skills-scanner.js +2 -12
  230. package/src/dashboard/scanner/standards-scanner.js +4 -7
  231. package/src/dashboard/vite-plugin-morph-data.js +5 -19
  232. package/src/lib/ai/ai-checks.js +7 -52
  233. package/src/lib/ai/ai-project-scan.js +14 -108
  234. package/src/lib/ai/code-audit.js +7 -63
  235. package/src/lib/ai/pin-drift.js +8 -51
  236. package/src/lib/ai/registry-audit.js +11 -90
  237. package/src/lib/ci/ci-verify.js +14 -13
  238. package/src/lib/ci/github-ci.js +9 -37
  239. package/src/lib/ci/workflow-scaffold.js +2 -10
  240. package/src/lib/detectors/claude-config-detector.js +13 -74
  241. package/src/lib/detectors/index.js +8 -59
  242. package/src/lib/e2e/compose-env.js +5 -66
  243. package/src/lib/e2e/stack-teardown.js +6 -40
  244. package/src/lib/generators/architecture-scanner.js +18 -156
  245. package/src/lib/generators/handoff-generator.js +37 -112
  246. package/src/lib/generators/scaffold-generator.js +5 -101
  247. package/src/lib/generators/settings-generator.js +11 -122
  248. package/src/lib/git/branch-classifier.js +11 -84
  249. package/src/lib/git/default-branch.js +14 -169
  250. package/src/lib/git/evidence-staleness.js +2 -1
  251. package/src/lib/git/gh.js +2 -17
  252. package/src/lib/git/pending-prs.js +6 -37
  253. package/src/lib/git/pr-files.js +3 -28
  254. package/src/lib/git/pr-index.js +3 -34
  255. package/src/lib/git/tree-fingerprint.js +17 -17
  256. package/src/lib/git/tree-state.js +6 -33
  257. package/src/lib/graph/god-nodes.js +2 -22
  258. package/src/lib/graph/graph-health.js +3 -24
  259. package/src/lib/graph/graph-loader.js +5 -56
  260. package/src/lib/graph/graphify-runtime.js +7 -37
  261. package/src/lib/graph/graphifyignore.js +8 -74
  262. package/src/lib/graph/sanitize.js +16 -136
  263. package/src/lib/heavy/cleanup.js +2 -6
  264. package/src/lib/installers/effects.js +8 -93
  265. package/src/lib/installers/mcp-installer.js +9 -169
  266. package/src/lib/installers/memory-installer.js +8 -33
  267. package/src/lib/installers/templates-reconcile.js +5 -60
  268. package/src/lib/mutation/commands.js +3 -2
  269. package/src/lib/mutation/dotnet-introspection.js +281 -0
  270. package/src/lib/mutation/plan.js +14 -6
  271. package/src/lib/mutation/runner.js +1 -1
  272. package/src/lib/mutation/subset.js +47 -13
  273. package/src/lib/plan/artifact-vocabulary.js +40 -0
  274. package/src/lib/plan/checks.js +208 -0
  275. package/src/lib/plan/plan-parser.js +204 -0
  276. package/src/lib/plan/plan-template.js +18 -0
  277. package/src/lib/projects/registry.js +7 -44
  278. package/src/lib/review-reports.js +204 -0
  279. package/src/lib/risk-detector.js +131 -274
  280. package/src/lib/specs/adr-index.js +38 -85
  281. package/src/lib/specs/design-seed.js +18 -0
  282. package/src/lib/specs/frontmatter.js +31 -0
  283. package/src/lib/specs/gfm-table.js +11 -0
  284. package/src/lib/specs/revocations.js +31 -102
  285. package/src/lib/specs/screen-checklist.js +56 -132
  286. package/src/lib/stack/dotnet-build-ignores.js +43 -0
  287. package/src/lib/stack/stack-profile.js +1 -28
  288. package/src/lib/stack/stack-scan.js +260 -0
  289. package/src/lib/stack-filter.js +4 -27
  290. package/src/lib/standards/registry.js +37 -0
  291. package/src/lib/standards/sections.js +47 -0
  292. package/src/lib/standards/verified-against.js +19 -191
  293. package/src/lib/tasks/eval-node.js +23 -179
  294. package/src/lib/tasks/linux-runner.js +18 -142
  295. package/src/lib/tasks/test-nodes.js +43 -313
  296. package/src/lib/tasks/test-runner.js +107 -447
  297. package/src/lib/telemetry/metrics.js +13 -103
  298. package/src/lib/telemetry/telemetry-reader.js +13 -238
  299. package/src/lib/telemetry/verify-event.js +4 -34
  300. package/src/lib/validators/code-budget/code-budget-validator.js +4 -44
  301. package/src/lib/validators/code-budget/index.js +0 -7
  302. package/src/lib/validators/contracts/contract-compliance-validator.js +4 -26
  303. package/src/lib/validators/contracts/index.js +0 -6
  304. package/src/lib/validators/nextjs/index.js +0 -5
  305. package/src/lib/validators/nextjs/next-component-validator.js +4 -81
  306. package/src/lib/validators/packages/index.js +0 -6
  307. package/src/lib/validators/packages/package-validator.js +6 -56
  308. package/src/lib/validators/reuse/index.js +0 -8
  309. package/src/lib/validators/reuse/reuse-validator.js +24 -137
  310. package/src/lib/validators/reuse/symbol-scanner.js +6 -62
  311. package/src/lib/validators/traceability-check.js +54 -156
  312. package/src/lib/validators/validation-runner.js +20 -125
  313. package/src/lib/validators/verify-runner.js +152 -575
  314. package/src/lib/work-type-detector.js +5 -67
  315. package/src/lib/worktree/docker-audit.js +17 -137
  316. package/src/lib/worktree/env-allocator.js +10 -98
  317. package/src/lib/worktree/feature-truth.js +12 -115
  318. package/src/lib/worktree/finish-backup.js +32 -242
  319. package/src/lib/worktree/fleet-scanner.js +31 -126
  320. package/src/lib/worktree/ignored-triage.js +15 -91
  321. package/src/lib/worktree/vscode-settings.js +2 -3
  322. package/src/lib/worktree/worktree-audit.js +21 -213
  323. package/src/lib/worktree/worktree-include.js +3 -5
  324. package/src/scripts/global-install.js +3 -9
  325. package/src/scripts/install-plugin.js +1 -13
  326. package/src/scripts/setup-infra.js +17 -138
  327. package/src/utils/agents-installer.js +92 -272
  328. package/src/utils/banner.js +4 -25
  329. package/src/utils/claude-md-injector.js +1 -37
  330. package/src/utils/claude-settings-manager.js +1 -87
  331. package/src/utils/file-copier.js +32 -90
  332. package/src/utils/hooks-installer.js +26 -296
  333. package/src/utils/skills-installer.js +4 -102
  334. package/src/utils/version-checker.js +4 -83
  335. package/framework/commands/morph-proposal.md +0 -57
  336. package/framework/evals/trace-schema.md +0 -67
  337. package/framework/hooks/claude-code/core/tasks-json-guard.js +0 -83
  338. package/framework/hooks/claude-code/core/trace-autogen.js +0 -277
  339. package/framework/hooks/git/pre-commit/specs.sh +0 -50
  340. package/framework/hooks/shared/tasks-validator.js +0 -111
  341. package/framework/rules/morph-task-tracking.md +0 -54
  342. package/framework/rules/morph-workflow.md +0 -244
  343. package/framework/schemas/tasks.schema.json +0 -79
  344. package/framework/skills/core/morph-brainstorming/SKILL.md +0 -161
  345. package/framework/skills/core/morph-implement/SKILL.md +0 -194
  346. package/framework/skills/core/morph-proposal/SKILL.md +0 -152
  347. package/framework/skills/core/morph-stack-scan/SKILL.md +0 -145
  348. package/framework/templates/docs/proposal.md +0 -192
  349. package/framework/templates/docs/spec.md +0 -57
  350. package/framework/templates/docs/ui-components.md +0 -52
  351. package/framework/templates/docs/ui-design-system.md +0 -76
  352. package/framework/templates/docs/ui-flows.md +0 -167
  353. package/framework/templates/examples/spec-examples.md +0 -91
  354. package/framework/templates/feature/decisions.md +0 -124
  355. package/framework/templates/feature/recap.md +0 -145
  356. package/framework/templates/tasks.template.json +0 -17
  357. package/src/commands/state/usecase.js +0 -143
  358. package/src/commands/tasks/dag.js +0 -181
  359. package/src/commands/utils/index.js +0 -3
  360. package/src/lib/agents/output-collector.js +0 -76
  361. package/src/lib/detectors/design-system-detector.js +0 -188
  362. package/src/lib/evaluator-report.js +0 -104
  363. package/src/lib/generators/design-system-generator.js +0 -508
  364. package/src/lib/specs/acervo-format.js +0 -70
  365. package/src/lib/specs/acervo-lifecycle.js +0 -264
  366. package/src/lib/specs/done-criteria-check.js +0 -200
  367. package/src/lib/specs/usecase-check.js +0 -301
  368. package/src/lib/specs/usecase-promoter.js +0 -301
  369. package/src/lib/specs/usecase-registry.js +0 -237
  370. package/src/lib/tasks/dispatch-planner.js +0 -319
  371. package/src/lib/tasks/dotnet-test-introspection.js +0 -632
  372. package/src/lib/tasks/mermaid-renderer.js +0 -132
  373. package/src/lib/tasks/task-classifier.js +0 -30
  374. package/src/lib/tasks/task-parser.js +0 -209
  375. package/src/lib/tasks/tasks-json-parser.js +0 -296
  376. package/src/lib/tasks/test-scope.js +0 -597
  377. package/src/utils/agent-id-mapper.js +0 -11
@@ -1,109 +1,34 @@
1
- /**
2
- * MORPH-SPEC Feature Validation Command
3
- *
4
- * Content-aware validation of feature outputs at each phase.
5
- * Checks section presence, schema consistency, and contract correctness.
6
- *
7
- * Usage:
8
- * morph-spec validate <feature-name> [--phase <phase>] [--json] [--verbose]
9
- *
10
- * Example:
11
- * morph-spec validate user-portal --phase plan
12
- * morph-spec validate user-portal --json
13
- */
14
-
15
1
  import fs from 'fs';
16
2
  import path from 'path';
17
3
  import chalk from 'chalk';
18
- import { validateTasksJson } from '../../lib/tasks/tasks-json-parser.js';
19
-
20
- /**
21
- * Expected sections per output file — realigned with what the core skills
22
- * actually emit (`morph-brainstorming`, `morph-plan`, `morph-review`) so that
23
- * the framework's own output passes its own validator.
24
- *
25
- * Three tiers:
26
- * required → ERROR if absent. Strict subset of what the skills always emit.
27
- * recommended → WARNING if absent. Skills emit these, but a lean doc may skip.
28
- * optional → silent. Tracked when present, never penalized.
29
- *
30
- * Each entry is a string or an array of acceptable strings (any-of). The array
31
- * form carries bilingual aliases (pt-BR section names the skills emit AND their
32
- * English equivalents in the canonical templates), e.g. ['Escopo', 'Scope'].
33
- *
34
- * Matching is done against *section markers* (headings and line-start bold
35
- * labels), not whole-file substrings — see `extractSectionMarkers`.
36
- */
4
+ import { parsePlan } from '../../lib/plan/plan-parser.js';
5
+ import { knownPersonas, planHash, validatePlan } from '../../lib/plan/checks.js';
6
+
7
+ // Matched against section markers (headings and line-start bold labels), never whole-file
8
+ // substrings. required → ERROR, recommended → WARNING, optional → never penalized; an array is any-of.
37
9
  const OUTPUT_SECTIONS = {
38
- // morph-brainstorming emits: Problema, Escopo, Usuários e fluxos críticos,
39
- // Stack, Riscos e dependências, Compliance de stack, Conflitos com o acervo.
40
- //
41
- // "Critérios de aceite" is now OPTIONAL, not required: the behaviour layer
42
- // moved to the use cases (2-plan/usecases/), whose post-conditions must be
43
- // observable in a test, and morph-brainstorming no longer emits the section.
44
- // `optional` — not `recommended` — precisely because the skill never emits it
45
- // anymore: a warning on every new proposal would be systematic noise. Legacy
46
- // proposals that DO carry the section keep validating exactly as before.
47
- //
48
- // "Conflitos com o acervo" is recommended: morph-brainstorming always emits
49
- // it ("nenhum" included), so its absence means the acervo check never ran.
50
- // Not required — proposals written before the section existed stay valid.
51
- 'proposal.md': {
10
+ 'verifier.md': {
52
11
  required: [
53
- ['Problema', 'Problem'],
54
- ['Escopo', 'Scope'],
12
+ ['Verdict', 'Veredito'],
55
13
  ],
56
14
  recommended: [
57
- ['Riscos', 'Risks'],
58
- ['Conflitos', 'Conflicts'],
59
- ],
60
- optional: [
61
- ['Critérios de aceite', 'Critério', 'Aceite', 'Acceptance Criteria', 'Acceptance', 'Success Criteria', 'Success Metrics'],
62
- 'Stack',
63
- ['Usuários', 'Usuarios', 'Users', 'User Journey', 'User Stories', 'Fluxos'],
64
- ['Dependências', 'Dependencias', 'Dependencies'],
65
- ['Compliance'],
66
- ['Overview', 'Visão geral', 'Visao geral', 'Resumo'],
67
- ],
68
- },
69
- // morph-plan (spec.md) emits: Arquitetura da solução, Edge cases,
70
- // Integrações externas e contratos esperados.
71
- 'spec.md': {
72
- required: [
73
- ['Arquitetura', 'Architecture'],
74
- ['Integrações', 'Integracoes', 'Integrations', 'Contratos', 'Contracts', 'Data Model', 'Modelo de Dados'],
75
- ],
76
- recommended: [
77
- ['Edge cases', 'Edge Cases', 'Casos limite', 'Casos Limite', 'Casos de borda'],
78
- ],
79
- optional: [
80
- ['Overview', 'Visão geral', 'Resumo'],
81
- ['Requirements', 'Requisitos'],
82
- ['Security', 'Segurança', 'Seguranca'],
83
- ['Testing', 'Testes', 'Estratégia de Testes'],
84
- ['Performance', 'Desempenho'],
15
+ ['Bloqueadores', 'Bloqueantes', 'Blockers'],
16
+ 'Checks',
85
17
  ],
18
+ optional: [],
86
19
  },
87
- // decisions.md follows the ADR convention: an `### ADR-NNN` heading with
88
- // `**Status:** / **Context:** / **Decision:**` line-start bold labels.
89
- 'decisions.md': {
20
+ 'reviewer.md': {
90
21
  required: [
91
- 'ADR',
92
- 'Status',
93
- ['Contexto', 'Context'],
94
- ['Decisão', 'Decisao', 'Decision'],
22
+ ['Verdict', 'Veredito'],
95
23
  ],
96
24
  recommended: [
97
- ['Consequências', 'Consequencias', 'Consequences', 'Implicações', 'Trade-offs', 'Trade-off'],
98
- ],
99
- optional: [
100
- ['Alternativas', 'Alternatives'],
101
- ['Custos', 'Costs'],
25
+ ['Bloqueadores', 'Bloqueantes', 'Blockers'],
102
26
  ],
27
+ optional: [],
103
28
  },
104
- 'review-report.md': {
29
+ 'security.md': {
105
30
  required: [
106
- ['Veredito', 'Verdict'],
31
+ ['Verdict', 'Veredito'],
107
32
  ],
108
33
  recommended: [
109
34
  ['Bloqueadores', 'Bloqueantes', 'Blockers'],
@@ -112,51 +37,21 @@ const OUTPUT_SECTIONS = {
112
37
  },
113
38
  };
114
39
 
115
- /**
116
- * Phase-to-output mapping (v5 NLH)
117
- */
118
40
  const PHASE_OUTPUTS = {
119
- proposal: ['proposal.md'],
41
+ plan: ['plan.md', 'checks.json'],
120
42
  uiux: ['design-system.md', 'mockups.md', 'components.md', 'flows.md'],
121
- plan: ['spec.md', 'tasks.json'],
122
- implement: ['recap.md'],
123
- review: ['review-report.md'],
43
+ implement: [],
44
+ review: ['verifier.md', 'reviewer.md'],
124
45
  };
125
46
 
126
- // Work types whose plan phase (see src/core/work-types.js) skips proposal.md/
127
- // spec.md — chore and hotfix stamp proposal+plan gates at birth
128
- // (policy-approved, no human deliberation over those docs) and go straight to
129
- // tasks.json. Validating the full plan doc set against a feature that was
130
- // never asked to write those docs would be a false failure, not a real gap.
131
- const LEAN_PLAN_WORK_TYPES = ['chore', 'hotfix'];
132
- const LEAN_PLAN_OUTPUTS = ['tasks.json'];
133
-
134
- /**
135
- * Phase-to-folder mapping (v5 filesystem convention)
136
- */
137
47
  const PHASE_FOLDERS = {
138
- proposal: '0-proposal',
139
- uiux: '1-design',
140
48
  plan: '2-plan',
49
+ uiux: '1-design',
141
50
  implement: '3-implement',
142
51
  review: '4-review',
143
52
  };
144
53
 
145
- /**
146
- * Extract section markers from markdown content.
147
- *
148
- * A marker is a line that structurally introduces a section:
149
- * - a markdown heading → `## Arquitetura da solução`
150
- * - a line-start bold label → `**Status:** Aceito`
151
- *
152
- * Bold labels are included on purpose (deviation from heading-only): the ADR
153
- * convention used in `decisions.md` — and in the spec.md ADR block — writes
154
- * Status/Context/Decision as line-start bold labels, not headings. They are
155
- * structural, not prose, so this keeps ADRs valid without reintroducing the
156
- * accidental-prose-match problem that whole-file substring matching had.
157
- *
158
- * Returns lowercased marker texts.
159
- */
54
+ // Line-start bold labels count: reports write `**Verdict:**` as a label, not a heading.
160
55
  function extractSectionMarkers(content) {
161
56
  const markers = [];
162
57
  for (const rawLine of content.split('\n')) {
@@ -174,9 +69,6 @@ function extractSectionMarkers(content) {
174
69
  return markers;
175
70
  }
176
71
 
177
- /**
178
- * Validate a single output file
179
- */
180
72
  function validateOutput(featurePath, outputFile) {
181
73
  const filePath = path.join(featurePath, outputFile);
182
74
  const result = {
@@ -197,22 +89,22 @@ function validateOutput(featurePath, outputFile) {
197
89
  const content = fs.readFileSync(filePath, 'utf8');
198
90
  result.lineCount = content.split('\n').length;
199
91
 
200
- // tasks.json: structural validation against the schema, not markdown sections.
201
- if (outputFile === 'tasks.json') {
202
- validateTasksJsonOutput(content, result);
92
+ if (outputFile === 'plan.md') {
93
+ validatePlanOutput(content, featurePath, result);
94
+ return result;
95
+ }
96
+ if (outputFile === 'checks.json') {
97
+ validateChecksOutput(content, featurePath, result);
203
98
  return result;
204
99
  }
205
100
 
206
- // Skip section checks for files without defined sections
207
101
  const sections = OUTPUT_SECTIONS[outputFile];
208
102
  if (!sections) {
209
103
  return result;
210
104
  }
211
105
 
212
- // v5: only markdown outputs — contracts moved into spec.md
213
106
  validateMarkdownSections(content, sections, result);
214
107
 
215
- // Size warnings
216
108
  if (result.lineCount < 10) {
217
109
  result.warnings.push(`File is very short (${result.lineCount} lines) — may be incomplete`);
218
110
  }
@@ -220,40 +112,32 @@ function validateOutput(featurePath, outputFile) {
220
112
  return result;
221
113
  }
222
114
 
223
- /**
224
- * Validate tasks.json structurally: parseable JSON + conforms to the schema +
225
- * has at least one task.
226
- */
227
- function validateTasksJsonOutput(content, result) {
228
- let data;
115
+ // `planDir` is `.morph/features/{f}/2-plan`, so the project is four levels up.
116
+ function validatePlanOutput(content, planDir, result) {
117
+ const plan = parsePlan(content);
118
+ const { errors, warnings } = validatePlan(plan, { personas: knownPersonas(path.resolve(planDir, '..', '..', '..', '..')) });
119
+ result.errors.push(...errors);
120
+ result.warnings.push(...warnings);
121
+ result.sections.found.push(...plan.sections.filter((x) => x.key).map((x) => x.name));
122
+ }
123
+
124
+ function validateChecksOutput(content, planDir, result) {
125
+ let doc;
229
126
  try {
230
- data = JSON.parse(content);
127
+ doc = JSON.parse(content);
231
128
  } catch (err) {
232
- result.errors.push(`tasks.json is not valid JSON: ${err.message}`);
129
+ result.errors.push(`checks.json is not valid JSON: ${err.message}`);
233
130
  return;
234
131
  }
235
- const { valid, errors } = validateTasksJson(data);
236
- if (!valid) {
237
- for (const e of errors) result.errors.push(e);
132
+ const planPath = path.join(planDir, 'plan.md');
133
+ if (!fs.existsSync(planPath)) return;
134
+ if (doc?.planHash !== planHash(fs.readFileSync(planPath, 'utf8'))) {
135
+ result.errors.push('checks.json is stale — plan.md changed after it was generated; run `morph-spec plan-check`');
238
136
  return;
239
137
  }
240
- if (data.tasks.length === 0) {
241
- result.errors.push('tasks.json has no task entries');
242
- return;
243
- }
244
- result.sections.found.push(`${data.tasks.length} task(s)`);
138
+ result.sections.found.push(`${doc.checks?.length ?? 0} check(s), ${doc.slices?.length ?? 0} slice(s)`);
245
139
  }
246
140
 
247
- /**
248
- * Validate markdown sections against section markers (headings + bold labels).
249
- *
250
- * Each `entry` is a string or array of acceptable aliases (any-of). A section
251
- * is present when at least one alias is a substring of at least one marker.
252
- *
253
- * required → missing produces an ERROR
254
- * recommended → missing produces a WARNING
255
- * optional → tracked when present, never penalized
256
- */
257
141
  function validateMarkdownSections(content, sections, result) {
258
142
  const markers = extractSectionMarkers(content);
259
143
  const match = (entry) => {
@@ -289,30 +173,17 @@ function validateMarkdownSections(content, sections, result) {
289
173
  }
290
174
  }
291
175
 
292
- /**
293
- * Resolve the list of `{ file, dir }` outputs to validate.
294
- *
295
- * @param {string} featurePath Absolute path to the feature directory.
296
- * @param {string|null} phase Phase key, or null to validate everything.
297
- * @param {string|undefined} workType Feature's workType (see src/core/work-types.js).
298
- * When `phase === 'plan'` and workType is 'chore'/'hotfix', only tasks.json
299
- * is required (see LEAN_PLAN_WORK_TYPES above).
300
- * @returns {{ outputFiles?: Array<{file:string, dir:string}>, error?: string }}
301
- */
302
- function resolveOutputFiles(featurePath, phase, workType) {
176
+ function resolveOutputFiles(featurePath, phase) {
303
177
  if (phase) {
304
- const files = (phase === 'plan' && LEAN_PLAN_WORK_TYPES.includes(workType))
305
- ? LEAN_PLAN_OUTPUTS
306
- : PHASE_OUTPUTS[phase];
178
+ const files = PHASE_OUTPUTS[phase];
307
179
  if (!files) return { error: `Unknown phase: ${phase}` };
308
180
  const phaseFolder = PHASE_FOLDERS[phase];
309
181
  const searchPath = phaseFolder ? path.join(featurePath, phaseFolder) : featurePath;
310
182
  return { outputFiles: files.map(file => ({ file, dir: searchPath })) };
311
183
  }
312
184
 
313
- // Validate every existing output across the feature root + phase folders.
314
185
  const outputFiles = [];
315
- const isOutput = name => name.endsWith('.md') || name.endsWith('.cs') || name === 'tasks.json';
186
+ const isOutput = name => name.endsWith('.md') || name.endsWith('.cs') || name === 'checks.json';
316
187
  const entries = fs.readdirSync(featurePath, { withFileTypes: true });
317
188
  for (const entry of entries) {
318
189
  if (entry.isDirectory()) {
@@ -327,23 +198,12 @@ function resolveOutputFiles(featurePath, phase, workType) {
327
198
  return { outputFiles };
328
199
  }
329
200
 
330
- /**
331
- * Pure validation core — no console output, no process.exit.
332
- *
333
- * @param {string} featurePath Absolute path to the feature directory.
334
- * @param {{ phase?: string, workType?: string }} [options]
335
- * @returns {{
336
- * feature: string, phase: string, valid: boolean, error?: string,
337
- * totalErrors: number, totalWarnings: number, totalFound: number,
338
- * results: object[]
339
- * }}
340
- */
201
+ /** Pure core: no console output, no process.exit. */
341
202
  export function runFeatureValidation(featurePath, options = {}) {
342
203
  const phase = options.phase || null;
343
- const workType = options.workType || null;
344
204
  const feature = path.basename(featurePath);
345
205
 
346
- const { outputFiles, error } = resolveOutputFiles(featurePath, phase, workType);
206
+ const { outputFiles, error } = resolveOutputFiles(featurePath, phase);
347
207
  if (error) {
348
208
  return {
349
209
  feature,
@@ -373,9 +233,6 @@ export function runFeatureValidation(featurePath, options = {}) {
373
233
  };
374
234
  }
375
235
 
376
- /**
377
- * Main validate command (CLI wrapper around `runFeatureValidation`)
378
- */
379
236
  export async function validateFeatureCommand(featureName, options = {}) {
380
237
  if (!featureName) {
381
238
  console.error(chalk.red('Error: Feature name required'));
@@ -397,25 +254,10 @@ export async function validateFeatureCommand(featureName, options = {}) {
397
254
  process.exit(1);
398
255
  }
399
256
 
400
- // workType is read straight off the feature's own feature.json (not via
401
- // state-manager's getFeature/loadState) so a broken/missing root state.json
402
- // elsewhere in the project can never make `validate` itself throw — it just
403
- // falls back to the full (non-lean) output set, same as today.
404
- let workType;
405
- try {
406
- const fjPath = path.join(featurePath, 'feature.json');
407
- if (fs.existsSync(fjPath)) {
408
- workType = JSON.parse(fs.readFileSync(fjPath, 'utf8')).workType;
409
- }
410
- } catch {
411
- workType = undefined;
412
- }
413
-
414
- const validation = runFeatureValidation(featurePath, { phase, workType });
257
+ const validation = runFeatureValidation(featurePath, { phase });
415
258
  const { results, totalErrors, totalWarnings, totalFound } = validation;
416
- const schemaWarnings = []; // v5: cross-validation removed (contracts in spec.md)
259
+ const schemaWarnings = [];
417
260
 
418
- // JSON output mode
419
261
  if (options.json) {
420
262
  const output = {
421
263
  feature: featureName,
@@ -442,7 +284,6 @@ export async function validateFeatureCommand(featureName, options = {}) {
442
284
  return;
443
285
  }
444
286
 
445
- // Visual output
446
287
  console.log(chalk.cyan('\n┌────────────────────────────────────────────────────────────┐'));
447
288
  console.log(chalk.cyan('│ MORPH-SPEC FEATURE VALIDATOR │'));
448
289
  console.log(chalk.cyan('└────────────────────────────────────────────────────────────┘\n'));
@@ -451,7 +292,6 @@ export async function validateFeatureCommand(featureName, options = {}) {
451
292
  if (phase) console.log(chalk.gray(`Phase: ${phase}`));
452
293
  console.log('');
453
294
 
454
- // File-by-file results
455
295
  for (const result of results) {
456
296
  const symbol = result.exists
457
297
  ? (result.errors.length === 0 ? '✅' : '❌')
@@ -462,25 +302,21 @@ export async function validateFeatureCommand(featureName, options = {}) {
462
302
 
463
303
  console.log(`${symbol} ${name}${result.exists ? chalk.gray(` (${result.lineCount} lines)`) : ''}`);
464
304
 
465
- // Sections found
466
305
  if (result.sections.found.length > 0 && (options.verbose || result.errors.length > 0)) {
467
306
  result.sections.found.forEach(s => {
468
307
  console.log(chalk.green(` ✓ ${s}`));
469
308
  });
470
309
  }
471
310
 
472
- // Errors
473
311
  result.errors.forEach(err => {
474
312
  console.log(chalk.red(` ✗ ${err}`));
475
313
  });
476
314
 
477
- // Warnings
478
315
  result.warnings.forEach(warn => {
479
316
  console.log(chalk.yellow(` ⚠ ${warn}`));
480
317
  });
481
318
  }
482
319
 
483
- // Summary
484
320
  console.log('');
485
321
  console.log(chalk.gray('─'.repeat(60)));
486
322