@polymorphism-tech/morph-spec 8.38.0 → 8.41.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 (242) hide show
  1. package/CLAUDE.md +20 -9
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +60 -43
  4. package/claude-plugin.json +1 -1
  5. package/docs/CHEATSHEET.md +1 -1
  6. package/docs/QUICKSTART.md +1 -1
  7. package/framework/CLAUDE.md +4 -3
  8. package/framework/MORPH.md +10 -9
  9. package/framework/agents.json +43 -26
  10. package/framework/docs/CLI.md +7 -5
  11. package/framework/evals/rubrics/code-quality.md +4 -4
  12. package/framework/evals/rubrics/condensed.md +2 -2
  13. package/framework/hooks/README.md +1 -1
  14. package/framework/hooks/claude-code/core/telemetry-log.js +39 -8
  15. package/framework/hooks/claude-code/core/worktree-create.js +22 -6
  16. package/framework/hooks/shared/git-paths.js +38 -5
  17. package/framework/mcp/registry.json +58 -66
  18. package/framework/rules/infrastructure-standards.md +0 -1
  19. package/framework/rules/morph-workflow.md +9 -4
  20. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  21. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  22. package/framework/skills/core/morph-apply/SKILL.md +59 -25
  23. package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
  24. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  25. package/framework/skills/core/morph-hotfix/SKILL.md +2 -2
  26. package/framework/skills/core/morph-implement/SKILL.md +48 -24
  27. package/framework/skills/core/morph-media/SKILL.md +2 -2
  28. package/framework/skills/core/morph-plan/SKILL.md +10 -3
  29. package/framework/skills/core/morph-proposal/SKILL.md +1 -1
  30. package/framework/skills/core/morph-review/SKILL.md +1 -1
  31. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  32. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  33. package/framework/skills/core/morph-uiux/SKILL.md +7 -6
  34. package/framework/standards/PROVENANCE.json +4 -4
  35. package/framework/standards/STANDARDS.json +9 -9
  36. package/framework/standards/ai-agents/context-providers.md +16 -26
  37. package/framework/standards/ai-agents/durable-workflows-hitl.md +15 -21
  38. package/framework/standards/ai-agents/modalities-image-gen.md +21 -25
  39. package/framework/standards/ai-agents/modalities-speech-to-text.md +4 -15
  40. package/framework/standards/ai-agents/modalities-text-to-speech.md +2 -11
  41. package/framework/standards/ai-agents/modalities-vision.md +1 -18
  42. package/framework/standards/ai-agents/prompt-sources.md +0 -4
  43. package/framework/standards/architecture/code-comments.md +52 -16
  44. package/framework/standards/backend/dotnet/testing.md +4 -2
  45. package/framework/standards/backend/integrations/neon-auth/neon-auth.md +63 -50
  46. package/framework/standards/frontend/design-system/ai-image-generation.md +42 -28
  47. package/framework/standards/frontend/design-system/ai-video-generation.md +24 -9
  48. package/framework/standards/frontend/nextjs/testing.md +4 -2
  49. package/framework/standards/integration/mcp/mcp-tools.md +64 -126
  50. package/framework/templates/code/dotnet/abstractions/result.cs +0 -2
  51. package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +26 -39
  52. package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +28 -68
  53. package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +99 -117
  54. package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +2 -44
  55. package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +40 -61
  56. package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +54 -107
  57. package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +53 -58
  58. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +192 -281
  59. package/framework/templates/code/dotnet/database/migration.cs +49 -83
  60. package/framework/templates/code/dotnet/database/vector-entity.cs +2 -46
  61. package/framework/templates/code/dotnet/extensions/result-extensions.cs +0 -2
  62. package/framework/templates/code/dotnet/feature/validator.cs.hbs +11 -15
  63. package/framework/templates/code/dotnet/jobs/agent.cs +3 -51
  64. package/framework/templates/code/dotnet/jobs/job.cs +2 -97
  65. package/framework/templates/code/dotnet/test.cs +2 -87
  66. package/framework/templates/code/typescript/contracts.ts +140 -167
  67. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentApi.cs +1 -48
  68. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs +3 -79
  69. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactoryOptions.cs +1 -70
  70. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs +1 -47
  71. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpecOptions.cs +2 -99
  72. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/AiKitAssemblyMarker.cs +0 -6
  73. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/ConversationStore.cs +3 -88
  74. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/IConversationStore.cs +1 -41
  75. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/InMemoryConversationStore.cs +0 -21
  76. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/CountingChatClient.cs +1 -25
  77. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalAssertion.cs +2 -63
  78. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheMissException.cs +0 -30
  79. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheOptions.cs +1 -52
  80. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheStamp.cs +3 -78
  81. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalFixture.cs +4 -109
  82. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalMode.cs +0 -22
  83. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalQualityEvaluators.cs +1 -36
  84. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalScenario.cs +2 -57
  85. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalSummary.cs +0 -75
  86. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/OfflineChatClient.cs +2 -59
  87. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/ShortPathResponseCache.cs +4 -111
  88. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaGenerator.cs +0 -34
  89. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaProvider.cs +1 -57
  90. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaArtifact.cs +0 -19
  91. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaDisclosure.cs +2 -74
  92. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaGenerator.cs +2 -33
  93. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaIdempotencyKey.cs +1 -43
  94. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJob.cs +1 -96
  95. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobId.cs +0 -13
  96. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobState.cs +0 -27
  97. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaPricing.cs +0 -33
  98. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaProvenance.cs +0 -31
  99. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaRequest.cs +3 -75
  100. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaResult.cs +0 -42
  101. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaReview.cs +0 -39
  102. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaSeams.cs +1 -55
  103. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaStore.cs +3 -59
  104. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MorphMedia.cs +0 -46
  105. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/GoogleImageProvider.cs +3 -28
  106. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs +7 -61
  107. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/VeoVideoProvider.cs +2 -37
  108. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/IUsageCostSink.cs +1 -23
  109. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs +2 -82
  110. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostRecord.cs +1 -68
  111. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs +1 -62
  112. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphTelemetryOptions.cs +2 -62
  113. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/IProviderClientFactory.cs +1 -25
  114. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs +0 -124
  115. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs +1 -73
  116. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaIngest.cs +1 -66
  117. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaPlan.cs +0 -41
  118. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentFactoryTests.cs +2 -112
  119. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentSpecTests.cs +2 -43
  120. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ConversationStoreTests.cs +5 -110
  121. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/DeltaIngestTests.cs +7 -103
  122. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalAssertionTests.cs +1 -42
  123. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheMissTests.cs +1 -30
  124. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheStampTests.cs +1 -19
  125. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFailuresTests.cs +0 -48
  126. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFixtureTests.cs +1 -29
  127. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalRefreshTests.cs +2 -38
  128. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalWorkspace.cs +1 -14
  129. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/KitEvals.cs +4 -69
  130. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/OfflineChatClientTests.cs +1 -10
  131. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs +1 -57
  132. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClientTests.cs +0 -26
  133. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeClock.cs +1 -19
  134. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeMediaProvider.cs +0 -32
  135. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeProviderClientFactory.cs +0 -14
  136. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeUsageCostSink.cs +0 -24
  137. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/InMemoryMediaStore.cs +0 -32
  138. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAccessibilityTests.cs +0 -37
  139. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAliasIsNotAnAgentTests.cs +0 -24
  140. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +0 -78
  141. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaGeneratorTests.cs +0 -53
  142. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaIdempotencyKeyTests.cs +0 -44
  143. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaJobStateTests.cs +0 -44
  144. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaReviewTests.cs +0 -19
  145. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaStoreTests.cs +0 -24
  146. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ModelRegistryTests.cs +6 -48
  147. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/SkeletonSmokeTests.cs +1 -13
  148. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/TelemetryTests.cs +2 -71
  149. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/UsageCostMiddlewareTests.cs +5 -100
  150. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +39 -43
  151. package/framework/templates/frontend/nextjs/env.mjs.hbs +29 -32
  152. package/framework/templates/frontend/nextjs/page.tsx.hbs +21 -22
  153. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +42 -54
  154. package/framework/templates/integrations/asaas-client.cs +332 -387
  155. package/framework/templates/integrations/asaas-webhook.cs +290 -351
  156. package/framework/templates/integrations/neon-auth-config.cs +9 -105
  157. package/framework/templates/project/validate.js +97 -120
  158. package/package.json +2 -2
  159. package/src/commands/dashboard/dashboard.js +80 -53
  160. package/src/commands/mcp/mcp-setup.js +37 -9
  161. package/src/commands/project/doctor.js +12 -6
  162. package/src/commands/project/init.js +6 -3
  163. package/src/commands/project/install-plugin-cmd.js +1 -1
  164. package/src/commands/project/update.js +5 -0
  165. package/src/commands/project/worktree.js +60 -4
  166. package/src/commands/state/gate-check.js +5 -0
  167. package/src/commands/tasks/dag.js +27 -4
  168. package/src/commands/validation/verify.js +22 -38
  169. package/src/dashboard/app/App.jsx +80 -16
  170. package/src/dashboard/app/components/ActivityFeed.jsx +172 -0
  171. package/src/dashboard/app/components/CommandPalette.jsx +155 -0
  172. package/src/dashboard/app/components/DetailPanel.jsx +47 -11
  173. package/src/dashboard/app/components/EntityLink.jsx +55 -0
  174. package/src/dashboard/app/components/ErrorBoundary.jsx +54 -0
  175. package/src/dashboard/app/components/FlowGraph.jsx +19 -17
  176. package/src/dashboard/app/components/KnowledgeMarkdown.jsx +53 -0
  177. package/src/dashboard/app/components/Markdown.jsx +47 -0
  178. package/src/dashboard/app/components/PhaseRail.jsx +111 -0
  179. package/src/dashboard/app/components/SearchFilter.jsx +40 -22
  180. package/src/dashboard/app/components/Sidebar.jsx +146 -37
  181. package/src/dashboard/app/hooks/useMorphQuery.js +54 -0
  182. package/src/dashboard/app/hooks/usePref.js +38 -0
  183. package/src/dashboard/app/lib/format.js +69 -0
  184. package/src/dashboard/app/lib/phases.js +56 -0
  185. package/src/dashboard/app/lib/project.js +50 -0
  186. package/src/dashboard/app/pages/Activity.jsx +24 -0
  187. package/src/dashboard/app/pages/AgentMap.jsx +371 -370
  188. package/src/dashboard/app/pages/FeatureDetail.jsx +604 -0
  189. package/src/dashboard/app/pages/Features.jsx +400 -0
  190. package/src/dashboard/app/pages/Guide.jsx +146 -0
  191. package/src/dashboard/app/pages/HookInspector.jsx +357 -322
  192. package/src/dashboard/app/pages/PhasePipeline.jsx +277 -408
  193. package/src/dashboard/app/pages/Portfolio.jsx +156 -0
  194. package/src/dashboard/app/pages/Rubrics.jsx +101 -0
  195. package/src/dashboard/app/pages/RulesMap.jsx +300 -273
  196. package/src/dashboard/app/pages/SkillsLibrary.jsx +483 -366
  197. package/src/dashboard/app/pages/Standards.jsx +407 -332
  198. package/src/dashboard/app/styles/index.css +187 -47
  199. package/src/dashboard/index.html +14 -12
  200. package/src/dashboard/package.json +32 -24
  201. package/src/dashboard/scanner/activity-scanner.js +351 -0
  202. package/src/dashboard/scanner/agents-scanner.js +59 -1
  203. package/src/dashboard/scanner/docs-scanner.js +59 -0
  204. package/src/dashboard/scanner/feature-status.js +10 -0
  205. package/src/dashboard/scanner/features-scanner.js +360 -0
  206. package/src/dashboard/scanner/index.js +14 -7
  207. package/src/dashboard/scanner/phases-scanner.js +14 -15
  208. package/src/dashboard/scanner/portfolio.js +153 -0
  209. package/src/dashboard/scanner/project-api.js +195 -0
  210. package/src/dashboard/scanner/rules-scanner.js +42 -37
  211. package/src/dashboard/scanner/skills-scanner.js +105 -43
  212. package/src/dashboard/scanner/standards-scanner.js +2 -0
  213. package/src/dashboard/vite-plugin-morph-data.js +134 -17
  214. package/src/lib/detectors/claude-config-detector.js +2 -7
  215. package/src/lib/detectors/index.js +5 -1
  216. package/src/lib/evaluator-report.js +22 -0
  217. package/src/lib/generators/settings-generator.js +208 -209
  218. package/src/lib/installers/mcp-installer.js +724 -719
  219. package/src/lib/installers/memory-installer.js +1 -2
  220. package/src/lib/projects/registry.js +154 -0
  221. package/src/lib/risk-detector.js +13 -0
  222. package/src/lib/tasks/tasks-json-parser.js +21 -0
  223. package/src/lib/validators/code-budget/code-budget-validator.js +32 -4
  224. package/src/lib/worktree/env-allocator.js +9 -3
  225. package/src/scripts/install-plugin.js +1 -1
  226. package/src/scripts/setup-infra.js +2 -4
  227. package/src/utils/agents-installer.js +108 -13
  228. package/src/utils/banner.js +1 -1
  229. package/src/commands/index.js +0 -13
  230. package/src/commands/project/checkpoint.js +0 -209
  231. package/src/core/state/phase-state-machine.js +0 -197
  232. package/src/dashboard/app/hooks/useDetailPanel.js +0 -15
  233. package/src/dashboard/app/pages/LiveState.jsx +0 -206
  234. package/src/dashboard/scanner/squads-scanner.js +0 -13
  235. package/src/dashboard/scanner/state-scanner.js +0 -85
  236. package/src/lib/generators/index.js +0 -10
  237. package/src/lib/hooks/hook-executor.js +0 -167
  238. package/src/lib/validators/checkpoint-persistence.js +0 -39
  239. package/src/lib/validators/shared/emit-validator-dispatch.js +0 -14
  240. package/src/lib/validators/shared/index.js +0 -12
  241. package/src/lib/validators/shared/issue-counter.js +0 -14
  242. package/src/lib/validators/shared/result-formatter.js +0 -124
@@ -58,6 +58,42 @@ function findDotGit(startDir) {
58
58
  }
59
59
  }
60
60
 
61
+ /**
62
+ * A linked worktree's `.git` FILE holds `gitdir: <path>` (absolute or relative
63
+ * to the file) pointing at its private gitdir. `null` when the line is absent.
64
+ *
65
+ * @param {string} dotGitFile
66
+ * @returns {string|null}
67
+ */
68
+ function privateGitDirOf(dotGitFile) {
69
+ const match = readFileSync(dotGitFile, 'utf8').match(/^gitdir:\s*(.+?)\s*$/m);
70
+ if (!match) return null;
71
+ return isAbsolute(match[1]) ? match[1] : resolve(dirname(dotGitFile), match[1]);
72
+ }
73
+
74
+ const MORPH_BRANCH = /^ref:\s*refs\/heads\/morph\/([A-Za-z0-9._-]+)\s*$/;
75
+
76
+ /**
77
+ * The feature a checkout is bound to by its branch `morph/<feature>`, read from
78
+ * `<root>/.git` exactly (no climbing) — the primary's `.git/HEAD` or, for a
79
+ * linked worktree, `<gitdir>/HEAD`. `null` for any other branch (`morph-task/*`
80
+ * included), a detached HEAD, or no `.git` at `root`.
81
+ *
82
+ * @param {string} root
83
+ * @returns {string|null}
84
+ */
85
+ export function morphBranchFeature(root) {
86
+ try {
87
+ const dotGit = join(root, '.git');
88
+ const gitDir = statSync(dotGit).isDirectory() ? dotGit : privateGitDirOf(dotGit);
89
+ if (!gitDir) return null;
90
+ const name = MORPH_BRANCH.exec(readFileSync(join(gitDir, 'HEAD'), 'utf8').trim())?.[1];
91
+ return name && name !== '.' && name !== '..' ? name : null;
92
+ } catch {
93
+ return null;
94
+ }
95
+ }
96
+
61
97
  /**
62
98
  * Is `startDir` inside a LINKED (secondary) worktree?
63
99
  *
@@ -119,11 +155,8 @@ export function resolveGitCommonDir(startDir) {
119
155
  return found.path;
120
156
  }
121
157
 
122
- // `.git` is a FILE: `gitdir: <path>` → this worktree's private gitdir.
123
- const content = readFileSync(found.path, 'utf8');
124
- const match = content.match(/^gitdir:\s*(.+?)\s*$/m);
125
- if (!match) return null;
126
- const privateGitDir = isAbsolute(match[1]) ? match[1] : resolve(dirname(found.path), match[1]);
158
+ const privateGitDir = privateGitDirOf(found.path);
159
+ if (!privateGitDir) return null;
127
160
 
128
161
  // Inside the private gitdir, `commondir` points (relative to itself, or
129
162
  // absolute) at the real common dir.
@@ -5,6 +5,7 @@
5
5
  "context7": {
6
6
  "phases": ["proposal", "plan", "implement"],
7
7
  "tools": ["resolve-library-id", "query-docs"],
8
+ "serverNames": ["context7", "plugin_context7_context7"],
8
9
  "detection": "enabledPlugins includes context7 or mcpServers includes context7",
9
10
  "fallback": "WebSearch + WebFetch for library documentation",
10
11
  "usage": "Library documentation lookups, API reference, implementation patterns",
@@ -33,7 +34,8 @@
33
34
  "playwright": {
34
35
  "phases": ["uiux", "implement"],
35
36
  "tools": ["browser_navigate", "browser_snapshot", "browser_take_screenshot", "browser_console_messages", "browser_click", "browser_resize"],
36
- "detection": "mcpServers includes playwright",
37
+ "serverNames": ["playwright", "plugin_playwright_playwright"],
38
+ "detection": "mcpServers includes playwright or enabledPlugins includes playwright",
37
39
  "fallback": "WebFetch for read-only page content, manual testing",
38
40
  "usage": "UI preview, smoke testing, page inspection, responsive testing, screenshot capture",
39
41
  "healthCheck": {
@@ -165,61 +167,21 @@
165
167
  "description": "Official Stitch agent skills for Claude Code — design generation, multi-page loops, design.md export"
166
168
  }
167
169
  },
168
- "gemini-image": {
170
+ "morph-assets": {
169
171
  "phases": ["uiux", "implement"],
170
- "tools": ["generate_image", "edit_image", "continue_editing", "list_images", "get_image_info", "get_configuration_status"],
171
- "detection": "mcpServers includes gemini-image-mcp",
172
- "fallback": "Manual image creation, stock photos, or placeholder divs",
173
- "usage": "AI image generation for project assets (heroes, illustrations, brand images) using Gemini models",
172
+ "tools": ["generate_image", "edit_image", "continue_editing", "generate_video", "generate_loop_video", "get_video", "media_tool", "list_models", "library", "usage"],
173
+ "serverNames": ["morph-assets"],
174
+ "detection": "mcpServers includes morph-assets",
175
+ "fallback": "Manual image creation, stock photos or client-provided footage; a static poster image instead of video. Canvas frame-scrub works from any frame sequence, AI-generated or not",
176
+ "usage": "Single MCP for AI image and video generation plus local post-production, all models via OpenRouter. Images: default openai/gpt-image-2.5-flare, drafts microsoft/mai-image-2.6-flash, google/gemini-3.1-flash-image for 2K/4K or 6-14 references; `models` compares the same request across 2-4 models. Video: default bytedance/seedance-1-5-pro (draft/loop), final bytedance/seedance-2.0 1080p via promoteFrom; generate_video with endImage produces the directional footage that frame-scrub needs (start frame differs from end frame), generate_loop_video is only for seamless ambient loops. media_tool (ffmpeg) extracts scrub frames, posters, concat, compress and builds the approval picker. library replaces the old list_images/get_image_info/list_videos",
174
177
  "healthCheck": {
175
- "toolPattern": "gemini-image",
176
- "testCall": "Call get_configuration_status to verify API key and server health",
177
- "testParams": {},
178
- "successIndicator": "Returns status with valid API key configured",
179
- "failureHint": "Gemini Image MCP not responding. Check that GEMINI_API_KEY is set in the MCP env config and that MORPH_HUB points at a built morph-HUB checkout."
180
- },
181
- "install": {
182
- "autoInstall": false,
183
- "transport": "stdio",
184
- "config": {
185
- "type": "stdio",
186
- "command": "node",
187
- "args": ["${MORPH_HUB}/mcps/gemini-image/dist/index.js"]
188
- },
189
- "credentials": [
190
- {
191
- "name": "Gemini API Key",
192
- "envVar": "GEMINI_API_KEY",
193
- "secret": true,
194
- "helpUrl": "https://aistudio.google.com/apikey"
195
- }
196
- ],
197
- "prerequisites": [
198
- "Google AI Studio API key",
199
- "Local morph-HUB checkout with mcps/gemini-image built, exposed via the MORPH_HUB env var"
200
- ],
201
- "stackRelevance": ["nextjs", "next"],
202
- "warnings": [
203
- "Internal Polymorphism MCP, not published to npm. The public gemini-image-mcp package was unpublished in 2025-04, so npx installs no longer work.",
204
- "Requires GEMINI_API_KEY environment variable. Image generation costs apply per Google AI pricing."
205
- ],
206
- "setupGuide": "1. Get an API key at https://aistudio.google.com/apikey\n2. Build the MCP: cd $MORPH_HUB/mcps/gemini-image && npm install && npm run build\n3. Run: claude mcp add gemini-image-mcp -e GEMINI_API_KEY=<key> -- node $MORPH_HUB/mcps/gemini-image/dist/index.js\n4. Verify with get_configuration_status"
207
- }
208
- },
209
- "seedance": {
210
- "phases": ["uiux", "implement"],
211
- "tools": ["generate_video", "generate_loop_video", "get_video", "list_videos"],
212
- "detection": "mcpServers includes seedance",
213
- "fallback": "Use client-provided footage or a static poster image; canvas frame-scrub works from any frame sequence, AI-generated or not",
214
- "usage": "AI video generation for scroll-driven heroes and ambient backgrounds. generate_video with endImage produces the directional footage that frame-scrub needs (start frame differs from end frame); generate_loop_video is only for seamless ambient loops",
215
- "healthCheck": {
216
- "toolPattern": "seedance",
217
- "testCall": "Call list_videos with limit 1 to verify the server responds (reads local history, spends no credits)",
178
+ "toolPattern": "morph-assets",
179
+ "testCall": "Call usage with op 'balance' to verify the OpenRouter key (reads the credit balance, spends no credits)",
218
180
  "testParams": {
219
- "limit": 1
181
+ "op": "balance"
220
182
  },
221
- "successIndicator": "Returns the local job history, or 'No videos in history yet'",
222
- "failureHint": "Seedance MCP not responding. Check that REPLICATE_API_TOKEN is set in the MCP env config and that MORPH_HUB points at a built morph-HUB checkout."
183
+ "successIndicator": "Returns the OpenRouter credit balance",
184
+ "failureHint": "morph-assets MCP not responding. Check that OPENROUTER_API_KEY is set (morph-HUB root .env or the MCP env config) and that MORPH_HUB points at a morph-HUB checkout with mcps/morph-assets built."
223
185
  },
224
186
  "install": {
225
187
  "autoInstall": false,
@@ -227,28 +189,30 @@
227
189
  "config": {
228
190
  "type": "stdio",
229
191
  "command": "node",
230
- "args": ["${MORPH_HUB}/mcps/seedance/dist/index.js"]
192
+ "args": ["${MORPH_HUB}/mcps/morph-assets/dist/index.js"]
231
193
  },
232
194
  "credentials": [
233
195
  {
234
- "name": "Replicate API Token",
235
- "envVar": "REPLICATE_API_TOKEN",
196
+ "name": "OpenRouter API Key",
197
+ "envVar": "OPENROUTER_API_KEY",
236
198
  "secret": true,
237
- "helpUrl": "https://replicate.com/account/api-tokens"
199
+ "helpUrl": "https://openrouter.ai/settings/keys"
238
200
  }
239
201
  ],
240
202
  "prerequisites": [
241
- "Replicate account with billing enabled",
242
- "Local morph-HUB checkout with mcps/seedance built, exposed via the MORPH_HUB env var",
243
- "ffmpeg on PATH to extract frames for scroll-scrubbing"
203
+ "OpenRouter account with credits",
204
+ "Local morph-HUB checkout with mcps/morph-assets built, exposed via the MORPH_HUB env var",
205
+ "ffmpeg on PATH for media_tool (scrub frames, poster, concat, compress)"
244
206
  ],
245
- "stackRelevance": ["next", "react", "vite", "astro"],
207
+ "stackRelevance": ["next", "nextjs", "react", "vite", "astro"],
246
208
  "warnings": [
247
- "Internal Polymorphism MCP, not published to npm. Requires a local morph-HUB checkout.",
248
- "Paid per generation. Draft at fast/480p/4s first, render 1080p only after the take is approved.",
209
+ "Internal Polymorphism MCP, not published to npm. Requires a local morph-HUB checkout. Replaces the former gemini-image and seedance MCPs.",
210
+ "Paid per generation. Every call estimates cost first; dryRun only estimates. Above US$2, over the project budget or with unknown price it returns CONFIRMATION_REQUIRED + confirmToken: get human approval, then repeat the same call with the token.",
211
+ "Video is async: if generate_video returns 'generating', poll get_video with the ids. Never resend generate_video (a different request is billed again). Draft at 480p first, promote to 1080p only after the take is approved.",
212
+ "Video has no ZDR on OpenRouter and human faces in img2vid frames trigger moderation: keep sensitive content and faces out of the frames.",
249
213
  "Generation is stochastic and needs a human approval gate. Do not wire it into an unattended phase."
250
214
  ],
251
- "setupGuide": "1. Get a token at https://replicate.com/account/api-tokens\n2. Build the MCP: cd $MORPH_HUB/mcps/seedance && npm install && npm run build\n3. Run: claude mcp add seedance -e REPLICATE_API_TOKEN=<token> -- node $MORPH_HUB/mcps/seedance/dist/index.js\n4. Verify with list_videos (reads local history, spends no credits)"
215
+ "setupGuide": "1. Get a key at https://openrouter.ai/settings/keys and set OPENROUTER_API_KEY in the morph-HUB root .env\n2. Build the MCP: cd $MORPH_HUB && npm install && npm run build -w mcps/morph-assets\n3. Run: claude mcp add morph-assets -e OPENROUTER_API_KEY=<key> -- node $MORPH_HUB/mcps/morph-assets/dist/index.js\n4. Verify with usage op 'balance' (spends no credits)"
252
216
  }
253
217
  },
254
218
  "graphify": {
@@ -285,14 +249,42 @@
285
249
  ],
286
250
  "setupGuide": null
287
251
  }
252
+ },
253
+ "neon": {
254
+ "phases": ["plan", "implement"],
255
+ "tools": ["list_projects", "describe_table_schema", "get_database_tables", "run_sql", "explain_sql_statement", "prepare_database_migration", "complete_database_migration", "compare_database_schema", "create_branch", "list_branches", "get_connection_string"],
256
+ "serverNames": ["neon", "Neon"],
257
+ "detection": "mcpServers includes neon (case-insensitive)",
258
+ "fallback": "SQL via the connection string (psql / dotnet ef) and the neonctl CLI for branches",
259
+ "usage": "Schema inspection, migration dry-run on a throwaway branch (prepare_database_migration → complete_database_migration), query tuning. The server exposes DESTRUCTIVE tools (delete_branch, delete_project, reset_from_parent): never call one without explicit human confirmation",
260
+ "healthCheck": {
261
+ "toolPattern": "neon",
262
+ "testCall": "Call list_projects with limit 1",
263
+ "testParams": { "limit": 1 },
264
+ "successIndicator": "Returns the project list (possibly empty)",
265
+ "failureHint": "Neon MCP not responding. Re-run the OAuth flow: claude mcp add --transport http neon https://mcp.neon.tech/mcp"
266
+ },
267
+ "install": {
268
+ "autoInstall": false,
269
+ "transport": "http",
270
+ "config": {
271
+ "type": "http",
272
+ "url": "https://mcp.neon.tech/mcp"
273
+ },
274
+ "credentials": [],
275
+ "prerequisites": [],
276
+ "stackRelevance": ["neon"],
277
+ "warnings": ["OAuth against your Neon account on first use. The server can delete branches and projects: keep destructive calls behind a human."],
278
+ "setupGuide": "Run: claude mcp add --transport http neon https://mcp.neon.tech/mcp"
279
+ }
288
280
  }
289
281
  },
290
- "_phaseMatrixNote": "Keys must be the v5 phases from framework/phases.json. The v4 keys 'design' and 'tasks' both collapsed into 'plan'; 'review' was absent entirely, so a project in review resolved to undefined. Stack-scoped MCPs (asaas) stay out of this matrix on purpose — only universal ones are listed.",
282
+ "_phaseMatrixNote": "Keys must be the v5 phases from framework/phases.json. The v4 keys 'design' and 'tasks' both collapsed into 'plan'; 'review' was absent entirely, so a project in review resolved to undefined. Stack-scoped MCPs (asaas, neon) stay out of this matrix on purpose — only universal ones are listed.",
291
283
  "phaseMatrix": {
292
284
  "proposal": ["context7", "graphify"],
293
- "uiux": ["playwright", "context7", "stitch", "gemini-image", "seedance"],
285
+ "uiux": ["playwright", "context7", "stitch", "morph-assets"],
294
286
  "plan": ["context7", "graphify"],
295
- "implement": ["context7", "playwright", "vercel", "gemini-image", "seedance", "graphify"],
287
+ "implement": ["context7", "playwright", "vercel", "morph-assets", "graphify"],
296
288
  "review": ["playwright", "context7", "graphify"]
297
289
  }
298
290
  }
@@ -12,7 +12,6 @@ stacks:
12
12
 
13
13
  @.morph/framework/standards/infrastructure/docker/coolify-deploy.md
14
14
  @.morph/framework/standards/infrastructure/docker/local-compose-isolation.md
15
- @.morph/framework/standards/infrastructure/docker/local-compose-isolation.md
16
15
 
17
16
  ## Infrastructure Templates
18
17
 
@@ -192,16 +192,21 @@ Every task in `tasks.json` MUST reference its FR(s) in the `description` field s
192
192
 
193
193
  ## Debugging
194
194
 
195
- When a bug or unexpected behavior shows up mid-task, invoke `superpowers:systematic-debugging`
196
- with the `Skill()` tool **before proposing a fix** — root cause first, never a patch on the
197
- symptom. This is MANDATORY; do NOT skip it.
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.
198
203
 
199
204
  Everything else that a rule like this might list is owned by the flow itself, and duplicating it
200
205
  here would put a second, staler copy in permanent context:
201
206
 
202
207
  | Concern | Where it actually lives |
203
208
  |---------|-------------------------|
204
- | TDD before writing code | The feature's `mandate.md` (TDD is built in) — the resident `.claude/CLAUDE.md` says to prefer `morph-*` over the generic `superpowers:*` equivalents |
209
+ | How many tests to write | The test budget copied into the feature's `mandate.md`: one test per postcondition, same-behavior cases in one table, no test that only pins text |
205
210
  | Verifying a task before `status: "done"` | `morph-spec verify {feature} [task]` (build + tests + validators + e2e), then the `morph-eval` skill for the 0-10 score |
206
211
  | Parallel dispatch | `morph-spec dag {feature}` decides sequential vs parallel; execution and isolation rules are in `morph-apply` §2/§3b |
207
212
  | Closing the phase / opening the PR | `morph-review` for Gate 3, then `morph-spec finish {feature} --pr\|--merge` |
@@ -4,7 +4,7 @@ description: Guia a criação de uma landing page nova ponta-a-ponta a partir do
4
4
  version: core
5
5
  when-to-invoke: ao iniciar um novo projeto de LP com o template Umbraco genérico
6
6
  user-invokable: true
7
- cliVersion: "8.38.0"
7
+ cliVersion: "8.41.0"
8
8
  stacks:
9
9
  - umbraco
10
10
  ---
@@ -4,7 +4,7 @@ description: Migra uma landing page existente (React/Vite, Next.js estático ou
4
4
  version: core
5
5
  when-to-invoke: ao receber instrução "use /migrate-lp-to-umbraco {projeto}" do usuário, ou quando o usuário descrever necessidade de migrar uma LP para Umbraco
6
6
  user-invokable: true
7
- cliVersion: "8.38.0"
7
+ cliVersion: "8.41.0"
8
8
  stacks:
9
9
  - umbraco
10
10
  ---
@@ -4,7 +4,7 @@ description: Orquestra a execução autônoma de tasks de uma feature morph-spec
4
4
  version: core
5
5
  when-to-invoke: após Gate 2 aprovado, ao receber instrução "use /morph-apply" ou "implementar feature"
6
6
  user-invokable: true
7
- cliVersion: "8.38.0"
7
+ cliVersion: "8.41.0"
8
8
  ---
9
9
 
10
10
  # morph-apply
@@ -138,7 +138,7 @@ while (true):
138
138
  options: [aceitar (marca done com ressalva no recap), continuar tentando (+3 tentativas), pular task (marca blocked)]
139
139
  ```
140
140
 
141
- > **Loop por task filtra; Gate 3 e CI não.** No loop o filtro é **automático**: `verify {feature} {task.id}` deixa o `group` da task escolher os nós e os arquivos de teste de `outputs` estreitarem o comando — cada nó **aparece** em `nodes.tests.runs[]` com `selection` (`narrowed`/`whole`/`out-of-scope`/`full` e o motivo), nenhum some. `--filter {ids}` só força a escolha de nós (os não casados aparecem como `skip` nomeando o filtro, e um `--filter` que não casa nada é erro de uso, exit 2, nunca um verde); `--full` desliga o recorte. A verificação pós-batch e a do Gate 3 (`morph-spec verify {feature} --json`) rodam **sem filtro**, e `verify {feature}` **nunca recorta**: a prova que o avaliador lê tem de cobrir todos os nós, e o CI idem. Forma de `project.tests[]`, regras e limites do recorte, e a tabela da divisão: `.morph/framework/CLI.md`, seção "Suítes de teste".
141
+ > **Loop por task filtra; Gate 3 e CI não.** O sub-agent despachado não roda `verify`: só o filtro dos próprios testes, uma vez (cláusula 3). No loop o filtro é **automático**: `verify {feature} {task.id}` deixa o `group` da task escolher os nós e os arquivos de teste de `outputs` estreitarem o comando — cada nó **aparece** em `nodes.tests.runs[]` com `selection` (`narrowed`/`whole`/`out-of-scope`/`full` e o motivo), nenhum some. `--filter {ids}` só força a escolha de nós (os não casados aparecem como `skip` nomeando o filtro, e um `--filter` que não casa nada é erro de uso, exit 2, nunca um verde); `--full` desliga o recorte. A verificação pós-batch e a do Gate 3 (`morph-spec verify {feature} --json`) rodam **sem filtro**, e `verify {feature}` **nunca recorta**: a prova que o avaliador lê tem de cobrir todos os nós, e o CI idem. Forma de `project.tests[]`, regras e limites do recorte, e a tabela da divisão: `.morph/framework/CLI.md`, seção "Suítes de teste".
142
142
  >
143
143
  > **Verify vermelho consome uma tentativa** do loop (≤3) e devolve `feedback[]` acionável (erros de build, falhas de teste — linhas prefixadas por `[tests/{id}]`, que nomeiam a suíte —, issues de validador). O `morph-eval` NUNCA é invocado sobre código que não passou no verify — o juiz julga arquitetura/contratos/qualidade, o que o código determinístico não pega sozinho. Código roda antes, grátis; o juiz gasta tokens só no que sobra.
144
144
 
@@ -156,15 +156,18 @@ while (true):
156
156
  - **Standard(s):** use `task.standards` quando presente; senão, do array `standards` do agente resolvido acima em `agents.json` (e/ou do `mandate.md`), selecione o(s) path(s) `.md` relevante(s) à task.
157
157
  - **Fallback (tipo não registrado):** se `morph-{id}` não estiver na sua lista de subagent types (stack não instalado neste projeto), use `subagent_type: "general-purpose"` colando o campo `persona` no prompt — e **registre nas `notes` da task**: `dispatch-fallback: general-purpose ({id} não registrado)`. O recap deve refletir o mecanismo real.
158
158
 
159
+ **Cole o template literal**: só os campos entre `<>` mudam; não parafraseie cláusula nem omita os parágrafos de leitura, ferramentas e comentário.
160
+
159
161
  ```
160
162
  dispatch Agent (subagent_type: "morph-{id}") with prompt:
161
163
  contexto: spec.md, mandate.md, task description completa, doneCriteria,
162
164
  task.reuse (veredito REUSAR/ESTENDER/CRIAR por conceito), os paths
163
165
  dos alvos de reuso e o que você já leu para a task (`arquivo:linhas`
164
166
  + o trecho)
165
- standard: <path(s) .md do(s) standard(s) do domínio — leia-o(s) antes de implementar>
167
+ standards: <por standard: id + digest do `standards --find` + as 3-8 regras do
168
+ .md que ESTA task aplica, coladas; o path só para consulta pontual>
166
169
  instrução: |
167
- Leia o(s) standard(s) indicado(s) antes de escrever código.
170
+ Siga as regras dos standards acima; abra o .md só para uma dúvida pontual.
168
171
  Implemente esta task (ou cadeia de tasks do fluxo) sem depender do trabalho
169
172
  dos outros agentes deste batch: seu ISOLAMENTO é de ESTADO e de ÁRVORE DE
170
173
  TRABALHO — nunca de conhecimento do codebase. Antes de criar tipo,
@@ -173,9 +176,24 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
173
176
  (`no-graph`), caia para `grep -rn "<nome>"` e siga — a ausência de grafo
174
177
  nunca bloqueia. Se algo cobre o caso, reuse ou estenda; se criar mesmo
175
178
  assim, diga por que em uma linha no relatório.
176
- Leitura: não releia o que este prompt já traz. Em arquivo grande, `Grep`
177
- acha a linha e `Read` com `offset`/`limit` lê só o trecho; leituras que não
178
- dependem uma da outra vão no mesmo turno, em paralelo.
179
+ Leitura e turnos: cada turno custa ~10 s antes de a tool rodar, e o teto de
180
+ turnos corta sem aviso. Chamadas que não dependem uma da outra vão no MESMO
181
+ turno: leia de uma vez todos os arquivos que este prompt lista, dispare os
182
+ Grep juntos. Use Read/Grep/Glob — nunca `grep`, `sed -n`, `cat`, `find`,
183
+ `ls` via Bash. Não releia o que este prompt já traz. Em arquivo grande, `Grep`
184
+ acha a linha e `Read` com `offset`/`limit` lê só o trecho; log de build/teste
185
+ se lê pelo `Grep` do erro, não inteiro.
186
+
187
+ Ferramentas: antes de supor a API de uma biblioteca (MAF, EF Core, Next,
188
+ shadcn, SDK de provedor), consulte o MCP `context7` (`resolve-library-id` →
189
+ `query-docs`). Impacto e vizinhança de símbolo vêm do grafo
190
+ (`morph-spec graph`), não de varredura por grep. Tool `mcp__…` que não esteja
191
+ carregada se carrega com `ToolSearch` (`select:<nome>`); MCP ausente nunca
192
+ bloqueia — siga com o fallback.
193
+ Comentário: o padrão é nenhum. Nome, tipo e teste explicam o código; sem
194
+ `///`/JSDoc em membro de aplicação, cabeçalho, banner de seção ou história
195
+ da task. Só o porquê que o código não mostra, em uma linha
196
+ (`architecture-code-comments`).
179
197
  Não modifique spec.md, mandate.md.
180
198
 
181
199
  Contrato do relatório final:
@@ -188,17 +206,21 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
188
206
  2. NÃO toque em tasks.json, feature.json, state.json nem no board de
189
207
  sessão — todo estado (status de task, scores, gates) é gravado
190
208
  exclusivamente pelo orquestrador.
191
- 3. Verificação condicional ao isolamento:
192
- - Batch SEM isolamento (working tree compartilhada): NÃO rode build/test da
193
- suíte compartilhada — edições concorrentes quebram o build umas das outras;
194
- a verificação é do orquestrador, pós-batch (`morph-spec verify`).
195
- - Batch COM isolamento (você recebeu `isolation: "worktree"`): rode build/test
196
- DENTRO do seu worktree; commite seu trabalho na branch do worktree como
197
- último ato antes do relatório; reporte a branch — nunca faça merge nem
198
- toque na árvore principal.
199
- - Ao rodar teste: compile uma vez e rode sem recompilar (`dotnet test
200
- --no-build`); só os testes que a mudança toca (`--filter`) e, depois de
201
- uma falha, só os que falharam. Grave a saída em arquivo uma vez
209
+ 3. TESTE — a prova é do orquestrador (`morph-spec verify`), não sua.
210
+ Escreva os testes pelo orçamento: um por pós-condição, um de regressão
211
+ por bug, variantes numa tabela (`[Theory]`/`it.each`). NÃO rode teste a
212
+ cada marco nem faça ciclo red→green: escreva código e testes, compile, e
213
+ rode SÓ o filtro dos seus testes UMA vez, antes do relatório; se falhar,
214
+ corrija e rode só os que falharam. Não rode `morph-spec verify`.
215
+ - Batch SEM isolamento (working tree compartilhada): só compile —
216
+ edições concorrentes quebram o build umas das outras; o teste roda no
217
+ verify do orquestrador, pós-batch.
218
+ - Batch COM isolamento (você recebeu `isolation: "worktree"`): a regra
219
+ acima vale DENTRO do seu worktree; commite seu trabalho na branch do
220
+ worktree como último ato antes do relatório; reporte a branch — nunca
221
+ faça merge nem toque na árvore principal.
222
+ - Ao rodar: compile uma vez e rode sem recompilar (`dotnet test
223
+ --no-build`), com `--filter`. Grave a saída em arquivo uma vez
202
224
  (`… > .morph/logs/test-last.log 2>&1`, sem nada depois) e leia o arquivo:
203
225
  rodar de novo com outro `| tail`/`| grep` repete o teste para ver outras
204
226
  linhas, e com pipe ou `; echo` o exit é o do último comando, não o do teste.
@@ -206,8 +228,8 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
206
228
  4. ESCOPO: no máximo 3 tasks e ~4 arquivos por dispatch. Escopo maior falha e
207
229
  volta — fatie antes, não depois.
208
230
  5. SOBREVIVÊNCIA: o limite de turnos (`maxTurns`, no seu system prompt)
209
- corta sem aviso: commite `wip({taskId})` a cada marco (arquivo que
210
- compila, teste que passa), não só ao fim da task — e só os seus arquivos
231
+ corta sem aviso: commite `wip({taskId})` a cada marco (um arquivo ou
232
+ uma fatia coerente escrita — sem rodar teste para isso), não só ao fim da task — e só os seus arquivos
211
233
  (`git add <paths>`, nunca `-A`). Sem commit, a retomada recomeça do zero.
212
234
  A ~70% do limite, grave o relatório parcial no arquivo canônico: `PARCIAL`
213
235
  na 1ª linha, o feito e o que falta, sem auto-score. Depois siga ou pare,
@@ -217,6 +239,9 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
217
239
  sessões). Encerre dev server pelo PID que você mesmo subiu.
218
240
  7. RETORNO: o relatório no arquivo canônico é o retorno. `SendMessage` não é
219
241
  substituto do relatório e não deve ser chamado.
242
+ 8. MUTAÇÃO: nunca altere, reverta, mova ou apague código de produção para ver
243
+ um teste falhar (`sed`, `mv`, `git show HEAD:… >`, `git stash`, `git
244
+ checkout --`). A prova de que o teste morde é do avaliador no Gate 3.
220
245
 
221
246
  Seu relatório final deve conter APENAS: (1) o que foi feito em 2-3
222
247
  frases, (2) arquivos modificados, (3) problemas encontrados e como foram
@@ -239,11 +264,11 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
239
264
  > re-despache só o que falta a partir do último `wip`. Nunca pontue nem marque `done` sobre um
240
265
  > parcial.
241
266
 
242
- > Este template é deliberadamente paritário com o template sequencial em `morph-implement` §4: ambos despacham o **subagent registrado do domínio (`morph-{id}`)** com standard escopado e as **mesmas 7 cláusulas** do contrato do relatório final (as 3 do relatório + escopo, sobrevivência, processos e retorno) e os mesmos 4 itens de relatório — racional completo em `MORPH.md` §6. A única diferença é que aqui múltiplos agentes rodam ao mesmo tempo, um por fluxo independente.
267
+ > Este template é deliberadamente paritário com o template sequencial em `morph-implement` §4: ambos despacham o **subagent registrado do domínio (`morph-{id}`)** com standard escopado e as **mesmas 8 cláusulas** do contrato do relatório final (relatório, estado, teste, escopo, sobrevivência, processos, retorno e mutação), os mesmos parágrafos de leitura/turnos e ferramentas e os mesmos 4 itens de relatório — racional completo em `MORPH.md` §6. A única diferença é que aqui múltiplos agentes rodam ao mesmo tempo, um por fluxo independente.
243
268
 
244
269
  > **Alternativa quando os fluxos tocam os mesmos projetos/arquivos** (ex.: o mesmo csproj de testes compartilhado): siga a §3b-w abaixo em vez desta seção — despache com `isolation: "worktree"`, cada agente trabalha numa working tree própria e o orquestrador integra ao final.
245
270
 
246
- Aguardar todos os agentes terminarem, depois **auditar os relatórios contra o trabalho** com `morph-spec report-check {feature} {T1} {T2} … --json` (os ids do batch: sem eles o modo feature só audita tasks já `done`, e as do batch ainda não estão) — determinístico e independente da palavra dos agentes; é o passo que pega tanto o relatório ausente quanto o `report-stale` (completo, porém gravado antes do fim do trabalho: o agente relatou cedo e continuou escrevendo). Em `report-stale`, **não re-despache** — leia o campo `observed` (writes reais do `events.jsonl`) e atualize o relatório a partir dele. Vereditos e ações: `MORPH.md` §6. Em seguida **ler** `.morph/features/{feature}/3-implement/reports/{taskId}.md` de cada task — é o valor de retorno autoritativo; a mensagem de texto do dispatch, se chegou inteira, é só um atalho que economiza essa leitura. Depois, sequencialmente:
271
+ **Batch SEM isolamento:** aguardar todos os agentes terminarem, depois **auditar os relatórios contra o trabalho** com `morph-spec report-check {feature} {T1} {T2} … --json` (os ids do batch: sem eles o modo feature só audita tasks já `done`, e as do batch ainda não estão) — determinístico e independente da palavra dos agentes; é o passo que pega tanto o relatório ausente quanto o `report-stale` (completo, porém gravado antes do fim do trabalho: o agente relatou cedo e continuou escrevendo). Em `report-stale`, **não re-despache** — leia o campo `observed` (writes reais do `events.jsonl`) e atualize o relatório a partir dele. Vereditos e ações: `MORPH.md` §6. Em seguida **ler** `.morph/features/{feature}/3-implement/reports/{taskId}.md` de cada task — é o valor de retorno autoritativo; a mensagem de texto do dispatch, se chegou inteira, é só um atalho que economiza essa leitura. Depois, sequencialmente:
247
272
  - **Rodar `morph-spec verify {feature} --json` uma única vez, pós-batch** (escopo feature, **sem `--filter`**) — os agentes não a rodaram (cláusula 3). Vermelho: use `verify.feedback` para corrigir/redespachar ANTES de qualquer morph-eval. (Com isolamento por worktree, cada agente já rodou o verify dentro do seu worktree; o orquestrador roda o verify compartilhado UMA vez após o merge — ver §3b-w.)
248
273
  - Para cada relatório retornado:
249
274
  - Aplicar `Skill(morph-eval)`.
@@ -253,13 +278,22 @@ Aguardar todos os agentes terminarem, depois **auditar os relatórios contra o t
253
278
 
254
279
  Depois do batch paralelo, executar o restante em modo sequencial (passo 3a).
255
280
 
281
+ **Batch COM isolamento (§3b-w): dispatch rolling, não por onda.** Nenhum agente escreve na
282
+ árvore principal, então o orquestrador não espera o batch inteiro: a cada relatório que chega,
283
+ audita (`report-check {feature} {taskId}`), integra aquela branch (§3b-w passo 2), roda
284
+ `verify {feature} {taskId}` e `morph-eval` + `score` daquela task, e **despacha na hora** toda
285
+ task que ficou `ready` (`getReadyTasks`) cujos `outputs` não colidem com os das tasks em voo —
286
+ o worktree nasce da branch da feature, já com o merge que acabou de entrar. Cap de 4 em voo. O
287
+ `verify {feature}` de escopo feature roda uma vez, quando nada mais está em voo. Medido: uma task
288
+ esperou 43 min pela onda depois de a dependência dela já estar pronta.
289
+
256
290
  ### 3b-w. Batch isolado por worktree (quando o dag recomenda)
257
291
 
258
292
  Quando o `morph-spec dag {feature}` reporta `isolation.recommended: "worktree"` (dois fluxos paralelos planejam escrever no mesmo path — colisão de `outputs`), despache cada fluxo com o parâmetro `isolation: "worktree"` do tool Agent. Cada agente trabalha numa working tree própria; build/test rodam lá dentro sem colidir.
259
293
 
260
- 1. **Dispatch:** mesmo `subagent_type: "morph-{id}"` e standards de §3b, mais `isolation: "worktree"`. O worktree vem do hook `WorktreeCreate` do morph: nasce em `worktrees/<n>` na branch `morph-task/<n>`, com junctions (`node_modules`, `.claude`, `.morph/framework`) e `.morph/worktree.env` já prontos — se faltar infra mesmo assim, o agente roda `morph-spec worktree link --all` (fail-open); se ainda impossível, reporta "verificação: não executada" (o verify pós-merge cobre). Dev server/compose dentro do worktree já sai nas portas do bloco (o hook `worktree-env-inject` prefixa o comando; fora do Claude, `eval "$(morph-spec env)"`). O agente commita na branch do worktree como último ato e reporta a branch. Um `morph-spec verify {feature} {task}` rodado ali pelo agente é **consultivo**: lê os `outputs` **planejados** (o sub-agent não edita `tasks.json` — cláusula 2), não é persistido (worktree não registrado: `unregistered-worktree`) e não prova nada — a prova é o verify de escopo feature do passo 3.
261
- 2. **Integração (orquestrador, após todos os relatórios):** faça o merge de cada branch reportada, uma por vez, na ordem de chegada — `git merge --no-ff <branch>`. Conflito → `git merge --abort`, marque a task de volta a `pending` com nota "merge conflict — reexecutar sequencial", siga para a próxima branch. Os paths em conflito são exatamente os de `isolation.collisions` do dag.
262
- 3. **Pós-merge:** rode `morph-spec verify {feature} --json` UMA vez (o merge é o novo ponto de integração — verificação compartilhada obrigatória), depois `morph-eval` + `morph-spec score` por relatório, como em §3b.
294
+ 1. **Dispatch:** mesmo `subagent_type: "morph-{id}"` e standards de §3b, mais `isolation: "worktree"`. O worktree vem do hook `WorktreeCreate` do morph: nasce em `worktrees/<n>` na branch `morph-task/<n>`, com junctions (`node_modules`, `.claude`, `.morph/framework`) e `.morph/worktree.env` já prontos — se faltar infra mesmo assim, o agente roda `morph-spec worktree link --all` (fail-open); se ainda impossível, reporta "verificação: não executada" (o verify pós-merge cobre). Dev server/compose dentro do worktree já sai nas portas do bloco (o hook `worktree-env-inject` prefixa o comando; fora do Claude, `eval "$(morph-spec env)"`). O worktree nasce da branch `morph/<feature>` quando a sessão está nela (o trabalho já integrado da feature vem junto, sem `merge` manual) e com os `.env*` da raiz copiados — o prompt de dispatch não manda o agente preparar nada disso. Sessão fora de `morph/<feature>` (orquestrador na raiz) faz o worktree nascer da default: aí, e só aí, o prompt abre com `git merge --ff-only morph/<feature>`. O agente commita na branch do worktree como último ato e reporta a branch. Ele não roda `morph-spec verify` (cláusula 3): a prova é o verify do orquestrador depois do merge.
295
+ 2. **Integração (orquestrador, a cada relatório que chega):** faça o merge de cada branch reportada, uma por vez, na ordem de chegada — `git merge --no-ff <branch>`. Conflito → `git merge --abort`, marque a task de volta a `pending` com nota "merge conflict — reexecutar sequencial", siga para a próxima branch. Os paths em conflito são exatamente os de `isolation.collisions` do dag.
296
+ 3. **Pós-merge:** `verify {feature} {taskId}` no merge de cada task (dispatch rolling, §3b), depois `morph-eval` + `morph-spec score`; `morph-spec verify {feature} --json` de escopo feature UMA vez, quando nada mais está em voo (o merge é o novo ponto de integração — verificação compartilhada obrigatória).
263
297
  4. **Cleanup:** o hook `WorktreeRemove` remove o worktree **limpo** ao fim do subagent (branch sobrevive) — mas não conte com ele: rode `morph-spec worktree remove --target <path>` por worktree que sobrou (NUNCA `git worktree remove` cru — as junctions do passo 1 seriam atravessadas e o `node_modules`/`.claude` da raiz apagados) + `git branch -d morph-task/<n>` das branches integradas + `git worktree prune` (fail-open). Worktree sujo (subagent não commitou) fica, vira `unintegrated-work` no `doctor --worktrees`, e a task volta a `pending`. Branches não integradas ficam e são registradas no recap com o motivo.
264
298
  5. **Agente morto no meio:** se commitou, a branch sobrevive (retomável); senão, a task volta a `pending` na lane sequencial. Registre a falha de protocolo no recap.
265
299
 
@@ -4,7 +4,7 @@ description: Entende o negócio, os usuários e a arquitetura antes de qualquer
4
4
  version: core
5
5
  when-to-invoke: ao receber um novo request de feature, antes de morph-plan
6
6
  user-invokable: true
7
- cliVersion: "8.38.0"
7
+ cliVersion: "8.41.0"
8
8
  ---
9
9
 
10
10
  # morph-brainstorming
@@ -4,7 +4,7 @@ description: Avalia a qualidade de uma tarefa ou fase com rubricas graduadas 0-1
4
4
  version: core
5
5
  when-to-invoke: ao completar uma tarefa ou ao finalizar uma fase de implementação
6
6
  user-invokable: false
7
- cliVersion: "8.38.0"
7
+ cliVersion: "8.41.0"
8
8
  ---
9
9
 
10
10
  # morph-eval
@@ -4,7 +4,7 @@ description: ADW cirúrgico de hotfix — resolve uma queda/bug crítico de prod
4
4
  version: core
5
5
  when-to-invoke: ao receber "/morph-hotfix {feature}", quando a morph-proposal classifica o pedido como workType hotfix (Passo 0), ou o usuário diz "produção caiu / hotfix / urgente"
6
6
  user-invokable: true
7
- cliVersion: "8.38.0"
7
+ cliVersion: "8.41.0"
8
8
  ---
9
9
 
10
10
  # morph-hotfix
@@ -43,7 +43,7 @@ subagent_type: "morph-scout"
43
43
 
44
44
  **Fallback** (se `morph-scout` não estiver registrado nos subagent types deste projeto): `general-purpose` com o campo `persona` do agente `scout` colado no prompt, **registrando o fallback nas notes da task**.
45
45
 
46
- Peça ao scout: localizar o root cause provável, os arquivos afetados e o blast radius (o que mais pode quebrar). Ele é read-only (Read/Glob/Grep/Bash somente-leitura) — não escreve código. Inclua as 7 cláusulas do contrato do relatório final no prompt (template literal em `morph-implement` §4 / `morph-apply` §3b): relatório no arquivo canônico como retorno, sem `SendMessage`; não tocar `tasks.json`/`feature.json`/`state.json` nem o board de sessão; sem build/test da suíte compartilhada em batch paralelo; no máximo 3 tasks por dispatch; commit `wip({taskId})` ao fim de cada task; nunca `taskkill /IM node.exe`.
46
+ Peça ao scout: localizar o root cause provável, os arquivos afetados e o blast radius (o que mais pode quebrar). Ele é read-only (Read/Glob/Grep/Bash somente-leitura) — não escreve código. Inclua as 8 cláusulas do contrato do relatório final no prompt (template literal em `morph-implement` §4 / `morph-apply` §3b): relatório no arquivo canônico como retorno, sem `SendMessage`; não tocar `tasks.json`/`feature.json`/`state.json` nem o board de sessão; sem build/test da suíte compartilhada em batch paralelo; no máximo 3 tasks por dispatch; commit `wip({taskId})` ao fim de cada task; nunca `taskkill /IM node.exe`; nunca mutar código de produção para ver teste falhar.
47
47
 
48
48
  ### 3. Hotfix brief (`0-proposal/proposal.md`)
49
49