@polymorphism-tech/morph-spec 4.3.7 → 4.5.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 (375) hide show
  1. package/.morph/.morphversion +3 -3
  2. package/.morph/analytics/threads-log.jsonl +44 -9
  3. package/.morph/config/config.json +2 -3
  4. package/.morph/framework/standards/STANDARDS.json +812 -0
  5. package/.morph/{standards → framework/standards}/ai-agents/team-orchestration.md +3 -3
  6. package/.morph/framework/standards/integration/mcp/mcp-tools.md +384 -0
  7. package/.morph/{templates → framework/templates}/README.md +17 -17
  8. package/.morph/{templates → framework/templates}/REGISTRY.json +48 -233
  9. package/.morph/framework/templates/code/dotnet/contracts/contracts.cs.hbs +172 -0
  10. package/.morph/{templates → framework/templates}/context/CONTEXT-FEATURE.md +1 -1
  11. package/.morph/{templates → framework/templates}/context/CONTEXT.md +3 -3
  12. package/.morph/framework/templates/docs/clarifications.md +253 -0
  13. package/.morph/framework/templates/docs/onboarding.md +123 -0
  14. package/.morph/framework/templates/docs/schema-analysis.md +119 -0
  15. package/.morph/{templates → framework/templates}/docs/spec.md +149 -149
  16. package/.morph/framework/templates/docs/ui-components.md +124 -0
  17. package/.morph/framework/templates/docs/ui-design-system.md +76 -0
  18. package/.morph/framework/templates/docs/ui-flows.md +167 -0
  19. package/.morph/framework/templates/docs/ui-mockups.md +98 -0
  20. package/.morph/{templates → framework/templates}/examples/spec-examples.md +1 -1
  21. package/.morph/{templates → framework/templates}/infrastructure/github/README.md +11 -11
  22. package/.morph/{templates → framework/templates}/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +2 -2
  23. package/.morph/{templates → framework/templates}/meta-prompts/parallel-workers/parallel-worker.md +2 -2
  24. package/.morph/{templates → framework/templates}/meta-prompts/validators/pre-commit-validator.md +1 -1
  25. package/.morph/logs/tool-failures.log +51 -0
  26. package/.morph/memory/pre-compact-2026-02-22T17-01-01-658Z.json +16 -0
  27. package/.morph/state.json +1 -1
  28. package/CLAUDE.md +20 -119
  29. package/README.md +20 -18
  30. package/bin/detect-agents.js +1 -1
  31. package/bin/morph-spec.js +116 -266
  32. package/bin/task-manager.cjs +2 -2
  33. package/bin/validate.js +1 -1
  34. package/claude-plugin.json +14 -0
  35. package/docs/claude-alignment-report.md +137 -0
  36. package/docs/plans/2026-02-22-claude-docs-morph-alignment-analysis.md +512 -0
  37. package/docs/plans/2026-02-22-claude-settings.md +515 -0
  38. package/docs/plans/2026-02-22-morph-cc-alignment-impl.md +728 -0
  39. package/docs/plans/2026-02-22-morph-spec-next.md +478 -0
  40. package/docs/plans/2026-02-22-native-alignment-design.md +199 -0
  41. package/docs/plans/2026-02-22-native-alignment-impl.md +925 -0
  42. package/docs/plans/2026-02-22-native-enrichment-design.md +244 -0
  43. package/docs/plans/2026-02-22-native-enrichment.md +735 -0
  44. package/framework/CLAUDE.md +77 -0
  45. package/framework/commands/morph-apply.md +9 -9
  46. package/framework/commands/morph-archive.md +8 -8
  47. package/framework/commands/morph-infra.md +1 -1
  48. package/framework/commands/morph-proposal.md +9 -9
  49. package/framework/commands/morph-status.md +3 -3
  50. package/framework/commands/morph-troubleshoot.md +1 -1
  51. package/framework/hooks/README.md +201 -282
  52. package/framework/hooks/claude-code/notification/approval-reminder.js +52 -0
  53. package/framework/hooks/claude-code/post-tool-use/dispatch.js +83 -0
  54. package/framework/hooks/claude-code/post-tool-use/handle-tool-failure.js +42 -0
  55. package/framework/hooks/claude-code/pre-compact/save-morph-context.js +61 -0
  56. package/framework/hooks/claude-code/pre-tool-use/enforce-phase-writes.js +71 -0
  57. package/framework/hooks/claude-code/pre-tool-use/protect-readonly-files.js +58 -0
  58. package/framework/hooks/claude-code/pre-tool-use/protect-spec-files.js +64 -0
  59. package/framework/hooks/claude-code/session-start/inject-morph-context.js +94 -0
  60. package/framework/hooks/claude-code/statusline.py +239 -0
  61. package/framework/hooks/claude-code/statusline.sh +7 -0
  62. package/framework/hooks/claude-code/stop/validate-completion.js +88 -0
  63. package/framework/hooks/claude-code/user-prompt/enrich-prompt.js +91 -0
  64. package/framework/hooks/shared/hook-response.js +45 -0
  65. package/framework/hooks/shared/phase-utils.js +129 -0
  66. package/framework/hooks/shared/state-reader.js +138 -0
  67. package/framework/hooks/shared/stdin-reader.js +26 -0
  68. package/framework/phases.json +145 -0
  69. package/framework/rules/csharp-standards.md +10 -0
  70. package/framework/rules/frontend-standards.md +14 -0
  71. package/framework/rules/infrastructure-standards.md +13 -0
  72. package/framework/rules/morph-workflow.md +86 -0
  73. package/framework/rules/testing-standards.md +11 -0
  74. package/framework/skills/level-0-meta/brainstorming.md +133 -0
  75. package/framework/skills/level-0-meta/code-review.md +12 -4
  76. package/framework/skills/level-0-meta/mcp-registry.json +207 -0
  77. package/framework/skills/level-0-meta/morph-checklist.md +9 -1
  78. package/framework/skills/level-0-meta/simulation-checklist.md +9 -1
  79. package/framework/skills/level-0-meta/tool-usage-guide.md +335 -0
  80. package/framework/skills/level-0-meta/verification-before-completion.md +145 -0
  81. package/framework/skills/level-1-workflows/morph-replicate.md +9 -1
  82. package/framework/skills/level-1-workflows/phase-clarify.md +65 -4
  83. package/framework/skills/level-1-workflows/phase-codebase-analysis.md +182 -0
  84. package/framework/skills/level-1-workflows/phase-design.md +342 -80
  85. package/framework/skills/level-1-workflows/phase-implement.md +254 -0
  86. package/framework/skills/level-1-workflows/phase-setup.md +76 -10
  87. package/framework/skills/level-1-workflows/phase-tasks.md +88 -7
  88. package/framework/skills/level-1-workflows/phase-uiux.md +95 -17
  89. package/framework/skills/level-2-domains/ai-agents/ai-system-architect.md +8 -1
  90. package/framework/skills/level-2-domains/architecture/po-pm-advisor.md +8 -1
  91. package/framework/skills/level-2-domains/architecture/prompt-engineer.md +8 -1
  92. package/framework/skills/level-2-domains/architecture/seo-growth-hacker.md +8 -1
  93. package/framework/skills/level-2-domains/architecture/standards-architect.md +11 -4
  94. package/framework/skills/level-2-domains/backend/api-designer.md +8 -1
  95. package/framework/skills/level-2-domains/backend/dotnet-senior.md +8 -1
  96. package/framework/skills/level-2-domains/backend/ef-modeler.md +8 -1
  97. package/framework/skills/level-2-domains/backend/hangfire-orchestrator.md +9 -2
  98. package/framework/skills/level-2-domains/backend/ms-agent-expert.md +8 -1
  99. package/framework/skills/level-2-domains/frontend/blazor-builder.md +8 -1
  100. package/framework/skills/level-2-domains/frontend/nextjs-expert.md +8 -1
  101. package/framework/skills/level-2-domains/frontend/ui-ux-designer.md +9 -2
  102. package/framework/skills/level-2-domains/infrastructure/azure-architect.md +8 -1
  103. package/framework/skills/level-2-domains/infrastructure/azure-deploy-specialist.md +8 -1
  104. package/framework/skills/level-2-domains/infrastructure/bicep-architect.md +8 -1
  105. package/framework/skills/level-2-domains/infrastructure/container-specialist.md +8 -1
  106. package/framework/skills/level-2-domains/infrastructure/devops-engineer.md +8 -1
  107. package/framework/skills/level-2-domains/integrations/asaas-financial.md +8 -1
  108. package/framework/skills/level-2-domains/integrations/azure-identity.md +8 -1
  109. package/framework/skills/level-2-domains/integrations/clerk-auth.md +8 -1
  110. package/framework/skills/level-2-domains/integrations/{hangfire-orchestrator.md → hangfire-integration.md} +8 -1
  111. package/framework/skills/level-2-domains/integrations/resend-email.md +8 -1
  112. package/framework/skills/level-2-domains/quality/code-analyzer.md +10 -3
  113. package/framework/skills/level-2-domains/quality/testing-specialist.md +8 -1
  114. package/framework/standards/STANDARDS.json +812 -0
  115. package/framework/standards/ai-agents/team-orchestration.md +3 -3
  116. package/framework/standards/frontend/nextjs/nextjs-patterns.md +17 -0
  117. package/framework/standards/integration/mcp/mcp-tools.md +384 -0
  118. package/framework/templates/README.md +17 -17
  119. package/framework/templates/REGISTRY.json +48 -233
  120. package/framework/templates/code/dotnet/contracts/contracts.cs.hbs +172 -0
  121. package/framework/templates/context/CONTEXT-FEATURE.md +1 -1
  122. package/framework/templates/context/CONTEXT.md +3 -3
  123. package/framework/templates/docs/clarifications.md +253 -0
  124. package/framework/templates/docs/onboarding.md +123 -0
  125. package/framework/templates/docs/schema-analysis.md +119 -0
  126. package/framework/templates/docs/spec.md +149 -149
  127. package/framework/templates/docs/ui-components.md +124 -0
  128. package/framework/templates/docs/ui-design-system.md +76 -0
  129. package/framework/templates/docs/ui-flows.md +167 -0
  130. package/framework/templates/docs/ui-mockups.md +98 -0
  131. package/framework/templates/docs/user-stories.md +34 -0
  132. package/framework/templates/examples/spec-examples.md +1 -1
  133. package/framework/templates/infrastructure/github/README.md +11 -11
  134. package/framework/templates/infrastructure/github/workflows/deploy-azure-app-service.yml.hbs +2 -2
  135. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +2 -2
  136. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +1 -1
  137. package/framework/workflows/configs/express.json +45 -0
  138. package/framework/workflows/configs/spec-only.json +43 -0
  139. package/framework/workflows/docs/enforcement-pipeline.md +8 -8
  140. package/framework/workflows/docs/full-morph.md +3 -3
  141. package/package.json +3 -1
  142. package/scripts/generate-refs.js +336 -0
  143. package/scripts/generate-standards-registry.js +44 -0
  144. package/scripts/validate-real.mjs +255 -0
  145. package/src/commands/feature/create-story.js +362 -361
  146. package/src/commands/feature/shard-spec.js +225 -224
  147. package/src/commands/feature/sprint-status.js +1 -1
  148. package/src/commands/generation/generate-onboarding.js +169 -0
  149. package/src/commands/generation/generate.js +2 -2
  150. package/src/commands/mcp/mcp-setup.js +315 -0
  151. package/src/commands/project/changes.js +66 -0
  152. package/src/commands/project/checkpoint.js +209 -0
  153. package/src/commands/project/cost.js +179 -0
  154. package/src/commands/project/diff.js +278 -0
  155. package/src/commands/project/doctor.js +55 -7
  156. package/src/commands/project/init.js +318 -76
  157. package/src/commands/project/revert.js +173 -0
  158. package/src/commands/project/standards.js +80 -0
  159. package/src/commands/project/status.js +376 -0
  160. package/src/commands/project/update-agents.js +23 -0
  161. package/src/commands/project/update.js +63 -30
  162. package/src/commands/state/advance-phase.js +4 -3
  163. package/src/commands/state/state.js +10 -3
  164. package/src/commands/state/validate-phase.js +19 -2
  165. package/src/commands/templates/template-customize.js +4 -4
  166. package/src/commands/templates/template-render.js +1 -1
  167. package/src/commands/templates/template-show.js +1 -1
  168. package/src/commands/validation/validate-feature.js +359 -0
  169. package/src/core/orchestrator.js +3 -38
  170. package/src/core/paths/output-schema.js +135 -0
  171. package/src/core/state/state-manager.js +831 -592
  172. package/src/core/templates/template-registry.js +2 -2
  173. package/src/core/workflows/workflow-detector.js +17 -1
  174. package/src/lib/agents/micro-agent-factory.js +1 -1
  175. package/src/lib/context/context-bundler.js +2 -1
  176. package/src/lib/detectors/claude-config-detector.js +392 -0
  177. package/src/lib/detectors/conversation-analyzer.js +4 -4
  178. package/src/lib/detectors/design-system-detector.js +6 -5
  179. package/src/lib/detectors/standards-generator.js +2 -2
  180. package/src/lib/generators/context-generator.js +539 -538
  181. package/src/lib/generators/recap-generator.js +1 -1
  182. package/src/lib/generators/settings-generator.js +210 -0
  183. package/src/lib/hooks/hook-executor.js +1 -1
  184. package/src/lib/installers/mcp-installer.js +299 -0
  185. package/src/lib/learning/learning-system.js +3 -3
  186. package/src/lib/orchestration/team-orchestrator.js +1 -1
  187. package/src/lib/standards/standards-context-injector.js +7 -7
  188. package/src/lib/threads/thread-coordinator.js +1 -1
  189. package/src/lib/troubleshooting/troubleshoot-grep.js +1 -1
  190. package/src/lib/validators/contracts/contract-compliance-validator.js +274 -273
  191. package/src/lib/validators/design-system/design-system-validator.js +1 -1
  192. package/src/lib/validators/spec-validator.js +258 -258
  193. package/src/lib/validators/validation-runner.js +270 -269
  194. package/src/utils/agents-installer.js +206 -0
  195. package/src/utils/claude-settings-manager.js +258 -0
  196. package/src/utils/file-copier.js +1 -1
  197. package/src/utils/hooks-installer.js +354 -28
  198. package/src/utils/skills-installer.js +74 -0
  199. package/.morph/project/context/detection-log.md +0 -16
  200. package/.morph/project/standards/inferred.md +0 -59
  201. package/framework/hooks/agent-stop/validate-and-continue.js +0 -96
  202. package/framework/hooks/agent-stop/validate-checkpoints.js +0 -101
  203. package/framework/hooks/agent-stop/validate-tests.js +0 -109
  204. package/framework/hooks/agent-teams/dispatch.js +0 -67
  205. package/framework/hooks/agent-teams/phase-advanced.js +0 -80
  206. package/framework/hooks/agent-teams/task-completed.js +0 -76
  207. package/framework/hooks/agent-teams/teammate-idle.js +0 -70
  208. package/src/commands/agents/agents-fuse.js +0 -97
  209. package/src/commands/agents/micro-agent.js +0 -112
  210. package/src/commands/agents/spawn-team.js +0 -237
  211. package/src/commands/agents/squad-template.js +0 -146
  212. package/src/commands/analytics/analytics.js +0 -176
  213. package/src/commands/context/context-prime.js +0 -63
  214. package/src/commands/context/core-four.js +0 -54
  215. package/src/commands/generation/generate-context.js +0 -40
  216. package/src/commands/project/detect-agents.js +0 -207
  217. package/src/commands/project/detect-workflow.js +0 -174
  218. package/src/commands/threads/thread-template.js +0 -103
  219. package/src/commands/threads/threads.js +0 -261
  220. package/src/commands/utils/session-summary.js +0 -291
  221. package/src/llm/analyzer.js +0 -215
  222. package/src/llm/few-shot-examples.js +0 -216
  223. package/src/llm/project-config-schema.json +0 -188
  224. package/src/llm/prompt-builder.js +0 -96
  225. /package/.morph/{project/context → context}/README.md +0 -0
  226. /package/.morph/{config → framework}/agents.json +0 -0
  227. /package/.morph/{standards → framework/standards}/ai-agents/blazor-ui.md +0 -0
  228. /package/.morph/{standards → framework/standards}/ai-agents/production.md +0 -0
  229. /package/.morph/{standards → framework/standards}/ai-agents/setup.md +0 -0
  230. /package/.morph/{standards → framework/standards}/ai-agents/workflows.md +0 -0
  231. /package/.morph/{standards → framework/standards}/architecture/ddd/aggregates.md +0 -0
  232. /package/.morph/{standards → framework/standards}/architecture/ddd/entities.md +0 -0
  233. /package/.morph/{standards → framework/standards}/architecture/ddd/value-objects.md +0 -0
  234. /package/.morph/{standards → framework/standards}/backend/api/minimal-api.md +0 -0
  235. /package/.morph/{standards → framework/standards}/backend/api/rest.md +0 -0
  236. /package/.morph/{standards → framework/standards}/backend/api/validation.md +0 -0
  237. /package/.morph/{standards → framework/standards}/backend/authentication/passkeys.md +0 -0
  238. /package/.morph/{standards → framework/standards}/backend/database/ef-core.md +0 -0
  239. /package/.morph/{standards → framework/standards}/backend/database/migrations.md +0 -0
  240. /package/.morph/{standards → framework/standards}/backend/database/postgresql/database.md +0 -0
  241. /package/.morph/{standards → framework/standards}/backend/database/repository-patterns.md +0 -0
  242. /package/.morph/{standards → framework/standards}/backend/database/vector-search-rag.md +0 -0
  243. /package/.morph/{standards → framework/standards}/backend/dotnet/async.md +0 -0
  244. /package/.morph/{standards → framework/standards}/backend/dotnet/core.md +0 -0
  245. /package/.morph/{standards → framework/standards}/backend/dotnet/di.md +0 -0
  246. /package/.morph/{standards → framework/standards}/backend/dotnet/program-cs-checklist.md +0 -0
  247. /package/.morph/{standards → framework/standards}/backend/integrations/asaas/asaas-api.md +0 -0
  248. /package/.morph/{standards → framework/standards}/backend/integrations/clerk/clerk-auth.md +0 -0
  249. /package/.morph/{standards → framework/standards}/backend/integrations/hangfire/hangfire-jobs.md +0 -0
  250. /package/.morph/{standards → framework/standards}/backend/integrations/resend/resend-email.md +0 -0
  251. /package/.morph/{standards → framework/standards}/context/analytics.md +0 -0
  252. /package/.morph/{standards → framework/standards}/context/bundles.md +0 -0
  253. /package/.morph/{standards → framework/standards}/context/priming.md +0 -0
  254. /package/.morph/{standards → framework/standards}/core/architecture.md +0 -0
  255. /package/.morph/{standards → framework/standards}/core/coding.md +0 -0
  256. /package/.morph/{standards → framework/standards}/core/git-branching-strategy.md +0 -0
  257. /package/.morph/{standards → framework/standards}/core/git.md +0 -0
  258. /package/.morph/{standards → framework/standards}/core/testing.md +0 -0
  259. /package/.morph/{standards → framework/standards}/data/nosql/blob-storage.md +0 -0
  260. /package/.morph/{standards → framework/standards}/data/nosql/cache/redis.md +0 -0
  261. /package/.morph/{standards → framework/standards}/data/nosql/cosmos-db.md +0 -0
  262. /package/.morph/{standards → framework/standards}/data/vector-search/azure-ai-search.md +0 -0
  263. /package/.morph/{standards → framework/standards}/data/vector-search/rag-chunking.md +0 -0
  264. /package/.morph/{standards → framework/standards}/frontend/blazor/design-checklist.md +0 -0
  265. /package/.morph/{standards → framework/standards}/frontend/blazor/fluent-ui-setup.md +0 -0
  266. /package/.morph/{standards → framework/standards}/frontend/blazor/fluent-ui.md +0 -0
  267. /package/.morph/{standards → framework/standards}/frontend/blazor/html-conversion.md +0 -0
  268. /package/.morph/{standards → framework/standards}/frontend/blazor/lifecycle.md +0 -0
  269. /package/.morph/{standards → framework/standards}/frontend/blazor/pitfalls.md +0 -0
  270. /package/.morph/{standards → framework/standards}/frontend/blazor/state.md +0 -0
  271. /package/.morph/{standards → framework/standards}/frontend/design-system/animations.md +0 -0
  272. /package/.morph/{standards → framework/standards}/frontend/design-system/naming.md +0 -0
  273. /package/.morph/{standards → framework/standards}/frontend/nextjs/nextjs-patterns.md +0 -0
  274. /package/.morph/{standards → framework/standards}/infrastructure/azure/azure.md +0 -0
  275. /package/.morph/{standards → framework/standards}/infrastructure/azure/bicep/bicep-patterns.md +0 -0
  276. /package/.morph/{standards → framework/standards}/infrastructure/azure/devops/azure-devops-setup.md +0 -0
  277. /package/.morph/{standards → framework/standards}/infrastructure/azure/devops/local-development.md +0 -0
  278. /package/.morph/{standards → framework/standards}/infrastructure/azure/services/functions.md +0 -0
  279. /package/.morph/{standards → framework/standards}/infrastructure/azure/services/service-bus.md +0 -0
  280. /package/.morph/{standards → framework/standards}/infrastructure/azure/services/storage.md +0 -0
  281. /package/.morph/{standards → framework/standards}/infrastructure/docker/easypanel-deploy.md +0 -0
  282. /package/.morph/{standards → framework/standards}/infrastructure/supabase/mcp-setup.md +0 -0
  283. /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-auth.md +0 -0
  284. /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-pgvector.md +0 -0
  285. /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-rls.md +0 -0
  286. /package/.morph/{standards → framework/standards}/infrastructure/supabase/supabase-storage.md +0 -0
  287. /package/.morph/{standards → framework/standards}/integration/api/graphql.md +0 -0
  288. /package/.morph/{standards → framework/standards}/integration/api/grpc.md +0 -0
  289. /package/.morph/{standards → framework/standards}/integration/api/rest-design.md +0 -0
  290. /package/.morph/{standards → framework/standards}/integration/event-driven/cqrs.md +0 -0
  291. /package/.morph/{standards → framework/standards}/integration/event-driven/event-sourcing.md +0 -0
  292. /package/.morph/{standards → framework/standards}/integration/event-driven/service-bus.md +0 -0
  293. /package/.morph/{standards → framework/standards}/observability/logging.md +0 -0
  294. /package/.morph/{standards → framework/standards}/observability/metrics.md +0 -0
  295. /package/.morph/{standards → framework/standards}/observability/monitoring.md +0 -0
  296. /package/.morph/{standards → framework/standards}/observability/tracing.md +0 -0
  297. /package/.morph/{standards → framework/standards}/workflows/parallel-execution.md +0 -0
  298. /package/.morph/{standards → framework/standards}/workflows/thread-management.md +0 -0
  299. /package/.morph/{templates → framework/templates}/.idea/morph-templates.xml +0 -0
  300. /package/.morph/{templates → framework/templates}/.vscode/morph-templates.code-snippets +0 -0
  301. /package/.morph/{templates → framework/templates}/IDE-SNIPPETS.md +0 -0
  302. /package/.morph/{templates → framework/templates}/code/dotnet/backend/repository.cs +0 -0
  303. /package/.morph/{templates → framework/templates}/code/dotnet/backend/service.cs +0 -0
  304. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/Commands.cs +0 -0
  305. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/Entities.cs +0 -0
  306. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/Queries.cs +0 -0
  307. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/README.md +0 -0
  308. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/api-contracts.cs +0 -0
  309. /package/.morph/{templates → framework/templates}/code/dotnet/contracts/contracts.cs +0 -0
  310. /package/.morph/{templates → framework/templates}/code/dotnet/database/migration.cs +0 -0
  311. /package/.morph/{templates → framework/templates}/code/dotnet/frontend/component.razor +0 -0
  312. /package/.morph/{templates → framework/templates}/code/dotnet/jobs/agent.cs +0 -0
  313. /package/.morph/{templates → framework/templates}/code/dotnet/jobs/job.cs +0 -0
  314. /package/.morph/{templates → framework/templates}/code/dotnet/test.cs +0 -0
  315. /package/.morph/{templates → framework/templates}/code/sql/rls-policy.sql +0 -0
  316. /package/.morph/{templates → framework/templates}/code/sql/supabase-migration.sql +0 -0
  317. /package/.morph/{templates → framework/templates}/code/sql/supabase-migration.template.sql +0 -0
  318. /package/.morph/{templates → framework/templates}/code/typescript/contracts.ts +0 -0
  319. /package/.morph/{templates → framework/templates}/docs/proposal.md +0 -0
  320. /package/.morph/{templates → framework/templates}/examples/design-system-examples.md +0 -0
  321. /package/.morph/{templates → framework/templates}/feature/decisions.md +0 -0
  322. /package/.morph/{templates → framework/templates}/feature/recap.md +0 -0
  323. /package/.morph/{templates → framework/templates}/feature/tasks.md +0 -0
  324. /package/.morph/{templates → framework/templates}/infrastructure/azure/Dockerfile.example +0 -0
  325. /package/.morph/{templates → framework/templates}/infrastructure/azure/README.md +0 -0
  326. /package/.morph/{templates → framework/templates}/infrastructure/azure/app-insights.bicep +0 -0
  327. /package/.morph/{templates → framework/templates}/infrastructure/azure/app-service.bicep +0 -0
  328. /package/.morph/{templates → framework/templates}/infrastructure/azure/container-app-env.bicep +0 -0
  329. /package/.morph/{templates → framework/templates}/infrastructure/azure/container-app.bicep +0 -0
  330. /package/.morph/{templates → framework/templates}/infrastructure/azure/deploy-checklist.md +0 -0
  331. /package/.morph/{templates → framework/templates}/infrastructure/azure/deploy.ps1 +0 -0
  332. /package/.morph/{templates → framework/templates}/infrastructure/azure/deploy.sh +0 -0
  333. /package/.morph/{templates → framework/templates}/infrastructure/azure/key-vault.bicep +0 -0
  334. /package/.morph/{templates → framework/templates}/infrastructure/azure/main.bicep +0 -0
  335. /package/.morph/{templates → framework/templates}/infrastructure/azure/parameters.dev.json +0 -0
  336. /package/.morph/{templates → framework/templates}/infrastructure/azure/parameters.prod.json +0 -0
  337. /package/.morph/{templates → framework/templates}/infrastructure/azure/parameters.staging.json +0 -0
  338. /package/.morph/{templates → framework/templates}/infrastructure/azure/sql-database.bicep +0 -0
  339. /package/.morph/{templates → framework/templates}/infrastructure/azure/storage.bicep +0 -0
  340. /package/.morph/{templates → framework/templates}/infrastructure/docker/Dockerfile.template +0 -0
  341. /package/.morph/{templates → framework/templates}/infrastructure/docker/docker-compose.template.yml +0 -0
  342. /package/.morph/{templates → framework/templates}/infrastructure/docker/dockerfile-api.dockerfile +0 -0
  343. /package/.morph/{templates → framework/templates}/infrastructure/docker/dockerfile-web.dockerfile +0 -0
  344. /package/.morph/{templates → framework/templates}/infrastructure/docker/easypanel.template.json +0 -0
  345. /package/.morph/{templates → framework/templates}/infrastructure/github/actions/azure-auth/action.yml.hbs +0 -0
  346. /package/.morph/{templates → framework/templates}/infrastructure/github/actions/docker-build-push/action.yml.hbs +0 -0
  347. /package/.morph/{templates → framework/templates}/infrastructure/github/actions/health-check/action.yml.hbs +0 -0
  348. /package/.morph/{templates → framework/templates}/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -0
  349. /package/.morph/{templates → framework/templates}/infrastructure/github/workflows/docker-build-push.yml.hbs +0 -0
  350. /package/.morph/{templates → framework/templates}/infrastructure/github/workflows/dotnet-build.yml.hbs +0 -0
  351. /package/.morph/{templates → framework/templates}/integrations/asaas-client.cs +0 -0
  352. /package/.morph/{templates → framework/templates}/integrations/asaas-webhook.cs +0 -0
  353. /package/.morph/{templates → framework/templates}/integrations/azure-identity-config.cs +0 -0
  354. /package/.morph/{templates → framework/templates}/integrations/clerk-config.cs +0 -0
  355. /package/.morph/{templates → framework/templates}/meta-prompts/fusion/fusion-agent.md +0 -0
  356. /package/.morph/{templates → framework/templates}/meta-prompts/fusion/fusion-aggregator.md +0 -0
  357. /package/.morph/{templates → framework/templates}/meta-prompts/hops/hop-retry.md +0 -0
  358. /package/.morph/{templates → framework/templates}/meta-prompts/hops/hop-validation.md +0 -0
  359. /package/.morph/{templates → framework/templates}/meta-prompts/hops/hop-wrapper.md +0 -0
  360. /package/.morph/{templates → framework/templates}/meta-prompts/parallel-workers/parallel-coordinator.md +0 -0
  361. /package/.morph/{templates → framework/templates}/meta-prompts/squad-leaders/backend-squad.md +0 -0
  362. /package/.morph/{templates → framework/templates}/meta-prompts/squad-leaders/frontend-squad.md +0 -0
  363. /package/.morph/{templates → framework/templates}/meta-prompts/squad-leaders/squad-leader.md +0 -0
  364. /package/.morph/{templates → framework/templates}/meta-prompts/validators/checkpoint-validator.md +0 -0
  365. /package/.morph/{templates → framework/templates}/saas/subscription.cs +0 -0
  366. /package/.morph/{templates → framework/templates}/saas/tenant.cs +0 -0
  367. /package/.morph/{templates → framework/templates}/state.template.json +0 -0
  368. /package/.morph/{templates → framework/templates}/ui/FluentDesignTheme.cs +0 -0
  369. /package/.morph/{templates → framework/templates}/ui/MudTheme.cs +0 -0
  370. /package/.morph/{templates → framework/templates}/ui/design-system.css +0 -0
  371. /package/framework/hooks/{commit-msg → git/commit-msg}/conventional-commits.sh +0 -0
  372. /package/framework/hooks/{pre-commit → git/pre-commit}/agents.sh +0 -0
  373. /package/framework/hooks/{pre-commit → git/pre-commit}/orchestrator.sh +0 -0
  374. /package/framework/hooks/{pre-commit → git/pre-commit}/specs.sh +0 -0
  375. /package/framework/hooks/{pre-push → git/pre-push}/run-tests.sh +0 -0
@@ -0,0 +1,925 @@
1
+ # Native Alignment Implementation Plan
2
+
3
+ > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
4
+
5
+ **Goal:** Align MORPH-SPEC with Claude Code's native platform patterns across 6 areas: skills format, rules as @-imports, CLAUDE.md consolidation, test file policy, standards additions, and state.json simplification.
6
+
7
+ **Architecture:** Non-breaking changes first (Tasks 1-5), state.json simplification last (Tasks 6-8). All 614 existing tests must pass at each commit. Each task is independently testable.
8
+
9
+ **Tech Stack:** Node.js ESM, `node:test`, `node:fs`, `node:path`. Run tests with `npm test`. Single test file: `node --test test/path/to/file.test.js`.
10
+
11
+ ---
12
+
13
+ ## Task 1: Fix Skills File Format (flat → subdirectory/SKILL.md)
14
+
15
+ **Files:**
16
+ - Modify: `src/utils/skills-installer.js`
17
+ - Modify: `test/utils/skills-installer.test.js`
18
+
19
+ **Context:** Claude Code's native skill format is `.claude/skills/<name>/SKILL.md`, not `.claude/skills/<name>.md`. Flat files prevent frontmatter features (allowed-tools, argument-hint) from working. Current code in `installSkillsFromDir()` does `copyFileSync(srcPath, join(destDir, entry))` — we change it to `mkdir(join(destDir, skillName))` + `copyFile(srcPath, join(destDir, skillName, 'SKILL.md'))`.
20
+
21
+ **Step 1: Update skills-installer.js**
22
+
23
+ Replace the body of `installSkillsFromDir` in `src/utils/skills-installer.js`:
24
+
25
+ ```javascript
26
+ function installSkillsFromDir(srcDir, destDir) {
27
+ const entries = readdirSync(srcDir);
28
+ for (const entry of entries) {
29
+ const srcPath = join(srcDir, entry);
30
+ const stat = statSync(srcPath);
31
+
32
+ if (stat.isDirectory()) {
33
+ installSkillsFromDir(srcPath, destDir);
34
+ } else if (entry.endsWith('.md') && entry !== 'README.md') {
35
+ const skillName = entry.slice(0, -3); // strip .md
36
+ const skillDir = join(destDir, skillName);
37
+ mkdirSync(skillDir, { recursive: true });
38
+ copyFileSync(srcPath, join(skillDir, 'SKILL.md'));
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ Also add `mkdirSync` to the imports at line 11:
45
+ ```javascript
46
+ import { mkdirSync, copyFileSync, existsSync, readdirSync, statSync } from 'fs';
47
+ ```
48
+ (mkdirSync is already imported — verify it's there, add if missing)
49
+
50
+ **Step 2: Run single test file to verify it fails**
51
+
52
+ ```bash
53
+ node --test test/utils/skills-installer.test.js
54
+ ```
55
+
56
+ Expected: FAIL — assertions check for `.md` filenames like `morph-checklist.md` which no longer exist.
57
+
58
+ **Step 3: Update skills-installer.test.js**
59
+
60
+ Replace the entire test file content:
61
+
62
+ ```javascript
63
+ /**
64
+ * Tests for src/utils/skills-installer.js
65
+ */
66
+
67
+ import { test, describe, before, after } from 'node:test';
68
+ import assert from 'node:assert/strict';
69
+ import { mkdtemp, rm, readdir, stat } from 'node:fs/promises';
70
+ import { join } from 'path';
71
+ import { tmpdir } from 'os';
72
+ import { installSkills } from '../../src/utils/skills-installer.js';
73
+
74
+ describe('installSkills', () => {
75
+ let tmpDir;
76
+
77
+ before(async () => {
78
+ tmpDir = await mkdtemp(join(tmpdir(), 'morph-skills-'));
79
+ });
80
+
81
+ after(async () => {
82
+ await rm(tmpDir, { recursive: true, force: true });
83
+ });
84
+
85
+ test('creates .claude/skills/ directory', async () => {
86
+ await installSkills(tmpDir);
87
+ const entries = await readdir(join(tmpDir, '.claude', 'skills'));
88
+ assert.ok(entries.length > 0, 'should have skill directories installed');
89
+ });
90
+
91
+ test('installs skills as subdirectories (not flat .md files)', async () => {
92
+ await installSkills(tmpDir);
93
+ const entries = await readdir(join(tmpDir, '.claude', 'skills'));
94
+ // All entries should be directories, not .md files
95
+ for (const entry of entries) {
96
+ assert.ok(!entry.endsWith('.md'), `${entry} should be a directory, not a flat .md file`);
97
+ }
98
+ });
99
+
100
+ test('each skill directory contains SKILL.md', async () => {
101
+ await installSkills(tmpDir);
102
+ const entries = await readdir(join(tmpDir, '.claude', 'skills'));
103
+ for (const entry of entries) {
104
+ const skillMd = join(tmpDir, '.claude', 'skills', entry, 'SKILL.md');
105
+ const s = await stat(skillMd).catch(() => null);
106
+ assert.ok(s?.isFile(), `${entry}/SKILL.md should exist and be a file`);
107
+ }
108
+ });
109
+
110
+ test('installs level-0-meta skills (morph-checklist, code-review)', async () => {
111
+ await installSkills(tmpDir);
112
+ const entries = await readdir(join(tmpDir, '.claude', 'skills'));
113
+ assert.ok(entries.includes('morph-checklist'), 'morph-checklist/ directory should be installed');
114
+ assert.ok(entries.includes('code-review'), 'code-review/ directory should be installed');
115
+ });
116
+
117
+ test('installs level-1-workflows skills (phase-design, phase-implement)', async () => {
118
+ await installSkills(tmpDir);
119
+ const entries = await readdir(join(tmpDir, '.claude', 'skills'));
120
+ assert.ok(entries.includes('phase-design'), 'phase-design/ directory should be installed');
121
+ assert.ok(entries.includes('phase-implement'), 'phase-implement/ directory should be installed');
122
+ });
123
+
124
+ test('does not install README.md files as skills', async () => {
125
+ await installSkills(tmpDir);
126
+ const entries = await readdir(join(tmpDir, '.claude', 'skills'));
127
+ assert.ok(!entries.includes('README'), 'README should not be installed as a skill');
128
+ assert.ok(!entries.includes('README.md'), 'README.md should not appear in skills dir');
129
+ });
130
+
131
+ test('installs at least 10 skills total', async () => {
132
+ await installSkills(tmpDir);
133
+ const entries = await readdir(join(tmpDir, '.claude', 'skills'));
134
+ assert.ok(entries.length >= 10, `should install at least 10 skills, got ${entries.length}`);
135
+ });
136
+
137
+ test('is idempotent — running twice produces same directory count', async () => {
138
+ await installSkills(tmpDir);
139
+ const firstCount = (await readdir(join(tmpDir, '.claude', 'skills'))).length;
140
+ await installSkills(tmpDir);
141
+ const secondCount = (await readdir(join(tmpDir, '.claude', 'skills'))).length;
142
+ assert.strictEqual(firstCount, secondCount, 'directory count should not change on second run');
143
+ });
144
+ });
145
+ ```
146
+
147
+ **Step 4: Run test to verify it passes**
148
+
149
+ ```bash
150
+ node --test test/utils/skills-installer.test.js
151
+ ```
152
+
153
+ Expected: all 8 tests PASS.
154
+
155
+ **Step 5: Run full suite**
156
+
157
+ ```bash
158
+ npm test
159
+ ```
160
+
161
+ Expected: 614+ tests pass, 0 fail.
162
+
163
+ **Step 6: Commit**
164
+
165
+ ```bash
166
+ git add src/utils/skills-installer.js test/utils/skills-installer.test.js
167
+ git commit -m "feat(skills): install as subdirectory/SKILL.md — native Claude Code format"
168
+ ```
169
+
170
+ ---
171
+
172
+ ## Task 2: Rules as Dynamic @-imports
173
+
174
+ **Files:**
175
+ - Modify: `framework/rules/csharp-standards.md`
176
+ - Modify: `framework/rules/frontend-standards.md`
177
+ - Modify: `framework/rules/testing-standards.md`
178
+ - Modify: `framework/rules/infrastructure-standards.md`
179
+
180
+ **Context:** Rules currently contain static copies of standards content. Replacing with @-imports makes them always current. The @-import paths use `.morph/framework/standards/` because rules are installed into user projects where that path is valid after `morph-spec init`. `morph-workflow.md` is NOT changed here — it has its own content (not a standards file).
181
+
182
+ No code changes — only markdown content changes. No tests needed (framework content files have no unit tests).
183
+
184
+ **Step 1: Replace csharp-standards.md body**
185
+
186
+ Replace everything after the frontmatter (after line 5 `---`) in `framework/rules/csharp-standards.md` with:
187
+
188
+ ```markdown
189
+ ---
190
+ paths:
191
+ - "**/*.cs"
192
+ - "**/*.csproj"
193
+ ---
194
+
195
+ # C# and .NET Standards
196
+
197
+ @.morph/framework/standards/core/coding.md
198
+ @.morph/framework/standards/backend/dotnet.md
199
+ ```
200
+
201
+ > **Note:** Verify the exact filenames exist in `framework/standards/core/` and `framework/standards/backend/`. Run `ls framework/standards/core/` and `ls framework/standards/backend/` first. Use the actual filenames found.
202
+
203
+ **Step 2: Replace frontend-standards.md body**
204
+
205
+ ```markdown
206
+ ---
207
+ paths:
208
+ - "**/*.razor"
209
+ - "**/*.tsx"
210
+ - "**/*.ts"
211
+ - "**/*.css"
212
+ - "**/*.scss"
213
+ ---
214
+
215
+ # Frontend Standards
216
+
217
+ @.morph/framework/standards/frontend/blazor.md
218
+ @.morph/framework/standards/frontend/nextjs.md
219
+ @.morph/framework/standards/frontend/css.md
220
+ ```
221
+
222
+ > Same note: verify filenames first with `ls framework/standards/frontend/`.
223
+
224
+ **Step 3: Replace testing-standards.md body**
225
+
226
+ ```markdown
227
+ ---
228
+ paths:
229
+ - "tests/**"
230
+ - "**/*.test.*"
231
+ - "**/*.spec.*"
232
+ - "**/*Tests.cs"
233
+ ---
234
+
235
+ # Testing Standards
236
+
237
+ @.morph/framework/standards/core/testing.md
238
+ ```
239
+
240
+ **Step 4: Replace infrastructure-standards.md body**
241
+
242
+ ```markdown
243
+ ---
244
+ paths:
245
+ - "**/*.bicep"
246
+ - "**/Dockerfile"
247
+ - "**/docker-compose*.yml"
248
+ - "**/pipelines/**"
249
+ - "**/.github/workflows/**"
250
+ ---
251
+
252
+ # Infrastructure Standards
253
+
254
+ @.morph/framework/standards/infrastructure/azure.md
255
+ @.morph/framework/standards/infrastructure/docker.md
256
+ ```
257
+
258
+ **Step 5: Verify actual standard filenames before writing**
259
+
260
+ ```bash
261
+ ls framework/standards/core/
262
+ ls framework/standards/backend/
263
+ ls framework/standards/frontend/
264
+ ls framework/standards/infrastructure/
265
+ ```
266
+
267
+ Adjust @-import paths above to match actual filenames.
268
+
269
+ **Step 6: Run full suite (no tests for framework content, but verify nothing broke)**
270
+
271
+ ```bash
272
+ npm test
273
+ ```
274
+
275
+ Expected: same pass count as before.
276
+
277
+ **Step 7: Commit**
278
+
279
+ ```bash
280
+ git add framework/rules/csharp-standards.md framework/rules/frontend-standards.md framework/rules/testing-standards.md framework/rules/infrastructure-standards.md
281
+ git commit -m "feat(rules): replace static content with @-imports from framework/standards"
282
+ ```
283
+
284
+ ---
285
+
286
+ ## Task 3: CLAUDE.md Consolidation
287
+
288
+ **Files:**
289
+ - Modify: `framework/CLAUDE.md` — merge both files into one
290
+ - Delete: `framework/CLAUDE_runtime.md`
291
+ - Modify: `src/commands/project/init.js` — change CLAUDE_runtime.md → CLAUDE.md as source
292
+ - Modify: `src/commands/project/update.js` — same
293
+ - Modify: `test/commands/init.test.js` — update source file reference
294
+ - Modify: `test/commands/update.test.js` — update source file reference
295
+
296
+ **Context:** `init.js` copies `framework/CLAUDE_runtime.md` → `.claude/CLAUDE.md` in user projects. After this task, it copies `framework/CLAUDE.md` instead. The merged file has all content from both plus MCP deferred mode note.
297
+
298
+ **Step 1: Find the CLAUDE_runtime.md copy line in init.js**
299
+
300
+ ```bash
301
+ grep -n "CLAUDE_runtime" src/commands/project/init.js
302
+ grep -n "CLAUDE_runtime" src/commands/project/update.js
303
+ ```
304
+
305
+ Note the exact line numbers.
306
+
307
+ **Step 2: Write new merged framework/CLAUDE.md**
308
+
309
+ Replace the entire content of `framework/CLAUDE.md`:
310
+
311
+ ```markdown
312
+ # MORPH-SPEC Runtime Instructions
313
+
314
+ > by Polymorphism Tech — Spec-driven development for .NET/Blazor/Next.js/Azure
315
+
316
+ ---
317
+
318
+ ## Project Context
319
+
320
+ @.morph/context/README.md
321
+
322
+ ---
323
+
324
+ ## Critical Rules
325
+
326
+ **NEVER:**
327
+ - Skip to code without a specification
328
+ - Implement without design approval
329
+ - Ignore standards in `.morph/framework/standards/`
330
+ - Create infrastructure manually
331
+ - Generate code without defined contracts
332
+
333
+ **ALWAYS:**
334
+ - Follow the mandatory phases
335
+ - Generate outputs in `.morph/features/{feature}/`
336
+ - Document decisions in `decisions.md`
337
+ - Checkpoint every 3 implemented tasks
338
+ - Use Infrastructure as Code
339
+
340
+ ---
341
+
342
+ ## Quick Reference
343
+
344
+ | Command | Purpose |
345
+ |---------|---------|
346
+ | `/morph-proposal {feature}` | Full spec pipeline (phases 1–4, pauses for approval) |
347
+ | `/morph-apply {feature}` | Implement feature (phase 5) |
348
+ | `/morph-status` | Feature status dashboard |
349
+ | `/morph-preflight` | Pre-implementation validation |
350
+
351
+ ---
352
+
353
+ ## State & Outputs
354
+
355
+ | Path | Notes |
356
+ |------|-------|
357
+ | `.morph/state.json` | **READ-ONLY** — use `morph-spec` CLI to update |
358
+ | `.morph/features/{feature}/{phase}/` | Feature outputs organized by phase |
359
+ | `.morph/framework/` | **READ-ONLY** — framework files managed by morph-spec |
360
+ | `.morph/config/config.json` | Project configuration (editable) |
361
+
362
+ ---
363
+
364
+ ## Phase Sequence
365
+
366
+ ```
367
+ proposal → setup → [uiux] → design → clarify → tasks → implement → [sync]
368
+ ```
369
+
370
+ Use `morph-spec state show {feature}` to see current phase and pending approval gates.
371
+
372
+ ---
373
+
374
+ ## Agents
375
+
376
+ Tier-1 and tier-2 MORPH agents are available as native subagents in `.claude/agents/`.
377
+ They can be invoked directly by Claude Code during multi-agent workflows.
378
+
379
+ ---
380
+
381
+ ## Context Window Tip
382
+
383
+ When using 3+ MCPs, add `"experimental": { "mcpCliMode": true }` to `.claude/settings.json`.
384
+ MCP tools load on-demand instead of all at startup — keeps context clean for actual work.
385
+
386
+ ---
387
+
388
+ *MORPH-SPEC v4.5.0 by Polymorphism Tech*
389
+ ```
390
+
391
+ **Step 3: Update init.js source reference**
392
+
393
+ Find the line that copies CLAUDE_runtime.md and change it to CLAUDE.md. It will look something like:
394
+
395
+ ```javascript
396
+ // BEFORE (find exact line with grep result from Step 1):
397
+ await copyFile(join(frameworkDir, 'CLAUDE_runtime.md'), join(projectDir, '.claude', 'CLAUDE.md'));
398
+
399
+ // AFTER:
400
+ await copyFile(join(frameworkDir, 'CLAUDE.md'), join(projectDir, '.claude', 'CLAUDE.md'));
401
+ ```
402
+
403
+ **Step 4: Update update.js source reference**
404
+
405
+ Same change in `src/commands/project/update.js`.
406
+
407
+ **Step 5: Run test files to find failing assertions**
408
+
409
+ ```bash
410
+ node --test test/commands/init.test.js
411
+ node --test test/commands/update.test.js
412
+ ```
413
+
414
+ Find any assertions referencing `CLAUDE_runtime.md` and change them to `CLAUDE.md`.
415
+
416
+ **Step 6: Delete framework/CLAUDE_runtime.md**
417
+
418
+ ```bash
419
+ git rm framework/CLAUDE_runtime.md
420
+ ```
421
+
422
+ **Step 7: Run full suite**
423
+
424
+ ```bash
425
+ npm test
426
+ ```
427
+
428
+ Expected: same pass count, 0 fail.
429
+
430
+ **Step 8: Commit**
431
+
432
+ ```bash
433
+ git add framework/CLAUDE.md src/commands/project/init.js src/commands/project/update.js test/commands/init.test.js test/commands/update.test.js
434
+ git commit -m "feat(claude-md): merge CLAUDE.md + CLAUDE_runtime.md into single unified file"
435
+ ```
436
+
437
+ ---
438
+
439
+ ## Task 4: Test File Policy in morph-workflow.md
440
+
441
+ **Files:**
442
+ - Modify: `framework/rules/morph-workflow.md`
443
+
444
+ **Context:** No hook — behavioral guidance only. Add "Test File Policy" section at the end of the file (before the final `*MORPH-SPEC by Polymorphism Tech*` footer). No tests needed.
445
+
446
+ **Step 1: Add section to framework/rules/morph-workflow.md**
447
+
448
+ Append before the final footer line:
449
+
450
+ ```markdown
451
+ ---
452
+
453
+ ## Test File Policy
454
+
455
+ When a test fails, always follow this order:
456
+
457
+ 1. **Analyze first** — determine if the IMPLEMENTATION is wrong or the TEST SPEC is wrong
458
+ 2. **Fix implementation first** — the test is the spec; trust it by default
459
+ 3. **Only modify a test file if the test expectation itself is incorrect** — wrong expected value, wrong behavior modeled
460
+ 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
461
+
462
+ Do not modify test files to make a failing test pass when the implementation is the actual problem.
463
+
464
+ ---
465
+ ```
466
+
467
+ **Step 2: Run full suite**
468
+
469
+ ```bash
470
+ npm test
471
+ ```
472
+
473
+ Expected: same pass count.
474
+
475
+ **Step 3: Commit**
476
+
477
+ ```bash
478
+ git add framework/rules/morph-workflow.md
479
+ git commit -m "feat(rules): add Test File Policy to morph-workflow rule"
480
+ ```
481
+
482
+ ---
483
+
484
+ ## Task 5: Standards and Templates Additions
485
+
486
+ **Files:**
487
+ - Modify: `framework/rules/frontend-standards.md` — note: already updated in Task 2 with @-imports, so also update the source standard file
488
+ - Create: `framework/templates/docs/user-stories.md`
489
+
490
+ **Context:** TypeScript strict mode guidance goes into the actual standards file (which the rule now @-imports). User stories template is a new Handlebars template.
491
+
492
+ **Step 1: Check if TypeScript strict is already in frontend standards**
493
+
494
+ ```bash
495
+ grep -r "strict" framework/standards/frontend/
496
+ ```
497
+
498
+ If not present, add to the appropriate standards file (e.g., `framework/standards/frontend/typescript.md` or whatever file exists):
499
+
500
+ ```markdown
501
+ ## TypeScript Strict Mode (Required)
502
+
503
+ Always enable `"strict": true` in `tsconfig.json`. This is non-negotiable for
504
+ agent-assisted development because agents rely on compiler errors to self-correct.
505
+ Without strict mode, type/null errors only surface at runtime where agents cannot observe them.
506
+
507
+ ```json
508
+ {
509
+ "compilerOptions": {
510
+ "strict": true,
511
+ "noUncheckedIndexedAccess": true
512
+ }
513
+ }
514
+ ```
515
+
516
+ Strict mode enables: `strictNullChecks`, `noImplicitAny`, `strictFunctionTypes`, `strictPropertyInitialization`.
517
+ ```
518
+
519
+ **Step 2: Create framework/templates/docs/user-stories.md**
520
+
521
+ ```markdown
522
+ # User Stories: {{featureName}}
523
+
524
+ > Generated: {{date}} | Feature: {{featureName}} | Status: Draft
525
+
526
+ ---
527
+
528
+ ## Story 1: [Actor] [Action]
529
+
530
+ **Feature:** {{featureName}}
531
+ **Priority:** High / Medium / Low
532
+
533
+ ### Optimal Path
534
+ 1. [Step 1]
535
+ 2. [Step 2]
536
+ 3. [Step 3 — success state]
537
+
538
+ ### Edge Cases
539
+ - [Edge case] → [Expected behavior]
540
+ - [Error condition] → [Expected error handling]
541
+
542
+ ### Acceptance Criteria
543
+ - [ ] [Measurable criterion 1]
544
+ - [ ] [Measurable criterion 2]
545
+ - [ ] Edge: [edge case criterion]
546
+
547
+ ---
548
+
549
+ ## Story 2: [Actor] [Action]
550
+
551
+ [Repeat structure above]
552
+
553
+ ---
554
+
555
+ *Generated by MORPH-SPEC — complete before implementation begins*
556
+ ```
557
+
558
+ **Step 3: Run full suite**
559
+
560
+ ```bash
561
+ npm test
562
+ ```
563
+
564
+ Expected: same pass count.
565
+
566
+ **Step 4: Commit**
567
+
568
+ ```bash
569
+ git add framework/standards/ framework/templates/docs/user-stories.md
570
+ git commit -m "feat(standards): add TypeScript strict mode requirement; add user-stories template"
571
+ ```
572
+
573
+ ---
574
+
575
+ ## Task 6: Remove `outputs` and `phase` from state-manager.js
576
+
577
+ **Files:**
578
+ - Modify: `src/core/state/state-manager.js`
579
+ - Modify: `test/lib/state-manager.test.js`
580
+
581
+ **Context:** `ensureFeature()` at line 191 sets `outputs: getAllOutputPaths(featureName)` and `phase: "proposal"`. Remove both fields. Add two new exported helper functions: `derivePhase(featurePath)` and `deriveOutputs(featureName)`. Add v4→v5 migration in `loadState()`.
582
+
583
+ **Step 1: Add helper functions to state-manager.js**
584
+
585
+ Add these two new exported functions after the existing `getStatePath()` function (around line 25):
586
+
587
+ ```javascript
588
+ /**
589
+ * Derive current phase from filesystem — checks for phase folders in descending order.
590
+ * Returns the phase corresponding to the highest-numbered folder present.
591
+ *
592
+ * @param {string} featurePath - Absolute path to .morph/features/{feature}/
593
+ * @returns {string} Phase name: 'implement' | 'tasks' | 'uiux' | 'design' | 'proposal' | 'setup'
594
+ */
595
+ export function derivePhase(featurePath) {
596
+ const phaseMap = [
597
+ ['4-implement', 'implement'],
598
+ ['3-tasks', 'tasks'],
599
+ ['2-ui', 'uiux'],
600
+ ['1-design', 'design'],
601
+ ['0-proposal', 'proposal'],
602
+ ];
603
+ for (const [folder, phase] of phaseMap) {
604
+ if (existsSync(join(featurePath, folder))) return phase;
605
+ }
606
+ return 'setup';
607
+ }
608
+
609
+ /**
610
+ * Derive output existence from filesystem — checks if each output file exists at its expected path.
611
+ * Returns an object matching the old outputs shape for backwards-compatible display.
612
+ *
613
+ * @param {string} featureName - Feature name
614
+ * @param {string} [baseDir] - Project base dir (defaults to cwd)
615
+ * @returns {Object} Map of outputType → { created: boolean, path: string }
616
+ */
617
+ export function deriveOutputs(featureName, baseDir = process.cwd()) {
618
+ const outputPaths = getAllOutputPaths(featureName);
619
+ const result = {};
620
+ for (const [type, { path: relPath }] of Object.entries(outputPaths)) {
621
+ const absPath = join(baseDir, relPath);
622
+ result[type] = { created: existsSync(absPath), path: relPath };
623
+ }
624
+ return result;
625
+ }
626
+ ```
627
+
628
+ **Step 2: Remove `outputs` and `phase` from ensureFeature()**
629
+
630
+ In `ensureFeature()` (around line 191), change:
631
+
632
+ ```javascript
633
+ // REMOVE these two lines:
634
+ phase: "proposal",
635
+ outputs: getAllOutputPaths(featureName),
636
+ ```
637
+
638
+ The feature object after the change should NOT have `phase` or `outputs` keys.
639
+
640
+ **Step 3: Add v4→v5 migration in loadState()**
641
+
642
+ In `loadState()`, after the existing v3→v4 migration block (around line 65), add:
643
+
644
+ ```javascript
645
+ // Migrate v4.x → v5.0.0: remove outputs and phase (now derived from filesystem)
646
+ if (state.version && state.version.startsWith('4.')) {
647
+ state.version = '5.0.0';
648
+ for (const feature of Object.values(state.features || {})) {
649
+ delete feature.outputs;
650
+ delete feature.phase;
651
+ }
652
+ writeFileSync(statePath, JSON.stringify(state, null, 2), 'utf8');
653
+ }
654
+ ```
655
+
656
+ **Step 4: Update initState() version string**
657
+
658
+ Change `version: "4.0.0"` to `version: "5.0.0"` in `initState()`.
659
+
660
+ **Step 5: Run state-manager tests to find failures**
661
+
662
+ ```bash
663
+ node --test test/lib/state-manager.test.js
664
+ ```
665
+
666
+ Find tests that assert on `feature.phase` or `feature.outputs` and update them:
667
+ - Tests asserting `feature.phase === 'design'` → remove or replace with `derivePhase()` call
668
+ - Tests asserting `feature.outputs.spec.created` → remove or replace with `deriveOutputs()` call
669
+ - Tests asserting `state.version === '4.0.0'` → change to `'5.0.0'`
670
+
671
+ **Step 6: Add new tests for derivePhase and deriveOutputs**
672
+
673
+ In `test/lib/state-manager.test.js`, add:
674
+
675
+ ```javascript
676
+ import { derivePhase, deriveOutputs } from '../../src/core/state/state-manager.js';
677
+ import { mkdirSync } from 'fs';
678
+
679
+ describe('derivePhase', () => {
680
+ test('returns setup when no phase folders exist', () => {
681
+ const dir = createTempDir();
682
+ assert.strictEqual(derivePhase(join(dir, '.morph', 'features', 'f')), 'setup');
683
+ cleanupTempDir(dir);
684
+ });
685
+
686
+ test('returns proposal when 0-proposal/ exists', () => {
687
+ const dir = createTempDir();
688
+ const featurePath = join(dir, '.morph', 'features', 'f');
689
+ mkdirSync(join(featurePath, '0-proposal'), { recursive: true });
690
+ assert.strictEqual(derivePhase(featurePath), 'proposal');
691
+ cleanupTempDir(dir);
692
+ });
693
+
694
+ test('returns tasks when 3-tasks/ is highest folder', () => {
695
+ const dir = createTempDir();
696
+ const featurePath = join(dir, '.morph', 'features', 'f');
697
+ mkdirSync(join(featurePath, '0-proposal'), { recursive: true });
698
+ mkdirSync(join(featurePath, '1-design'), { recursive: true });
699
+ mkdirSync(join(featurePath, '3-tasks'), { recursive: true });
700
+ assert.strictEqual(derivePhase(featurePath), 'tasks');
701
+ cleanupTempDir(dir);
702
+ });
703
+
704
+ test('returns implement when 4-implement/ exists', () => {
705
+ const dir = createTempDir();
706
+ const featurePath = join(dir, '.morph', 'features', 'f');
707
+ mkdirSync(join(featurePath, '4-implement'), { recursive: true });
708
+ assert.strictEqual(derivePhase(featurePath), 'implement');
709
+ cleanupTempDir(dir);
710
+ });
711
+ });
712
+
713
+ describe('state migration v4 → v5', () => {
714
+ test('removes outputs and phase from v4 state on load', () => {
715
+ const dir = createTempDir();
716
+ process.chdir(dir);
717
+ // Write a v4.0.0 state with outputs and phase
718
+ const v4State = {
719
+ version: '4.0.0',
720
+ project: { name: 'Test' },
721
+ features: {
722
+ 'my-feature': {
723
+ phase: 'design',
724
+ outputs: { spec: { created: true, path: 'some/path' } },
725
+ workflow: 'standard'
726
+ }
727
+ }
728
+ };
729
+ mkdirSync(join(dir, '.morph'), { recursive: true });
730
+ writeFileSync(join(dir, '.morph', 'state.json'), JSON.stringify(v4State), 'utf8');
731
+
732
+ const state = loadState();
733
+ assert.strictEqual(state.version, '5.0.0');
734
+ assert.strictEqual(state.features['my-feature'].phase, undefined);
735
+ assert.strictEqual(state.features['my-feature'].outputs, undefined);
736
+ assert.strictEqual(state.features['my-feature'].workflow, 'standard'); // kept
737
+
738
+ process.chdir(originalCwd);
739
+ cleanupTempDir(dir);
740
+ });
741
+ });
742
+ ```
743
+
744
+ **Step 7: Run full suite**
745
+
746
+ ```bash
747
+ npm test
748
+ ```
749
+
750
+ Expected: 614+ tests pass, 0 fail.
751
+
752
+ **Step 8: Commit**
753
+
754
+ ```bash
755
+ git add src/core/state/state-manager.js test/lib/state-manager.test.js
756
+ git commit -m "feat(state): remove outputs+phase fields; derive from filesystem at runtime"
757
+ ```
758
+
759
+ ---
760
+
761
+ ## Task 7: Delete track-output-creation hook + unregister it
762
+
763
+ **Files:**
764
+ - Delete: `framework/hooks/claude-code/post-tool-use/track-output-creation.js`
765
+ - Modify: `src/utils/hooks-installer.js` — remove PostToolUse/Write entry for track-output-creation
766
+ - Delete: `test/hooks/track-output-creation.test.js`
767
+ - Modify: `test/hooks/hooks-installer.test.js` — verify hook no longer registered
768
+
769
+ **Context:** `track-output-creation.js` existed solely to mark `outputs.{type}.created = true` in state.json. With `outputs` removed from state.json (Task 6), this hook has no purpose.
770
+
771
+ **Step 1: Remove the PostToolUse/Write hook entry from hooks-installer.js**
772
+
773
+ In `src/utils/hooks-installer.js`, find and delete the entire block (around lines 92-100):
774
+
775
+ ```javascript
776
+ // DELETE this entire block:
777
+ // === PostToolUse: Write ===
778
+ {
779
+ event: 'PostToolUse',
780
+ matcher: 'Write',
781
+ hooks: [{
782
+ type: 'command',
783
+ command: 'node framework/hooks/claude-code/post-tool-use/track-output-creation.js'
784
+ }]
785
+ },
786
+ ```
787
+
788
+ **Step 2: Delete the hook file**
789
+
790
+ ```bash
791
+ git rm framework/hooks/claude-code/post-tool-use/track-output-creation.js
792
+ git rm test/hooks/track-output-creation.test.js
793
+ ```
794
+
795
+ **Step 3: Update hooks-installer.test.js**
796
+
797
+ Find any test that asserts `PostToolUse` is installed with `track-output-creation` and either remove it or change it to assert the hook is NOT registered. Add:
798
+
799
+ ```javascript
800
+ test('does NOT register track-output-creation hook (removed in v5)', async () => {
801
+ await installClaudeHooks(tempDir);
802
+ const settings = readSettings();
803
+ const postToolUseHooks = settings.hooks?.PostToolUse ?? [];
804
+ const commands = postToolUseHooks.flatMap(h => h.hooks ?? []).map(h => h.command ?? '');
805
+ assert.ok(
806
+ !commands.some(c => c.includes('track-output-creation')),
807
+ 'track-output-creation should not be registered'
808
+ );
809
+ });
810
+ ```
811
+
812
+ **Step 4: Run hooks tests**
813
+
814
+ ```bash
815
+ node --test test/hooks/hooks-installer.test.js
816
+ ```
817
+
818
+ Expected: all pass.
819
+
820
+ **Step 5: Run full suite**
821
+
822
+ ```bash
823
+ npm test
824
+ ```
825
+
826
+ Expected: test count slightly lower (track-output-creation.test.js removed), 0 fail.
827
+
828
+ **Step 6: Commit**
829
+
830
+ ```bash
831
+ git add src/utils/hooks-installer.js test/hooks/hooks-installer.test.js
832
+ git commit -m "feat(hooks): remove track-output-creation — outputs now derived from filesystem"
833
+ ```
834
+
835
+ ---
836
+
837
+ ## Task 8: Update status command + version bump
838
+
839
+ **Files:**
840
+ - Modify: `src/commands/project/status.js` — use derivePhase/deriveOutputs
841
+ - Modify: `test/commands/status.test.js` — update assertions
842
+ - Modify: `package.json` — version 4.4.0 → 4.5.0
843
+
844
+ **Context:** `morph-spec status <feature>` currently reads `feature.phase` and `feature.outputs` from state.json. After Task 6 these fields don't exist. Update status to call `derivePhase()` and `deriveOutputs()` instead.
845
+
846
+ **Step 1: Find where status.js reads phase and outputs**
847
+
848
+ ```bash
849
+ grep -n "\.phase\|\.outputs" src/commands/project/status.js
850
+ ```
851
+
852
+ **Step 2: Update status.js to use derive helpers**
853
+
854
+ Import and use the new helpers:
855
+
856
+ ```javascript
857
+ import { loadState, derivePhase, deriveOutputs } from '../../core/state/state-manager.js';
858
+ import { join } from 'path';
859
+
860
+ // Where phase was read:
861
+ // BEFORE: const phase = feature.phase;
862
+ // AFTER:
863
+ const featurePath = join(process.cwd(), '.morph', 'features', featureName);
864
+ const phase = derivePhase(featurePath);
865
+
866
+ // Where outputs were read:
867
+ // BEFORE: const outputs = feature.outputs;
868
+ // AFTER:
869
+ const outputs = deriveOutputs(featureName);
870
+ ```
871
+
872
+ **Step 3: Run status tests**
873
+
874
+ ```bash
875
+ node --test test/commands/status.test.js
876
+ ```
877
+
878
+ Fix any failing assertions — they'll be about phase values or outputs shape. The shape of `deriveOutputs()` return value matches the old `feature.outputs` shape (`{ type: { created: boolean, path: string } }`), so display logic should need minimal changes.
879
+
880
+ **Step 4: Bump version in package.json**
881
+
882
+ Change `"version": "4.4.0"` to `"version": "4.5.0"`.
883
+
884
+ **Step 5: Update version reference in framework/CLAUDE.md footer**
885
+
886
+ Change `*MORPH-SPEC v4.4.0 by Polymorphism Tech*` to `*MORPH-SPEC v4.5.0 by Polymorphism Tech*`.
887
+ (This file was already rewritten in Task 3 with v4.5.0, so just verify it's correct.)
888
+
889
+ **Step 6: Run full suite — final verification**
890
+
891
+ ```bash
892
+ npm test
893
+ ```
894
+
895
+ Expected: all tests pass, 0 fail. Count may differ from original (some tests removed, some added).
896
+
897
+ **Step 7: Final commit**
898
+
899
+ ```bash
900
+ git add src/commands/project/status.js test/commands/status.test.js package.json framework/CLAUDE.md
901
+ git commit -m "feat(status): derive phase+outputs from filesystem; bump version to 4.5.0"
902
+ ```
903
+
904
+ ---
905
+
906
+ ## Final Verification
907
+
908
+ After all 8 tasks:
909
+
910
+ ```bash
911
+ npm test
912
+ git log --oneline -8
913
+ ```
914
+
915
+ Expected log:
916
+ ```
917
+ feat(status): derive phase+outputs from filesystem; bump version to 4.5.0
918
+ feat(hooks): remove track-output-creation — outputs now derived from filesystem
919
+ feat(state): remove outputs+phase fields; derive from filesystem at runtime
920
+ feat(standards): add TypeScript strict mode requirement; add user-stories template
921
+ feat(rules): add Test File Policy to morph-workflow rule
922
+ feat(claude-md): merge CLAUDE.md + CLAUDE_runtime.md into single unified file
923
+ feat(rules): replace static content with @-imports from framework/standards
924
+ feat(skills): install as subdirectory/SKILL.md — native Claude Code format
925
+ ```