@polymorphism-tech/morph-spec 8.46.0 → 9.0.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 (304) hide show
  1. package/CLAUDE.md +53 -44
  2. package/README.md +3 -4
  3. package/bin/morph-spec.js +38 -55
  4. package/bin/validate.js +5 -134
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +2 -2
  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 +75 -18
  11. package/framework/commands/create-umbraco-lp.md +2 -0
  12. package/framework/commands/migrate-lp-to-umbraco.md +2 -0
  13. package/framework/commands/morph-apply.md +5 -28
  14. package/framework/commands/morph-archive.md +2 -2
  15. package/framework/commands/morph-hotfix.md +8 -8
  16. package/framework/commands/morph-infra.md +17 -203
  17. package/framework/commands/morph-media.md +3 -0
  18. package/framework/commands/morph-preflight.md +7 -31
  19. package/framework/commands/morph-proposal.md +2 -50
  20. package/framework/commands/morph-status.md +3 -3
  21. package/framework/commands/morph-troubleshoot.md +2 -14
  22. package/framework/docs/CLI.md +585 -286
  23. package/framework/evals/review-checklist.md +82 -41
  24. package/framework/hooks/README.md +10 -11
  25. package/framework/hooks/claude-code/core/comment-guard.js +1 -1
  26. package/framework/hooks/claude-code/core/denylist.json +33 -3
  27. package/framework/hooks/claude-code/core/enforce-phase-writes.js +16 -20
  28. package/framework/hooks/claude-code/core/gate-guard.js +2 -11
  29. package/framework/hooks/claude-code/core/pre-bash-denylist.js +38 -0
  30. package/framework/hooks/claude-code/core/protect-spec-files.js +30 -242
  31. package/framework/hooks/claude-code/core/state-sync.js +17 -19
  32. package/framework/hooks/claude-code/core/telemetry-log.js +3 -3
  33. package/framework/hooks/claude-code/core/validate-completion.js +33 -97
  34. package/framework/hooks/claude-code/core/warn-bash-source-write.js +31 -0
  35. package/framework/hooks/claude-code/core/worktree-context.js +5 -4
  36. package/framework/hooks/claude-code/statusline.py +55 -41
  37. package/framework/hooks/package.json +3 -0
  38. package/framework/hooks/shared/activity-logger.js +1 -1
  39. package/framework/hooks/shared/build-check.js +10 -6
  40. package/framework/hooks/shared/command-tokens.js +169 -0
  41. package/framework/hooks/shared/comment-rules.js +1 -1
  42. package/framework/hooks/shared/comment-scanner.js +10 -23
  43. package/framework/hooks/shared/comment-stripper.js +1 -1
  44. package/framework/hooks/shared/e2e-check.js +67 -31
  45. package/framework/hooks/shared/errata.js +72 -0
  46. package/framework/hooks/shared/feature-locator.js +1 -1
  47. package/framework/hooks/shared/frontend-locations.js +6 -0
  48. package/framework/hooks/shared/gate-question.js +18 -0
  49. package/framework/hooks/shared/phase-utils.js +15 -32
  50. package/framework/hooks/shared/slice-progress.js +118 -0
  51. package/framework/hooks/shared/spawn-command.js +23 -0
  52. package/framework/hooks/shared/state-reader.js +61 -87
  53. package/framework/hooks/shared/state-writer.js +3 -3
  54. package/framework/mcp/registry.json +3 -4
  55. package/framework/phases.json +23 -39
  56. package/framework/rules/ai-agents-standards.md +18 -16
  57. package/framework/rules/asaas-standards.md +3 -1
  58. package/framework/rules/csharp-standards.md +10 -8
  59. package/framework/rules/data-standards.md +5 -5
  60. package/framework/rules/dotnet-templates.md +1 -1
  61. package/framework/rules/frontend-standards.md +4 -2
  62. package/framework/rules/gsap-standards.md +10 -5
  63. package/framework/rules/hangfire-standards.md +3 -1
  64. package/framework/rules/infrastructure-standards.md +4 -2
  65. package/framework/rules/neon-auth-standards.md +3 -1
  66. package/framework/rules/neon-standards.md +6 -4
  67. package/framework/rules/nextjs-standards.md +13 -11
  68. package/framework/rules/nextjs-templates.md +1 -1
  69. package/framework/rules/resend-standards.md +3 -1
  70. package/framework/schemas/config.schema.json +14 -9
  71. package/framework/schemas/feature.schema.json +15 -52
  72. package/framework/skills/README.md +4 -5
  73. package/framework/skills/core/create-umbraco-lp/SKILL.md +3 -3
  74. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +3 -3
  75. package/framework/skills/core/morph-apply/SKILL.md +150 -223
  76. package/framework/skills/core/morph-hotfix/SKILL.md +34 -43
  77. package/framework/skills/core/morph-machine/SKILL.md +4 -4
  78. package/framework/skills/core/morph-media/SKILL.md +3 -3
  79. package/framework/skills/core/morph-plan/SKILL.md +138 -300
  80. package/framework/skills/core/morph-review/SKILL.md +112 -137
  81. package/framework/skills/core/morph-standards/SKILL.md +29 -41
  82. package/framework/skills/core/morph-uiux/SKILL.md +78 -153
  83. package/framework/standards/STANDARDS.json +90 -1219
  84. package/framework/standards/STANDARDS.meta.json +1305 -0
  85. package/framework/standards/ai-agents/evals-with-cache.md +2 -3
  86. package/framework/standards/ai-agents/llm-runtime-defaults.md +1 -1
  87. package/framework/standards/ai-agents/modalities-speech-to-text.md +36 -26
  88. package/framework/standards/ai-agents/prompt-sources.md +6 -4
  89. package/framework/standards/ai-agents/providers/model-registry.md +1 -1
  90. package/framework/standards/ai-agents/rag-custom-pgvector.md +67 -39
  91. package/framework/standards/ai-agents/setup.md +2 -2
  92. package/framework/standards/ai-agents/structured-output.md +1 -1
  93. package/framework/standards/ai-agents/sweet-spot.md +1 -1
  94. package/framework/standards/architecture/code-comments.md +8 -8
  95. package/framework/standards/architecture/vertical-slice/vertical-slice.md +18 -9
  96. package/framework/standards/backend/api/validation.md +135 -47
  97. package/framework/standards/backend/database/postgresql/database.md +11 -7
  98. package/framework/standards/backend/database/vector-search-rag.md +207 -324
  99. package/framework/standards/backend/dotnet/fluent-validation-vsa.md +14 -8
  100. package/framework/standards/backend/dotnet/result-pattern.md +40 -6
  101. package/framework/standards/backend/dotnet/scalar-ui.md +13 -7
  102. package/framework/standards/backend/dotnet/scrutor.md +1 -1
  103. package/framework/standards/backend/dotnet/testing.md +1 -1
  104. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +7 -7
  105. package/framework/standards/backend/integrations/asaas/asaas-api.md +309 -165
  106. package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +134 -154
  107. package/framework/standards/data/nosql/cache/redis.md +120 -44
  108. package/framework/standards/data/nosql/cosmos-db.md +114 -71
  109. package/framework/standards/frontend/design-system/animations.md +1 -1
  110. package/framework/standards/frontend/design-system/naming.md +1 -1
  111. package/framework/standards/frontend/nextjs/motion-patterns.md +45 -29
  112. package/framework/standards/frontend/nextjs/naming-conventions.md +1 -1
  113. package/framework/standards/infrastructure/docker/coolify-deploy.md +8 -6
  114. package/framework/standards/infrastructure/neon/neon-pgvector.md +120 -75
  115. package/framework/standards/infrastructure/neon/neon-setup.md +53 -31
  116. package/framework/standards/integration/mcp/mcp-tools.md +7 -7
  117. package/framework/templates/README.md +2 -3
  118. package/framework/templates/REGISTRY.json +6 -170
  119. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +2 -2
  120. package/framework/templates/code/dotnet/extensions/database-extensions.cs +1 -1
  121. package/framework/templates/code/dotnet/extensions/result-extensions.cs +27 -0
  122. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +2 -2
  123. package/framework/templates/docs/plan.md +72 -0
  124. package/framework/templates/dotnet/ai-kit/README.md +1 -9
  125. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +1 -1
  126. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +0 -10
  127. package/framework/templates/infrastructure/docker/coolify.template.json +3 -3
  128. package/framework/templates/infrastructure/github/README.md +2 -1
  129. package/framework/templates/infrastructure/github/workflows/deploy-coolify.yml.hbs +2 -1
  130. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -1
  131. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +1 -1
  132. package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +1 -1
  133. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +3 -4
  134. package/package.json +1 -1
  135. package/src/commands/e2e/e2e.js +2 -2
  136. package/src/commands/observability/cost.js +18 -60
  137. package/src/commands/observability/telemetry.js +3 -5
  138. package/src/commands/project/doctor-procs.js +1 -1
  139. package/src/commands/project/doctor.js +9 -9
  140. package/src/commands/project/fleet.js +4 -4
  141. package/src/commands/project/heavy.js +3 -3
  142. package/src/commands/project/init.js +6 -1
  143. package/src/commands/project/setup-infra-cmd.js +2 -1
  144. package/src/commands/project/stack-scan.js +58 -0
  145. package/src/commands/project/standards.js +79 -25
  146. package/src/commands/project/status.js +29 -69
  147. package/src/commands/project/update.js +33 -19
  148. package/src/commands/project/worktree.js +1 -1
  149. package/src/commands/state/advance.js +62 -46
  150. package/src/commands/state/approve.js +95 -138
  151. package/src/commands/state/archive.js +20 -84
  152. package/src/commands/state/auto-approval.js +68 -0
  153. package/src/commands/state/create.js +28 -1
  154. package/src/commands/state/delete.js +1 -1
  155. package/src/commands/state/finish.js +11 -23
  156. package/src/commands/state/gate-check.js +86 -95
  157. package/src/commands/state/gate-decision.js +6 -4
  158. package/src/commands/state/handoff.js +1 -1
  159. package/src/commands/state/list.js +9 -9
  160. package/src/commands/state/report-check.js +157 -311
  161. package/src/commands/state/retype.js +9 -3
  162. package/src/commands/validation/mutate.js +77 -14
  163. package/src/commands/validation/plan-check.js +81 -0
  164. package/src/commands/validation/validate-feature.js +60 -135
  165. package/src/commands/validation/verify.js +41 -82
  166. package/src/core/paths/output-schema.js +20 -67
  167. package/src/core/state/gate-order.js +5 -6
  168. package/src/core/state/lifecycle-audit.js +2 -2
  169. package/src/core/state/state-manager.js +17 -98
  170. package/src/core/templates/template-registry.js +2 -2
  171. package/src/core/templates/template-seed.js +22 -0
  172. package/src/core/work-types.js +10 -10
  173. package/src/dashboard/app/App.jsx +0 -2
  174. package/src/dashboard/app/components/ActivityFeed.jsx +2 -3
  175. package/src/dashboard/app/components/CommandPalette.jsx +7 -8
  176. package/src/dashboard/app/components/EntityLink.jsx +1 -2
  177. package/src/dashboard/app/components/Markdown.jsx +1 -1
  178. package/src/dashboard/app/components/Sidebar.jsx +1 -2
  179. package/src/dashboard/app/hooks/useMorphQuery.js +1 -1
  180. package/src/dashboard/app/lib/phases.js +2 -4
  181. package/src/dashboard/app/pages/Activity.jsx +1 -1
  182. package/src/dashboard/app/pages/FeatureDetail.jsx +139 -129
  183. package/src/dashboard/app/pages/Features.jsx +9 -9
  184. package/src/dashboard/app/pages/Guide.jsx +2 -2
  185. package/src/dashboard/app/pages/PhasePipeline.jsx +3 -4
  186. package/src/dashboard/app/pages/RulesMap.jsx +3 -3
  187. package/src/dashboard/app/pages/SkillsLibrary.jsx +3 -3
  188. package/src/dashboard/app/pages/Standards.jsx +1 -1
  189. package/src/dashboard/scanner/activity-scanner.js +6 -16
  190. package/src/dashboard/scanner/agents-scanner.js +1 -1
  191. package/src/dashboard/scanner/docs-scanner.js +5 -23
  192. package/src/dashboard/scanner/features-scanner.js +95 -60
  193. package/src/dashboard/scanner/index.js +0 -2
  194. package/src/dashboard/scanner/project-api.js +1 -1
  195. package/src/dashboard/scanner/rules-scanner.js +15 -10
  196. package/src/dashboard/scanner/skills-scanner.js +2 -3
  197. package/src/dashboard/scanner/standards-scanner.js +2 -1
  198. package/src/lib/ci/ci-verify.js +17 -1
  199. package/src/lib/ci/github-ci.js +1 -1
  200. package/src/lib/detectors/index.js +3 -8
  201. package/src/lib/generators/handoff-generator.js +34 -65
  202. package/src/lib/generators/settings-generator.js +11 -89
  203. package/src/lib/git/evidence-staleness.js +1 -1
  204. package/src/lib/git/tree-fingerprint.js +19 -7
  205. package/src/lib/git/tree-state.js +2 -2
  206. package/src/lib/heavy/cleanup.js +1 -5
  207. package/src/lib/installers/memory-installer.js +6 -8
  208. package/src/lib/mutation/commands.js +3 -2
  209. package/src/lib/{tasks/dotnet-test-introspection.js → mutation/dotnet-introspection.js} +17 -282
  210. package/src/lib/mutation/plan.js +14 -6
  211. package/src/lib/mutation/runner.js +1 -1
  212. package/src/lib/mutation/subset.js +46 -9
  213. package/src/lib/plan/artifact-vocabulary.js +60 -0
  214. package/src/lib/plan/checks.js +234 -0
  215. package/src/lib/plan/plan-parser.js +209 -0
  216. package/src/lib/plan/plan-template.js +18 -0
  217. package/src/lib/review-reports.js +222 -0
  218. package/src/lib/risk-detector.js +134 -135
  219. package/src/lib/specs/adr-index.js +50 -69
  220. package/src/lib/specs/design-seed.js +18 -0
  221. package/src/lib/specs/frontmatter.js +44 -0
  222. package/src/lib/specs/gfm-table.js +17 -0
  223. package/src/lib/specs/old-format.js +68 -0
  224. package/src/lib/specs/revocations.js +37 -95
  225. package/src/lib/specs/screen-checklist.js +18 -17
  226. package/src/lib/stack/dotnet-build-ignores.js +47 -0
  227. package/src/lib/stack/stack-profile.js +1 -1
  228. package/src/lib/stack/stack-scan.js +267 -0
  229. package/src/lib/standards/registry.js +43 -0
  230. package/src/lib/standards/sections.js +58 -0
  231. package/src/lib/tasks/eval-node.js +4 -12
  232. package/src/lib/tasks/test-nodes.js +1 -74
  233. package/src/lib/tasks/test-runner.js +75 -117
  234. package/src/lib/telemetry/metrics.js +8 -69
  235. package/src/lib/telemetry/telemetry-reader.js +5 -118
  236. package/src/lib/telemetry/verify-event.js +5 -7
  237. package/src/lib/validators/code-budget/code-budget-validator.js +1 -1
  238. package/src/lib/validators/contracts/contract-compliance-validator.js +2 -2
  239. package/src/lib/validators/reuse/reuse-validator.js +24 -48
  240. package/src/lib/validators/reuse/symbol-scanner.js +2 -4
  241. package/src/lib/validators/traceability-check.js +85 -129
  242. package/src/lib/validators/validation-runner.js +8 -88
  243. package/src/lib/validators/verify-runner.js +134 -301
  244. package/src/lib/worktree/docker-audit.js +1 -2
  245. package/src/lib/worktree/fleet-scanner.js +25 -38
  246. package/src/scripts/setup-infra.js +42 -22
  247. package/src/utils/agents-installer.js +92 -13
  248. package/src/utils/claude-settings-manager.js +0 -35
  249. package/src/utils/file-copier.js +34 -6
  250. package/src/utils/hooks-installer.js +16 -9
  251. package/src/utils/skills-installer.js +1 -2
  252. package/framework/commands/commit.md +0 -166
  253. package/framework/evals/trace-schema.md +0 -67
  254. package/framework/hooks/claude-code/core/tasks-json-guard.js +0 -83
  255. package/framework/hooks/claude-code/core/trace-autogen.js +0 -277
  256. package/framework/hooks/git/pre-commit/specs.sh +0 -50
  257. package/framework/hooks/shared/tasks-validator.js +0 -111
  258. package/framework/rubrics/backend.json +0 -41
  259. package/framework/rubrics/default.json +0 -36
  260. package/framework/rubrics/frontend.json +0 -36
  261. package/framework/rules/morph-task-tracking.md +0 -54
  262. package/framework/rules/morph-workflow.md +0 -244
  263. package/framework/schemas/tasks.schema.json +0 -79
  264. package/framework/skills/core/morph-brainstorming/SKILL.md +0 -161
  265. package/framework/skills/core/morph-implement/SKILL.md +0 -194
  266. package/framework/skills/core/morph-proposal/SKILL.md +0 -152
  267. package/framework/skills/core/morph-stack-scan/SKILL.md +0 -145
  268. package/framework/templates/docs/proposal.md +0 -192
  269. package/framework/templates/docs/spec.md +0 -57
  270. package/framework/templates/docs/ui-components.md +0 -52
  271. package/framework/templates/docs/ui-design-system.md +0 -76
  272. package/framework/templates/docs/ui-flows.md +0 -167
  273. package/framework/templates/examples/spec-examples.md +0 -91
  274. package/framework/templates/feature/decisions.md +0 -124
  275. package/framework/templates/feature/recap.md +0 -145
  276. package/framework/templates/project/validate.js +0 -97
  277. package/framework/templates/tasks.template.json +0 -17
  278. package/src/commands/state/usecase.js +0 -143
  279. package/src/commands/tasks/dag.js +0 -181
  280. package/src/dashboard/app/pages/Rubrics.jsx +0 -97
  281. package/src/dashboard/scanner/rubrics-scanner.js +0 -12
  282. package/src/lib/agents/output-collector.js +0 -76
  283. package/src/lib/evaluator-report.js +0 -91
  284. package/src/lib/specs/acervo-format.js +0 -70
  285. package/src/lib/specs/acervo-lifecycle.js +0 -264
  286. package/src/lib/specs/done-criteria-check.js +0 -200
  287. package/src/lib/specs/usecase-check.js +0 -301
  288. package/src/lib/specs/usecase-promoter.js +0 -301
  289. package/src/lib/specs/usecase-registry.js +0 -237
  290. package/src/lib/tasks/dispatch-planner.js +0 -319
  291. package/src/lib/tasks/mermaid-renderer.js +0 -132
  292. package/src/lib/tasks/task-classifier.js +0 -30
  293. package/src/lib/tasks/task-parser.js +0 -209
  294. package/src/lib/tasks/tasks-json-parser.js +0 -296
  295. package/src/lib/tasks/test-scope.js +0 -597
  296. package/src/lib/validators/architecture/architecture-validator.js +0 -270
  297. package/src/lib/validators/architecture/index.js +0 -7
  298. package/src/lib/validators/css/css-validator.js +0 -340
  299. package/src/lib/validators/css/index.js +0 -7
  300. package/src/lib/validators/design-system/design-system-validator.js +0 -237
  301. package/src/lib/validators/design-system/index.js +0 -7
  302. package/src/lib/validators/score-aggregator.js +0 -244
  303. package/src/lib/validators/ui/index.js +0 -7
  304. package/src/lib/validators/ui/ui-contrast-validator.js +0 -422
@@ -29,84 +29,18 @@
29
29
  ],
30
30
  "templates": [
31
31
  {
32
- "id": "proposal",
32
+ "id": "plan",
33
33
  "kind": "template",
34
- "name": "Feature Proposal",
35
- "path": "docs/proposal.md",
36
- "location": "framework",
37
- "category": "documentation",
38
- "phase": "proposal",
39
- "required": true,
40
- "description": "Feature proposal with overview, problem statement, solution approach, and cost estimates",
41
- "outputName": "proposal.md",
42
- "placeholders": [
43
- "AUTHOR",
44
- "DATE",
45
- "STACK"
46
- ],
47
- "stackSpecific": false,
48
- "engine": "handlebars",
49
- "deprecated": false,
50
- "technology": "handlebars",
51
- "validatePlaceholders": true
52
- },
53
- {
54
- "id": "spec",
55
- "kind": "template",
56
- "name": "Technical Specification",
57
- "path": "docs/spec.md",
58
- "location": "framework",
59
- "category": "documentation",
60
- "phase": "plan",
61
- "required": true,
62
- "description": "Detailed technical spec with architecture, data model, API contracts",
63
- "outputName": "spec.md",
64
- "placeholders": [
65
- "DATE",
66
- "FEATURE_NAME",
67
- "STACK"
68
- ],
69
- "stackSpecific": false,
70
- "engine": "handlebars",
71
- "deprecated": false,
72
- "technology": "handlebars",
73
- "validatePlaceholders": true
74
- },
75
- {
76
- "id": "decisions",
77
- "kind": "template",
78
- "name": "Architecture Decision Records",
79
- "path": "feature/decisions.md",
34
+ "name": "Feature Plan",
35
+ "path": "docs/plan.md",
80
36
  "location": "framework",
81
37
  "category": "documentation",
82
38
  "phase": "plan",
83
39
  "required": true,
84
- "description": "ADR format for documenting architectural decisions with context, alternatives, consequences",
85
- "outputName": "decisions.md",
40
+ "description": "Single source of a feature: problem, scenarios (Cn with proof), decisions (ADRs), reuse, slices (Fn) and errata — parsed by morph-spec plan-check into checks.json",
41
+ "outputName": "plan.md",
86
42
  "placeholders": [
87
- "DATE"
88
- ],
89
- "stackSpecific": false,
90
- "engine": "handlebars",
91
- "deprecated": false,
92
- "technology": "handlebars",
93
- "validatePlaceholders": true
94
- },
95
- {
96
- "id": "recap",
97
- "kind": "template",
98
- "name": "Feature Recap",
99
- "path": "feature/recap.md",
100
- "location": "framework",
101
- "category": "documentation",
102
- "phase": "implement",
103
- "required": true,
104
- "description": "Post-implementation summary with deliverables, metrics, lessons learned",
105
- "outputName": "recap.md",
106
- "placeholders": [
107
- "DATE",
108
- "FEATURE_NAME",
109
- "STACK"
43
+ "FEATURE_NAME"
110
44
  ],
111
45
  "stackSpecific": false,
112
46
  "engine": "handlebars",
@@ -132,24 +66,6 @@
132
66
  "technology": "handlebars",
133
67
  "validatePlaceholders": true
134
68
  },
135
- {
136
- "id": "spec-examples",
137
- "kind": "template",
138
- "name": "Spec Examples",
139
- "path": "examples/spec-examples.md",
140
- "location": "framework",
141
- "category": "examples",
142
- "phase": null,
143
- "required": false,
144
- "description": "Example technical specs for reference",
145
- "outputName": null,
146
- "placeholders": [],
147
- "stackSpecific": false,
148
- "engine": null,
149
- "deprecated": false,
150
- "technology": null,
151
- "validatePlaceholders": true
152
- },
153
69
  {
154
70
  "id": "design-system-examples",
155
71
  "kind": "template",
@@ -614,71 +530,6 @@
614
530
  "technology": "handlebars",
615
531
  "validatePlaceholders": true
616
532
  },
617
- {
618
- "id": "ui-flows",
619
- "kind": "template",
620
- "name": "UI Flows",
621
- "path": "docs/ui-flows.md",
622
- "location": "framework",
623
- "category": "documentation",
624
- "phase": "uiux",
625
- "required": false,
626
- "description": "User flows and interaction patterns with state diagrams and edge cases",
627
- "outputName": "flows.md",
628
- "placeholders": [
629
- "DATE",
630
- "FEATURE_NAME"
631
- ],
632
- "stackSpecific": false,
633
- "engine": "handlebars",
634
- "deprecated": false,
635
- "technology": "handlebars",
636
- "validatePlaceholders": true
637
- },
638
- {
639
- "id": "ui-components",
640
- "kind": "template",
641
- "name": "UI Components",
642
- "path": "docs/ui-components.md",
643
- "location": "framework",
644
- "category": "documentation",
645
- "phase": "uiux",
646
- "required": false,
647
- "description": "Component specifications mapping UI elements to shadcn/ui components with props and events",
648
- "outputName": "components.md",
649
- "placeholders": [
650
- "DATE",
651
- "FEATURE_NAME",
652
- "STACK"
653
- ],
654
- "stackSpecific": false,
655
- "engine": "handlebars",
656
- "deprecated": false,
657
- "technology": "handlebars",
658
- "validatePlaceholders": true
659
- },
660
- {
661
- "id": "ui-design-system",
662
- "kind": "template",
663
- "name": "UI Design System",
664
- "path": "docs/ui-design-system.md",
665
- "location": "framework",
666
- "category": "documentation",
667
- "phase": "uiux",
668
- "required": false,
669
- "description": "Design system documentation with color palette, typography, spacing, and semantic tokens",
670
- "outputName": "design-system.md",
671
- "placeholders": [
672
- "DATE",
673
- "FEATURE_NAME",
674
- "PROJECT_NAME"
675
- ],
676
- "stackSpecific": false,
677
- "engine": "handlebars",
678
- "deprecated": false,
679
- "technology": "handlebars",
680
- "validatePlaceholders": true
681
- },
682
533
  {
683
534
  "id": "github-workflow-dotnet-build",
684
535
  "kind": "template",
@@ -1460,21 +1311,6 @@
1460
1311
  "TIMESTAMP"
1461
1312
  ],
1462
1313
  "validatePlaceholders": true
1463
- },
1464
- {
1465
- "id": "tasks-template",
1466
- "kind": "template",
1467
- "consumption": "reference",
1468
- "name": "tasks.json",
1469
- "path": "tasks.template.json",
1470
- "category": "context",
1471
- "phase": null,
1472
- "outputName": null,
1473
- "description": "Initial tasks.json scaffold",
1474
- "engine": "handlebars",
1475
- "deprecated": false,
1476
- "placeholders": [],
1477
- "validatePlaceholders": true
1478
1314
  }
1479
1315
  ]
1480
1316
  }
@@ -183,10 +183,10 @@ internal sealed class Create{{pascalCase FEATURE_NAME}}Endpoint : IApiEndpoint
183
183
  var result = await handler.HandleAsync(command, cancellationToken);
184
184
  return result.Match(
185
185
  onSuccess: () => Results.Ok(result.Value),
186
- onFailure: error => Results.BadRequest(error));
186
+ onFailure: error => error.ToHttpResult());
187
187
  })
188
188
  .WithTags("{{pascalCase FEATURE_NAME}}s")
189
189
  .Produces<Create{{pascalCase FEATURE_NAME}}Response>(StatusCodes.Status200OK)
190
- .Produces(StatusCodes.Status400BadRequest);
190
+ .ProducesProblem(StatusCodes.Status400BadRequest);
191
191
  }
192
192
  }
@@ -11,7 +11,7 @@ namespace {{pascalCase PROJECT_NAME}}.Extensions
11
11
 
12
12
  services.AddDbContext<ApplicationDbContext>(options =>
13
13
  {
14
- options.UseNpgsql(configuration.GetConnectionString("connection"));
14
+ options.UseNpgsql(configuration.GetConnectionString("DefaultConnection"));
15
15
  });
16
16
 
17
17
  return services;
@@ -25,3 +25,30 @@ public static class ResultExtensions
25
25
  : onFailure(result.Error);
26
26
  }
27
27
  }
28
+
29
+ public static class ErrorHttpMapping
30
+ {
31
+ public static int StatusCodeFor(ErrorType type) => type switch
32
+ {
33
+ ErrorType.Validation => StatusCodes.Status400BadRequest,
34
+ ErrorType.NotFound => StatusCodes.Status404NotFound,
35
+ ErrorType.Conflict => StatusCodes.Status409Conflict,
36
+ ErrorType.Unauthorized => StatusCodes.Status401Unauthorized,
37
+ ErrorType.Forbidden => StatusCodes.Status403Forbidden,
38
+ ErrorType.Unexpected => StatusCodes.Status500InternalServerError,
39
+ _ => StatusCodes.Status400BadRequest
40
+ };
41
+
42
+ public static IResult ToHttpResult(this Error error)
43
+ {
44
+ Dictionary<string, object?>? extensions = error is ValidationError validation
45
+ ? new() { ["errors"] = validation.Errors.Select(e => new { e.Code, e.Description }).ToArray() }
46
+ : null;
47
+
48
+ return Results.Problem(
49
+ title: error.Code,
50
+ detail: error.Description,
51
+ statusCode: StatusCodeFor(error.Type),
52
+ extensions: extensions);
53
+ }
54
+ }
@@ -12,10 +12,10 @@ internal sealed class {{pascalCase SLICE_NAME}}Endpoint : IApiEndpoint
12
12
  var result = await handler.HandleAsync(command, cancellationToken);
13
13
  return result.Match(
14
14
  onSuccess: () => Results.Ok(result.Value),
15
- onFailure: error => Results.BadRequest(error));
15
+ onFailure: error => error.ToHttpResult());
16
16
  })
17
17
  .WithTags(ApiTags.{{pascalCase FEATURE_NAME}}s)
18
18
  .Produces<{{pascalCase SLICE_NAME}}Response>(StatusCodes.Status200OK)
19
- .Produces(StatusCodes.Status400BadRequest);
19
+ .ProducesProblem(StatusCodes.Status400BadRequest);
20
20
  }
21
21
  }
@@ -0,0 +1,72 @@
1
+ # Plano — {{FEATURE_NAME}}
2
+
3
+ <!-- Fonte única da feature. `morph-spec plan-check {{FEATURE_NAME}}` lê este arquivo e grava 2-plan/checks.json.
4
+ Depois do gate plan, o corpo congela: fato errado sobre o código vai em ## Errata (append-only). -->
5
+
6
+ ## Problema
7
+
8
+ <O que dói hoje, para quem, e como se percebe. Duas a cinco frases.>
9
+
10
+ ## Fora de escopo
11
+
12
+ - <o que esta feature deliberadamente não faz>
13
+
14
+ ## Suposições não confirmadas
15
+
16
+ - <o que foi assumido sem prova; "nenhuma" vale>
17
+
18
+ ## Cenários
19
+
20
+ <!-- Um cenário por comportamento observável. `prova:` é teste | e2e | eval | manual.
21
+ Cenário que fala de arquivo, grep ou texto exige a linha "> Por que artefato:" logo abaixo. -->
22
+
23
+ - **C1** — Dado <estado>, quando <ação>, então <resultado observável>.
24
+ prova: teste
25
+
26
+ ## Decisões
27
+
28
+ ### ADR-001 — <título>
29
+ **Alcance:** feature
30
+
31
+ <Contexto, decisão e consequência. `projeto` quando a decisão vale além desta feature.>
32
+
33
+ ### Conflitos com o acervo
34
+
35
+ <!-- ADR do índice (.morph/specs/adrs/) que este plano contradiz: "nenhum", ou a tabela abaixo fora do bloco.
36
+ O finish aplica cada linha: total retira o ADR do índice; parcial o mantém com o escopo onde ainda vale.
37
+ ```
38
+ | ADR | Mudança | Escopo em que o antigo ainda vale |
39
+ |---|---|---|
40
+ | {feature}/ADR-{nnn} | parcial | <onde o antigo ainda vale> |
41
+ | {feature}/ADR-{nnn} | total | — |
42
+ ```
43
+ -->
44
+
45
+ nenhum
46
+
47
+ ## Arquitetura
48
+
49
+ <Onde o código entra, o que conversa com o quê. Diagrama só se ajudar.>
50
+
51
+ ## Reuso
52
+
53
+ | conceito | veredito | alvo | why |
54
+ |---|---|---|---|
55
+ | <conceito> | REUSAR | <arquivo ou símbolo existente> | |
56
+
57
+ ## Fatias
58
+
59
+ <!-- Uma fatia = uma unidade de entrega (com ou sem dispatch), relatório em 3-implement/reports/Fn.md.
60
+ arquivos ≤ 8; superfície e depende são opcionais; toda Cn é coberta por alguma fatia. -->
61
+
62
+ ### F1 — <título>
63
+ - persona: dotnet-senior
64
+ - standards: <id>
65
+ - arquivos: <caminho/a.cs>, <caminho/b.cs>
66
+ - cobre: C1
67
+
68
+ ## Contrato de implementação
69
+
70
+ <Assinaturas, records, enums e rotas que as fatias precisam honrar.>
71
+
72
+ ## Errata
@@ -58,15 +58,7 @@ dotnet test --solution Morph.AiKit.sln -c Release --no-build
58
58
  > do `morph-spec verify`); por isso nenhum chamador repassa a flag. Ao adicionar
59
59
  > testes, suba o piso — `test/framework/ai-kit-ci-packaging.test.js` reprova um
60
60
  > piso que ficou para trás da contagem de `[Fact]`/`[Theory]`.
61
- > **Consequência para o recorte por task:** `--minimum-expected-tests 1` na
62
- > linha de comando não sobrescreve o valor do projeto (medido: o recorte verde
63
- > sai 9 do mesmo jeito), mas a propriedade global do MSBuild sim. Por isso
64
- > `morph-spec verify {f} {task}` estreita este projeto repassando
65
- > `"-p:TestingPlatformCommandLineArguments=…"` com o valor do `.csproj` e o piso
66
- > em 1 — verde sai 0, zero testes segue saindo 8, nada recompila (issue #114).
67
- > Mantenha o piso **nesse** elemento, literal (sem `Condition`, sem `$(…)`, sem
68
- > outra declaração da propriedade em `Directory.Build.*`): em qualquer outra
69
- > forma o recorte volta a rodar o nó inteiro.
61
+
70
62
 
71
63
  > **`dotnet test` precisa rodar COM O CWD DENTRO deste diretório.** O opt-in do
72
64
  > Microsoft.Testing.Platform (que `xunit.v3` 4.x usa) vive em `global.json`, e o
@@ -49,7 +49,7 @@ public sealed class MediaDisclosureTests
49
49
  Assert.False(
50
50
  result.IsSuccess,
51
51
  "publicar sem marcacao e o caminho que a obrigacao legal existe para fechar; " +
52
- "se ele existe, a afirmacao da rubrica media-claims esta presa so por prosa");
52
+ "se ele existe, a prova de midia do Gate 3 esta presa so por prosa");
53
53
  Assert.Equal(MediaErrorCode.InvalidTransition, result.Error!.Code);
54
54
  Assert.Contains("marcacao", result.Error.Message, StringComparison.OrdinalIgnoreCase);
55
55
  }
@@ -30,16 +30,6 @@
30
30
  de workflow. Uma unica verdade: nenhum chamador repassa a flag na linha de
31
31
  comando, porque repassa-la duplicaria a opcao.
32
32
 
33
- Consequencia para o recorte por task (`morph-spec verify {f} {task}`): a
34
- mesma opcao com valor 1 na linha de comando NAO sobrescreve o valor do
35
- projeto (medido: o recorte verde sai 9 do mesmo jeito), mas a propriedade
36
- global do MSBuild sim. O recorte estreita este projeto repassando
37
- "-p:TestingPlatformCommandLineArguments=" com ESTE valor e o piso em 1
38
- (issue #114: verde sai 0, zero testes segue saindo 8, nada recompila). Por
39
- isso o piso fica NESTE elemento, literal: sem Condition, sem $(...), sem
40
- outra declaracao da propriedade em Directory.Build.* — em qualquer outra
41
- forma o recorte volta a rodar o no inteiro.
42
-
43
33
  O numero e o total de CASOS EXECUTADOS (275), nao de atributos nem de casos
44
34
  DESCOBERTOS (276): os [Theory] expandem, e um caso IGNORADO nao conta para o piso — a
45
35
  suite descobre 276 e executa 275, porque o semeador da cache exemplar de eval
@@ -3,10 +3,10 @@
3
3
  "provider": "coolify",
4
4
  "access": {
5
5
  "method": "ssh",
6
- "note": "No MCP/CLI exists for Coolify — replace sshHost with the real SSH alias for the target VPS. The API is reached only from inside the VPS, at apiBaseUrl.",
6
+ "note": "We use no Coolify MCP/CLI — replace sshHost with the real SSH alias for the target VPS and tokenPath with the chmod-600 token file in that user's home. The API is reached only from inside the VPS, at apiBaseUrl; the deploy trigger is POST /deploy?uuid= (GET is refused by Coolify 4.3.23).",
7
7
  "sshHost": "REPLACE_WITH_VPS_SSH_ALIAS",
8
8
  "apiBaseUrl": "http://localhost:8000/api/v1",
9
- "tokenPath": "~/.coolify-token"
9
+ "tokenPath": "~/REPLACE_WITH_TOKEN_FILE"
10
10
  },
11
11
  "application": {
12
12
  "uuid": "REPLACE_WITH_COOLIFY_APPLICATION_UUID",
@@ -45,5 +45,5 @@
45
45
  "https": true
46
46
  }
47
47
  ],
48
- "deployCommand": "ssh REPLACE_WITH_VPS_SSH_ALIAS 'T=$(cat ~/.coolify-token); curl -s -X GET -H \"Authorization: Bearer $T\" \"http://localhost:8000/api/v1/deploy?uuid=REPLACE_WITH_COOLIFY_APPLICATION_UUID\"'"
48
+ "deployCommand": "ssh REPLACE_WITH_VPS_SSH_ALIAS 'T=$(cat ~/REPLACE_WITH_TOKEN_FILE); curl -s -X POST -H \"Authorization: Bearer $T\" \"http://localhost:8000/api/v1/deploy?uuid=REPLACE_WITH_COOLIFY_APPLICATION_UUID\"'"
49
49
  }
@@ -39,7 +39,8 @@ infrastructure/github/
39
39
  - Push to container registry (GHCR or Docker Hub)
40
40
 
41
41
  ### Deploy Coolify (`deploy-coolify.yml.hbs`)
42
- - SSHes into the VPS and calls the local Coolify API (`localhost:8000/api/v1/deploy?uuid=...`) after Docker push
42
+ - SSHes into the VPS and calls the local Coolify API (`POST localhost:8000/api/v1/deploy?uuid=...`) after Docker push; the step fails unless the response carries a `deployment_uuid`
43
+ - The token is read on the VPS from `~/<token-file>` (secret `COOLIFY_TOKEN_FILE` holds the file name) and never leaves the SSH session
43
44
  - Runs health check after deployment
44
45
  - Supports staging + production environments
45
46
 
@@ -25,7 +25,8 @@ jobs:
25
25
  - name: Trigger Coolify Deploy (via SSH — the Coolify API is not publicly exposed)
26
26
  run: |
27
27
  ssh -i ~/.ssh/id_ed25519 ${{{{ secrets.COOLIFY_SSH_USER }}}}@${{{{ secrets.COOLIFY_SSH_HOST }}}} \
28
- 'T=$(cat ~/.coolify-token); curl -s -X GET -H "Authorization: Bearer $T" "http://localhost:8000/api/v1/deploy?uuid=${{{{ secrets.COOLIFY_APPLICATION_UUID }}}}"'
28
+ 'T=$(cat ~/${{{{ secrets.COOLIFY_TOKEN_FILE }}}}); curl -s --fail-with-body -X POST -H "Authorization: Bearer $T" "http://localhost:8000/api/v1/deploy?uuid=${{{{ secrets.COOLIFY_APPLICATION_UUID }}}}"' \
29
+ | grep -q deployment_uuid
29
30
 
30
31
  - name: Health Check
31
32
  run: |
@@ -78,7 +78,7 @@ Backend deliverables typically include:
78
78
  2. Create migrations before writing service logic
79
79
  3. Implement services with proper unit-testable interfaces
80
80
  4. Wire up API endpoints last (depends on services)
81
- 5. After every 3 tasks, persist completed tasks to `tasks.json` (`status`/`outputs`/`notes` only) and run the checkpoint
81
+ 5. After every 3 slices, write each finished slice's report (`3-implement/reports/F{n}.md`) and run the checkpoint
82
82
  6. If blocked (compilation error, migration conflict), document and continue with next unblocked task
83
83
 
84
84
  ## Report Back When Done
@@ -72,7 +72,7 @@ Frontend deliverables typically include:
72
72
  2. Build reusable sub-components before composing pages
73
73
  3. Wire up API calls/services last (after UI is structured)
74
74
  4. Test each component with loading + error + empty states
75
- 5. After every 3 tasks, persist completed tasks to `tasks.json` (`status`/`outputs`/`notes` only) and run the checkpoint
75
+ 5. After every 3 slices, write each finished slice's report (`3-implement/reports/F{n}.md`) and run the checkpoint
76
76
 
77
77
  ## Report Back When Done
78
78
  Provide a summary of:
@@ -32,7 +32,7 @@ You are a **Squad Leader** in the MORPH-SPEC agent hierarchy.
32
32
  ## How to Work
33
33
  1. Read your standards carefully before starting
34
34
  2. Implement each task in order (respecting dependencies)
35
- 3. After every 3 tasks, persist completed tasks to `tasks.json` (`status`/`outputs`/`notes` only) and run the checkpoint
35
+ 3. After every 3 slices, write each finished slice's report (`3-implement/reports/F{n}.md`) and run the checkpoint
36
36
  4. If blocked, document the blocker and continue with the next unblocked task
37
37
  5. Report completion with: files created, any blockers, checkpoint results
38
38
 
@@ -46,11 +46,10 @@ If `.morph/framework/agents.json` is in staged files:
46
46
  - No duplicate agentIds
47
47
  - Valid tier values (1-4)
48
48
 
49
- ### 4. Spec Format Validation (if spec.md staged)
50
- If any `spec.md` is staged:
51
- - Has required sections: Overview, Requirements, Technical Design, Data Model, API Contracts
49
+ ### 4. Plan Format Validation (if plan.md staged)
50
+ If any `.morph/features/*/2-plan/plan.md` is staged:
51
+ - `morph-spec plan-check <feature>` exits 0 (sections, scenarios with `prova:`, slices that cover them)
52
52
  - No placeholder text (`{{TODO}}`, `TBD`, `[PLACEHOLDER]`)
53
- - Word count > 200 (meaningful spec)
54
53
 
55
54
  ### 5. Stack-Specific Validation
56
55
  {{#if IS_CSHARP}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polymorphism-tech/morph-spec",
3
- "version": "8.46.0",
3
+ "version": "9.0.0",
4
4
  "description": "MORPH-SPEC: NLH (Natural Language Harness) for spec-driven development with Claude Code",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -232,7 +232,7 @@ export async function e2eUpCommand(featureName, options = {}) {
232
232
  /**
233
233
  * Where the app actually landed.
234
234
  *
235
- * The reviewer hands this to the evaluator instead of letting it guess
235
+ * The orchestrator hands this to the verifier instead of letting it guess
236
236
  * `localhost:3000` — each feature owns a port block, so the default port is the
237
237
  * one address most likely to be wrong. Mirrors what `playwright.config.ts` is
238
238
  * asked to do, deliberately: one rule, two readers.
@@ -331,7 +331,7 @@ export async function e2eDownCommand(featureName, options = {}) {
331
331
  volumes: Boolean(options.volumes),
332
332
  });
333
333
  const stampDeleted = deleteStamp(ctx.gitCommonDir, ctx.projectName);
334
- const cleanup = afterHeavyRun({ projectPath: ctx.cwd, config: readHeavyConfig(ctx.cwd), scope: 'e2e-down' });
334
+ const cleanup = afterHeavyRun({ projectPath: ctx.cwd, config: readHeavyConfig(ctx.cwd) });
335
335
 
336
336
  if (options.json) {
337
337
  console.log(JSON.stringify(