@polymorphism-tech/morph-spec 8.43.0 → 8.45.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 (203) hide show
  1. package/CLAUDE.md +16 -13
  2. package/README.md +10 -10
  3. package/bin/morph-spec.js +10 -13
  4. package/bin/validate.js +379 -379
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +2 -4
  7. package/docs/QUICKSTART.md +6 -6
  8. package/framework/CLAUDE.md +6 -8
  9. package/framework/MORPH.md +39 -45
  10. package/framework/agents.json +8 -9
  11. package/framework/commands/morph-apply.md +1 -3
  12. package/framework/commands/morph-hotfix.md +1 -1
  13. package/framework/commands/morph-proposal.md +2 -2
  14. package/framework/docs/CLI.md +22 -17
  15. package/framework/evals/review-checklist.md +90 -0
  16. package/framework/evals/trace-schema.md +2 -12
  17. package/framework/hooks/README.md +2 -3
  18. package/framework/hooks/claude-code/core/heavy-gate.js +1 -1
  19. package/framework/hooks/claude-code/core/protect-spec-files.js +2 -2
  20. package/framework/hooks/claude-code/core/telemetry-log.js +2 -2
  21. package/framework/hooks/claude-code/core/trace-autogen.js +1 -22
  22. package/framework/hooks/claude-code/core/validate-completion.js +3 -56
  23. package/framework/hooks/claude-code/core/worktree-env-inject.js +1 -4
  24. package/framework/hooks/claude-code/statusline.sh +11 -11
  25. package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
  26. package/framework/hooks/git/pre-commit/agents.sh +25 -25
  27. package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
  28. package/framework/hooks/git/pre-commit/specs.sh +50 -50
  29. package/framework/hooks/git/pre-push/run-tests.sh +44 -44
  30. package/framework/hooks/shared/build-check.js +1 -1
  31. package/framework/hooks/shared/comment-scanner.js +1 -1
  32. package/framework/hooks/shared/phase-utils.js +0 -5
  33. package/framework/hooks/shared/stdin-reader.js +26 -26
  34. package/framework/phases.json +4 -6
  35. package/framework/rubrics/backend.json +1 -1
  36. package/framework/rubrics/default.json +1 -1
  37. package/framework/rubrics/frontend.json +1 -1
  38. package/framework/rules/ai-agents-standards.md +1 -0
  39. package/framework/rules/morph-workflow.md +6 -6
  40. package/framework/schemas/feature.schema.json +2 -28
  41. package/framework/schemas/tasks.schema.json +6 -2
  42. package/framework/skills/README.md +1 -2
  43. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  44. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  45. package/framework/skills/core/morph-apply/SKILL.md +145 -246
  46. package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
  47. package/framework/skills/core/morph-hotfix/SKILL.md +5 -3
  48. package/framework/skills/core/morph-implement/SKILL.md +101 -201
  49. package/framework/skills/core/morph-machine/SKILL.md +3 -3
  50. package/framework/skills/core/morph-media/SKILL.md +1 -1
  51. package/framework/skills/core/morph-plan/SKILL.md +171 -287
  52. package/framework/skills/core/morph-proposal/SKILL.md +4 -5
  53. package/framework/skills/core/morph-review/SKILL.md +109 -430
  54. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  55. package/framework/skills/core/morph-standards/SKILL.md +2 -2
  56. package/framework/skills/core/morph-uiux/SKILL.md +2 -3
  57. package/framework/standards/STANDARDS.json +54 -10
  58. package/framework/standards/ai-agents/agent-archetypes.md +1 -1
  59. package/framework/standards/ai-agents/agent-session.md +1 -1
  60. package/framework/standards/ai-agents/agent-spec.md +1 -1
  61. package/framework/standards/ai-agents/batching.md +1 -1
  62. package/framework/standards/ai-agents/context-providers.md +1 -1
  63. package/framework/standards/ai-agents/conversational-agent-with-phases.md +1 -1
  64. package/framework/standards/ai-agents/cost-and-budget.md +1 -1
  65. package/framework/standards/ai-agents/durable-workflows-hitl.md +1 -1
  66. package/framework/standards/ai-agents/guardrails.md +1 -1
  67. package/framework/standards/ai-agents/llm-runtime-defaults.md +1 -1
  68. package/framework/standards/ai-agents/mcp-server.md +1 -1
  69. package/framework/standards/ai-agents/mcp-tools.md +1 -1
  70. package/framework/standards/ai-agents/media-pipeline.md +1 -1
  71. package/framework/standards/ai-agents/media-video.md +1 -1
  72. package/framework/standards/ai-agents/middleware-patterns.md +1 -1
  73. package/framework/standards/ai-agents/modalities-image-gen.md +1 -1
  74. package/framework/standards/ai-agents/modalities-speech-to-text.md +1 -1
  75. package/framework/standards/ai-agents/modalities-text-to-speech.md +1 -1
  76. package/framework/standards/ai-agents/modalities-vision.md +1 -1
  77. package/framework/standards/ai-agents/multi-agent-patterns.md +1 -1
  78. package/framework/standards/ai-agents/observability-patterns.md +3 -3
  79. package/framework/standards/ai-agents/production.md +2 -2
  80. package/framework/standards/ai-agents/prompt-sources.md +1 -1
  81. package/framework/standards/ai-agents/providers/model-registry.md +1 -1
  82. package/framework/standards/ai-agents/rag-custom-pgvector.md +1 -1
  83. package/framework/standards/ai-agents/service-tier-flex.md +1 -1
  84. package/framework/standards/ai-agents/setup.md +1 -1
  85. package/framework/standards/ai-agents/structured-output.md +1 -1
  86. package/framework/standards/ai-agents/sweet-spot.md +1 -1
  87. package/framework/standards/ai-agents/testing-ai.md +1 -1
  88. package/framework/standards/ai-agents/tool-adapters.md +226 -0
  89. package/framework/standards/ai-agents/vector-data-extensions.md +1 -1
  90. package/framework/standards/ai-agents/workflows.md +1 -1
  91. package/framework/standards/infrastructure/docker/local-compose-isolation.md +11 -1
  92. package/framework/templates/CLAUDE.md.core.template +1 -1
  93. package/framework/templates/IDE-SNIPPETS.md +262 -262
  94. package/framework/templates/README.md +1 -1
  95. package/framework/templates/REGISTRY.json +0 -81
  96. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
  97. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
  98. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
  99. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
  100. package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
  101. package/framework/templates/docs/spec.md +19 -205
  102. package/framework/templates/docs/ui-components.md +52 -52
  103. package/framework/templates/docs/ui-design-system.md +76 -76
  104. package/framework/templates/docs/ui-flows.md +167 -167
  105. package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
  106. package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
  107. package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
  108. package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
  109. package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
  110. package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
  111. package/framework/templates/infrastructure/github/README.md +56 -56
  112. package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
  113. package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
  114. package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
  115. package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
  116. package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
  117. package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
  118. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
  119. package/framework/templates/state.template.json +17 -17
  120. package/framework/templates/ui/design-system.css +226 -226
  121. package/package.json +2 -2
  122. package/src/commands/e2e/e2e.js +1 -1
  123. package/src/commands/project/heavy.js +1 -1
  124. package/src/commands/project/status.js +3 -3
  125. package/src/commands/project/worktree.js +34 -16
  126. package/src/commands/state/approve.js +9 -50
  127. package/src/commands/state/finish.js +4 -0
  128. package/src/commands/state/gate-check.js +18 -107
  129. package/src/commands/state/gate-decision.js +1 -1
  130. package/src/commands/state/report-check.js +42 -17
  131. package/src/commands/validation/mutate.js +1 -1
  132. package/src/commands/validation/scout-check.js +28 -0
  133. package/src/commands/validation/validate-feature.js +5 -32
  134. package/src/commands/validation/verify.js +16 -25
  135. package/src/core/paths/output-schema.js +0 -2
  136. package/src/core/state/state-manager.js +1 -2
  137. package/src/core/templates/template-renderer.js +477 -477
  138. package/src/dashboard/app/lib/format.js +5 -0
  139. package/src/dashboard/app/main.jsx +13 -13
  140. package/src/dashboard/app/pages/FeatureDetail.jsx +16 -22
  141. package/src/dashboard/app/pages/Features.jsx +7 -7
  142. package/src/dashboard/app/pages/PhasePipeline.jsx +1 -1
  143. package/src/dashboard/app/pages/Rubrics.jsx +7 -11
  144. package/src/dashboard/scanner/docs-scanner.js +1 -2
  145. package/src/dashboard/scanner/features-scanner.js +3 -4
  146. package/src/dashboard/scanner/rubrics-scanner.js +12 -12
  147. package/src/dashboard/vite.config.js +24 -24
  148. package/src/lib/agents/output-collector.js +0 -1
  149. package/src/lib/detectors/design-system-detector.js +188 -188
  150. package/src/lib/e2e/compose-env.js +5 -2
  151. package/src/lib/evaluator-report.js +52 -334
  152. package/src/lib/generators/design-system-generator.js +508 -508
  153. package/src/lib/generators/handoff-generator.js +4 -5
  154. package/src/lib/git/evidence-staleness.js +39 -0
  155. package/src/lib/installers/memory-installer.js +2 -2
  156. package/src/lib/mutation/manifest.js +8 -2
  157. package/src/lib/mutation/report.js +5 -3
  158. package/src/lib/mutation/runner.js +9 -7
  159. package/src/lib/risk-detector.js +63 -125
  160. package/src/lib/scout/scout-check.js +293 -0
  161. package/src/lib/tasks/eval-node.js +4 -34
  162. package/src/lib/tasks/task-classifier.js +30 -30
  163. package/src/lib/tasks/task-parser.js +209 -209
  164. package/src/lib/tasks/tasks-json-parser.js +7 -5
  165. package/src/lib/tasks/test-nodes.js +1 -1
  166. package/src/lib/tasks/test-runner.js +1 -1
  167. package/src/lib/validators/contracts/contract-compliance-validator.js +4 -42
  168. package/src/lib/validators/css/css-validator.js +340 -340
  169. package/src/lib/validators/reuse/reuse-validator.js +6 -8
  170. package/src/lib/validators/verify-runner.js +1 -1
  171. package/src/lib/worktree/env-allocator.js +35 -5
  172. package/src/scripts/setup-infra.js +1 -1
  173. package/src/utils/agent-id-mapper.js +11 -11
  174. package/src/utils/agents-installer.js +5 -9
  175. package/src/utils/claude-settings-manager.js +300 -300
  176. package/src/utils/hooks-installer.js +3 -10
  177. package/src/utils/skills-installer.js +1 -1
  178. package/framework/evals/proof-rubrics/README.md +0 -76
  179. package/framework/evals/proof-rubrics/eval-de-modelo.md +0 -80
  180. package/framework/evals/proof-rubrics/fiacao.md +0 -54
  181. package/framework/evals/proof-rubrics/guard-cego.md +0 -52
  182. package/framework/evals/proof-rubrics/media-claims.md +0 -109
  183. package/framework/evals/proof-rubrics/mutation-proof.md +0 -107
  184. package/framework/evals/proof-rubrics/observabilidade-genai.md +0 -119
  185. package/framework/evals/proof-rubrics/verde-nao-e-coberto.md +0 -48
  186. package/framework/evals/rubrics/README.md +0 -45
  187. package/framework/evals/rubrics/architecture.md +0 -103
  188. package/framework/evals/rubrics/code-quality.md +0 -98
  189. package/framework/evals/rubrics/condensed.md +0 -57
  190. package/framework/evals/rubrics/contracts.md +0 -67
  191. package/framework/evals/rubrics/test-coverage.md +0 -99
  192. package/framework/evals/scenarios/dotnet-crud.yaml +0 -42
  193. package/framework/evals/scenarios/nextjs-auth.yaml +0 -38
  194. package/framework/evals/suites/standard.yaml +0 -5
  195. package/framework/hooks/claude-code/core/post-edit-typecheck.js +0 -127
  196. package/framework/skills/core/morph-eval/SKILL.md +0 -64
  197. package/framework/templates/.idea/morph-templates.xml +0 -92
  198. package/framework/templates/.vscode/morph-templates.code-snippets +0 -186
  199. package/framework/templates/docs/clarifications.md +0 -253
  200. package/framework/templates/docs/onboarding.md +0 -122
  201. package/framework/templates/docs/schema-analysis.md +0 -119
  202. package/framework/templates/docs/user-stories.md +0 -34
  203. package/src/commands/state/score.js +0 -147
@@ -4,7 +4,7 @@ description: Orquestra a fase de proposta+plano de uma feature morph-spec. Encad
4
4
  version: core
5
5
  when-to-invoke: ao receber instrução "use /morph-proposal" do usuário, ou ao iniciar uma nova feature
6
6
  user-invokable: true
7
- cliVersion: "8.43.0"
7
+ cliVersion: "8.45.0"
8
8
  ---
9
9
 
10
10
  # morph-proposal
@@ -112,8 +112,8 @@ Critério objetivo em `MORPH.md` §2.1: a mudança cria ou altera superfície de
112
112
  ### 5. Invocar `Skill(morph-plan)`
113
113
 
114
114
  A skill lê `proposal.md` e produz:
115
- - `spec.md` — especificação técnica detalhada
116
- - `mandate.md` — contrato de implementação (stack defaults + padrões proibidos)
115
+ - `usecases/UC-*.md` — o comportamento, com pós-condições testáveis
116
+ - `spec.md` — especificação técnica, com a seção `## Contrato de implementação`
117
117
  - `tasks.json` — task breakdown estruturado validado contra `.morph/framework/schemas/tasks.schema.json`
118
118
  - `decisions.md` — apenas se houver decisões não triviais
119
119
 
@@ -130,7 +130,7 @@ Mesma mecânica do passo 3: a decisão já foi tomada e persistida pela `morph-p
130
130
 
131
131
  - Não pular o Gate 1 mesmo em trust:auto se houver divergência detectada.
132
132
  - Não escrever código nesta fase — apenas artefatos de planejamento.
133
- - Não perguntar sobre stack — o stack padrão está em MORPH.md / mandate.
133
+ - Não perguntar sobre stack — o stack padrão está em MORPH.md.
134
134
  - Não rodar o pipeline completo de 5 fases num `chore` ou `bug` óbvio — o Passo 0 existe para dimensionar o trabalho pelo `workType`, não para ser pulado "para simplificar".
135
135
 
136
136
  ## Output esperado
@@ -138,7 +138,6 @@ Mesma mecânica do passo 3: a decisão já foi tomada e persistida pela `morph-p
138
138
  - `.morph/features/{feature}/0-proposal/proposal.md`
139
139
  - `.morph/features/{feature}/1-design/` (se o ramo uiux — passo 3a — foi tomado)
140
140
  - `.morph/features/{feature}/2-plan/spec.md`
141
- - `.morph/features/{feature}/2-plan/mandate.md`
142
141
  - `.morph/features/{feature}/2-plan/tasks.json`
143
142
  - Gates 1 e 2 registrados aprovados em `.morph/features/{feature}/feature.json` (autoritativo) — via `morph-spec approve`/`morph-spec advance` em auto, ou via hook state-sync no caminho manual.
144
143
 
@@ -4,455 +4,134 @@ description: Conduz a fase de revisão e produz o review-report.md para o Gate 3
4
4
  version: core
5
5
  when-to-invoke: ao iniciar a fase review, após todas as tasks de tasks.json estarem com status `done`
6
6
  user-invokable: true
7
- cliVersion: "8.43.0"
7
+ cliVersion: "8.45.0"
8
8
  ---
9
9
 
10
10
  # morph-review
11
11
 
12
12
  ## Objetivo
13
- Verificar se a implementação atende ao mandate.md e produzir um review-report.md
14
- claro o suficiente para que o usuário tome a decisão de aprovação ou rejeição.
13
+ Responder, com evidência, uma pergunta: **a entrega faz o que os use cases dizem, sem quebrar o que
14
+ já funcionava?** O Gate 3 decide por veredito (`SHIP`/`FIX`) e bloqueadores tipados — não por nota.
15
15
 
16
16
  ## Quando invocar
17
- Ao iniciar a fase review — após todas as tasks de `tasks.json` estarem com status `done`
18
- e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `morph-apply`.
17
+ Fase review, com todas as tasks `done` e o `recap.md` em dia. Normalmente chamada pela `morph-apply`.
19
18
 
20
- ## O que fazer
21
-
22
- 1. **Garanta que todos os artefatos de plano estão no seu contexto antes de revisar.** Se você não tem o conteúdo atual em contexto (sessão fresca, ou conteúdo possivelmente desatualizado), **use a tool Read para carregá-los** — não confie em cache de turnos anteriores que pode ter sido truncado ou evictado. Na dúvida, Read:
23
- - `.morph/features/{feature}/2-plan/mandate.md` — critérios de done, standards obrigatórios, patterns proibidos.
24
- - `.morph/features/{feature}/2-plan/spec.md` — arquitetura, FRs/NFRs, contratos esperados.
25
- - `.morph/features/{feature}/2-plan/decisions.md` (se existir) — ADRs que devem ter sido seguidos pela implementação. Use para validar coerência entre decisão registrada e código produzido.
26
-
27
- > O contrato é o conteúdo estar em contexto, não o número de chamadas a Read. Numa sessão quente onde você acabou de produzir esses artefatos, eles já estão disponíveis. Mas uma revisão sem o mandate em contexto não é uma revisão — é um chute. Nunca produza o review-report sem ter o mandate, spec e decisions disponíveis.
28
-
29
- 2. **Use a tool Read em `.morph/features/{feature}/3-implement/recap.md`**. Verifique se todas as tarefas têm entrada e se os problemas foram resolvidos.
30
-
31
- 3. Para cada critério do mandate.md, verifique se foi atendido:
32
- - Se atendido: registre como "aprovado" com evidência (arquivo ou comportamento).
33
- - Se não atendido: registre como "bloqueante" com descrição do gap.
34
- - Se parcialmente atendido: registre como "pendência" com o que falta.
35
-
36
- **Verificações mecânicas sempre-rodar** (independente do mandate mencionar ou não — cobrem bugs
37
- reais já vistos em produção, ver `.morph/framework/evals/rubrics/architecture.md` → "Verificações
38
- mecânicas obrigatórias"), quando o diff tocar endpoints minimal API ou fetch cross-camada:
39
- - Todo serviço injetado numa lambda de endpoint tem `AddScoped`/`AddSingleton`/`AddTransient`
40
- correspondente em `Program.cs`. Falha aqui é bloqueante — a app não sobe.
41
- - Se há chamada server-direct ao backend e chamada client-side via proxy para o mesmo recurso,
42
- confirme que usam duas constantes de prefixo nomeadas distintas, nenhuma reusada para o
43
- outro propósito. Falha aqui é bloqueante — quebra silenciosa em runtime, não em build.
44
-
45
- 4. **Antes de despachar, verifique se já existe um relatório íntegro** — inclusive em sessão
46
- retomada. **Esta verificação NÃO é pulada porque a sessão foi retomada** — é exatamente esse o
47
- cenário que já mordeu em produção: 4 sessões retomadas re-despacharam o avaliador do Gate 3 sem
48
- nunca ler o `evaluator-report.md` que já existia, íntegro, desde o 1º dispatch (`APPROVED`, score
49
- 9.3) — e a 4ª sessão chegou a afirmar, falsamente, que "o avaliador nunca rodou". `SessionStart:
50
- resume`/`init` não reseta este passo: ele roda sempre, a cada retomada de controle, antes de
51
- cogitar um dispatch.
52
- - Rode `morph-spec report-check {feature} --json` (sem `task`, modo feature inteira) e leia o
53
- campo `evaluator` da resposta — ou, equivalente, leia `4-review/evaluator-report.md` direto e
54
- confira: scores por dimensão presentes + a linha `**Composite-Score:**` presente = **íntegro**.
55
- - **Se íntegro** (`evaluator.exists && evaluator.complete`): **NÃO despache de novo.** Pule direto
56
- para "**Leia primeiro**" logo abaixo — leia o arquivo e siga para o passo 5 (síntese do
57
- review-report a partir dele). Re-despachar aqui joga fora um veredito de Gate 3 já válido.
58
- - **Se ausente, oco, ou sem scores por dimensão:** este é exatamente o caso de falha de protocolo
59
- que este passo trata — prossiga com o dispatch abaixo.
60
- - **Se `PARCIAL` na 1ª linha** (`evaluator.partial: true` no `report-check`): o avaliador anterior
61
- parou no limite de turnos — não é ausente nem oco. Antes de um dispatch frio, siga o bullet
62
- `PARCIAL` do "Leia primeiro" abaixo: continuar quem já provou metade custa menos que refazer a
63
- rodada.
64
-
65
- **Despache o avaliador independente** — o score do Gate 3 nunca é auto-atribuído por quem implementou:
66
- - Rode `morph-spec verify {feature} --json` (escopo feature; exit 3 / `status: "busy"` é fila de slot pesado cheia, não vermelho: repita a chamada) e capture o JSON — é a saída real de build+testes+validadores+e2e que você anexa ao prompt do avaliador independente (`morph-evaluator`). **Sem `--filter`, sempre:** o `--filter` é do loop por task, onde o relógio de uma task não paga a suíte inteira; a prova que o avaliador lê tem de cobrir **todos** os nós de `nodes.tests.runs[]` (uma suíte filtrada aparece como `skip` nomeando o filtro — Gate 3 aberto sobre isso é verde sobre código não testado). Se a suíte inteira não couber numa chamada, rode-a em background; não a encolha com `--filter`. `verify {feature}` (sem task) **nunca recorta** — o recorte automático é só do escopo de task —, e um `verify {feature} --filter …` nem persiste o stamp (`persisted: false`, `reason: 'filtered'`) — o mesmo vale para `--skip-tests`/`--skip-build` no escopo de feature. Rode-o **depois** da última task: o `gate-check {feature} review` pausa quando o último stamp `verification` é de escopo `task:{id}`, porque aquela rodada cobriu só a task. Uma rodada por árvore: se o JSON vier com `repeatOf`, nada mudou fora de `.morph/` desde o verify de feature anterior — use aquele resultado em vez de rodar de novo; depois de uma correção a árvore mudou, e a nova rodada é a prova.
67
- - **Confira o nó `e2e` do verify antes de despachar.** Ele carrega o estado do stack:
68
- - `pass` → a aplicação subiu e está saudável; o avaliador pode navegá-la. **Passe a URL no prompt**
69
- — cada feature roda no seu bloco de portas, não em `localhost:3000`; pegue de
70
- `morph-spec e2e status {feature} --json` (`baseUrl`) e não deixe o avaliador adivinhar.
71
- - `fail` → **não abra o Gate 3.** Volte ao loop de correção: a app não sobe, ou as specs quebraram.
72
- - `skip` → **a classificação já é do `gate-check`, não sua.** A razão literal do skip viaja no
73
- stamp `verification` (`e2eReason`) e `classifyE2eSkip` — em `risk-detector.js`, fonte única —
74
- decide: `project` ("não containeriza") e `scope` ("o grupo de tasks não toca runtime") são
75
- **dispensa legítima** e passam com o motivo gravado em `gateDecisions.review.signals`;
76
- `environment` ("docker indisponível"), `requested` (`--skip-e2e`) e `unknown` (qualquer outra
77
- razão, **inclusive razão nenhuma**) **pausam o Gate 3 sozinhos**. Não registre `gate-decision`
78
- à mão para esses casos — deixou de ser necessário. O que continua sendo seu: dizer ao avaliador
79
- que a app **não** foi exercida, e atacar a causa (rodar o e2e onde ele possa rodar) em vez de
80
- despachar como se ela tivesse sido.
81
- - **Confira também `traceability.warnings`** (advisory, nunca faz `verify` falhar): cada entrada é
82
- um arquivo citado no `recap.md` sem task dona em `outputs` — repasse ao avaliador como sinal de
83
- rastreabilidade para a dimensão de qualidade, não como bloqueio automático do gate.
84
- - **Anexe o `reuse-map.md`** (`.morph/features/{feature}/2-plan/reuse-map.md`), quando existir: é o
85
- que o plano decidiu por conceito (REUSAR/ESTENDER/CRIAR) e o único insumo que permite ao
86
- avaliador julgar a dimensão `code-quality` **contra o codebase**, não só contra o diff — símbolo
87
- recriado não aparece no diff como problema. Junto dele, repasse os achados do validador `reuse`
88
- do nó `validators` do verify. Sem `reuse-map.md` (plano anterior a este passo), diga isso ao
89
- avaliador em vez de deixá-lo supor que não havia conceito a reusar.
90
- - **Anexe as evidências de runtime** (`.morph/features/{feature}/3-implement/evidencias/*.md`),
91
- quando existirem — insumo, não veredito. São o que as tasks de critério sobre saída de LLM
92
- gravaram rodando o eval (`morph-plan` §5); não confunda com `3-implement/reports/`, que diz o
93
- que o sub-agente fez.
94
- - Gere o **diff da implementação** (`git diff` do range da feature, ou a lista de arquivos do recap.md com seus conteúdos atuais).
95
- - **Blast radius dos símbolos do diff (se houver grafo).** Para cada símbolo público que o diff tocou, rode `morph-spec graph affected <símbolo> --prod --json` e inclua o resultado no contexto do avaliador. É o que permite perguntar *"o que esta mudança pode ter quebrado FORA do diff"* sem que o avaliador leia o repositório inteiro. **Fallback:** `no-graph`, `not-found` ou `ambiguous` — siga sem o blast radius e **registre a ausência na seção de método do review-report**; o gate não depende disso. **Trate o resultado como possivelmente stale:** o refresh automático só cobre a raiz. Numa worktree o grafo é o semeado da raiz e não vê o que o diff trouxe — com `graph status --json` stale e `refresh.auto: false`, rode `morph-spec graph refresh` antes do blast radius; na raiz, enquanto o refresh em background corre (`refresh.running`), o grafo ainda é o anterior. E lembre que em frontend ele responde "quem importa", não "quem chama".
96
- - **Tire a foto da árvore imediatamente antes do dispatch:** `morph-spec report-check {feature} --before-eval --json`, depois do verify e de qualquer correção sua. É contra ela que a higiene abaixo prova que o avaliador reverteu o que mutou.
97
- - Despache o subagent registrado `morph-evaluator` (gerado de `agents.json` — a persona do avaliador é o system prompt dele, com Read/Glob/Grep + Bash somente para verificação + Playwright para navegar, sem Write/Edit), com contexto fresco:
98
- ```
99
- dispatch Agent (subagent_type: "morph-evaluator") with prompt:
100
- contexto: mandate.md + spec.md + reuse-map.md + diff da implementação
101
- + saída real dos testes + nó e2e do verify (stack no ar? em qual URL?)
102
- + 3-implement/evidencias/*.md (quando existir)
103
- + 1-design/mockups.md (quando existir — o checklist de tela a conferir)
104
- instrução: |
105
- Você NÃO participou da implementação — avalie o que está no diff,
106
- contra o mandate. NÃO leia `4-review/evaluator-report.md` neste
107
- caminho antes de escrever o seu: se esse arquivo já existir quando
108
- você começar, é resíduo de uma tentativa anterior — NÃO é insumo,
109
- é o SEU caminho de escrita, não de leitura. Sua nota nasce do
110
- mandate + spec + diff + testes, nunca do veredito de outro
111
- avaliador; ler o relatório de um antecessor antes de pontuar é
112
- ancoragem — exatamente o que "contexto fresco" existe para evitar.
113
- Você tem Bash: use `morph-spec verify`, testes/build
114
- do stack e `git log/diff/show` para conferir por conta própria o que
115
- foi reportado, em vez de confiar cegamente. Aplique as rubricas em
116
- .morph/framework/evals/rubrics/ (architecture 30%, contracts 25%,
117
- code-quality 25%, test-coverage 20%) seguindo as bandas 0-10 de cada uma.
118
- Se o nó e2e subiu o stack, NAVEGUE a aplicação com Playwright e
119
- percorra os fluxos desta feature como um usuário faria — ler o diff
120
- prova que o código existe, usar a aplicação prova que ela funciona.
121
- Confira console e network atrás de erro que teste nenhum cobriu.
122
- Registre no relatório o que você navegou e o que viu. Se um fluxo que
123
- você exercitou merece virar regressão, RECOMENDE a spec Playwright —
124
- recomendar é seu papel, escrever a spec não é.
125
- NÃO suba nem derrube o stack por conta própria (`morph-spec e2e` e o
126
- nó de verify fazem isso): stack que não sobe é achado de INFRA a
127
- reportar, não defeito de implementação a pontuar.
128
- NÃO reescreva código. NÃO toque em tasks.json, feature.json nem no board
129
- de sessão — Bash é só para verificação, nunca para mudar estado.
130
- Se o que você avalia é uma CORREÇÃO (rodada do loop, fix de achado
131
- anterior), responda no relatório: O QUE ESTA CORREÇÃO ABRIU? Que
132
- comportamento antes correto pode ter regredido, e há teste que
133
- pegaria? Um fix que fecha um defeito e abre outro pontua alto em toda
134
- dimensão e ainda assim piorou o produto — e essa pergunta é a única
135
- que o score não faz sozinho. Não aceite "agora tem teste" como
136
- fechamento: RE-EXECUTE os probes da rodada anterior.
137
- PROCURE O QUE ESTÁ ERRADO — não confirme o que já foi dito.
138
- Um relatório que só concorda com o recap não avaliou nada. A
139
- pergunta que orienta a sua sessão inteira é: O QUE O IMPLEMENTADOR
140
- NÃO VIU? O que ele não podia ver do lugar onde estava, o que ele
141
- viu e não mediu, e o que ele mediu com a régua errada.
142
- PROVE, não confie: um teste verde prova que o código RODA, nunca
143
- que o teste MORDE. Aplique as cinco rubricas de PROVA e pontue-as
144
- 0-10 (elas NÃO são dimensões do composto; impõem teto em
145
- test-coverage):
146
- .morph/framework/evals/proof-rubrics/mutation-proof.md
147
- .morph/framework/evals/proof-rubrics/verde-nao-e-coberto.md
148
- .morph/framework/evals/proof-rubrics/fiacao.md
149
- .morph/framework/evals/proof-rubrics/guard-cego.md
150
- .morph/framework/evals/proof-rubrics/eval-de-modelo.md
151
- Para a eval-de-modelo: se existir
152
- `.morph/features/{feature}/3-implement/evidencias/`, LEIA antes de pontuar `eval`:
153
- confronte o veredito com a saída registrada, e degrade o cenário que a
154
- evidência aponta. Evidência é insumo, não veredito.
155
- E, SÓ quando a feature chama LLM, mais uma — que impõe teto em
156
- code-quality, não em test-coverage:
157
- .morph/framework/evals/proof-rubrics/observabilidade-genai.md
158
- A aplicabilidade dela NÃO é determinística, e isso é deliberado:
159
- nenhuma leitura de tasks.json ou do mandate mede "esta feature
160
- chama um modelo". São DUAS etapas. (1) FILTRO mecânico, de alta
161
- recall: o mandate.md cita ao menos um standard ai-agents — falso
162
- ⇒ `not_evaluated`, sem mais discussão. (2) DETERMINAÇÃO sua, por
163
- escrito: a feature entrega código que CHAMA um modelo? Registre a
164
- resposta COM O MOTIVO (o símbolo/arquivo que chama, ou por que o
165
- diff não chama nada). Task com group em {docs, tests} é INDÍCIO
166
- contra, nunca veredito — um harness de agente vive inteiro em
167
- `tests`. `not_evaluated` NÃO aplica teto, e um not_evaluated MUDO
168
- não é dispensa: é o escape que o standard ai-agents-guardrails
169
- proíbe (standard, não rubrica — não existe rubrica de guardrails).
170
- Ela pergunta a PROPRIEDADE ("dá para reconstruir o que foi
171
- ao provedor, e o que ele respondeu, neste turno?"), nunca "tem span
172
- OpenTelemetry?": telemetria própria COM teste de fidelidade alcança
173
- 9-10 igual, e wiring sem evidência capturada não passa de 8.
174
- MUTAÇÃO — o método, e a ordem dele importa:
175
- - COMMITE O FIX ANTES DE MUTAR. Se a sessão morrer no meio, o
176
- que sobrevive é a mutação, não a correção.
177
- - VOCÊ ESCOLHE os mutantes: ancore no CALL SITE que carrega a
178
- decisão, não no `if` refatorado. Uma rodada POR CLÁUSULA de um
179
- predicado composto — cada cláusula é um mutante próprio.
180
- - ESCREVA `.morph/features/{feature}/4-review/mutants.json`:
181
- {"mutants":[{"id":"M1","file":"src/x.cs","line":42,
182
- "find":"a && b","replace":"a"}]}. `find` começa na `line` e é
183
- único nela; arquivo:linha, diff e md5 saem da ferramenta.
184
- Com a ferramenta Write, se você a tem; só com Bash, heredoc
185
- de delimitador entre aspas simples. O transporte do Bash
186
- reduz `\\` a `\` e decodifica escapes unicode, então escreva
187
- cada barra invertida do código como `{{BS}}` (a ferramenta a
188
- expande): atravessa qualquer transporte. `find` que deixa de
189
- bater com o arquivo é recusado com o erro, nunca aplicado.
190
- - RODE `morph-spec mutate {feature}` UMA vez, com o Bash. Ela
191
- faz o lote inteiro: um build só (chaves por variável de
192
- ambiente; o que a chave não compila cai para rebuild real),
193
- subconjunto de testes primeiro — escolhido por ela, não por
194
- você — e, para CADA sobrevivente, o mutante compilado de
195
- verdade contra a suíte INTEIRA. Só esse caminho produz
196
- "sobreviveu"; "derruba K de M" sempre diz o escopo do K
197
- (≥K no subconjunto, K na suíte inteira); na suíte inteira a
198
- falha tem de se repetir, senão é instabilidade e o mutante
199
- sobrevive. Sem a ferramenta,
200
- mute e rode a suíte INTEIRA à mão, um mutante por vez.
201
- - LEIA O MOTIVO da falha, não só o md5: md5 prova que ALGO
202
- mudou, jamais O QUÊ. Falha de build não é morte, e
203
- `inconclusive` não conta como nada.
204
- - A REVERSÃO é da ferramenta: bytes do snapshot com md5
205
- conferido, por escrita NOVA, rebuild forçado e a DLL final
206
- igual (md5) à construída antes do 1º mutante. NUNCA `os.utime`
207
- para devolver o mtime: o MSBuild acha o binário do último
208
- mutante em dia e a rodada-base roda sobre ele. NUNCA
209
- `git checkout --`: ele descarta trabalho não commitado de
210
- outra pessoa — aconteceu de verdade num Gate 3 desta epic.
211
- Rodada que morreu no meio: `morph-spec mutate --restore`.
212
- - TERMINE com `git status --porcelain src/` VAZIO e exit 0. Exit
213
- 4 é inseguro (arquivo não restaurado, árvore ou binário
214
- diferentes): resolva antes de pontuar.
215
- Cole no relatório a seção `## Mutações` que a ferramenta imprime
216
- (ela também a grava em `4-review/mutation-section.md`), uma linha
217
- por mutação, com os CINCO campos: arquivo:linha | diff | md5
218
- antes/depois | quantos testes derrubou (com o escopo) | o MOTIVO
219
- literal da falha. Feature sem código de produção declara a seção
220
- com a linha `não aplicável — feature sem código de produção`. A
221
- seção é OBRIGATÓRIA: sem ela o `morph-spec gate-check` PAUSA o
222
- Gate 3 sozinho, e nenhum score alto compra a passagem.
223
- MÍDIA GERADA — rubrica CONDICIONAL, aplique SÓ se a feature gera
224
- mídia (alguma task de tasks.json cita, em standards[], um destes:
225
- standards/ai-agents/modalities-image-gen.md,
226
- standards/ai-agents/media-video.md,
227
- standards/ai-agents/media-pipeline.md). Nesse caso aplique também
228
- e pontue 0-10:
229
- .morph/framework/evals/proof-rubrics/media-claims.md
230
- Ela cobra QUATRO afirmações — custo, revisão humana, marcação e
231
- hot path não bloqueado — cada uma com o código que a prende e o
232
- teste que a prova. Grave a seção `## Mídia gerada` com uma linha
233
- por afirmação. A seção é OBRIGATÓRIA nessa condição: sem ela o
234
- `morph-spec gate-check` PAUSA o Gate 3. Feature que NÃO gera mídia
235
- não declara a seção nem a chave — a isenção é automática, e
236
- escrever a seção "por precaução" é cerimônia vazia.
237
- CHECKLIST DE TELA — CONDICIONAL, aplique SÓ se
238
- `.morph/features/{feature}/1-design/mockups.md` existe com telas
239
- `## Tela:`. Para cada tela, confira cada item decidido do seu
240
- `### Checklist de tela` (volume, paginação, ordenação, filtro, os
241
- três estados, mobile, abas) contra a tela ENTREGUE — navegando
242
- quando o stack subiu, lendo o código quando não (a query pagina e
243
- ordena no servidor? o estado vazio existe?). Grave a seção
244
- `## Checklist de tela`, uma linha por item decidido de cada tela:
245
- | Tela | Item | Mockup (planejado) | Entregue (observado) | Veredito |
246
- com o nome da tela como está no mockup e veredito cumpre / diverge
247
- / não verificável (com o motivo). Itens "não se aplica" e a
248
- Superfície não precisam de linha. Divergência pesa em CONTRATOS
249
- (.morph/framework/evals/rubrics/contracts.md, "Contrato de tela").
250
- Sem a seção, ou com item decidido sem linha, o `morph-spec
251
- gate-check` PAUSA o Gate 3.
252
- Grave também a linha literal, machine-readable:
253
- `**Proof-Scores:** mutation={n} verde={n} fiacao={n} guard={n} eval={n}`
254
- — os cinco 0-10, na ordem das rubricas acima. O MENOR deles
255
- impõe o teto em test-coverage (tabela em
256
- .morph/framework/evals/rubrics/test-coverage.md).
257
- Se a feature gera mídia, acrescente ` media={n}` à MESMA linha.
258
- Se a rubrica de observabilidade GenAI se aplicar, acrescente
259
- ` obs={n}` (ou ` obs=not_evaluated`) à MESMA linha.
260
- As duas são lidas À PARTE: NÃO entram no mínimo acima (um media ou
261
- um obs baixo não pode derrubar o teto de teste por um motivo que
262
- não é de teste). `media` impõe teto em ARQUITETURA (tabela em
263
- .morph/framework/evals/rubrics/architecture.md) e `obs` impõe teto
264
- em CODE-QUALITY (tabela em
265
- .morph/framework/evals/rubrics/code-quality.md).
266
- Contrato do relatório final: GRAVE seu relatório em
267
- `.morph/features/{feature}/4-review/evaluator-report.md` ANTES de
268
- encerrar — esse arquivo é o valor de retorno autoritativo desta
269
- sessão. A sua última mensagem de texto é cortesia best-effort: pode
270
- não chegar inteira ao orquestrador (o evento recebido às vezes é só
271
- um idle_notification, sem texto). Ainda assim NÃO chame SendMessage:
272
- ele gera um evento a mais além da notificação de término, custando
273
- um turno inútil ao orquestrador.
274
- Limite de turnos: se chegar a ~70% dele sem terminar, grave o
275
- relatório com `PARCIAL` na 1ª linha e SEM `**Composite-Score:**`
276
- (o que já provou, o que falta) — o gate-check leria o token como
277
- final. Ao concluir, o relatório final substitui o parcial.
278
- Seu relatório (no arquivo, e na mensagem final quando ela chega)
279
- deve conter: score 0-10 por dimensão, score composto (arch×0.30 +
280
- contracts×0.25 + quality×0.25 + tests×0.20) gravado TAMBÉM como a
281
- linha literal `**Composite-Score:** {n.n}` (machine-readable — o
282
- `morph-spec gate-check` lê o score real daí em vez do proxy de
283
- taskScores), feedback priorizado (bloqueantes primeiro) para
284
- qualquer dimensão < 9, e — quando o stack estava no ar — o que você
285
- navegou e o que observou. Relatório ausente, oco, ou sem esses itens,
286
- é falha de protocolo.
287
- ```
288
- - **Fallback (tipo não registrado):** se `morph-evaluator` não estiver na sua lista de subagent types, despache `general-purpose` colando o campo `persona` do agente `evaluator` (Read em `.morph/framework/agents.json`) no topo do prompt — e **registre o fallback no review-report** (seção de método).
289
- - **Ao retomar o controle, HIGIENE DA ÁRVORE antes de qualquer leitura de score.** ANTES de
290
- abrir o relatório, rode `morph-spec report-check {feature} --json`. A foto que o
291
- `--before-eval` gravou antes do dispatch fica em `4-review/`, e é contra ela que o bloco `tree`
292
- compara, em qualquer sessão — inclusive a que retoma depois de o avaliador morrer no meio:
293
- - `tree.sinceBeforeEval.changed` vazio = o conteúdo de todo arquivo fora de `.morph/` é o de
294
- antes do dispatch, e o avaliador reverteu o que mutou. Com arquivos listados, a mutação
295
- ficou no disco (ou foi commitada) nesses arquivos;
296
- - `tree.markers` vazio = nenhum marcador `MUTACAO` esquecido;
297
- - `tree.sinceBeforeEval` `null` = não há foto (dispatch anterior a ela): confira cada arquivo
298
- da seção `## Mutações` contra o md5 "antes" registrado; `tree` `null` = o git não respondeu,
299
- e nada foi conferido.
300
-
301
- Não tire a foto de novo antes desta higiene passar: a foto nova apagaria a prova da anterior.
302
-
303
- **Por que antes:** o avaliador
304
- muta código de produção de propósito, e um avaliador que morreu no meio da rodada deixa a
305
- mutação NO DISCO. Ler o score primeiro e só depois descobrir a árvore suja significa ter
306
- avaliado — e possivelmente aprovado — um estado que ninguém quis. E **não rode build/teste
307
- enquanto o agente ainda está `running`**: ele muta o disco a meio, e o vermelho que você veria
308
- seria da mutação dele, não do produto.
309
-
310
- Árvore suja aqui é **falha de protocolo**. Reverta **pela mesma disciplina que o prompt exige
311
- do avaliador** — nunca por git: peça o snapshot que ele diz ter feito (`cp` ANTES de mutar) e
312
- restaure por cópia, conferindo `md5sum` de cada arquivo. Sem snapshot recuperável, o caminho é
313
- desfazer a edição **linha a linha**, a partir do `diff` que a seção `## Mutações` obriga a
314
- registrar. Registre o que fez na seção de método do review-report.
315
-
316
- > **NUNCA `git checkout -- src/` aqui**, nem com ressalva. Na árvore típica de uma feature em
317
- > review **não existe nenhum commit da feature** — o trabalho inteiro está não commitado, e o
318
- > `checkout` o apaga junto com a mutação. Numa árvore desta epic havia 23 arquivos modificados
319
- > e zero commits próprios; nesta mesma epic um avaliador rodou esse comando e destruiu
320
- > alterações não commitadas de outro agente (só não houve perda porque ele tinha capturado o
321
- > diff antes). É a mesma proibição que o prompt do passo 4 já dá ao avaliador: aqui ela vale
322
- > para VOCÊ.
323
- - **Leia primeiro** `.morph/features/{feature}/4-review/evaluator-report.md` — é o valor de retorno autoritativo, não a mensagem de texto do dispatch (que é cortesia, útil só quando chega inteira). Os scores por dimensão e o composto do review-report vêm **desse arquivo**, não da sua auto-avaliação. Se o arquivo vier ausente, oco, ou sem os scores por dimensão, registre a falha de protocolo na seção de método do review-report e re-despache.
324
- - Com o relatório lido, rode `morph-spec worktree reap --json`: a árvore do avaliador que parou limpa sai sozinha; a que ficou com trabalho vem listada com a razão.
325
- - **`PARCIAL` na 1ª linha = o avaliador parou antes do fim** (limite de turnos; o `report-check` devolve `evaluator.partial: true`). Não leia score dele — o parcial não tem `**Composite-Score:**`, e o `gate-check` pausaria de qualquer jeito — e não re-despache frio: um avaliador novo refaz a rodada inteira (probes, mutações, navegação). Retome o MESMO avaliador por `SendMessage`, como no passo 6, colando `tree.dirty` e `tree.commits` do `report-check` no recado; ele completa o relatório, e o final substitui o parcial. Só se o id não retomar, despache um novo pelo caminho normal — o parcial no disco é resíduo, não insumo, como o prompt já diz. Antes de qualquer das duas, a higiene da árvore acima continua valendo: um avaliador cortado no meio pode ter deixado mutação no disco.
326
-
327
- 5. Produza `review-report.md` em `.morph/features/{feature}/4-review/` com:
328
- - **`**Reviewed-SHA:** {git rev-parse HEAD}`** — o commit que você revisou, **obrigatório**.
329
- Um review revisa uma ÁRVORE, e a árvore anda: sem esse carimbo, um relatório escrito antes
330
- da última task fica no repo afirmando números e cobertura que já não valem. O
331
- `morph-spec approve {feature} review` compara o carimbo com o HEAD e **recusa** se divergirem
332
- (aconteceu de verdade: relatório de `b30ac6e` sobrevivendo à T3, que inverteu o default de
333
- uma regra de negócio, e ainda dizendo `976/976` quando eram 982).
334
- - Scores por dimensão (arquitetura, contratos, qualidade, cobertura)
335
- - Score composto final
336
- - **Verificação de runtime** — o resultado do nó `e2e` (`pass`/`fail`/`skip` + razão), e o que o
337
- avaliador navegou. Dispensa (`skip`) entra aqui **por extenso**: o valor de um gate está tanto
338
- no que ele provou quanto no que ele deixou de provar, e uma dispensa silenciosa se lê como
339
- aprovação. Se houver spec Playwright recomendada pelo avaliador, liste-a como melhoria.
340
- - **Prova de mutação** — a seção `## Mutações` do `evaluator-report.md`, repassada aqui em
341
- resumo (quantas mutações, quantas derrubaram teste, e a linha `**Proof-Scores:**`). O formato
342
- que o avaliador grava, e que o `morph-spec gate-check` cobra:
343
-
344
- ```markdown
345
- ## Mutações
346
-
347
- | # | Arquivo:linha | Mutação (diff) | md5 antes | md5 depois | Testes derrubados | Motivo da falha |
348
- |---|---|---|---|---|---|---|
349
- | M1 | src/lib/x.js:42 | `- if (a && b)` / `+ if (a)` | abc… | def… | ≥3 de 212 (subconjunto) | `expected 3 got 0` em x.test.js:88 |
350
- | M2 | src/lib/y.js:7 | `- return ok` / `+ return true` | 123… | 456… | 0 de 2684 (SOBREVIVEU, suíte inteira) | nenhum teste falhou na suíte inteira |
351
-
352
- **Reversão:** snapshot/restore de bytes por escrita nova; DLL final igual (md5); `git status --porcelain src/` vazio.
353
- **Proof-Scores:** mutation=9 verde=8 fiacao=9 guard=7
354
- ```
355
-
356
- Feature sem código de produção declara a seção com `não aplicável — feature sem código de
357
- produção`. **Sem a seção, o `gate-check review` PAUSA** — a regra vive em código
358
- (`risk-detector.js`), não na boa vontade do prompt.
359
- - **Checklist de tela** (feature com `1-design/mockups.md`) — a seção `## Checklist de tela` do
360
- `evaluator-report.md` em resumo: quantas telas e itens conferidos, e cada `diverge` por extenso
361
- (tela, item, planejado × entregue). Sem ela, havendo item decidido a conferir, o `gate-check review` **pausa** — o design decidiu
362
- como a tela pagina, ordena e falha, e o Gate 3 registra se a tela entregue cumpre.
363
- - Lista de itens bloqueantes (se houver) — com descrição e critério de resolução
364
- - Lista de melhorias recomendadas (não bloqueantes)
365
- - Recomendação final: Aprovado / Rejeitar com condições / Reprovar
19
+ ## Ritmo
20
+ - Comando em **primeiro plano**, com timeout. O único que pode passar do teto de 10 min do Bash é o
21
+ `verify {feature}` de um projeto grande: aí rode-o com `run_in_background` e espere a notificação
22
+ de término. Nunca `sleep`/`until` consultando um processo: a espera custa a máquina e não produz prova.
23
+ - **Bloqueio de ambiente não é laço.** Memória baixa, slot pesado ocupado (`verify` exit 3 /
24
+ `status: "busy"`), Docker fora: tente **uma** vez mais. Persistiu, siga com o que tem — o
25
+ `gate-check` pausa com a razão e o humano decide. Nunca agende retentativas.
366
26
 
367
- 6. Se houver itens bloqueantes (score < 8 em qualquer dimensão bloqueante), corrija antes
368
- de apresentar o review-report.md ao usuário. Não abra o Gate 3 com bloqueantes em aberto.
369
- (A barra de avanço por task é 9; uma dimensão individual abaixo de 8 no review da feature
370
- inteira é um bloqueante crítico que o loop de correção deveria ter pego.)
371
-
372
- **Para CONFIRMAR uma correção, retome o MESMO avaliador — não despache um frio.** Use
373
- `SendMessage` com o id do agente que já avaliou, colando no recado `tree.dirty` e `tree.commits`
374
- do `report-check {feature} --json` — o que mudou desde o relatório dele. Antes do recado, tire a foto de novo (`--before-eval`): suas correções mudaram a árvore, e a próxima higiene compara com a árvore que ele vai receber. Ele já tem em contexto o que apontou e
375
- os probes que rodou; um avaliador novo re-descobre o produto inteiro para checar um item, e
376
- re-executa do zero os probes da rodada anterior.
377
-
378
- > Isto **não** contradiz a cláusula que proíbe o **sub-agent** de chamar `SendMessage`. As
379
- > direções são opostas: o sub-agent não chama `SendMessage` porque o retorno dele é o ARQUIVO, e
380
- > uma mensagem a mais custa um turno inútil ao orquestrador. Aqui quem fala é o ORQUESTRADOR,
381
- > para dentro de uma sessão que ele mesmo abriu — a única forma de continuar uma avaliação em vez
382
- > de recomeçá-la. Se o agente já encerrou e o id não retoma, aí sim despache um novo, e diga a
383
- > ele no prompt que é uma REAVALIAÇÃO (o relatório é append-only: ele acrescenta ao fim, e o
384
- > `gate-check` lê o token do FIM, o vigente).
385
-
386
- 7. **NÃO finalize o trace manualmente.** O hook `trace-autogen` gera e finaliza `.morph/traces/YYYY-MM-DD-{feature}-implement.json` automaticamente (incl. `phase_summary` e `completed_at`) no último write de `tasks.json` — quando a última task sai de `pending`/`in_progress`. Se o trace parecer desatualizado, a causa é um `morph-spec score` faltante ou um recap sem o bloco da task — corrija a fonte, não o trace.
387
-
388
- 8. Apresente o Gate 3 segundo trust mode — **única apresentação do gate**: `morph-apply` §5 aponta
389
- para cá em vez de duplicar; ao devolver o controle a ela, o gate já está decidido.
390
-
391
- Rode `morph-spec gate-check {feature} review [--json]` — lê `trust` de `.morph/config/config.json`, decide via `shouldPauseGate` e persiste `gateDecisions.review` com timestamp server-side, imprimindo `pause`/`reason`/`signals`. É o default — não recompute a tabela do MORPH.md §5 em linguagem natural.
392
-
393
- **NÃO passe `evalScore` por `--signals` aqui.** O composto do avaliador é lido do disco sozinho: o `gate-check` procura o token `**Composite-Score:**` em `4-review/evaluator-report.md` (passo 4) e carimba `evalScoreSource: evaluator-report` — a **única** procedência que o Gate 3 aceita. Um `evalScore` vindo por override troca o valor mas rebaixa a procedência para `signals-override`, e o Gate 3 **pausa** por "sem score do avaliador independente" sem sequer olhar o número — inclusive quando é o mesmo número do relatório. Sem o token (relatório ausente ou oco), o `evalScore` cai na **PROXY** das `taskScores` — auto-avaliação de quem implementou — e o gate pausa igual. A correção, nos dois casos, é produzir o relatório íntegro do passo 4; nunca o override.
27
+ ## O que fazer
394
28
 
395
- Os itens bloqueantes das **verificações mecânicas sempre-rodar** do passo 3 continuam entrando por `--signals` — é para isso que a flag serve aqui:
29
+ 1. **Contexto.** Tenha em contexto `2-plan/spec.md`, os use cases (`2-plan/usecases/UC-*.md`),
30
+ `2-plan/decisions.md` (se existir) e `3-implement/recap.md`. Numa sessão quente eles já estão
31
+ lá; numa fria, Read.
32
+
33
+ 2. **Relatório já íntegro?** Rode `morph-spec report-check {feature} --json` (sem task) e leia o
34
+ campo `evaluator` — também em sessão retomada: retomar não reseta este passo.
35
+ - `evaluator.complete` (tem `**Verdict:**` válido e não é parcial): **não re-despache** — vá ao
36
+ passo 5.
37
+ - `evaluator.partial: true` (`PARCIAL` na 1ª linha): ver "PARCIAL" no passo 4.
38
+ - Ausente ou sem veredito: siga para o passo 3.
39
+
40
+ 3. **Prova da suíte — uma rodada, sua.** Rode `morph-spec verify {feature} --json` **depois da
41
+ última task** (o `gate-check` pausa o ship se o último stamp é de escopo `task:{id}`).
42
+ **Sem `--filter`, sempre**: `verify {feature}` **nunca recorta**, e um verify filtrado não persiste o
43
+ stamp. Se o JSON vier com `repeatOf`, nada mudou desde a rodada anterior — use aquela. Esta é a
44
+ única execução de testes do Gate 3: o avaliador não roda a suíte de novo.
45
+ - Nó `e2e`: `pass` → passe a URL ao avaliador (`morph-spec e2e status {feature} --json` →
46
+ `baseUrl`). `fail` → volte à correção. `skip` → quem classifica é o `gate-check`
47
+ (`classifyE2eSkip`, em `risk-detector.js`): dispensa de projeto/escopo passa; ambiente,
48
+ `--skip-e2e` ou razão desconhecida pausam sozinhos. Diga ao avaliador que a app não foi exercida.
49
+ - `traceability.warnings`: repasse ao avaliador como sinal, não bloqueio.
50
+
51
+ 4. **Despache o avaliador independente** (`morph-evaluator`, contexto fresco, sem Write/Edit).
52
+ - Tire a foto da árvore e escolha o modelo: `morph-spec report-check {feature} --before-eval --json`.
53
+ O campo `evaluatorModel.model` é `sonnet` por padrão e `opus` quando o diff toca auth, segredo,
54
+ pagamento, migração, prompt/modelo ou mídia gerada (`evaluatorModel.reasons` diz por quê).
55
+ - Blast radius: para cada símbolo público do diff, `morph-spec graph affected <símbolo> --prod --json`.
56
+ Sem grafo (`no-graph`/`not-found`/`ambiguous`), siga sem o blast radius e registre a ausência no
57
+ review-report. Numa worktree com grafo stale, `morph-spec graph refresh` antes.
396
58
  ```
397
- morph-spec gate-check {feature} review --signals '{"standardsViolations":[]}'
59
+ dispatch Agent (subagent_type: "morph-evaluator", model: {evaluatorModel.model}) with prompt:
60
+ contexto: use cases + spec.md + diff da feature + JSON do verify (nós, e2e, URL)
61
+ + blast radius + 1-design/mockups.md (se existir) + 3-implement/evidencias/*.md (se existir)
62
+ instrução: |
63
+ Siga .morph/framework/evals/review-checklist.md e grave
64
+ .morph/features/{feature}/4-review/evaluator-report.md ANTES de encerrar — o arquivo é o
65
+ retorno; não chame SendMessage. Se o arquivo já existir quando você começar, é resíduo de
66
+ outra tentativa: não o leia antes de escrever o seu (ancoragem no veredito alheio).
67
+ A suíte já rodou (JSON acima): você NÃO roda verify, build nem testes. Bash é para ler
68
+ (git diff/log/show, grep, morph-spec graph) e para no máximo UMA rodada de
69
+ `morph-spec mutate {feature}` (até 3 mutantes com `expect`), só quando o checklist pede.
70
+ Nada em segundo plano, nada de laço de espera. NUNCA `git checkout --`: descarta trabalho
71
+ não commitado.
72
+ Com stack no ar, navegue os fluxos da feature e confira console/network.
73
+ Limite de turnos: a ~70% sem terminar, grave o relatório com `PARCIAL` na 1ª linha e SEM
74
+ `**Verdict:**`; o relatório final substitui o parcial.
398
75
  ```
399
-
400
- Julgamento do revisor que nenhuma dessas chaves representa — e forçar a passagem apesar da pausa: use `gate-decision` direto em vez de `gate-check` (`morph-spec gate-decision {feature} review --pause false --reason "..."`), que é explícito e fica registrado.
401
-
402
- **Nunca edite `feature.json` à mão** (colide com o hook state-sync — erro "file modified since read"). Os caminhos acima gravam no mesmo lugar; o hook `gate-guard.js` confere depois se a ação bateu com a decisão persistida.
403
-
404
- **Se `pause === true`**, use `AskUserQuestion`:
405
-
76
+ Tipo `morph-evaluator` não registrado: `general-purpose` com o campo `persona` do `evaluator`
77
+ (`.morph/framework/agents.json`) no topo do prompt, e registre o fallback no review-report.
78
+
79
+ **Ao retomar o controle — higiene antes de ler o veredito.** Rode `morph-spec report-check {feature} --json`:
80
+ - `tree.sinceBeforeEval.changed` vazio e `tree.markers` vazio = árvore como antes do dispatch.
81
+ Arquivo listado = mutação que ficou no disco: `morph-spec mutate --restore` devolve os bytes do
82
+ snapshot conferindo md5; fora de uma rodada de mutação, desfaça linha a linha pelo diff.
83
+ **NUNCA `git checkout -- src/` aqui**: na árvore de
84
+ uma feature em review não existe nenhum commit da feature, e o checkout apaga o trabalho junto.
85
+ - `tree.sinceBeforeEval` `null` = sem foto; `tree` `null` = git não respondeu, nada foi conferido.
86
+ - Não rode build/teste enquanto o agente está `running`.
87
+
88
+ Depois leia `4-review/evaluator-report.md` e rode `morph-spec worktree reap --json`.
89
+
90
+ **PARCIAL** (`evaluator.partial: true`): não leia veredito dele e não re-despache frio — retome o
91
+ MESMO avaliador por `SendMessage`, colando `tree.dirty` e `tree.commits` no recado. Só se o id não
92
+ retomar, despache um novo.
93
+
94
+ 5. **Bloqueadores.** `**Verdict:** FIX` ou bloqueador aberto: corrija (loop da `morph-apply`), rode o
95
+ verify de novo e **confirme só os bloqueadores** retomando o MESMO avaliador por `SendMessage`
96
+ (com `tree.dirty`/`tree.commits` e uma foto `--before-eval` nova). Ele não reavalia a feature
97
+ inteira, e **nota nunca motiva nova rodada**. Avaliador encerrado: despache um novo dizendo que
98
+ é uma confirmação dos bloqueadores Bn — o relatório é append-only e vale o último `**Verdict:**`.
99
+
100
+ 6. **`4-review/review-report.md`**, curto:
101
+ - **`**Reviewed-SHA:** {git rev-parse HEAD}`** — obrigatório. O `approve` recusa se o HEAD andou
102
+ depois do review.
103
+ - `**Veredito:** SHIP|FIX` e a tabela de bloqueadores do evaluator-report (vazia = `Nenhum.`).
104
+ - Runtime: nó `e2e` (`pass`/`fail`/`skip` + razão por extenso) e o que foi navegado.
105
+ - Notas não bloqueantes, numa lista.
106
+
107
+ 7. **Gate 3.** Rode `morph-spec gate-check {feature} review [--json]` — ele lê o veredito do
108
+ evaluator-report e os demais sinais do disco e decide. Violação das verificações mecânicas entra
109
+ por `--signals '{"standardsViolations":[...]}'`. Forçar a passagem apesar de uma pausa:
110
+ `morph-spec gate-decision {feature} review --pause false --reason "..."` (explícito e registrado).
111
+ Nunca edite `feature.json` à mão.
112
+
113
+ **`pause === true`** → `AskUserQuestion`:
406
114
  ```
407
115
  question: "Gate 3 — Review de {feature} aprovado?{ reason ? ' Sinal: ' + reason : '' }"
408
116
  header: "Gate 3"
409
117
  options:
410
- - { label: "aprovado, fechar feature", description: "Marcar review aprovado; próximo passo é fechar com morph-spec finish --pr|--merge (ver morph-apply §6)" }
411
- - { label: "preciso ajustar", description: "Apontar correções necessárias antes de fechar" }
412
- - { label: "rollback", description: "Desfazer e voltar para implement" }
413
- ```
414
-
415
- **Se `pause === false`**, exibir summary curto e prosseguir:
416
-
417
- ```
418
- ## Gate 3 (auto-aprovado)
419
-
420
- **Composite score:** {score}/10
421
- **Dimensões:** arquitetura={X} contratos={Y} qualidade={Z} cobertura={W}
422
- **Runtime:** e2e={pass|skip} {razão, quando skip}
423
- **Bloqueantes:** {N (zero esperado em auto-aprovação)}
424
- **Recomendação:** Aprovado
118
+ - { label: "aprovado, fechar feature", description: "Próximo passo: morph-spec finish --pr|--merge (morph-apply §6)" }
119
+ - { label: "preciso ajustar", description: "Apontar correções antes de fechar" }
120
+ - { label: "rollback", description: "Voltar para implement" }
425
121
  ```
122
+ **`pause === false`** → resumo de 3 linhas (veredito, runtime, bloqueadores: 0) e
123
+ `morph-spec approve {feature} review --mode auto`. A pergunta nomeia a feature: é por ela que o
124
+ hook `state-sync` grava a aprovação.
426
125
 
427
- No caminho manual, o hook state-sync detecta a aprovação em answers de AskUserQuestion e grava `approvalGates.review = { approved: true, timestamp, approvedBy: "manual" }` no `feature.json` autoritativo da feature — **a atribuição vem do nome da feature na pergunta** (o template acima o carrega). Pergunta sem nome, com mais de uma feature na árvore: o hook recusa a gravar e avisa; aprove então por `morph-spec approve {feature} review`. Em auto sem AskUserQuestion, aprove via `morph-spec approve {feature} review --mode auto` — nunca via Edit à mão de state.json.
428
-
429
- **Próximo passo (não é desta skill):** com o Gate 3 aprovado, a feature fecha por `morph-spec finish {feature} --pr|--merge` — a `morph-apply` §6 conduz a escolha PR vs merge. Não arquive nem integre aqui. **`--pr` não encerra a feature** — arquiva e termina, mas só integra no merge (`integrated: false`, `awaiting: "merge"` no payload); até lá a feature fica `aguardando-merge` em `morph-spec list`/`fleet`. `finished: true` não é sinônimo de entregue.
126
+ Fechar não é desta skill: `finish {feature} --pr|--merge` (`morph-apply` §6). `--pr` deixa a
127
+ feature `aguardando-merge` até o merge.
430
128
 
431
129
  ## Output esperado
432
- - `.morph/features/{feature}/4-review/evaluator-report.md` — relatório bruto e autoritativo do
433
- `morph-evaluator` despachado no passo 4 (canal durável, ver MORPH.md §6)
434
- - `.morph/features/{feature}/4-review/review-report.md` — síntese do orquestrador a partir do
435
- evaluator-report, com scores e recomendação
436
- - Trace da fase com `phase_summary` preenchido
437
- - Gate 3 registrado aprovado em `.morph/features/{feature}/feature.json` (autoritativo), na forma canônica `{ approved, timestamp, approvedBy }` — via `morph-spec approve` em auto, ou pelo hook state-sync no caminho manual
130
+ - `4-review/evaluator-report.md` — veredito e bloqueadores do avaliador independente (retorno autoritativo)
131
+ - `4-review/review-report.md` — síntese com `Reviewed-SHA`
132
+ - Gate 3 registrado em `feature.json` via `approve` ou pelo hook `state-sync`
438
133
 
439
134
  ## Referências
440
- - `morph-spec verify {feature} [task] --json` — cadeia determinística build+testes+validadores+e2e anexada ao prompt do avaliador (passo 4)
441
- - `.morph/features/{feature}/2-plan/reuse-map.md` — veredito de reuso por conceito; insumo do avaliador para julgar `code-quality` contra o codebase
442
- - `.morph/framework/MORPH.md` — seção 5 (Gate 3 + regras de pausa), seção 1 (papel Evaluator), Trust Mode
443
- - `.claude/agents/morph-evaluator.md` — subagent do avaliador (gerado de `.morph/framework/agents.json`), despachado no passo 4
444
- - `.claude/skills/morph-eval/SKILL.md` — rubricas e bandas que o avaliador aplica
445
- - `.morph/framework/evals/proof-rubrics/` — as sete rubricas de PROVA citadas no prompt do passo 4
446
- (`mutation-proof.md`, `verde-nao-e-coberto.md`, `fiacao.md`, `guard-cego.md`, `eval-de-modelo.md`, `media-claims.md`, `observabilidade-genai.md`):
447
- não são dimensões do composto. **Cinco** impõem teto em `test-coverage` pelo MENOR delas — as quatro
448
- universais mais `eval-de-modelo`, que perguntam a mesma coisa: *a evidência é real?*. As outras
449
- duas são condicionais e entram FORA do menor-das-cinco: `media-claims.md`, em feature que gera
450
- mídia, impõe teto em `architecture`; `observabilidade-genai.md`, em feature que chama LLM, impõe
451
- teto em `code-quality`. Somá-las faria um `media=4` ou um `obs=4` derrubar o teto de TESTE por um
452
- motivo que não tem nada a ver com teste.
453
- - `.morph/framework/evals/trace-schema.md` — formato canônico do trace
454
- - `.morph/features/{feature}/2-plan/mandate.md` — critérios de done da feature
455
- - `.morph/features/{feature}/2-plan/spec.md` — arquitetura e contratos
456
- - `.morph/features/{feature}/2-plan/decisions.md` — ADRs registrados (se existir)
457
- - `.morph/features/{feature}/3-implement/recap.md` — registro de execução
458
- - `.morph/features/{feature}/1-design/mockups.md` — o checklist de tela que o avaliador confere no passo 4 (quando a feature tomou o ramo uiux)
135
+ - `.morph/framework/evals/review-checklist.md` — o que o avaliador procura e o formato do relatório
136
+ - `morph-spec verify|mutate|report-check|gate-check` — `.morph/framework/CLI.md`
137
+ - `.morph/framework/MORPH.md` §5 — sinais do Gate 3
@@ -4,7 +4,7 @@ description: Varre o codebase existente, detecta stack atual, compara com o stac
4
4
  version: core
5
5
  when-to-invoke: ao iniciar uma feature em projeto brownfield (codebase já existente)
6
6
  user-invokable: true
7
- cliVersion: "8.43.0"
7
+ cliVersion: "8.45.0"
8
8
  ---
9
9
 
10
10
  # morph-stack-scan