@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
@@ -1,111 +0,0 @@
1
- /**
2
- * tasks-validator.js — minimal hook-side schema validation for tasks.json.
3
- *
4
- * Mirrors VALID_STATUS / VALID_EFFORT from src/lib/tasks/tasks-json-parser.js.
5
- * Hooks are installed standalone into target projects (.morph/framework/hooks/),
6
- * so they cannot import from src/ — the enum lives here, duplicated on purpose
7
- * and covered by tests on both sides.
8
- */
9
-
10
- export const VALID_TASK_STATUS = ['pending', 'in_progress', 'done', 'skipped', 'blocked'];
11
- export const VALID_TASK_EFFORT = ['S', 'M', 'L', 'XL'];
12
-
13
- /**
14
- * Validate the parts of a tasks.json document that hooks care about:
15
- * a tasks[] array whose entries carry a valid status (and effort, when set).
16
- * The production failure this guards: a leaf agent writing status "completed"
17
- * (not in the enum) without any validation.
18
- *
19
- * @param {object} doc - parsed tasks.json
20
- * @returns {{ valid: boolean, errors: string[] }}
21
- */
22
- /** Human-readable type name for error messages ('array', not 'object'). */
23
- function typeName(value) {
24
- return Array.isArray(value) ? 'array' : typeof value;
25
- }
26
-
27
- export function validateTasksDoc(doc) {
28
- if (!doc || typeof doc !== 'object' || !Array.isArray(doc.tasks)) {
29
- return { valid: false, errors: ['tasks.json must be an object with a tasks[] array'] };
30
- }
31
-
32
- const errors = [];
33
- for (const task of doc.tasks) {
34
- const id = task?.id ?? '?';
35
- if (!VALID_TASK_STATUS.includes(task?.status)) {
36
- errors.push(`task '${id}': invalid status '${task?.status}' (valid: ${VALID_TASK_STATUS.join(', ')})`);
37
- }
38
- if (task?.effort !== undefined && !VALID_TASK_EFFORT.includes(task.effort)) {
39
- errors.push(`task '${id}': invalid effort '${task.effort}' (valid: ${VALID_TASK_EFFORT.join(', ')})`);
40
- }
41
- // Mutable-field type checks with the exact field/value in the message —
42
- // a malformed notes/outputs used to surface as the misleading generic
43
- // "notes is empty" downstream (MORPH_GHLBrain 2026-07-11).
44
- if (task?.notes !== undefined && typeof task.notes !== 'string') {
45
- errors.push(`task '${id}': 'notes' must be a string (got ${typeName(task.notes)})`);
46
- }
47
- if (task?.outputs !== undefined) {
48
- if (!Array.isArray(task.outputs)) {
49
- errors.push(`task '${id}': 'outputs' must be an array of path strings (got ${typeName(task.outputs)})`);
50
- } else {
51
- task.outputs.forEach((entry, i) => {
52
- if (typeof entry !== 'string') {
53
- errors.push(`task '${id}': outputs[${i}] must be a string path (got ${typeName(entry)})`);
54
- }
55
- });
56
- }
57
- }
58
- }
59
- return { valid: errors.length === 0, errors };
60
- }
61
-
62
- /**
63
- * Planned-vs-real outputs divergence: tasks whose `outputs` changed relative
64
- * to the previous document but whose `notes` is still empty. The divergence
65
- * itself is legitimate (outputs is a mutable progress field) — shipping it
66
- * without an explanatory note is what gets flagged.
67
- *
68
- * @param {object} oldDoc - parsed previous tasks.json
69
- * @param {object} newDoc - parsed proposed tasks.json
70
- * @returns {string[]} human-readable violation messages (empty = OK)
71
- */
72
- /** Compact outputs rendering for messages, capped so huge arrays stay readable. */
73
- function fmtOutputs(outputs) {
74
- const s = JSON.stringify(outputs ?? []);
75
- return s.length > 120 ? s.slice(0, 117) + '...' : s;
76
- }
77
-
78
- export function outputsDivergenceViolations(oldDoc, newDoc) {
79
- const violations = [];
80
- const oldById = new Map((oldDoc?.tasks ?? []).map(t => [t.id, t]));
81
-
82
- for (const task of newDoc?.tasks ?? []) {
83
- const old = oldById.get(task.id);
84
- if (!old) continue;
85
- const outputsChanged =
86
- JSON.stringify(old.outputs ?? []) !== JSON.stringify(task.outputs ?? []);
87
- if (!outputsChanged) continue;
88
-
89
- // A filled string note explains the divergence — done.
90
- if (typeof task.notes === 'string' && task.notes.trim().length > 0) continue;
91
-
92
- // Root-cause specific messages: a malformed notes value is a DIFFERENT
93
- // failure than a missing one — claiming "notes is empty" when the agent
94
- // just wrote an array reads as a false positive and burns a retry cycle.
95
- if (task.notes !== undefined && typeof task.notes !== 'string') {
96
- violations.push(
97
- `task '${task.id}': outputs diverged from the plan and 'notes' is not a string ` +
98
- `(got ${typeName(task.notes)}) — write the explanation as a single string in 'notes'`
99
- );
100
- continue;
101
- }
102
-
103
- violations.push(
104
- `task '${task.id}': outputs diverged from the plan ` +
105
- `(${fmtOutputs(old.outputs)} → ${fmtOutputs(task.outputs)}) but 'notes' is empty — ` +
106
- `record why in 'notes' in the same edit. ` +
107
- `Deletions and annotations belong in 'notes', not in 'outputs' (outputs = produced paths only).`
108
- );
109
- }
110
- return violations;
111
- }
@@ -1,41 +0,0 @@
1
- {
2
- "id": "backend",
3
- "version": "1.1.0",
4
- "description": "Backend-focused rubric. Higher weight on architecture, security, and package health. Deterministic-validator weights for the verify validators node; the score is informational — the node fails on validator errors.",
5
- "categories": {
6
- "functionality": {
7
- "weight": 0.25,
8
- "validators": ["contract-compliance"],
9
- "description": "Core feature correctness and contract compliance"
10
- },
11
- "code_quality": {
12
- "weight": 0.25,
13
- "validators": ["architecture", "reuse", "code-budget"],
14
- "description": "Architecture patterns, dependency direction, code structure, reuse of what the codebase already has, and comment and test budget"
15
- },
16
- "design_ui": {
17
- "weight": 0.05,
18
- "validators": ["design-system", "css", "contrast", "nextjs-component"],
19
- "description": "Design system compliance (minimal weight for backend projects)"
20
- },
21
- "security": {
22
- "weight": 0.15,
23
- "validators": [],
24
- "description": "Security posture (agent-evaluated, no automated validator)"
25
- },
26
- "packages": {
27
- "weight": 0.20,
28
- "validators": ["packages"],
29
- "description": "Dependency health, version compatibility, and deprecated packages"
30
- },
31
- "maf_compliance": {
32
- "weight": 0.10,
33
- "validators": [],
34
- "description": "MAF agent compliance (agent-evaluated, applies only when the feature touches AI agents): Microsoft.Agents.AI GA packages used; Model Registry alias referenced not hardcoded models; structured output for pipelined agents; prompts from DB not hardcoded; no Semantic Kernel; no hosted agent services."
35
- }
36
- },
37
- "thresholds": {
38
- "approve": 9.0,
39
- "retry": 6.0
40
- }
41
- }
@@ -1,36 +0,0 @@
1
- {
2
- "id": "default",
3
- "version": "1.1.0",
4
- "description": "Default rubric for general-purpose projects. Balanced weights across all categories. Deterministic-validator weights for the verify validators node; the score is informational — the node fails on validator errors.",
5
- "categories": {
6
- "functionality": {
7
- "weight": 0.30,
8
- "validators": ["contract-compliance"],
9
- "description": "Core feature correctness and contract compliance"
10
- },
11
- "code_quality": {
12
- "weight": 0.25,
13
- "validators": ["architecture", "reuse", "code-budget"],
14
- "description": "Architecture patterns, code structure, reuse of what the codebase already has, and comment and test budget"
15
- },
16
- "design_ui": {
17
- "weight": 0.15,
18
- "validators": ["design-system", "css", "contrast", "nextjs-component"],
19
- "description": "Design system compliance, CSS quality, and UI correctness"
20
- },
21
- "security": {
22
- "weight": 0.15,
23
- "validators": [],
24
- "description": "Security posture (agent-evaluated, no automated validator)"
25
- },
26
- "packages": {
27
- "weight": 0.15,
28
- "validators": ["packages"],
29
- "description": "Dependency health and compatibility"
30
- }
31
- },
32
- "thresholds": {
33
- "approve": 9.0,
34
- "retry": 6.0
35
- }
36
- }
@@ -1,36 +0,0 @@
1
- {
2
- "id": "frontend",
3
- "version": "1.1.0",
4
- "description": "Frontend-focused rubric. Higher weight on design system compliance and UI quality. Deterministic-validator weights for the verify validators node; the score is informational — the node fails on validator errors.",
5
- "categories": {
6
- "functionality": {
7
- "weight": 0.25,
8
- "validators": ["contract-compliance"],
9
- "description": "Core feature correctness and contract compliance"
10
- },
11
- "code_quality": {
12
- "weight": 0.15,
13
- "validators": ["architecture", "reuse", "code-budget"],
14
- "description": "Architecture patterns, code structure, reuse of what the codebase already has, and comment and test budget"
15
- },
16
- "design_ui": {
17
- "weight": 0.35,
18
- "validators": ["design-system", "css", "contrast", "nextjs-component"],
19
- "description": "Design system compliance, CSS quality, contrast ratios, and component correctness"
20
- },
21
- "security": {
22
- "weight": 0.10,
23
- "validators": [],
24
- "description": "Security posture (agent-evaluated, no automated validator)"
25
- },
26
- "packages": {
27
- "weight": 0.15,
28
- "validators": ["packages"],
29
- "description": "Dependency health and compatibility"
30
- }
31
- },
32
- "thresholds": {
33
- "approve": 9.0,
34
- "retry": 6.0
35
- }
36
- }
@@ -1,54 +0,0 @@
1
- ---
2
- stacks:
3
- - "*"
4
- ---
5
-
6
- # MORPH-SPEC Task Tracking
7
-
8
- > Progress lives in `tasks.json` — nowhere else. There is no CLI command to mark a task done and
9
- > no session-level checklist to keep in sync: this file IS the record of what happened.
10
-
11
- ## Persisting Progress to `tasks.json`
12
-
13
- To record task progress for the feature, write `.morph/features/{feature}/2-plan/tasks.json`,
14
- touching ONLY the mutable fields:
15
-
16
- - `status` — `pending` → `in_progress` → `done` (também: `skipped`, `blocked`)
17
- - `outputs` — the files the task produced
18
- - `notes` — free-text record (deviations, context, resolved blockers)
19
-
20
- > **O status terminal é `done`.** `completed` **não existe** no enum de
21
- > `.morph/framework/schemas/tasks.schema.json` — é vocabulário de outro sistema, e o hook
22
- > `protect-spec-files` rejeita a gravação.
23
-
24
- The plan contract — `title`, `description`, `dependencies`, `effort`, `doneCriteria`,
25
- `group`, `agent`, `standards` — is frozen after Gate 2. Any attempt to change it is
26
- blocked by the `protect-spec-files` hook. `agent` (persona id, no `morph-` prefix)
27
- and `standards` (paths pinned by morph-plan) are optional — legacy plans without
28
- them remain valid.
29
-
30
- Use the `Write` tool (whole-file rewrite) OR the `Edit` tool — `Edit` is allowed
31
- as long as it touches only `status`, `outputs`, and `notes`. State is then synced
32
- automatically by the `state-sync` PostToolUse hook; you do not call a CLI to mark
33
- output.
34
-
35
- Update each task as you go — `in_progress` when you pick it up, `done` when it is finished —
36
- rather than batching every write to the end of the phase. `morph-spec status`, `dag`, `verify`
37
- and the dashboard all read this file, so a stale `tasks.json` is a blind orchestrator.
38
-
39
- ## Deviation Tracking
40
-
41
- When completing a task differently than originally planned, record the reason in the
42
- task's `notes` field. `notes` is **uma única string** (o schema declara
43
- `"notes": { "type": "string" }`) — para registrar mais de um desvio, separe-os com
44
- `;` ou `\n` dentro da mesma string. Um array é **rejeitado** pelo validador, com a
45
- mensagem `'notes' must be a string`.
46
-
47
- ```json
48
- {
49
- "id": "T3",
50
- "status": "done",
51
- "outputs": ["Features/User/Update/Handler.cs"],
52
- "notes": "deviation: split validation into a separate validator for testability; blocker-resolved: EF migration conflict fixed by regenerating the snapshot"
53
- }
54
- ```
@@ -1,244 +0,0 @@
1
- ---
2
- stacks:
3
- - "*"
4
- ---
5
-
6
- # MORPH-SPEC Workflow Rules
7
-
8
- > Always-active rules for all MORPH-SPEC managed projects.
9
-
10
- ---
11
-
12
- ## Spec-First Mandate
13
-
14
- **NEVER skip to code without a specification.** Every feature must progress through phases:
15
-
16
- 1. **Proposal** — Problem statement + scope + risks (`0-proposal/proposal.md`). No acceptance criteria: verifiable behaviour lives in the use cases.
17
- 2. **UI/UX Design** (optional, UI-heavy) — Design system + mockups + flows. The phase id is `uiux` (that is the gate name); the folder is `1-design/`
18
- 3. **Plan** — Use cases first, then technical spec + tasks (`2-plan/usecases/UC-{nn}-{slug}.md`, `spec.md`, `tasks.json`). Each use case post-condition must be observable in a test and reaches the task's `doneCriteria` verbatim.
19
- 4. **Implement** — Code + recap (`3-implement/recap.md`)
20
- 5. **Review** — Review report + Gate 3 (`4-review/review-report.md`)
21
-
22
- ---
23
-
24
- ## Phase Sequence
25
-
26
- ```
27
- proposal → [uiux] → plan → implement → review
28
- ```
29
-
30
- Use `morph-spec status {feature}` to see current phase and pending approval gates.
31
-
32
- ---
33
-
34
- ## Phase Commands
35
-
36
- | Command | Purpose |
37
- |---------|---------|
38
- | `/morph-proposal {feature}` | Business understanding + plan — pauses at Gate 1 and Gate 2 |
39
- | `/morph-apply {feature}` | Autonomous execution + review — pauses at Gate 3 |
40
- | `/morph-status` | Feature dashboard |
41
-
42
- The full slash-command and CLI surface lives in the resident `.claude/CLAUDE.md` and in
43
- `.morph/framework/CLI.md` — this table only carries the three phase entry points.
44
-
45
- ---
46
-
47
- ## State & Outputs
48
-
49
- | Path | Notes |
50
- |------|-------|
51
- | `.morph/features/{feature}/feature.json` | **Authoritative + committed** feature state. Write it through the CLI (`create`, `score`, `gate-check`, `approve`) — a hand Edit collides with the `state-sync` hook |
52
- | `.morph/state.json` | **READ-ONLY** — thin, gitignored index rebuilt from `feature.json` on load; kept in sync by the `state-sync` hook |
53
- | `.morph/features/{feature}/{phase}/` | Feature outputs organized by phase |
54
- | `.morph/framework/` | **READ-ONLY** — framework files managed by morph-spec |
55
- | `.morph/config/config.json` | Project configuration (editable) |
56
-
57
- ### output types
58
-
59
- The canonical filename and phase folder of every output type are fixed by
60
- morph-spec itself — the concrete paths are in the table below. State sync is
61
- handled automatically by the `state-sync.js` PostToolUse hook: write the file
62
- at the right path and it is recorded; the agent does not call any CLI to
63
- register an output.
64
-
65
- ---
66
-
67
- ## Output Paths
68
-
69
- All outputs go in `.morph/features/{feature}/`:
70
-
71
- | Phase | Path |
72
- |-------|------|
73
- | Proposal | `0-proposal/proposal.md`, `stack-scan.md` |
74
- | Design (optional) | `1-design/design-system.md`, `mockups.md`, `components.md`, `flows.md` |
75
- | Plan | `2-plan/usecases/`, `spec.md`, `tasks.json`, `decisions.md` |
76
- | Implement | `3-implement/recap.md` + source code; `3-implement/evidencias/{taskId}.md` (condicional — task cujo `doneCriteria` julga saída de LLM) |
77
- | Review | `4-review/review-report.md` |
78
-
79
- ---
80
-
81
- ## Formato obrigatório do `3-implement/recap.md`
82
-
83
- > Esta exigência é **cobrada por hook** (`validate-completion`, no Stop). Ela está aqui, na regra
84
- > sempre-ativa, e não só na skill `morph-implement`: descobrir o formato quando o hook dispara
85
- > significa reescrever o recap depois de a fase já estar dada por encerrada.
86
-
87
- **Para CADA task com `status: "done"` em `tasks.json`**, o recap precisa de um bloco próprio:
88
-
89
- 1. um heading `## T{N}` (o hook casa `^## T\d+` — uma linha de tabela `| T1 | … | done |` conta
90
- como menção, **não** como bloco);
91
- 2. uma linha `**Standard:** {standard-id}` **dentro de 12 linhas** do heading. Sem standard que
92
- cubra o caso, registre a decisão em `decisions.md` e cite
93
- `**Standard:** ad-hoc (see decisions.md ADR-{N})`.
94
-
95
- ```markdown
96
- ## T{N} — {title}
97
-
98
- **Standard:** {standard-id} (`.morph/framework/standards/{path}.md`)
99
- **Persona:** {mecanismo real usado}
100
- **Files:**
101
- - `{path}`
102
-
103
- {2-3 frases sobre o que foi feito}
104
-
105
- **Issues encontrados:** {breve descrição ou "nenhum"}
106
- ```
107
-
108
- O `validate-completion` também acusa **drift**: uma task que aparece como concluída no recap mas
109
- ainda está `pending`/`in_progress` no `tasks.json`. Template completo e regras de exceção em
110
- `morph-implement` §6.
111
-
112
- ---
113
-
114
- ## Checkpoints
115
-
116
- Run a checkpoint every 3 completed tasks:
117
- - Validate architecture compliance
118
- - Check package versions
119
- - Scan for security issues
120
- - Verify design system adherence (UI features)
121
-
122
- ---
123
-
124
- ## Approval Gates
125
-
126
- Before completing any phase, verify pending approval gates:
127
- - `morph-spec approval-status <feature>` — check which gates are pending
128
- - `morph-spec approve <feature> <gate>` — approve a gate (`proposal`, `plan`, `review`; `uiux` if applicable)
129
- - `morph-spec advance <feature>` — approve the current gate AND scaffold the next phase folder in one step
130
- - Gates must be approved before advancing to the next phase
131
-
132
- ---
133
-
134
- ## Protected Files
135
-
136
- **NEVER directly edit:**
137
- - `.morph/state.json` — Managed by CLI only
138
- - `.morph/framework/**` — Read-only framework content
139
-
140
- ---
141
-
142
- ## Test File Policy
143
-
144
- When a test fails, always follow this order:
145
-
146
- 1. **Analyze first** — determine if the IMPLEMENTATION is wrong or the TEST SPEC is wrong
147
- 2. **Fix implementation first** — the test is the spec; trust it by default
148
- 3. **Only modify a test file if the test expectation itself is incorrect** — wrong expected value, wrong behavior modeled
149
- 4. **Before modifying any test file, explain WHY the test spec is wrong** — what the correct behavior is and why the test doesn't model it
150
-
151
- Do not modify test files to make a failing test pass when the implementation is the actual problem.
152
-
153
- ---
154
-
155
- ## Context Maintenance
156
-
157
- After making structural changes (new packages, dependencies, project config changes), update the project context:
158
- - Edit `.morph/context/README.md` — update Tech Stack, Architecture, Key Integrations sections
159
- - Any `.morph/context/*.md`: **rewrite the body, never stack** — the section that described the old fact now describes the new one (a value that still holds somewhere says where); a changelog keeps only date and reason
160
- - Update `.morph/config/config.json` — update stack, architecture, integrations, paths
161
- - Structural changes include: package.json, .csproj, next.config.*, tsconfig.json, docker-compose.yml
162
-
163
- ---
164
-
165
- ## Spec-Driven Task Execution (implement phase)
166
-
167
- BEFORE implementing ANY task during the implement phase:
168
-
169
- 1. **Read tasks.json** → identify the current task object (`id`, `description`, `doneCriteria`, `dependencies`)
170
- 2. **Read spec.md** → the FR sections that the task `description` references
171
- 3. **Read the contracts** → the DTOs/interfaces are defined inside `spec.md` (v5 keeps contracts in the spec, not separate files)
172
- 4. Only then begin implementation
173
-
174
- This is **NON-NEGOTIABLE**. The spec is the source of truth. Code that doesn't match the spec is a bug.
175
-
176
- Every task in `tasks.json` MUST reference its FR(s) in the `description` field so the link to the spec is explicit:
177
- ```json
178
- {
179
- "id": "T1",
180
- "title": "Create user endpoint",
181
- "description": "Implement user CRUD (FR001) and input validation (FR003). Contracts: CreateUserRequest, CreateUserResponse, UserErrors.",
182
- "dependencies": [],
183
- "effort": "M",
184
- "doneCriteria": "POST /users creates a user and rejects invalid input",
185
- "status": "pending",
186
- "outputs": ["Features/UserFeature/Create/Handler.cs", "Validator.cs", "Endpoint.cs"],
187
- "group": "backend"
188
- }
189
- ```
190
-
191
- ---
192
-
193
- ## Debugging
194
-
195
- When a bug or unexpected behavior shows up mid-task, find the **root cause before proposing a
196
- fix** — never a patch on the symptom. This is MANDATORY:
197
-
198
- 1. Reproduce it and read the full error, not the first line.
199
- 2. For a known .NET/Next.js error, run `/morph-troubleshoot <keywords>` first.
200
- 3. One hypothesis at a time, each tested by the smallest check that could refute it.
201
- 4. After three failed fixes, stop and question the design instead of trying a fourth.
202
- 5. Confirm the fix with the same check that reproduced the bug; add a test only when no existing one covers that behavior.
203
-
204
- Everything else that a rule like this might list is owned by the flow itself, and duplicating it
205
- here would put a second, staler copy in permanent context:
206
-
207
- | Concern | Where it actually lives |
208
- |---------|-------------------------|
209
- | How many tests to write | The test budget in `morph-plan` §5: one test per postcondition, same-behavior cases in one table, no test that only pins text |
210
- | Verifying a task before `status: "done"` | `morph-spec verify {feature} [task]` (build + tests + validators + e2e) green, and each `doneCriteria` with the test or `file:line` that proves it |
211
- | Parallel dispatch | `morph-spec dag {feature}` decides sequential vs parallel; execution and isolation rules are in `morph-apply` §2/§3b |
212
- | Closing the phase / opening the PR | `morph-review` for Gate 3, then `morph-spec finish {feature} --pr\|--merge` |
213
-
214
- ---
215
-
216
- ## Scope Escalation
217
-
218
- The plan contract frozen at Gate 2 — `spec.md` and the immutable `tasks.json`
219
- fields listed in `morph-task-tracking.md` — is enforced by the `protect-spec-files` hook. When a
220
- task turns out to be bigger than estimated, three different situations resolve three different ways:
221
-
222
- | Situation | Path |
223
- |-----------|------|
224
- | **Small addition**, still inside the task's scope | Record it in the task's `notes` (a mutable field) — no gate to revoke, no contract to amend |
225
- | **Error of fact**: the spec asserts something about the code that the code contradicts, with no scope change | Append an `## Errata` block at the END of the file. Body untouched, append-only, accepted by `protect-spec-files` **without revoking the gate** — freezing the CONTRACT is not freezing an ERROR OF FACT (MORPH.md §3) |
226
- | **The scope itself changed**: the contract no longer describes the work | `morph-spec unapprove {feature} plan --reason "..."`, amend the plan, then re-approve. There is no shortcut around the gate for this one |
227
-
228
- Scope ambiguity the plan does not cover is **not** an escalation: record it in
229
- `decisions.md`, resolve it the conservative way, and keep going — only pause if it is genuinely
230
- blocking (`morph-implement` §5).
231
-
232
- **Never** implement extra functionality within a task without registering it — `notes` for small
233
- additions, gate revocation for anything that changes the plan contract.
234
-
235
- ---
236
-
237
- ## Context Window Tip
238
-
239
- When using 3+ MCPs, add `"experimental": { "mcpCliMode": true }` to `.claude/settings.json`.
240
- MCP tools load on-demand instead of all at startup — keeps context clean for actual work.
241
-
242
- ---
243
-
244
- *MORPH-SPEC by Polymorphism Tech*
@@ -1,79 +0,0 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "title": "MORPH-SPEC tasks.json",
4
- "description": "Structured task list for a morph-spec feature. Replaces tasks.md.",
5
- "type": "object",
6
- "required": ["version", "feature", "tasks"],
7
- "properties": {
8
- "version": { "type": "string", "const": "1.0" },
9
- "feature": { "type": "string", "minLength": 1 },
10
- "tasks": {
11
- "type": "array",
12
- "items": {
13
- "type": "object",
14
- "required": ["id", "title", "description", "dependencies", "effort", "doneCriteria", "status"],
15
- "properties": {
16
- "id": { "type": "string", "pattern": "^T\\d+$" },
17
- "title": { "type": "string", "minLength": 1 },
18
- "description": { "type": "string", "minLength": 1 },
19
- "dependencies": {
20
- "type": "array",
21
- "items": { "type": "string", "pattern": "^T\\d+$" }
22
- },
23
- "effort": { "type": "string", "enum": ["S", "M", "L", "XL"] },
24
- "doneCriteria": { "type": "string", "minLength": 1 },
25
- "status": { "type": "string", "enum": ["pending", "in_progress", "done", "skipped", "blocked"] },
26
- "outputs": { "type": "array", "items": { "type": "string" } },
27
- "notes": { "type": "string" },
28
- "group": { "type": "string", "enum": ["backend", "frontend", "tests", "infra", "docs"] },
29
- "usecase": {
30
- "type": "string",
31
- "pattern": "^UC-\\d+$",
32
- "description": "ID of the use case this task realizes (2-plan/usecases/UC-{nn}-{slug}.md). Optional: technical tasks with no observable behaviour have none."
33
- },
34
- "agent": {
35
- "type": "string",
36
- "minLength": 1,
37
- "description": "Persona id assigned by morph-plan for this task — the bare framework/agents.json id, no 'morph-' prefix (e.g. \"dotnet-senior\"). Optional. Part of the plan contract: frozen after Gate 2."
38
- },
39
- "reuse": {
40
- "type": "array",
41
- "description": "Veredito de reuso por conceito que ESTA task introduz, carimbado por morph-plan. Optional. Part of the plan contract: frozen after Gate 2.",
42
- "items": {
43
- "type": "object",
44
- "required": ["concept", "verdict"],
45
- "properties": {
46
- "concept": {
47
- "type": "string",
48
- "minLength": 1,
49
- "description": "Nome do conceito/símbolo, como ele aparecerá no código (ex.: \"SimpleBuilding\")."
50
- },
51
- "verdict": {
52
- "type": "string",
53
- "enum": ["REUSAR", "ESTENDER", "CRIAR"],
54
- "description": "REUSAR: usar o que existe. ESTENDER: partir do que existe. CRIAR: nada cobre o caso — exige `why`."
55
- },
56
- "target": {
57
- "type": "string",
58
- "description": "Path (ou path:símbolo) do que será reusado/estendido. Vazio ou ausente em CRIAR."
59
- },
60
- "why": {
61
- "type": "string",
62
- "description": "Uma linha: por que nada existente cobre o caso. Exigido em CRIAR."
63
- }
64
- },
65
- "additionalProperties": false
66
- }
67
- },
68
- "standards": {
69
- "type": "array",
70
- "items": { "type": "string", "minLength": 1 },
71
- "description": "Standards pinned by morph-plan for this task, as PATHS relative to the framework root (e.g. \"standards/backend/dotnet/vsa-handler-patterns.md\"). Optional. Part of the plan contract: frozen after Gate 2. NOT the same vocabulary as agents.json's top-level `standards` field, which lists IDs (e.g. \"backend-dotnet-vsa-handler-patterns\", no slashes/extension) — same field name, different shape; do not treat one as the other."
72
- }
73
- },
74
- "additionalProperties": false
75
- }
76
- }
77
- },
78
- "additionalProperties": false
79
- }