@polymorphism-tech/morph-spec 8.34.2 → 8.35.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 (325) hide show
  1. package/CLAUDE.md +20 -3
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +18 -4
  4. package/bin/validate.js +379 -379
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +5 -4
  7. package/docs/QUICKSTART.md +1 -1
  8. package/framework/MORPH.md +16 -17
  9. package/framework/agents.json +197 -44
  10. package/framework/ai-pin.json +22 -0
  11. package/framework/commands/morph-media.md +45 -0
  12. package/framework/docs/CLI.md +234 -9
  13. package/framework/evals/proof-rubrics/README.md +76 -0
  14. package/framework/evals/proof-rubrics/eval-de-modelo.md +64 -0
  15. package/framework/evals/proof-rubrics/fiacao.md +54 -0
  16. package/framework/evals/proof-rubrics/guard-cego.md +52 -0
  17. package/framework/evals/proof-rubrics/media-claims.md +109 -0
  18. package/framework/evals/proof-rubrics/mutation-proof.md +77 -0
  19. package/framework/evals/proof-rubrics/observabilidade-genai.md +119 -0
  20. package/framework/evals/proof-rubrics/verde-nao-e-coberto.md +48 -0
  21. package/framework/evals/rubrics/architecture.md +30 -0
  22. package/framework/evals/rubrics/code-quality.md +26 -0
  23. package/framework/evals/rubrics/test-coverage.md +20 -0
  24. package/framework/hooks/claude-code/core/protect-spec-files.js +41 -4
  25. package/framework/hooks/claude-code/statusline.sh +11 -11
  26. package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
  27. package/framework/hooks/git/pre-commit/agents.sh +25 -25
  28. package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
  29. package/framework/hooks/git/pre-commit/specs.sh +50 -50
  30. package/framework/hooks/git/pre-push/run-tests.sh +44 -44
  31. package/framework/hooks/shared/e2e-check.js +135 -22
  32. package/framework/hooks/shared/stdin-reader.js +26 -26
  33. package/framework/rules/ai-agents-standards.md +14 -2
  34. package/framework/schemas/ai-pin.schema.json +97 -0
  35. package/framework/schemas/config.schema.json +107 -0
  36. package/framework/schemas/feature.schema.json +23 -4
  37. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  38. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  39. package/framework/skills/core/morph-apply/SKILL.md +26 -5
  40. package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
  41. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  42. package/framework/skills/core/morph-hotfix/SKILL.md +2 -2
  43. package/framework/skills/core/morph-implement/SKILL.md +18 -2
  44. package/framework/skills/core/morph-media/SKILL.md +215 -0
  45. package/framework/skills/core/morph-plan/SKILL.md +33 -2
  46. package/framework/skills/core/morph-proposal/SKILL.md +1 -1
  47. package/framework/skills/core/morph-review/SKILL.md +166 -9
  48. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  49. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  50. package/framework/skills/core/morph-uiux/SKILL.md +1 -1
  51. package/framework/standards/PROVENANCE.json +81 -3
  52. package/framework/standards/STANDARDS.json +1483 -839
  53. package/framework/standards/ai-agents/agent-archetypes.md +160 -0
  54. package/framework/standards/ai-agents/agent-session.md +164 -68
  55. package/framework/standards/ai-agents/agent-spec.md +196 -0
  56. package/framework/standards/ai-agents/batching.md +61 -37
  57. package/framework/standards/ai-agents/context-providers.md +97 -24
  58. package/framework/standards/ai-agents/conversational-agent-with-phases.md +239 -0
  59. package/framework/standards/ai-agents/cost-and-budget.md +256 -0
  60. package/framework/standards/ai-agents/durable-workflows-hitl.md +98 -5
  61. package/framework/standards/ai-agents/evals-with-cache.md +289 -0
  62. package/framework/standards/ai-agents/guardrails.md +222 -0
  63. package/framework/standards/ai-agents/llm-runtime-defaults.md +226 -0
  64. package/framework/standards/ai-agents/mcp-server.md +119 -18
  65. package/framework/standards/ai-agents/mcp-tools.md +85 -32
  66. package/framework/standards/ai-agents/media-pipeline.md +352 -0
  67. package/framework/standards/ai-agents/media-video.md +267 -0
  68. package/framework/standards/ai-agents/middleware-patterns.md +39 -5
  69. package/framework/standards/ai-agents/modalities-image-gen.md +354 -105
  70. package/framework/standards/ai-agents/modalities-speech-to-text.md +8 -2
  71. package/framework/standards/ai-agents/modalities-text-to-speech.md +10 -2
  72. package/framework/standards/ai-agents/modalities-vision.md +6 -2
  73. package/framework/standards/ai-agents/multi-agent-patterns.md +61 -5
  74. package/framework/standards/ai-agents/observability-patterns.md +227 -17
  75. package/framework/standards/ai-agents/production.md +38 -9
  76. package/framework/standards/ai-agents/prompt-sources.md +389 -0
  77. package/framework/standards/ai-agents/providers/model-registry.md +174 -39
  78. package/framework/standards/ai-agents/rag-custom-pgvector.md +69 -4
  79. package/framework/standards/ai-agents/service-tier-flex.md +27 -19
  80. package/framework/standards/ai-agents/setup.md +166 -50
  81. package/framework/standards/ai-agents/structured-output.md +34 -3
  82. package/framework/standards/ai-agents/sweet-spot.md +23 -3
  83. package/framework/standards/ai-agents/testing-ai.md +236 -0
  84. package/framework/standards/ai-agents/vector-data-extensions.md +50 -20
  85. package/framework/standards/ai-agents/workflows.md +27 -7
  86. package/framework/standards/frontend/design-system/ai-image-generation.md +12 -0
  87. package/framework/standards/frontend/design-system/ai-video-generation.md +13 -0
  88. package/framework/standards/infrastructure/docker/local-compose-isolation.md +3 -1
  89. package/framework/templates/.idea/morph-templates.xml +92 -0
  90. package/framework/templates/.vscode/morph-templates.code-snippets +186 -0
  91. package/framework/templates/IDE-SNIPPETS.md +262 -262
  92. package/framework/templates/REGISTRY.json +13 -0
  93. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
  94. package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
  95. package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
  96. package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
  97. package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +1 -1
  98. package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
  99. package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
  100. package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
  101. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -281
  102. package/framework/templates/code/dotnet/database/migration.cs +83 -83
  103. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
  104. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
  105. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
  106. package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
  107. package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +1 -1
  108. package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
  109. package/framework/templates/code/typescript/contracts.ts +167 -167
  110. package/framework/templates/docs/clarifications.md +253 -253
  111. package/framework/templates/docs/schema-analysis.md +119 -119
  112. package/framework/templates/docs/ui-components.md +52 -52
  113. package/framework/templates/docs/ui-design-system.md +76 -76
  114. package/framework/templates/docs/ui-flows.md +167 -167
  115. package/framework/templates/docs/ui-mockups.md +98 -98
  116. package/framework/templates/dotnet/ai-kit/Directory.Build.props +25 -0
  117. package/framework/templates/dotnet/ai-kit/Directory.Packages.props +26 -0
  118. package/framework/templates/dotnet/ai-kit/Morph.AiKit.sln +56 -0
  119. package/framework/templates/dotnet/ai-kit/NuGet.config +12 -0
  120. package/framework/templates/dotnet/ai-kit/README.md +128 -0
  121. package/framework/templates/dotnet/ai-kit/global.json +9 -0
  122. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentApi.cs +65 -0
  123. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs +289 -0
  124. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactoryOptions.cs +91 -0
  125. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs +91 -0
  126. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpecOptions.cs +181 -0
  127. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/AiKitAssemblyMarker.cs +14 -0
  128. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/ConversationStore.cs +174 -0
  129. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/IConversationStore.cs +54 -0
  130. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/InMemoryConversationStore.cs +75 -0
  131. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/CountingChatClient.cs +71 -0
  132. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalAssertion.cs +246 -0
  133. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheMissException.cs +57 -0
  134. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheOptions.cs +78 -0
  135. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheStamp.cs +225 -0
  136. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalFixture.cs +463 -0
  137. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalMode.cs +32 -0
  138. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalQualityEvaluators.cs +49 -0
  139. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalScenario.cs +214 -0
  140. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalSummary.cs +168 -0
  141. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/OfflineChatClient.cs +142 -0
  142. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/ShortPathResponseCache.cs +349 -0
  143. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaGenerator.cs +42 -0
  144. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaProvider.cs +77 -0
  145. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaArtifact.cs +28 -0
  146. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaDisclosure.cs +107 -0
  147. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaGenerator.cs +253 -0
  148. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaIdempotencyKey.cs +103 -0
  149. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJob.cs +259 -0
  150. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobId.cs +21 -0
  151. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobState.cs +47 -0
  152. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaPricing.cs +102 -0
  153. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaProvenance.cs +44 -0
  154. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaRequest.cs +192 -0
  155. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaResult.cs +94 -0
  156. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaReview.cs +99 -0
  157. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaSeams.cs +97 -0
  158. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaStore.cs +133 -0
  159. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MorphMedia.cs +93 -0
  160. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/GoogleImageProvider.cs +112 -0
  161. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs +288 -0
  162. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/VeoVideoProvider.cs +158 -0
  163. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/IUsageCostSink.cs +29 -0
  164. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs +208 -0
  165. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostRecord.cs +95 -0
  166. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Morph.AiKit.csproj +38 -0
  167. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs +119 -0
  168. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphTelemetryOptions.cs +82 -0
  169. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/IProviderClientFactory.cs +33 -0
  170. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs +267 -0
  171. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs +474 -0
  172. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/model-registry.v2.json +87 -0
  173. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaIngest.cs +169 -0
  174. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaPlan.cs +49 -0
  175. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentFactoryTests.cs +495 -0
  176. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentSpecTests.cs +260 -0
  177. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ConversationStoreTests.cs +405 -0
  178. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/DeltaIngestTests.cs +379 -0
  179. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalAssertionTests.cs +197 -0
  180. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheMissTests.cs +139 -0
  181. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheStampTests.cs +157 -0
  182. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFailuresTests.cs +178 -0
  183. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFixtureTests.cs +153 -0
  184. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalRefreshTests.cs +194 -0
  185. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalWorkspace.cs +86 -0
  186. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/KitEvals.cs +213 -0
  187. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/OfflineChatClientTests.cs +95 -0
  188. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs +225 -0
  189. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClientTests.cs +215 -0
  190. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeClock.cs +33 -0
  191. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeMediaProvider.cs +89 -0
  192. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeProviderClientFactory.cs +55 -0
  193. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeUsageCostSink.cs +60 -0
  194. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/InMemoryMediaStore.cs +131 -0
  195. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAccessibilityTests.cs +133 -0
  196. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAliasIsNotAnAgentTests.cs +127 -0
  197. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +216 -0
  198. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaGeneratorTests.cs +264 -0
  199. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaIdempotencyKeyTests.cs +148 -0
  200. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaJobStateTests.cs +184 -0
  201. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaReviewTests.cs +89 -0
  202. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaStoreTests.cs +98 -0
  203. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ModelRegistryTests.cs +451 -0
  204. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +76 -0
  205. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/SkeletonSmokeTests.cs +33 -0
  206. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/TelemetryTests.cs +261 -0
  207. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/UsageCostMiddlewareTests.cs +374 -0
  208. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/.morph-eval-cache.json +12 -0
  209. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/orcamento.acme.a-resposta-estruturada/1/CF70A7CE27BBD66A/contents.data +13 -0
  210. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/orcamento.acme.a-resposta-estruturada/1/CF70A7CE27BBD66A/entry.json +7 -0
  211. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.a-saudacao/1/19F631228C6E00BA/contents.data +13 -0
  212. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.a-saudacao/1/19F631228C6E00BA/entry.json +7 -0
  213. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.b-escalonamento/1/A24A7C9BDD8239D8/contents.data +13 -0
  214. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.b-escalonamento/1/A24A7C9BDD8239D8/entry.json +7 -0
  215. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.globex.a-saudacao/1/E38CD37DF003EDB7/contents.data +13 -0
  216. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.globex.a-saudacao/1/E38CD37DF003EDB7/entry.json +7 -0
  217. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/orcamento/acme/a-resposta-estruturada.json +24 -0
  218. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/acme/a-saudacao.json +23 -0
  219. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/acme/b-escalonamento.json +24 -0
  220. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/globex/a-saudacao.json +23 -0
  221. package/framework/templates/feature/decisions.md +122 -122
  222. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
  223. package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
  224. package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
  225. package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
  226. package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
  227. package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
  228. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
  229. package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
  230. package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
  231. package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
  232. package/framework/templates/infrastructure/github/README.md +56 -56
  233. package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
  234. package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
  235. package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
  236. package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
  237. package/framework/templates/integrations/asaas-client.cs +387 -387
  238. package/framework/templates/integrations/asaas-webhook.cs +351 -351
  239. package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
  240. package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
  241. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
  242. package/framework/templates/project/validate.js +120 -120
  243. package/framework/templates/state.template.json +17 -17
  244. package/framework/templates/ui/design-system.css +226 -226
  245. package/package.json +3 -3
  246. package/src/commands/dashboard/dashboard.js +53 -53
  247. package/src/commands/e2e/e2e.js +15 -2
  248. package/src/commands/index.js +13 -13
  249. package/src/commands/project/checkpoint.js +209 -209
  250. package/src/commands/project/doctor.js +140 -5
  251. package/src/commands/project/update.js +469 -153
  252. package/src/commands/project/worktree.js +8 -1
  253. package/src/commands/state/advance.js +24 -2
  254. package/src/commands/state/approve.js +33 -1
  255. package/src/commands/state/create.js +72 -11
  256. package/src/commands/state/finish.js +333 -21
  257. package/src/commands/state/gate-check.js +190 -6
  258. package/src/commands/state/score.js +36 -1
  259. package/src/commands/validation/verify.js +134 -25
  260. package/src/core/state/phase-state-machine.js +197 -197
  261. package/src/core/state/state-manager.js +9 -1
  262. package/src/core/templates/template-renderer.js +477 -477
  263. package/src/dashboard/app/components/DetailPanel.jsx +11 -11
  264. package/src/dashboard/app/components/FlowGraph.jsx +17 -17
  265. package/src/dashboard/app/components/SearchFilter.jsx +22 -22
  266. package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
  267. package/src/dashboard/app/main.jsx +13 -13
  268. package/src/dashboard/app/pages/AgentMap.jsx +370 -370
  269. package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
  270. package/src/dashboard/app/pages/RulesMap.jsx +273 -273
  271. package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
  272. package/src/dashboard/app/pages/Standards.jsx +332 -332
  273. package/src/dashboard/app/styles/index.css +47 -47
  274. package/src/dashboard/index.html +12 -12
  275. package/src/dashboard/package.json +24 -24
  276. package/src/dashboard/scanner/phases-scanner.js +15 -15
  277. package/src/dashboard/scanner/rubrics-scanner.js +12 -12
  278. package/src/dashboard/scanner/rules-scanner.js +37 -37
  279. package/src/dashboard/scanner/skills-scanner.js +43 -43
  280. package/src/dashboard/scanner/squads-scanner.js +13 -13
  281. package/src/dashboard/vite-plugin-morph-data.js +17 -17
  282. package/src/dashboard/vite.config.js +24 -24
  283. package/src/lib/ai/ai-checks.js +182 -0
  284. package/src/lib/ai/ai-project-scan.js +347 -0
  285. package/src/lib/ai/code-audit.js +181 -0
  286. package/src/lib/ai/comment-stripper.js +184 -0
  287. package/src/lib/ai/pin-drift.js +138 -0
  288. package/src/lib/ai/registry-audit.js +285 -0
  289. package/src/lib/detectors/design-system-detector.js +188 -188
  290. package/src/lib/detectors/index.js +217 -217
  291. package/src/lib/e2e/compose-env.js +50 -4
  292. package/src/lib/evaluator-report.js +269 -15
  293. package/src/lib/generators/design-system-generator.js +508 -508
  294. package/src/lib/generators/settings-generator.js +209 -209
  295. package/src/lib/git/default-branch.js +92 -4
  296. package/src/lib/hooks/hook-executor.js +167 -167
  297. package/src/lib/installers/effects.js +193 -0
  298. package/src/lib/installers/mcp-installer.js +719 -719
  299. package/src/lib/installers/templates-reconcile.js +3 -3
  300. package/src/lib/risk-detector.js +284 -0
  301. package/src/lib/standards/verified-against.js +276 -0
  302. package/src/lib/tasks/eval-node.js +485 -0
  303. package/src/lib/tasks/linux-runner.js +297 -0
  304. package/src/lib/tasks/task-classifier.js +30 -30
  305. package/src/lib/tasks/task-parser.js +209 -209
  306. package/src/lib/tasks/test-nodes.js +486 -0
  307. package/src/lib/tasks/test-runner.js +410 -33
  308. package/src/lib/validators/checkpoint-persistence.js +39 -39
  309. package/src/lib/validators/css/css-validator.js +340 -340
  310. package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
  311. package/src/lib/validators/shared/issue-counter.js +14 -14
  312. package/src/lib/validators/verify-runner.js +583 -28
  313. package/src/lib/worktree/docker-audit.js +287 -0
  314. package/src/lib/worktree/env-allocator.js +24 -0
  315. package/src/lib/worktree/worktree-audit.js +30 -1
  316. package/src/scripts/setup-infra.js +24 -11
  317. package/src/utils/agent-id-mapper.js +11 -11
  318. package/src/utils/agents-installer.js +18 -8
  319. package/src/utils/claude-md-injector.js +10 -5
  320. package/src/utils/claude-settings-manager.js +300 -300
  321. package/src/utils/file-copier.js +11 -4
  322. package/src/utils/hooks-installer.js +29 -26
  323. package/src/utils/skills-installer.js +36 -29
  324. package/src/utils/version-checker.js +68 -3
  325. package/framework/standards/ai-agents/prompts-in-db.md +0 -214
@@ -1006,8 +1006,15 @@ function isLiveSiblingWorktreeRegistration(relPath, root, feature) {
1006
1006
  * @param {string} rootPath - the primary root, for the replica comparison
1007
1007
  * @param {{ discardIgnored?: boolean }} options
1008
1008
  * @returns {{ shieldable: string[], blocking: string[], discarded: string[], replicable: string[] }}
1009
+ *
1010
+ * EXPORTADA para que o `finish --dry-run` (pré-voo) responda EXATAMENTE a
1011
+ * mesma pergunta que o teardown real vai responder. Uma segunda enumeração de
1012
+ * `git status --ignored` no finish.js — com a sua própria cópia de
1013
+ * IGNORED_SHIELDABLE_PREFIXES — faria o pré-voo prometer uma coisa e o
1014
+ * comando fazer outra, que é a única maneira de um dry-run ser pior que
1015
+ * nenhum. Consumida read-only: o pré-voo não copia, não apaga, não decide.
1009
1016
  */
1010
- function classifyIgnoredLeftovers(worktreePath, rootPath, options = {}) {
1017
+ export function classifyIgnoredLeftovers(worktreePath, rootPath, options = {}) {
1011
1018
  let out;
1012
1019
  try {
1013
1020
  // `-z` + execFile: NUL-delimited, no shell, no C-style quoting to undo —
@@ -198,7 +198,23 @@ export async function advanceCommand(featureName, options = {}) {
198
198
  process.exit(1);
199
199
  }
200
200
 
201
- if (gate) {
201
+ // Gate idempotency (F15): `setApprovalGate` REPLACES the gate object whole
202
+ // (state-manager.js), so re-writing an already-approved gate does not
203
+ // refresh it — it destroys `approvedBy`, `timestamp`, `notes` and
204
+ // `selfAssessed` in one assignment. And `resolveApprovedBy` above answers
205
+ // "auto" in every headless context, so `approve f proposal --approver
206
+ // lucas` followed by `advance f` used to rewrite a human's signature as
207
+ // "auto" — the one stamp the charter forbids on a human-approved gate.
208
+ // The state-sync hook already carries exactly this guard; `advance`, the
209
+ // other gate write-path, simply never got it.
210
+ //
211
+ // It skips ONLY the write. The scaffold and the handoff below still run,
212
+ // so re-running `advance` after a failed scaffold keeps working — the
213
+ // reason this is a guard and not an abort.
214
+ const priorGate = gate ? feature.approvalGates?.[gate] : null;
215
+ const alreadyApproved = priorGate?.approved === true;
216
+
217
+ if (gate && !alreadyApproved) {
202
218
  await setApprovalGate(featureName, gate, true, {
203
219
  approvedBy,
204
220
  approvedAt: new Date().toISOString(),
@@ -226,7 +242,13 @@ export async function advanceCommand(featureName, options = {}) {
226
242
  if (missingArtifacts.length) {
227
243
  console.log(chalk.yellow(` ⚠️ --force: avançou SEM ${missingArtifacts.join(', ')}.`));
228
244
  }
229
- if (gate) console.log(chalk.gray(` Gate "${gate}" approved (${approvedBy}).`));
245
+ // Report what actually happened: claiming "approved (auto)" when nothing
246
+ // was written is how the destroyed signature stayed invisible.
247
+ if (gate && alreadyApproved) {
248
+ console.log(chalk.gray(` Gate "${gate}" was already approved (${priorGate.approvedBy || 'unknown'}) — approval preserved, nothing re-written.`));
249
+ } else if (gate) {
250
+ console.log(chalk.gray(` Gate "${gate}" approved (${approvedBy}).`));
251
+ }
230
252
  if (nextDir) console.log(chalk.gray(` Scaffolded ${nextDir}/ — ready for the next phase's first artifact.\n`));
231
253
  else console.log('');
232
254
  } catch (error) {
@@ -180,7 +180,13 @@ export async function approveCommand(featureName, gateName, options = {}) {
180
180
  if (currentStatus?.approved) {
181
181
  console.log(chalk.yellow(`\n⚠️ Gate "${gateName}" is already approved`));
182
182
  console.log(chalk.gray(`Approved at: ${currentStatus.timestamp}`));
183
- console.log(chalk.gray(`Approved by: ${currentStatus.approvedBy || 'Unknown'}\n`));
183
+ console.log(chalk.gray(`Approved by: ${currentStatus.approvedBy || 'Unknown'}`));
184
+ // This early-out is a no-op that still exits 0 — deliberate, and
185
+ // `--force` does NOT cover it (that flag only covers gate ORDER). A
186
+ // caller who meant to re-approve therefore reads success and is left
187
+ // with nowhere to go. The way out already exists as `unapprove`; the
188
+ // message just never named it. Naming it is the whole fix (no new flag).
189
+ console.log(chalk.gray(`To approve it again, revoke it first: morph-spec unapprove ${featureName} ${gateName}\n`));
184
190
  return;
185
191
  }
186
192
 
@@ -349,6 +355,32 @@ export async function approveCommand(featureName, gateName, options = {}) {
349
355
  }
350
356
  selfAssessed = true;
351
357
  }
358
+
359
+ // REAVALIAÇÃO VISÍVEL. O `evaluator-report.md` é append-only, então uma
360
+ // segunda rodada acrescenta um `**Composite-Score:**` ao fim e o arquivo
361
+ // passa a carregar mais de um veredito. O gate decide pelo ÚLTIMO (o
362
+ // vigente) — mas aprovar em silêncio um relatório com notas superadas
363
+ // esconde do humano exatamente o fato que ele precisa ver: a nota MUDOU,
364
+ // e numa das rodadas medidas em campo ela CAIU (8.9 → 8.3, quando uma
365
+ // correção abriu um bloqueante).
366
+ //
367
+ // Aqui é o lugar: `approve` é a precondição humana do Gate 3 e a única
368
+ // superfície onde uma pessoa lê o veredito antes de carimbá-lo. Sem este
369
+ // bloco, `scoreTokens`/`superseded` seriam mitigação inerte — campo que
370
+ // ninguém lê não mitiga nada.
371
+ if (report.status === 'ok' && report.scoreTokens > 1) {
372
+ console.log(chalk.yellow(
373
+ `
374
+ ⚠️ O relatório do avaliador tem ${report.scoreTokens} vereditos (o arquivo é append-only).`
375
+ ));
376
+ console.log(chalk.gray(` Vigente (o que o gate usa): ${report.score}`));
377
+ console.log(chalk.gray(` Superado(s), na ordem do arquivo: ${report.superseded.join(', ')}`));
378
+ if (report.superseded.some((n) => n > report.score)) {
379
+ console.log(chalk.yellow(' A nota CAIU em relação a uma rodada anterior — confira o que a correção'));
380
+ console.log(chalk.yellow(' abriu antes de aprovar; o relatório mantém a análise das duas rodadas.'));
381
+ }
382
+ console.log('');
383
+ }
352
384
  }
353
385
  }
354
386
 
@@ -15,32 +15,61 @@ import { detectDefaultBranch } from '../../lib/git/default-branch.js';
15
15
  * `morph-spec finish` can later merge/PR it back. Symmetric with the worktree
16
16
  * flow, which gets its branch from `runWorktreeSetup`.
17
17
  *
18
+ * That checkout moves the dev's PRIMARY working tree, and `stdio: 'pipe'`
19
+ * swallows even git's own message — so the move is reported by the caller
20
+ * (`branchMoveWarning`), never silent. `checkout: false` (`--no-checkout`)
21
+ * still CREATES the branch — `finish --pr|--merge` depends on it existing in
22
+ * both flows — and only skips moving the tree.
23
+ *
18
24
  * Fail-open: outside a git repo, with no resolvable default, or on any git
19
25
  * error, the feature is simply left on the current branch — never a failed birth.
20
26
  *
21
27
  * @param {string} featureName
22
- * @returns {{ branched: boolean, branch?: string, from?: string, reason?: string }}
28
+ * @param {{ checkout?: boolean }} [opts] - `checkout: false` keeps the tree put
29
+ * @returns {{ branched: boolean, checkedOut: boolean, branch?: string, from?: string,
30
+ * movedFrom?: string, stayedOn?: string, reason?: string }}
31
+ * `movedFrom` is present ONLY when the working tree actually moved (it names
32
+ * the branch left behind); `stayedOn` only when the move was declined.
23
33
  */
24
- function branchCommonFlow(featureName) {
34
+ function branchCommonFlow(featureName, { checkout = true } = {}) {
25
35
  const cwd = process.cwd();
26
36
  try {
27
- if (!isGitRepo(cwd)) return { branched: false, reason: 'not-a-git-repo' };
37
+ if (!isGitRepo(cwd)) return { branched: false, checkedOut: false, reason: 'not-a-git-repo' };
28
38
  const branch = buildBranchName(featureName);
29
39
  const defaultBranch = detectDefaultBranch(cwd);
30
- if (!defaultBranch) return { branched: false, reason: 'no-default-branch' };
40
+ if (!defaultBranch) return { branched: false, checkedOut: false, reason: 'no-default-branch' };
31
41
  if (!branchExists(branch, cwd)) {
32
42
  execFileSync('git', ['branch', branch, defaultBranch], { cwd, stdio: 'pipe' });
33
43
  }
34
44
  const current = execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd, stdio: 'pipe' }).toString().trim();
35
- if (current !== branch) {
36
- execFileSync('git', ['checkout', branch], { cwd, stdio: 'pipe' });
37
- }
38
- return { branched: true, branch, from: defaultBranch };
45
+ // Already there: nothing moved, so nothing to warn about.
46
+ if (current === branch) return { branched: true, checkedOut: true, branch, from: defaultBranch };
47
+ if (!checkout) return { branched: true, checkedOut: false, branch, from: defaultBranch, stayedOn: current };
48
+ execFileSync('git', ['checkout', branch], { cwd, stdio: 'pipe' });
49
+ return { branched: true, checkedOut: true, branch, from: defaultBranch, movedFrom: current };
39
50
  } catch {
40
- return { branched: false, reason: 'git-error' };
51
+ return { branched: false, checkedOut: false, reason: 'git-error' };
41
52
  }
42
53
  }
43
54
 
55
+ /**
56
+ * The alert for a checkout that MOVED. Built once and rendered on both
57
+ * surfaces — stdout (human) and stderr (under `--json`, so it survives a
58
+ * stdout redirect) — so the two can never drift apart.
59
+ *
60
+ * @param {{ branch: string, movedFrom: string }} branchResult
61
+ * @returns {string[]} lines, unstyled and unindented
62
+ */
63
+ function branchMoveWarning({ branch, movedFrom }) {
64
+ return [
65
+ `⚠️ Working tree MOVED: ${movedFrom} → ${branch}`,
66
+ ` This checkout is now ON the feature branch — uncommitted work came along,`,
67
+ ` and anything committed here from now on lands on ${branch}, not ${movedFrom}.`,
68
+ ` Use --no-checkout to create the branch without moving the tree, or --worktree`,
69
+ ` (the recommended route for parallel work) to isolate the feature in its own tree.`,
70
+ ];
71
+ }
72
+
44
73
  /** Feature names are kebab-case: lowercase alphanumerics and hyphens. */
45
74
  const FEATURE_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
46
75
 
@@ -130,6 +159,24 @@ export async function createCommand(featureName, options = {}) {
130
159
  process.exit(1);
131
160
  }
132
161
 
162
+ // `--no-checkout` pede que o checkout PRINCIPAL não se mova; `--worktree`
163
+ // nunca o move — a feature nasce numa árvore separada, e o caminho de
164
+ // worktree sequer chama `branchCommonFlow`, que é o único leitor do flag.
165
+ // Aceitar a combinação em silêncio é dizer que o CLI honrou um pedido que
166
+ // ele ignorou — o mesmo anti-padrão que esta série de fixes tirou do
167
+ // `finish --pr --push`. Recusa ALTA, e AQUI: junto das outras validações
168
+ // de forma, ANTES de `createFeature` — a primeira mutação do `create`.
169
+ // Uma recusa depois dela deixaria a feature nascida por um comando que
170
+ // falhou, pior que o no-op que ela substitui.
171
+ if (options.worktree && options.checkout === false) {
172
+ console.error(chalk.red(`\n❌ no-checkout-with-worktree: --no-checkout não se combina com --worktree`));
173
+ console.error(chalk.gray(` O --worktree já não move o checkout desta árvore: a feature nasce em worktrees/${featureName},`));
174
+ console.error(chalk.gray(` na branch morph/${featureName}, e o caminho de worktree nem chega a ler o --no-checkout.`));
175
+ console.error(chalk.gray(` Para isolar a feature na própria árvore: morph-spec create ${featureName} --worktree`));
176
+ console.error(chalk.gray(` Para criar só a branch morph/${featureName} sem mover esta árvore: morph-spec create ${featureName} --no-checkout\n`));
177
+ process.exit(1);
178
+ }
179
+
133
180
  const now = new Date().toISOString();
134
181
  const { workType, workTypeDetection } = resolveWorkType(options, now);
135
182
 
@@ -225,7 +272,8 @@ export async function createCommand(featureName, options = {}) {
225
272
  } else {
226
273
  // Common flow: still isolate the feature on its own branch so `finish`
227
274
  // can merge/PR it back. Fail-open (see branchCommonFlow).
228
- branchResult = branchCommonFlow(featureName);
275
+ // Commander's `--no-checkout` sets options.checkout === false.
276
+ branchResult = branchCommonFlow(featureName, { checkout: options.checkout !== false });
229
277
  }
230
278
  }
231
279
 
@@ -238,6 +286,11 @@ export async function createCommand(featureName, options = {}) {
238
286
  const out = { feature: featureName, created, ...finalFeature };
239
287
  if (worktreeResult) out.worktree = worktreeResult;
240
288
  if (branchResult) out.branch = branchResult;
289
+ // The move of the PRIMARY checkout is never silent — under --json it goes
290
+ // to stderr so it survives `... --json > out.json` instead of vanishing.
291
+ if (branchResult?.movedFrom) {
292
+ console.error(chalk.yellow(branchMoveWarning(branchResult).join('\n')));
293
+ }
241
294
  console.log(JSON.stringify(out, null, 2));
242
295
  return;
243
296
  }
@@ -262,7 +315,15 @@ export async function createCommand(featureName, options = {}) {
262
315
  }
263
316
  } else if (branchResult?.branched) {
264
317
  console.log(chalk.green(` branch: ${branchResult.branch} (from ${branchResult.from})`));
265
- console.log(chalk.gray(` close it with: morph-spec finish ${featureName} --pr | --merge\n`));
318
+ console.log(chalk.gray(` close it with: morph-spec finish ${featureName} --pr | --merge`));
319
+ if (branchResult.movedFrom) {
320
+ // Alert, not one more success line: the tree the dev is standing in moved.
321
+ console.log('');
322
+ for (const line of branchMoveWarning(branchResult)) console.log(chalk.yellow(` ${line}`));
323
+ } else if (branchResult.checkedOut === false) {
324
+ console.log(chalk.gray(` working tree left on ${branchResult.stayedOn} (--no-checkout)`));
325
+ }
326
+ console.log('');
266
327
  }
267
328
  } else {
268
329
  console.log(chalk.yellow(`\n⚠️ Feature "${featureName}" already exists — left untouched`));