@polymorphism-tech/morph-spec 8.46.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) hide show
  1. package/CLAUDE.md +53 -44
  2. package/README.md +3 -4
  3. package/bin/morph-spec.js +38 -55
  4. package/bin/validate.js +5 -134
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +2 -2
  7. package/docs/QUICKSTART.md +1 -1
  8. package/framework/CLAUDE.md +41 -101
  9. package/framework/MORPH.md +95 -252
  10. package/framework/agents.json +75 -18
  11. package/framework/commands/create-umbraco-lp.md +2 -0
  12. package/framework/commands/migrate-lp-to-umbraco.md +2 -0
  13. package/framework/commands/morph-apply.md +5 -28
  14. package/framework/commands/morph-archive.md +2 -2
  15. package/framework/commands/morph-hotfix.md +8 -8
  16. package/framework/commands/morph-infra.md +17 -203
  17. package/framework/commands/morph-media.md +3 -0
  18. package/framework/commands/morph-preflight.md +7 -31
  19. package/framework/commands/morph-proposal.md +2 -50
  20. package/framework/commands/morph-status.md +3 -3
  21. package/framework/commands/morph-troubleshoot.md +2 -14
  22. package/framework/docs/CLI.md +585 -286
  23. package/framework/evals/review-checklist.md +82 -41
  24. package/framework/hooks/README.md +10 -11
  25. package/framework/hooks/claude-code/core/comment-guard.js +1 -1
  26. package/framework/hooks/claude-code/core/denylist.json +33 -3
  27. package/framework/hooks/claude-code/core/enforce-phase-writes.js +16 -20
  28. package/framework/hooks/claude-code/core/gate-guard.js +2 -11
  29. package/framework/hooks/claude-code/core/pre-bash-denylist.js +38 -0
  30. package/framework/hooks/claude-code/core/protect-spec-files.js +30 -242
  31. package/framework/hooks/claude-code/core/state-sync.js +17 -19
  32. package/framework/hooks/claude-code/core/telemetry-log.js +3 -3
  33. package/framework/hooks/claude-code/core/validate-completion.js +33 -97
  34. package/framework/hooks/claude-code/core/warn-bash-source-write.js +31 -0
  35. package/framework/hooks/claude-code/core/worktree-context.js +5 -4
  36. package/framework/hooks/claude-code/statusline.py +55 -41
  37. package/framework/hooks/package.json +3 -0
  38. package/framework/hooks/shared/activity-logger.js +1 -1
  39. package/framework/hooks/shared/build-check.js +10 -6
  40. package/framework/hooks/shared/command-tokens.js +169 -0
  41. package/framework/hooks/shared/comment-rules.js +1 -1
  42. package/framework/hooks/shared/comment-scanner.js +10 -23
  43. package/framework/hooks/shared/comment-stripper.js +1 -1
  44. package/framework/hooks/shared/e2e-check.js +67 -31
  45. package/framework/hooks/shared/errata.js +72 -0
  46. package/framework/hooks/shared/feature-locator.js +1 -1
  47. package/framework/hooks/shared/frontend-locations.js +6 -0
  48. package/framework/hooks/shared/gate-question.js +18 -0
  49. package/framework/hooks/shared/phase-utils.js +15 -32
  50. package/framework/hooks/shared/slice-progress.js +118 -0
  51. package/framework/hooks/shared/spawn-command.js +23 -0
  52. package/framework/hooks/shared/state-reader.js +61 -87
  53. package/framework/hooks/shared/state-writer.js +3 -3
  54. package/framework/mcp/registry.json +3 -4
  55. package/framework/phases.json +23 -39
  56. package/framework/rules/ai-agents-standards.md +18 -16
  57. package/framework/rules/asaas-standards.md +3 -1
  58. package/framework/rules/csharp-standards.md +10 -8
  59. package/framework/rules/data-standards.md +5 -5
  60. package/framework/rules/dotnet-templates.md +1 -1
  61. package/framework/rules/frontend-standards.md +4 -2
  62. package/framework/rules/gsap-standards.md +10 -5
  63. package/framework/rules/hangfire-standards.md +3 -1
  64. package/framework/rules/infrastructure-standards.md +4 -2
  65. package/framework/rules/neon-auth-standards.md +3 -1
  66. package/framework/rules/neon-standards.md +6 -4
  67. package/framework/rules/nextjs-standards.md +13 -11
  68. package/framework/rules/nextjs-templates.md +1 -1
  69. package/framework/rules/resend-standards.md +3 -1
  70. package/framework/schemas/config.schema.json +14 -9
  71. package/framework/schemas/feature.schema.json +15 -52
  72. package/framework/skills/README.md +4 -5
  73. package/framework/skills/core/create-umbraco-lp/SKILL.md +3 -3
  74. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +3 -3
  75. package/framework/skills/core/morph-apply/SKILL.md +150 -223
  76. package/framework/skills/core/morph-hotfix/SKILL.md +34 -43
  77. package/framework/skills/core/morph-machine/SKILL.md +4 -4
  78. package/framework/skills/core/morph-media/SKILL.md +3 -3
  79. package/framework/skills/core/morph-plan/SKILL.md +138 -300
  80. package/framework/skills/core/morph-review/SKILL.md +112 -137
  81. package/framework/skills/core/morph-standards/SKILL.md +29 -41
  82. package/framework/skills/core/morph-uiux/SKILL.md +78 -153
  83. package/framework/standards/STANDARDS.json +90 -1219
  84. package/framework/standards/STANDARDS.meta.json +1305 -0
  85. package/framework/standards/ai-agents/evals-with-cache.md +2 -3
  86. package/framework/standards/ai-agents/llm-runtime-defaults.md +1 -1
  87. package/framework/standards/ai-agents/modalities-speech-to-text.md +36 -26
  88. package/framework/standards/ai-agents/prompt-sources.md +6 -4
  89. package/framework/standards/ai-agents/providers/model-registry.md +1 -1
  90. package/framework/standards/ai-agents/rag-custom-pgvector.md +67 -39
  91. package/framework/standards/ai-agents/setup.md +2 -2
  92. package/framework/standards/ai-agents/structured-output.md +1 -1
  93. package/framework/standards/ai-agents/sweet-spot.md +1 -1
  94. package/framework/standards/architecture/code-comments.md +8 -8
  95. package/framework/standards/architecture/vertical-slice/vertical-slice.md +18 -9
  96. package/framework/standards/backend/api/validation.md +135 -47
  97. package/framework/standards/backend/database/postgresql/database.md +11 -7
  98. package/framework/standards/backend/database/vector-search-rag.md +207 -324
  99. package/framework/standards/backend/dotnet/fluent-validation-vsa.md +14 -8
  100. package/framework/standards/backend/dotnet/result-pattern.md +40 -6
  101. package/framework/standards/backend/dotnet/scalar-ui.md +13 -7
  102. package/framework/standards/backend/dotnet/scrutor.md +1 -1
  103. package/framework/standards/backend/dotnet/testing.md +1 -1
  104. package/framework/standards/backend/dotnet/vsa-handler-patterns.md +7 -7
  105. package/framework/standards/backend/integrations/asaas/asaas-api.md +309 -165
  106. package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +134 -154
  107. package/framework/standards/data/nosql/cache/redis.md +120 -44
  108. package/framework/standards/data/nosql/cosmos-db.md +114 -71
  109. package/framework/standards/frontend/design-system/animations.md +1 -1
  110. package/framework/standards/frontend/design-system/naming.md +1 -1
  111. package/framework/standards/frontend/nextjs/motion-patterns.md +45 -29
  112. package/framework/standards/frontend/nextjs/naming-conventions.md +1 -1
  113. package/framework/standards/infrastructure/docker/coolify-deploy.md +8 -6
  114. package/framework/standards/infrastructure/neon/neon-pgvector.md +120 -75
  115. package/framework/standards/infrastructure/neon/neon-setup.md +53 -31
  116. package/framework/standards/integration/mcp/mcp-tools.md +7 -7
  117. package/framework/templates/README.md +2 -3
  118. package/framework/templates/REGISTRY.json +6 -170
  119. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +2 -2
  120. package/framework/templates/code/dotnet/extensions/database-extensions.cs +1 -1
  121. package/framework/templates/code/dotnet/extensions/result-extensions.cs +27 -0
  122. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +2 -2
  123. package/framework/templates/docs/plan.md +72 -0
  124. package/framework/templates/dotnet/ai-kit/README.md +1 -9
  125. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +1 -1
  126. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +0 -10
  127. package/framework/templates/infrastructure/docker/coolify.template.json +3 -3
  128. package/framework/templates/infrastructure/github/README.md +2 -1
  129. package/framework/templates/infrastructure/github/workflows/deploy-coolify.yml.hbs +2 -1
  130. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +1 -1
  131. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +1 -1
  132. package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +1 -1
  133. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +3 -4
  134. package/package.json +1 -1
  135. package/src/commands/e2e/e2e.js +2 -2
  136. package/src/commands/observability/cost.js +18 -60
  137. package/src/commands/observability/telemetry.js +3 -5
  138. package/src/commands/project/doctor-procs.js +1 -1
  139. package/src/commands/project/doctor.js +9 -9
  140. package/src/commands/project/fleet.js +4 -4
  141. package/src/commands/project/heavy.js +3 -3
  142. package/src/commands/project/init.js +6 -1
  143. package/src/commands/project/setup-infra-cmd.js +2 -1
  144. package/src/commands/project/stack-scan.js +58 -0
  145. package/src/commands/project/standards.js +79 -25
  146. package/src/commands/project/status.js +29 -69
  147. package/src/commands/project/update.js +33 -19
  148. package/src/commands/project/worktree.js +1 -1
  149. package/src/commands/state/advance.js +62 -46
  150. package/src/commands/state/approve.js +95 -138
  151. package/src/commands/state/archive.js +20 -84
  152. package/src/commands/state/auto-approval.js +68 -0
  153. package/src/commands/state/create.js +28 -1
  154. package/src/commands/state/delete.js +1 -1
  155. package/src/commands/state/finish.js +11 -23
  156. package/src/commands/state/gate-check.js +86 -95
  157. package/src/commands/state/gate-decision.js +6 -4
  158. package/src/commands/state/handoff.js +1 -1
  159. package/src/commands/state/list.js +9 -9
  160. package/src/commands/state/report-check.js +157 -311
  161. package/src/commands/state/retype.js +9 -3
  162. package/src/commands/validation/mutate.js +77 -14
  163. package/src/commands/validation/plan-check.js +81 -0
  164. package/src/commands/validation/validate-feature.js +60 -135
  165. package/src/commands/validation/verify.js +41 -82
  166. package/src/core/paths/output-schema.js +20 -67
  167. package/src/core/state/gate-order.js +5 -6
  168. package/src/core/state/lifecycle-audit.js +2 -2
  169. package/src/core/state/state-manager.js +17 -98
  170. package/src/core/templates/template-registry.js +2 -2
  171. package/src/core/templates/template-seed.js +22 -0
  172. package/src/core/work-types.js +10 -10
  173. package/src/dashboard/app/App.jsx +0 -2
  174. package/src/dashboard/app/components/ActivityFeed.jsx +2 -3
  175. package/src/dashboard/app/components/CommandPalette.jsx +7 -8
  176. package/src/dashboard/app/components/EntityLink.jsx +1 -2
  177. package/src/dashboard/app/components/Markdown.jsx +1 -1
  178. package/src/dashboard/app/components/Sidebar.jsx +1 -2
  179. package/src/dashboard/app/hooks/useMorphQuery.js +1 -1
  180. package/src/dashboard/app/lib/phases.js +2 -4
  181. package/src/dashboard/app/pages/Activity.jsx +1 -1
  182. package/src/dashboard/app/pages/FeatureDetail.jsx +139 -129
  183. package/src/dashboard/app/pages/Features.jsx +9 -9
  184. package/src/dashboard/app/pages/Guide.jsx +2 -2
  185. package/src/dashboard/app/pages/PhasePipeline.jsx +3 -4
  186. package/src/dashboard/app/pages/RulesMap.jsx +3 -3
  187. package/src/dashboard/app/pages/SkillsLibrary.jsx +3 -3
  188. package/src/dashboard/app/pages/Standards.jsx +1 -1
  189. package/src/dashboard/scanner/activity-scanner.js +6 -16
  190. package/src/dashboard/scanner/agents-scanner.js +1 -1
  191. package/src/dashboard/scanner/docs-scanner.js +5 -23
  192. package/src/dashboard/scanner/features-scanner.js +95 -60
  193. package/src/dashboard/scanner/index.js +0 -2
  194. package/src/dashboard/scanner/project-api.js +1 -1
  195. package/src/dashboard/scanner/rules-scanner.js +15 -10
  196. package/src/dashboard/scanner/skills-scanner.js +2 -3
  197. package/src/dashboard/scanner/standards-scanner.js +2 -1
  198. package/src/lib/ci/ci-verify.js +17 -1
  199. package/src/lib/ci/github-ci.js +1 -1
  200. package/src/lib/detectors/index.js +3 -8
  201. package/src/lib/generators/handoff-generator.js +34 -65
  202. package/src/lib/generators/settings-generator.js +11 -89
  203. package/src/lib/git/evidence-staleness.js +1 -1
  204. package/src/lib/git/tree-fingerprint.js +19 -7
  205. package/src/lib/git/tree-state.js +2 -2
  206. package/src/lib/heavy/cleanup.js +1 -5
  207. package/src/lib/installers/memory-installer.js +6 -8
  208. package/src/lib/mutation/commands.js +3 -2
  209. package/src/lib/{tasks/dotnet-test-introspection.js → mutation/dotnet-introspection.js} +17 -282
  210. package/src/lib/mutation/plan.js +14 -6
  211. package/src/lib/mutation/runner.js +1 -1
  212. package/src/lib/mutation/subset.js +46 -9
  213. package/src/lib/plan/artifact-vocabulary.js +60 -0
  214. package/src/lib/plan/checks.js +234 -0
  215. package/src/lib/plan/plan-parser.js +209 -0
  216. package/src/lib/plan/plan-template.js +18 -0
  217. package/src/lib/review-reports.js +222 -0
  218. package/src/lib/risk-detector.js +134 -135
  219. package/src/lib/specs/adr-index.js +50 -69
  220. package/src/lib/specs/design-seed.js +18 -0
  221. package/src/lib/specs/frontmatter.js +44 -0
  222. package/src/lib/specs/gfm-table.js +17 -0
  223. package/src/lib/specs/old-format.js +68 -0
  224. package/src/lib/specs/revocations.js +37 -95
  225. package/src/lib/specs/screen-checklist.js +18 -17
  226. package/src/lib/stack/dotnet-build-ignores.js +47 -0
  227. package/src/lib/stack/stack-profile.js +1 -1
  228. package/src/lib/stack/stack-scan.js +267 -0
  229. package/src/lib/standards/registry.js +43 -0
  230. package/src/lib/standards/sections.js +58 -0
  231. package/src/lib/tasks/eval-node.js +4 -12
  232. package/src/lib/tasks/test-nodes.js +1 -74
  233. package/src/lib/tasks/test-runner.js +75 -117
  234. package/src/lib/telemetry/metrics.js +8 -69
  235. package/src/lib/telemetry/telemetry-reader.js +5 -118
  236. package/src/lib/telemetry/verify-event.js +5 -7
  237. package/src/lib/validators/code-budget/code-budget-validator.js +1 -1
  238. package/src/lib/validators/contracts/contract-compliance-validator.js +2 -2
  239. package/src/lib/validators/reuse/reuse-validator.js +24 -48
  240. package/src/lib/validators/reuse/symbol-scanner.js +2 -4
  241. package/src/lib/validators/traceability-check.js +85 -129
  242. package/src/lib/validators/validation-runner.js +8 -88
  243. package/src/lib/validators/verify-runner.js +134 -301
  244. package/src/lib/worktree/docker-audit.js +1 -2
  245. package/src/lib/worktree/fleet-scanner.js +25 -38
  246. package/src/scripts/setup-infra.js +42 -22
  247. package/src/utils/agents-installer.js +92 -13
  248. package/src/utils/claude-settings-manager.js +0 -35
  249. package/src/utils/file-copier.js +34 -6
  250. package/src/utils/hooks-installer.js +16 -9
  251. package/src/utils/skills-installer.js +1 -2
  252. package/framework/commands/commit.md +0 -166
  253. package/framework/evals/trace-schema.md +0 -67
  254. package/framework/hooks/claude-code/core/tasks-json-guard.js +0 -83
  255. package/framework/hooks/claude-code/core/trace-autogen.js +0 -277
  256. package/framework/hooks/git/pre-commit/specs.sh +0 -50
  257. package/framework/hooks/shared/tasks-validator.js +0 -111
  258. package/framework/rubrics/backend.json +0 -41
  259. package/framework/rubrics/default.json +0 -36
  260. package/framework/rubrics/frontend.json +0 -36
  261. package/framework/rules/morph-task-tracking.md +0 -54
  262. package/framework/rules/morph-workflow.md +0 -244
  263. package/framework/schemas/tasks.schema.json +0 -79
  264. package/framework/skills/core/morph-brainstorming/SKILL.md +0 -161
  265. package/framework/skills/core/morph-implement/SKILL.md +0 -194
  266. package/framework/skills/core/morph-proposal/SKILL.md +0 -152
  267. package/framework/skills/core/morph-stack-scan/SKILL.md +0 -145
  268. package/framework/templates/docs/proposal.md +0 -192
  269. package/framework/templates/docs/spec.md +0 -57
  270. package/framework/templates/docs/ui-components.md +0 -52
  271. package/framework/templates/docs/ui-design-system.md +0 -76
  272. package/framework/templates/docs/ui-flows.md +0 -167
  273. package/framework/templates/examples/spec-examples.md +0 -91
  274. package/framework/templates/feature/decisions.md +0 -124
  275. package/framework/templates/feature/recap.md +0 -145
  276. package/framework/templates/project/validate.js +0 -97
  277. package/framework/templates/tasks.template.json +0 -17
  278. package/src/commands/state/usecase.js +0 -143
  279. package/src/commands/tasks/dag.js +0 -181
  280. package/src/dashboard/app/pages/Rubrics.jsx +0 -97
  281. package/src/dashboard/scanner/rubrics-scanner.js +0 -12
  282. package/src/lib/agents/output-collector.js +0 -76
  283. package/src/lib/evaluator-report.js +0 -91
  284. package/src/lib/specs/acervo-format.js +0 -70
  285. package/src/lib/specs/acervo-lifecycle.js +0 -264
  286. package/src/lib/specs/done-criteria-check.js +0 -200
  287. package/src/lib/specs/usecase-check.js +0 -301
  288. package/src/lib/specs/usecase-promoter.js +0 -301
  289. package/src/lib/specs/usecase-registry.js +0 -237
  290. package/src/lib/tasks/dispatch-planner.js +0 -319
  291. package/src/lib/tasks/mermaid-renderer.js +0 -132
  292. package/src/lib/tasks/task-classifier.js +0 -30
  293. package/src/lib/tasks/task-parser.js +0 -209
  294. package/src/lib/tasks/tasks-json-parser.js +0 -296
  295. package/src/lib/tasks/test-scope.js +0 -597
  296. package/src/lib/validators/architecture/architecture-validator.js +0 -270
  297. package/src/lib/validators/architecture/index.js +0 -7
  298. package/src/lib/validators/css/css-validator.js +0 -340
  299. package/src/lib/validators/css/index.js +0 -7
  300. package/src/lib/validators/design-system/design-system-validator.js +0 -237
  301. package/src/lib/validators/design-system/index.js +0 -7
  302. package/src/lib/validators/score-aggregator.js +0 -244
  303. package/src/lib/validators/ui/index.js +0 -7
  304. package/src/lib/validators/ui/ui-contrast-validator.js +0 -422
@@ -2,9 +2,9 @@
2
2
  name: morph-media
3
3
  description: Conduz a AUTORIA de mídia gerada por IA — escolher o modelo pelo trabalho, montar o prompt como spec versionada, encadear derivadas a partir de um herói aprovado, subir a escada de custo e conduzir o gate humano de escolha entre N candidatas. É o lado processo; o conhecimento de API, custo e conformidade vive nos standards de mídia.
4
4
  version: core
5
- when-to-invoke: quando a tarefa é PRODUZIR imagem ou vídeo por IA (catálogo, marketing, asset de LP) e alguém precisa decidir modelo, prompt e aprovação
6
- user-invokable: true
7
- cliVersion: "8.46.0"
5
+ when_to_use: Use quando a tarefa for PRODUZIR imagem ou vídeo por IA (catálogo, marketing, asset de LP) e alguém precisar decidir modelo, prompt e aprovação
6
+ user-invocable: true
7
+ cliVersion: "9.0.0"
8
8
  stacks:
9
9
  - dotnet
10
10
  - nextjs
@@ -1,307 +1,145 @@
1
1
  ---
2
2
  name: morph-plan
3
- description: Guia a produção dos artefatos de planejamento de uma feature (use cases, spec.md, tasks.json) e apresenta o Gate 2 trust-aware.
3
+ description: Leva uma feature do pedido ao plano aprovado — roteia o tipo de trabalho, varre o ambiente, conduz a entrevista pela árvore de decisões, escreve 2-plan/plan.md, extrai checks.json com plan-check e apresenta o gate do plano.
4
4
  version: core
5
- when-to-invoke: ao iniciar a fase plan de uma feature, após o Gate 1 (proposal aprovado)
6
- user-invokable: true
7
- cliVersion: "8.46.0"
5
+ when_to_use: Use quando uma feature, bug ou chore começar ("/morph-proposal {feature}", "vamos planejar X"), ou ao retomar uma feature cujo gate plan ainda não foi aprovado
6
+ user-invocable: true
7
+ cliVersion: "9.0.0"
8
8
  ---
9
9
 
10
10
  # morph-plan
11
11
 
12
- ## Objetivo
13
-
14
- Produzir os **use cases**, o `spec.md` e o `tasks.json` com qualidade para abrir o Gate 2. Os use
15
- cases definem o **comportamento**; o spec diz **como**; as tasks dizem **em que ordem** e **quando
16
- cada uma está pronta**. Comportamento antes de solução técnica — sempre nessa ordem.
17
-
18
- ## Quando invocar
19
-
20
- Fase plan, depois do Gate 1. Normalmente chamada pela `morph-proposal`.
21
-
22
- ## O que fazer
23
-
24
- 1. **Garanta que `proposal.md` e `stack-scan.md` estão no seu contexto antes de planejar** (Read se
25
- a sessão é fresca). Em brownfield, o stack-scan manda: não invente padrão que conflita com o
26
- detectado.
27
-
28
- **E `.morph/features/{feature}/1-design/*.md`, quando o diretório existe** — leia todos os `.md`:
29
- descrevem comportamento de interface que o proposal não carrega. **Diretório ausente NÃO é erro**
30
- — a fase uiux é opcional (MORPH.md §2.1) e o plano segue igual.
31
-
32
- 1b. **Scout — mapa do território (default em feature grande ou brownfield).**
33
- Despache `subagent_type: "morph-scout"`: os arquivos que a feature vai tocar, o blast radius dos símbolos centrais e o que
34
- quebra junto. O scout começa por `morph-spec graph affected|explain` e **cai para grep sozinho
35
- quando não há grafo**. Não registrado: `general-purpose` com o campo `persona` do `scout`.
36
- Grave a resposta em `2-plan/scout-map.md` e audite:
37
- ```
38
- morph-spec scout-check .morph/features/{feature}/2-plan/scout-map.md --json
39
- ```
40
- Exit ≠ 0 → o mapa é descartado; re-despache **uma** vez com as `failures` coladas. Segunda
41
- reprovação: faça você o grep dos fatos que o plano precisa. Mapa aprovado prova que as citações
42
- existem, não que a conclusão está certa — confira com grep próprio o Inferido que muda o plano.
43
- Pular o scout em feature pequena no domínio carregado: uma linha em `decisions.md`.
44
-
45
- 1c. **Reuso — o que desta feature JÁ EXISTE.** Para cada conceito central que a feature introduz
46
- (entidade, DTO, componente, hook, serviço, helper, dublê de teste): `morph-spec graph explain
47
- <nome> --json` (existe? onde?) e `morph-spec graph affected <conceito> --uses-only --json` (quem
48
- usa de verdade). Antes, `morph-spec graph status --json`: stale numa worktree, ou sem refresh em
49
- andamento, `morph-spec graph refresh`. O inventário `.morph/context/README.md` (`morph-spec context
50
- refresh`) dá componentes e endpoints por path. **Sem grafo** (`no-graph`, `not-found` num grafo
51
- stale), caia para `grep -rn "<nome>"` e siga — a ausência de grafo nunca bloqueia.
52
-
53
- O veredito vai direto para a task que realiza o conceito (passo 5b): `REUSAR`, `ESTENDER` ou
54
- `CRIAR`. **`CRIAR` exige `why`** — uma linha com a consulta que respondeu "não existe" (`graph
55
- explain X → not-found; grep -rn X → 0`). Conceito de duas features vai para um módulo comum, nunca
56
- import cruzado entre slices. O validador `reuse` do `verify` cobra o resultado: símbolo novo
57
- homônimo de um existente reprova na mesma feature e avisa entre features; `CRIAR` declarado no
58
- plano rebaixa o achado a aviso.
59
-
60
- 1d. **O que esta feature supera no acervo.** Insumos: `Conflitos com o acervo` do `proposal.md`,
61
- `.morph/specs/usecases/` e o índice `.morph/specs/adrs/`. UC `status: superseded` não é o
62
- comportamento vigente — o `superseded_by` é. Cada conflito decidido vira uma linha na seção de
63
- revogação do `spec.md` (passo 3) e um ADR em `decisions.md`; ADR que vale além desta feature leva
64
- `**Alcance:** projeto` (é por ela que o `finish` o copia para o índice):
65
- ```markdown
66
- ## ADR-{nnn}: {a regra que vale no projeto}
67
-
68
- **Status:** Accepted
69
- **Alcance:** projeto
70
- ```
71
-
72
- 2. **Destile os use cases — ANTES de escrever `spec.md` e `tasks.json`.**
73
-
74
- Um arquivo por use case em `.morph/features/{feature}/2-plan/usecases/UC-{nn}-{slug}.md`:
75
-
76
- ```markdown
77
- ---
78
- id: UC-07
79
- title: Listar veterinários com suas especialidades
80
- actor: Visitante
81
- status: draft
82
- entities: [Vet, Specialty]
83
- ---
84
-
85
- ## Pré-condições
86
- - Existe ao menos um veterinário cadastrado
87
-
88
- ## Cenário principal
89
- 1. Visitante acessa a listagem de veterinários
90
- 2. Sistema retorna os veterinários ordenados por sobrenome
91
-
92
- ## Pós-condições
93
- - **P1** — A resposta contém todos os veterinários não arquivados
94
- - **P2** — Cada veterinário traz suas especialidades em lista, nunca string concatenada
95
-
96
- ## Fluxos alternativos (opcional)
97
- - **A1** — Nenhum veterinário cadastrado → sistema exibe estado vazio
98
- ```
99
-
100
- **A regra que sustenta a camada inteira: pós-condição precisa ser observável em teste.** Pergunte:
101
- *que asserção eu escreveria para verificar isto?* Sem resposta, reescreva ou descarte.
102
-
103
- **Artefato não é comportamento.** Pós-condição que cita arquivo, pasta, `grep`, "contém a
104
- string" ou "o binário" descreve o texto do repositório, não o que o sistema faz. Primeiro tente
105
- o efeito observável em runtime ("publicar tenant com `criterion_overrides` é recusado, nomeando a
106
- chave"). Se o artefato É o entregável, justifique **na linha logo abaixo**:
107
-
108
- ```markdown
109
- - **P4** — Nenhum arquivo em `tenants/**` contém a chave `criterion_overrides`
110
- > [!note] Por que artefato: a chave saiu do contrato; nenhum leitor de runtime a consulta.
111
- ```
112
-
113
- Nunca na mesma linha: a pós-condição viaja literal ao `doneCriteria`. Task sem `usecase`
114
- justifica no próprio `doneCriteria` (`… — Por que artefato: …`). Pós-condição sobre o que um
115
- **modelo** responde é observável em runtime, nunca no texto do prompt (passo 5).
116
-
117
- **Numeração:** `morph-spec usecase reserve --count {n} --feature {feature}` — nunca o maior
118
- `UC-{nn}` do disco: cada worktree vê só a sua cópia, e dois planos paralelos mintariam o mesmo id.
119
-
120
- **Seções:** obrigatórias `Pré-condições`, `Cenário principal` (curto) e `Pós-condições` (**P1**,
121
- **P2**…). Opcionais, só quando pedem: `Fluxos alternativos` (**A1**…) e `Delta de domínio`.
122
-
123
- | Tipo | Use case |
124
- |---|---|
125
- | `feature` | Obrigatório com comportamento observável; feature puramente técnica dispensa (registre em `decisions.md`). |
126
- | `bug` | Copie o `UC-{nn}-*.md` do acervo para `2-plan/usecases/` **com o mesmo nome de arquivo** e corrija ou adicione a pós-condição — não reserve número novo. |
127
- | `chore` | Nenhum. |
128
- | `hotfix` | Referencia se existir. |
129
-
130
- **Nunca edite `.morph/specs/usecases/` à mão** — a única escrita no acervo é a promoção do
131
- `finish`, que lê de `2-plan/usecases/`. O use case segue editável depois do Gate 2.
132
-
133
- 3. Produza `spec.md` em `2-plan/`:
134
- - Arquitetura: componentes, como se conectam, fluxos de dados. Edge cases **técnicos** (os de
135
- comportamento estão nos use cases) e integrações externas. Não repita o comportamento.
136
- - **UCs e ADRs que esta feature altera ou revoga** — seção obrigatória com este título; `Nenhum.`
137
- quando nada muda, senão:
138
-
139
- ```markdown
140
- ## UCs e ADRs que esta feature altera ou revoga
141
-
142
- | Id | Mudança | Substituto | Escopo em que o antigo ainda vale |
143
- |---|---|---|---|
144
- | UC-{nn} | parcial | UC-{nn} | {onde o antigo ainda vale} |
145
- | {feature}/ADR-{nnn} | total | — | — |
146
- ```
147
-
148
- `Id` é `UC-{nn}` ou `{feature}/ADR-{nnn}`. UC revogado exige `Substituto`; `parcial` exige
149
- `Escopo`. O `finish` aplica as linhas válidas e devolve as malformadas em `revocationProblems`.
150
- **Rode `morph-spec usecase check {feature}` logo depois de escrever a seção** — o spec congela no
151
- Gate 2.
152
-
153
- 4. **Seção `## Contrato de implementação` do `spec.md`** — o que quem implementa precisa saber e o
154
- código não diz. Curta; o resto já está nos standards que cada task carrega.
155
- - **Standards:** `morph-spec standards --find "<domínio>"` por domínio tocado (o digest decide);
156
- liste os ids. Inclua `architecture-code-comments` e o standard de teste do stack. Feature com
157
- agente MAF: os `standards/ai-agents/*.md` que ela exige (`--category ai-agents`) — convenção de
158
- projeto vem deles; superfície da API pode vir do context7.
159
- - **Proibições desta feature** além das de `MORPH.md` § "Stack baked-in", quando houver.
160
- - **Verificação de runtime** — como se prova que a feature funciona rodando:
161
- - O stack sobe pelo `docker compose` do projeto (`morph-spec e2e up {feature}`). Projeto que
162
- containeriza sem compose: **isso é uma task**.
163
- - Os fluxos que o avaliador vai navegar, nos verbos das pós-condições; quais viram spec
164
- Playwright (caminho crítico e bug corrigido).
165
- - Base URL do ambiente: `process.env.PLAYWRIGHT_BASE_URL ?? \`http://localhost:${process.env.PORT ?? 3000}\``,
166
- compose publicando `"${PORT:-3000}:3000"` e sem `container_name` (standard
167
- `infrastructure/docker/local-compose-isolation`). Cravado: **isso é uma task**.
168
- - App com login: `e2e.auth` em `config.json` (`mode: seed|storageState|bypass|none`,
169
- `seedCommand`, `storageStatePath`, `envFile`), credenciais num `.env.e2e` gitignored.
170
- **`mode` é obrigatório sempre que houver `seedCommand`** — sem ele o seed fica inerte. Sem setup de
171
- login, crie a task.
172
- - Não se aplica (biblioteca pura): registre a dispensa e o porquê.
173
- - **Baseline é um COMANDO, nunca um número.** O spec congela no Gate 2 e é lido por dias: número
174
- cravado (`2366 passando`) está errado na primeira task, e quem confia nele "conserta" o que não
175
- quebrou. Registre como medir (`npm test`, `dotnet test`); o `expectedCount` de `project.tests[]`
176
- é gravado por `morph-spec verify {feature} --record-baseline`, nunca digitado.
177
- - **Pré-requisito é um PREDICADO, nunca um SHA literal**: "`git merge-base --is-ancestor
178
- origin/main HEAD` sai 0", não "confirme que main contém `49dfba2`" — o SHA muda no primeiro
179
- squash.
180
-
181
- 5. Produza `tasks.json` em `.morph/features/{feature}/2-plan/` seguindo o schema
182
- `.morph/framework/schemas/tasks.schema.json` (o hook `tasks-json-guard` valida cada write):
183
-
184
- ```json
185
- {
186
- "version": "1.0",
187
- "feature": "{feature-name}",
188
- "tasks": [
189
- {
190
- "id": "T1",
191
- "title": "Título curto",
192
- "description": "O que esta task realiza e por quê",
193
- "dependencies": [],
194
- "effort": "S",
195
- "doneCriteria": "P2 — Cada veterinário traz suas especialidades em lista, nunca string concatenada",
196
- "status": "pending",
197
- "outputs": ["src/Vets/ListVets.cs", "tests/Vets/ListVetsTests.cs"],
198
- "group": "backend",
199
- "usecase": "UC-07",
200
- "agent": "dotnet-senior",
201
- "standards": ["standards/backend/dotnet/vsa-handler-patterns.md"],
202
- "reuse": [{ "concept": "VetDto", "verdict": "CRIAR", "why": "graph explain VetDto → not-found; grep -rn VetDto → 0" }]
203
- }
204
- ]
205
- }
206
- ```
207
-
208
- - `id` `T\d+`; `dependencies` com ids Tn; `effort` S (≤30min) | M (≤1h) | L (≤2h) | XL (>2h);
209
- `status` nasce `pending`; `group` backend | frontend | tests | infra | docs.
210
- - `usecase`: o **id** (`UC-07`), nunca o nome do arquivo.
211
- - `outputs`: paths planejados — o `dag` detecta colisão entre fluxos paralelos por eles.
212
- **No máximo 8 `outputs` por task** (testes incluídos): acima disso o sub-agente bate no teto de
213
- turnos; o `dag` recusa antes do Gate 2.
214
-
215
- **5a. Carimbe `agent` e `standards`** com UMA leitura de `.morph/framework/agents.json`: `agent` é
216
- o id da persona (sem `morph-`) cujo `domains` cobre o domínio da task; `standards`, o array dela
217
- mais o que a task exige. **Persona com `surfaces`** (a `ui-designer`): some a lista da superfície
218
- que o checklist de tela do `1-design/mockups.md` declara em `Superfície`, nunca de outra; sem
219
- mockup, escolha pela tela e registre em `decisions.md`. Task que cria ou altera UI carimba
220
- `agent: "ui-designer"` mesmo sem o ramo uiux. Task sem persona clara (config, docs) fica sem `agent`.
221
-
222
- **5b. Carimbe `reuse`** na task que escreve cada conceito do passo 1c: `concept`, `verdict`,
223
- `target` (o que reusar ou estender) e, em `CRIAR`, `why`. Conceito sem task: falta task ou o
224
- conceito não é desta feature — resolva antes do Gate 2.
225
-
226
- **O `doneCriteria` carrega a pós-condição LITERAL**, prefixada pelo rótulo (`"P2 — Cada
227
- veterinário traz..."`). Reescrever com outras palavras é onde o requisito se perde. Toda
228
- pós-condição de todo UC tem ao menos uma task.
229
-
230
- **`morph-spec dag {feature}` cobra o encanamento.** Ele reporta UC inexistente (erro), pós-condição sem task e `doneCriteria` parafraseado (avisos), e `doneCriteria` com vocabulário de artefato (`grep`, "contém a string", "o binário", "nenhum arquivo", "arquivo/pasta/diretório em", glob `**/`) sem `Por que artefato:` (aviso). Também aponta task sobre UC `superseded` e linha de revogação que o `finish` não aplicaria.
231
-
232
- **Orçamento de teste por task.** Cada pós-condição compra **um** teste, cada bug corrigido **um** de
233
- regressão; acima disso, uma linha de justificativa na `description`. Cenários do mesmo
234
- comportamento são linhas de tabela (`[Theory]`/`it.each`). **Nenhum teste que só fixa texto**
235
- (copy, config, prosa). O `verify` avisa quando o teste adicionado passa de 1,5× a produção.
236
-
237
- **Critério sobre saída de LLM vira eval de runtime — nunca "suíte estrutural".** Vale quando a seção
238
- de contrato cita um standard `ai-agents` e o `doneCriteria` julga o que o modelo *responde*:
239
- - a prova é um **eval de runtime**; a evidência vai em
240
- `.morph/features/{feature}/3-implement/evidencias/{taskId}.md`, e esse path entra em
241
- `outputs` — é por ele que implementador e avaliador sabem que ela é devida. Com nó
242
- `runner: "evals"` (standard `ai-agents-evals-with-cache`), o cenário mora no dataset do nó;
243
- - **no máximo 1 teste de estrutura** da fonte do prompt — nunca vocabulário do que o modelo
244
- deveria dizer;
245
- - as duas coisas vão na `description` da task.
246
-
247
- **5c. Cross-check do `1-design/` — todo aviso de capacidade tem destino.** Com o diretório
248
- presente, antes de fechar o array `tasks`:
249
-
250
- ```bash
251
- grep -riE "capacidade nova|precisa de backend|dimensionar junto" .morph/features/{feature}/1-design/
252
- ```
253
-
254
- Cada ocorrência vira **task irmã** ou exclusão registrada em `decisions.md` com o motivo —
255
- **nunca fica sem destino**. Sem hits, ou sem `1-design/`, o passo é um no-op.
256
-
257
- **5d. O checklist de tela vira critério.** A task que entrega uma `## Tela:` do
258
- `1-design/mockups.md` carrega no `doneCriteria` as decisões do `### Checklist de tela` (volume,
259
- paginação, ordenação, filtro, os três estados, mobile, abas), citando a seção por path
260
- (`1-design/mockups.md#tela-…`) — "lista pagina no servidor, 25 por página" é critério; "conforme
261
- o mockup" não é. Item "não se aplica" não vira critério.
262
-
263
- Antes de retornar, valide rodando `morph-spec dag {feature}` — schema do tasks.json (ids, enums,
264
- dependências) e a análise de DAG que a `/morph-apply` vai usar.
265
-
266
- 6. Apresente o Gate 2 segundo trust mode.
267
-
268
- Rode `morph-spec gate-check {feature} plan [--json]` — decide pelos sinais do disco e persiste
269
- `gateDecisions.plan`. Divergência de design system do Gate 1 sem resolução, ou violação de
270
- standard, entram por `--signals` (as únicas chaves aceitas):
271
- ```
272
- morph-spec gate-check {feature} plan --signals '{"designSystemDivergence":true,"standardsViolations":["<id>"]}'
273
- ```
274
- Risco que nenhuma chave representa: `gate-decision` direto. Nunca edite `feature.json` à mão.
275
- `morph-spec dag {feature} --mermaid` dá o diagrama do plano para o gate.
276
-
277
- **Se `pause === true`**, `AskUserQuestion`:
278
-
279
- ```
280
- question: "Gate 2 — Plano de {feature} aprovado?{ reason ? ' Sinal: ' + reason : '' }"
281
- header: "Gate 2"
282
- options:
283
- - { label: "aprovado, prosseguir", description: "Aceitar use cases, spec e tasks e habilitar /morph-apply" }
284
- - { label: "preciso ajustar", description: "Apontar mudanças no plano antes de prosseguir" }
285
- - { label: "cancelar feature", description: "Abortar" }
286
- ```
287
-
288
- **Se `pause === false`**: resumo de 3 linhas (problema → solução; tasks e esforço; caminho
289
- crítico) e `morph-spec approve {feature} plan --mode auto` (ou `advance {feature}`). A pergunta
290
- nomeia a feature — é por ela que o hook `state-sync` grava a aprovação.
291
-
292
- Aprovado o Gate 2, o frontmatter de cada use case passa de `status: draft` a `status: approved`.
293
- O `finish` os promove ao acervo com `status: implemented`.
294
-
295
- ## Output esperado
296
-
297
- - `2-plan/usecases/UC-{nn}-{slug}.md` — pós-condições testáveis
298
- - `2-plan/spec.md` — arquitetura, seção de revogação e `## Contrato de implementação`
299
- - `2-plan/tasks.json` — válido contra o schema, `doneCriteria` literal, `agent`/`standards`/`reuse`
300
- carimbados, `3-implement/evidencias/{taskId}.md` em `outputs` nas tasks de critério sobre LLM
301
- - Gate 2 registrado em `feature.json`
302
-
303
- ## Referências
304
-
305
- - `.morph/framework/MORPH.md` — §2 (fases), §3 (contratos de output), §5 (gates)
306
- - `morph-spec standards --find|graph explain|graph affected --uses-only|usecase reserve|usecase check|dag` — `.morph/framework/CLI.md`
307
- - `.morph/framework/schemas/tasks.schema.json`
12
+ ## 0. Contrato
13
+
14
+ Saída: `.morph/features/{feature}/2-plan/plan.md` (fonte única da feature) e `2-plan/checks.json`, gravado só por `morph-spec plan-check`. O usuário só toca a entrevista e o gate; o resto você resolve. Nada de código nesta fase. O `create` escreve o esqueleto de `plan.md` no nascimento: só é retomada com `2-plan/checks.json` no disco ou com o `plan.md` já sem os `<…>` do esqueleto — aí vá ao §5 (corrigir) ou ao §7 (gate).
15
+
16
+ ## 1. Roteamento
17
+
18
+ Sem nome de feature, pergunte (`AskUserQuestion`, header "Feature"). Feature que ainda não existe (sem `feature.json`), uma vez só:
19
+
20
+ ```
21
+ morph-spec create {feature} --request "<pedido do usuário>"
22
+ ```
23
+
24
+ Tipo óbvio pelo pedido: `--type <tipo> --description "<o quê/porquê>"`. O `--request` semeia a descrição; sem ele nem `--description`, o `create` recusa. **Exit 2** (empate ou nenhum sinal): você é o roteador — escolha entre os `candidates` e re-rode com `--type <tipo> --request "<pedido>"`. `AskUserQuestion` só quando o pedido é genuinamente indeterminado.
25
+
26
+ | Tipo | Caminho |
27
+ |---|---|
28
+ | `hotfix` | `Skill(morph-hotfix)` com o nome e **encerre** esta skill |
29
+ | `chore` | plan.md curto (§8), `plan-check`, e `Skill(morph-apply)` direto — a única exceção ao §9 |
30
+ | `bug` | fluxo inteiro em modo bug-lean (§8) |
31
+ | `feature` | fluxo inteiro (§2–§7) |
32
+
33
+ ## 2. Varredura — antes de qualquer pergunta
34
+
35
+ Fato não se pergunta: as decisões são do usuário, os fatos são seus.
36
+
37
+ 1. `morph-spec stack-scan {feature}` → `2-plan/stack-scan.md`. Greenfield sai curto; em brownfield lista desvios por severidade contra `project.stack`. Desvio Bloqueante ou Alto vira um nó da árvore ("a migração entra nesta feature ou vira feature separada?") — **dentro** da árvore, nunca uma pergunta antes dela.
38
+ 2. Leia `.morph/config/config.json`, `.morph/context/` (o inventário `README.md` dá componentes e endpoints; `morph-spec context refresh` o regera), as features ativas e o índice de ADRs `.morph/specs/adrs/`. Decisão vigente é a do índice; `decisions.md` e use cases de `.morph/archive/` são **história, não instrução** — abra um só para entender por que algo é como é.
39
+ 3. **Conflitos com o acervo — avise, não entreviste.** Para cada ADR ou documento de `.morph/context/` que o pedido contradiz: uma linha de aviso no resumo que abre o §3 (fonte, o que diz, o que o pedido muda). **Pedido explícito sobre o ponto → vale o mais novo**, e você segue. Só entra na árvore o conflito que o pedido deixa **ambíguo** ("o admin passa a Geist" não diz nada da vitrine: a vitrine é decisão, o admin não). Todo conflito, decidido ou não, vai para `### Conflitos com o acervo` do plan.md.
40
+ 4. **Design system:** compare `.morph/context/design-system.md` com o detectado e com mocks recentes do usuário. Divergência (tokens, versão, fonte aprovada) é **decisão da árvore** e sinal `designSystemDivergence` no §7. Resolvida, **reescreva o corpo** do arquivo com a fonte escolhida — a seção que descrevia a antiga passa a descrever a nova, com o escopo onde o valor antigo ainda vale; o changelog guarda **só data e motivo**, nunca o valor novo. Este é o protocolo que a `morph-uiux` reaplica.
41
+
42
+ ## 3. Árvore de decisões e modo
43
+
44
+ Entra na árvore só o que (a) muda escopo, comportamento ou arquitetura e (b) a varredura não respondeu. Ordene pelo que **poda**: "síncrono ou assíncrono?" vem antes de "qual política de retry". Publique a árvore ao usuário antes de perguntar.
45
+
46
+ **Pergunta de abertura** (só `feature` e `bug`; `chore` e `hotfix` não passam por aqui): uma `AskUserQuestion`, header "Descoberta", com a árvore resumida e o modo recomendado em primeiro lugar com `(Recomendado)` no label. Muitas decisões, ou decisões acopladas → entrevista; árvore rasa → automático.
47
+
48
+ - **Entrevista:** **uma pergunta por chamada** de `AskUserQuestion` — lote desorienta e impede que uma resposta pode ramos. Cada pergunta traz a resposta recomendada como primeira opção, `(Recomendado)`. Mostre a árvore quando ela mudar de forma. Termina quando a árvore zera; o usuário pode encerrar antes, e o que ficou aberto vira `## Fora de escopo`. O gate do plano pausa sempre neste modo (§7).
49
+ - **Automático:** até 4 perguntas, **só sobre nós abertos** da árvore — nunca uma lista fixa. Árvore vazia → nenhuma pergunta.
50
+
51
+ **Headless** (`AskUserQuestion` indisponível ou negada, como sob `claude -p`): nunca decida você os nós abertos. Escreva-os em texto, numerados, cada um com a resposta recomendada; rode `morph-spec gate-decision {feature} plan --pause true --reason "entrevista headless"` e **encerre o turno**. Retome quando o usuário responder.
52
+
53
+ ## 4. Território
54
+
55
+ Feature grande ou brownfield: despache `subagent_type: "morph-scout"` (não registrado: `general-purpose` com o campo `persona` do `scout` de `.morph/framework/agents.json`) para os arquivos que a feature toca e o blast radius dos símbolos centrais. Grave em `2-plan/scout-map.md` e audite:
56
+
57
+ ```
58
+ morph-spec scout-check .morph/features/{feature}/2-plan/scout-map.md --json
59
+ ```
60
+
61
+ Exit ≠ 0 → descarte o mapa e re-despache **uma** vez com as `failures` coladas; segunda reprovação: grep você mesmo. Mapa aprovado prova que as citações existem, não que a conclusão está certa — confira com grep próprio o Inferido que muda o plano. Pular o scout numa feature pequena no domínio carregado: uma linha em `## Arquitetura`.
62
+
63
+ **Reuso — o que já existe.** Para cada conceito central (entidade, DTO, componente, hook, helper, dublê de teste): `morph-spec graph explain <nome> --json` e `morph-spec graph affected <nome> --uses-only --json`. Antes, `morph-spec graph status --json`; stale numa worktree → `morph-spec graph refresh`. `--uses-only` importa: o grep conta herança como uso — no ProspectPRO apontou 23 arquivos onde 20 eram interfaces filhas herdando o contrato e só 2 usavam de verdade. **Sem grafo** (`no-graph`, `not-found` num grafo stale), caia para `grep -rn "<nome>"` e registre que a contagem veio do grep, que superestima consumidores. A ausência de grafo nunca bloqueia.
64
+
65
+ ## 5. plan.md
66
+
67
+ O `create` já escreveu o esqueleto em `2-plan/plan.md` (leia e preencha; `chore` e `hotfix` nascem com o gate carimbado e criam o arquivo numa única escrita); gramática completa: `morph-spec plan-check --help`. `plan-check` é o único leitor; o que ele não reconhece, ninguém lê.
68
+
69
+ **Cenários** (`## Cenários`): `- **Cn** — Dado …, quando …, então …`, com `prova:` (`teste` | `e2e` | `eval` | `manual`) **na linha seguinte, sem linha em branco** — linha vazia encerra o cenário.
70
+ - **Observável em teste**: que asserção eu escreveria? Sem resposta, reescreva ou descarte.
71
+ - **Artefato não é comportamento.** Cenário que cita `grep`, "contém a string", "o binário", "nenhum arquivo", "arquivo/pasta/diretório em" ou glob `**/` descreve o repositório. Tente o efeito em runtime; se o artefato É o entregável, justifique em `> Por que artefato:` logo abaixo (nunca na mesma linha, nunca `> [!note]`).
72
+ - **Saída de LLM** (o que o modelo responde) prova-se por `eval` de runtime, nunca pelo texto do prompt: evidência em `3-implement/evidencias/{Cn}.md`, path listado em `arquivos:` da fatia; com nó `runner: "evals"` (standard `ai-agents-evals-with-cache`) o cenário mora no dataset. No máximo 1 teste de estrutura da fonte do prompt.
73
+ - **"O comando de teste da raiz roda de ponta a ponta"** prova-se pelo `verify {feature}` (o nó `e2e` e o nó de teste `e2e: true` já percorrem a cadeia): nomeie essa rodada como a prova, nunca uma execução avulsa. Precisando mesmo rodar fora dele, numa linha só (o Bash não guarda o env entre chamadas): `eval "$(morph-spec env {feature})" && morph-spec heavy run -- <comando>` — o `COMPOSE_PROJECT_NAME` da feature é o que o `finish` derruba com os volumes. `prova: manual` registra passo e resultado em `3-implement/evidencias/{Cn}.md`.
74
+ - **Orçamento de teste**: um teste por cenário, um de regressão por bug; acima disso, uma linha de porquê. Cenários do mesmo comportamento são linhas de tabela (`[Theory]`/`it.each`); nenhum teste que só fixa texto. O `verify` avisa quando o teste passa de 1,5× a produção.
75
+
76
+ ```markdown
77
+ ## Cenários
78
+ - **C1** — Dado um tenant com `criterion_overrides`, quando ele é publicado, então a publicação é recusada nomeando a chave.
79
+ prova: teste
80
+ - **C2** — Nenhum arquivo em `tenants/**` contém a chave `criterion_overrides`.
81
+ prova: teste
82
+ > Por que artefato: a chave saiu do contrato; nenhum leitor de runtime a consulta.
83
+
84
+ ## Fatias
85
+ ### F1 — Recusar a chave na publicação
86
+ - persona: dotnet-senior
87
+ - standards: backend-dotnet-vsa-handler-patterns, backend-dotnet-testing, architecture-code-comments
88
+ - arquivos: src/Tenants/Publish.cs, tests/Tenants/PublishTests.cs
89
+ - cobre: C1, C2
90
+ ```
91
+
92
+ **Decisões** (`## Decisões`): uma `### ADR-001 — título` por decisão não trivial (alternativa descartada, motivo, quem decidiu), com `**Alcance:** feature` ou `projeto` — `projeto` quando vale além desta feature. Em projeto greenfield, a decisão que fixa stack, layout, infraestrutura ou test runner é `projeto`: a próxima feature a herda, e só o índice de ADRs a mostra. `### Conflitos com o acervo` existe sempre; "nenhum" vale. Proibição além das de `MORPH.md` § "Stack baked-in" é ADR.
93
+
94
+ **Arquitetura**: componentes, fluxo de dados, edge cases **técnicos** e integrações; não repita os cenários.
95
+
96
+ **Reuso**: tabela `| conceito | veredito | alvo | why |`, veredito `REUSAR` | `ESTENDER` | `CRIAR`. **`CRIAR` exige `why`** — a consulta que respondeu "não existe" (`graph explain X → not-found; grep -rn X → 0`). Conceito de duas features vai para um módulo comum, nunca import cruzado entre slices. O validador `reuse` do `verify` cobra: símbolo novo homônimo de um existente reprova na mesma feature e avisa entre features; `CRIAR` declarado rebaixa a aviso. Conceito sem fatia que o escreva: falta fatia ou o conceito não é desta feature — resolva antes do gate.
97
+
98
+ **Fatias** (`### Fn — título`): a unidade de entrega e de relatório (`3-implement/reports/Fn.md`).
99
+ - `persona:` obrigatório — o id sem `morph-`, cujo `domains` cobre a fatia (uma leitura de `agents.json`). Fatia que cria ou altera UI é `ui-designer`, mesmo sem o ramo de design; com `superfície:`, os standards são os daquela chave de `surfaces`.
100
+ - `standards:` — `morph-spec standards --find "<domínio>"` por domínio (o digest decide): os da persona mais o que a fatia exige, sempre `architecture-code-comments` e o de teste do stack; agente MAF soma `--category ai-agents`.
101
+ - `arquivos:` — os paths planejados, testes incluídos, **no máximo 8**: acima disso o sub-agente bate no teto de turnos.
102
+ - `depende:` opcional; `cobre:` lista os Cn — todo cenário é coberto por alguma fatia. Fatias sem `depende:` comum e sem arquivo em comum rodam em paralelo; o `plan-check` imprime as ondas.
103
+ - Cenário que se observa por um artefato de outra fatia (rota, endpoint, componente que ela cria) faz da fatia que o cobre um `depende:` daquela — senão as duas caem na mesma onda e o teste do cenário não tem por onde provar. O `plan-check` não vê de quem é a rota: a regra é sua.
104
+
105
+ **Contrato de implementação**: o que quem implementa precisa e o código não diz.
106
+ - **Verificação de runtime:** o stack sobe por `morph-spec e2e up {feature}` (compose do projeto; sem compose, isso é uma fatia); os fluxos que o verificador navega, nos verbos dos cenários; base URL `process.env.PLAYWRIGHT_BASE_URL ?? \`http://localhost:${process.env.PORT ?? 3000}\``, compose com `"${PORT:-3000}:3000"` e sem `container_name` (standard `infrastructure/docker/local-compose-isolation`). App com login: `e2e.auth` em `config.json` (`mode: seed|storageState|bypass|none`, `seedCommand`, `storageStatePath`, `envFile`), credenciais num `.env.e2e` gitignored — **`mode` é obrigatório sempre que houver `seedCommand`**, sem ele o seed fica inerte. Biblioteca pura: registre a dispensa e o porquê.
107
+ - **Baseline é um COMANDO, nunca um número.** O plano congela e é lido por dias: um número cravado está errado na primeira fatia, e quem confia nele "conserta" o que não quebrou. Registre como medir (`npm test`, `dotnet test`); o `expectedCount` sai de `morph-spec verify {feature} --record-baseline`, nunca digitado. Sem `project.stack`/`project.tests` no `config.json`, a `morph-apply` os declara a partir destes comandos antes do primeiro verify.
108
+ - **Pré-requisito é um PREDICADO, nunca um SHA literal:** "`git merge-base --is-ancestor origin/main HEAD` sai 0" — o SHA muda no primeiro squash.
109
+
110
+ Plano bom cabe em duas páginas; crescendo além, corte escopo. Feche com `morph-spec plan-check {feature}` até zero erro. Ele também recusa veredito de reuso fora do enum, id `C`/`F`/`ADR` duplicado, `## Errata` fora do fim, `## Cenários` vazio e fatia sem `persona:`; avisa chave de fatia desconhecida, superfície fora da `ui-designer`, ADR sem **Alcance**, fatia sem `cobre:` e mais de 12 fatias.
111
+
112
+ ## 6. Ramo de design
113
+
114
+ Critério objetivo, decidido **uma vez**, aqui: a feature cria ou altera superfície de UI (componente, página, tela, estilo, fluxo de navegação)? Sim → `morph-spec advance {feature} --design`, sempre por ele e nunca criando `1-design/` à mão: no gate auto-aprovado ele aprova `plan`; com o gate já aprovado pelo humano, só abre o ramo. Nos dois casos escreve `1-design/mockups.md` do template e, se faltar, `.morph/context/design-system.md`. Depois, `Skill(morph-uiux)`. Não → `morph-spec advance {feature}` leva a implement. Ninguém redecide adiante.
115
+
116
+ ## 7. Gate do plano
117
+
118
+ ```
119
+ morph-spec gate-check {feature} plan [--json]
120
+ ```
121
+
122
+ Divergência de design system ou violação de standard que o disco não vê entram por `--signals '{"designSystemDivergence":true,"standardsViolations":["<id>"]}'` (as únicas chaves aceitas). **Modo entrevista** pausa sempre, e `shouldPauseGate` não conhece isso — registre direto: `morph-spec gate-decision {feature} plan --pause true --reason "modo entrevista — entendimento compartilhado" --signals '{"discoveryMode":"interview"}'`. Outro risco que nenhuma chave representa: `gate-decision` também. Nunca edite `feature.json` à mão.
123
+
124
+ **`pause === true`**: apresente o entendimento compartilhado (problema, fora de escopo, cenários, fatias, riscos) e uma `AskUserQuestion`, header "Gate plano":
125
+
126
+ ```
127
+ question: "Gate do plano — Plano de {feature} aprovado?{ reason ? ' Sinal: ' + reason : '' }"
128
+ options: "aprovado, prosseguir" | "preciso ajustar" | "cancelar feature"
129
+ ```
130
+
131
+ A pergunta **nomeia a feature**: é por ela que o hook `state-sync` grava a aprovação; sem o nome, com mais de uma feature na árvore, ele recusa. O hook só aceita resposta que começa com "aprovado" ou contém "pode avançar", "pode implementar" ou "pode prosseguir" — "lgtm" não grava. Sem `AskUserQuestion` (headless): `morph-spec approve {feature} plan --approver <quem>`. "Preciso ajustar" → edite, `plan-check`, reapresente.
132
+
133
+ **`pause === false`**: resumo de 3 linhas (problema → solução; fatias e ondas; risco principal) e `morph-spec advance {feature}` (ou `--design`, §6).
134
+
135
+ **Congelamento:** aprovado o gate, o corpo do plan.md trava — fato errado sobre o código vai num bloco `## Errata` append-only no fim (não muda o `planHash`); `checks.json` só se regrava por `plan-check`. Mudança de escopo: `morph-spec unapprove {feature} plan`, editar, `plan-check`, reapresentar o gate.
136
+
137
+ ## 8. Deltas por tipo
138
+
139
+ - **`bug` (bug-lean):** a varredura roda inteira; a árvore é de repro, diagnóstico e comportamento do sistema, não de negócio; no modo automático, no máximo 1 pergunta de repro, e só se o pedido não deixar claro. `## Problema` traz repro, diagnóstico e causa provável; os cenários são o sintoma ausente e a regressão; `### Conflitos com o acervo` continua presente.
140
+ - **`chore`:** nasce com o gate `plan` carimbado por política. Escreva o plan.md curto numa única escrita (o gate já aprovado congela o arquivo depois de criado): `## Problema`, um ou dois cenários, `## Decisões` só com `### Conflitos com o acervo`, uma fatia. `plan-check` e `Skill(morph-apply)`.
141
+ - **`hotfix`:** é da `morph-hotfix`.
142
+
143
+ ## 9. Encerramento
144
+
145
+ Diga ao usuário: "Plano aprovado. Rode `/morph-apply {feature}` para implementar." Não despache a `morph-apply` — o usuário decide quando começar (exceção: `chore`).