@polymorphism-tech/morph-spec 8.44.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.
- package/CLAUDE.md +10 -9
- package/README.md +10 -10
- package/bin/morph-spec.js +10 -13
- package/bin/validate.js +379 -379
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +2 -4
- package/docs/QUICKSTART.md +6 -6
- package/framework/CLAUDE.md +6 -8
- package/framework/MORPH.md +39 -45
- package/framework/agents.json +8 -9
- package/framework/commands/morph-apply.md +1 -3
- package/framework/commands/morph-hotfix.md +1 -1
- package/framework/commands/morph-proposal.md +2 -2
- package/framework/docs/CLI.md +10 -10
- package/framework/evals/review-checklist.md +90 -0
- package/framework/evals/trace-schema.md +2 -12
- package/framework/hooks/README.md +2 -3
- package/framework/hooks/claude-code/core/heavy-gate.js +1 -1
- package/framework/hooks/claude-code/core/protect-spec-files.js +2 -2
- package/framework/hooks/claude-code/core/telemetry-log.js +2 -2
- package/framework/hooks/claude-code/core/trace-autogen.js +1 -22
- package/framework/hooks/claude-code/core/validate-completion.js +3 -56
- package/framework/hooks/claude-code/statusline.sh +11 -11
- package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
- package/framework/hooks/git/pre-commit/agents.sh +25 -25
- package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
- package/framework/hooks/git/pre-commit/specs.sh +50 -50
- package/framework/hooks/git/pre-push/run-tests.sh +44 -44
- package/framework/hooks/shared/build-check.js +1 -1
- package/framework/hooks/shared/comment-scanner.js +1 -1
- package/framework/hooks/shared/phase-utils.js +0 -5
- package/framework/hooks/shared/stdin-reader.js +26 -26
- package/framework/phases.json +4 -6
- package/framework/rubrics/backend.json +1 -1
- package/framework/rubrics/default.json +1 -1
- package/framework/rubrics/frontend.json +1 -1
- package/framework/rules/morph-workflow.md +6 -6
- package/framework/schemas/feature.schema.json +2 -28
- package/framework/schemas/tasks.schema.json +6 -2
- package/framework/skills/README.md +1 -2
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +145 -246
- package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +5 -3
- package/framework/skills/core/morph-implement/SKILL.md +101 -201
- package/framework/skills/core/morph-machine/SKILL.md +3 -3
- package/framework/skills/core/morph-media/SKILL.md +1 -1
- package/framework/skills/core/morph-plan/SKILL.md +171 -287
- package/framework/skills/core/morph-proposal/SKILL.md +4 -5
- package/framework/skills/core/morph-review/SKILL.md +109 -430
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +2 -2
- package/framework/skills/core/morph-uiux/SKILL.md +2 -3
- package/framework/standards/STANDARDS.json +10 -10
- package/framework/standards/ai-agents/agent-archetypes.md +1 -1
- package/framework/standards/ai-agents/agent-session.md +1 -1
- package/framework/standards/ai-agents/agent-spec.md +1 -1
- package/framework/standards/ai-agents/batching.md +1 -1
- package/framework/standards/ai-agents/context-providers.md +1 -1
- package/framework/standards/ai-agents/conversational-agent-with-phases.md +1 -1
- package/framework/standards/ai-agents/cost-and-budget.md +1 -1
- package/framework/standards/ai-agents/durable-workflows-hitl.md +1 -1
- package/framework/standards/ai-agents/guardrails.md +1 -1
- package/framework/standards/ai-agents/llm-runtime-defaults.md +1 -1
- package/framework/standards/ai-agents/mcp-server.md +1 -1
- package/framework/standards/ai-agents/mcp-tools.md +1 -1
- package/framework/standards/ai-agents/media-pipeline.md +1 -1
- package/framework/standards/ai-agents/media-video.md +1 -1
- package/framework/standards/ai-agents/middleware-patterns.md +1 -1
- package/framework/standards/ai-agents/modalities-image-gen.md +1 -1
- package/framework/standards/ai-agents/modalities-speech-to-text.md +1 -1
- package/framework/standards/ai-agents/modalities-text-to-speech.md +1 -1
- package/framework/standards/ai-agents/modalities-vision.md +1 -1
- package/framework/standards/ai-agents/multi-agent-patterns.md +1 -1
- package/framework/standards/ai-agents/observability-patterns.md +3 -3
- package/framework/standards/ai-agents/production.md +2 -2
- package/framework/standards/ai-agents/prompt-sources.md +1 -1
- package/framework/standards/ai-agents/providers/model-registry.md +1 -1
- package/framework/standards/ai-agents/rag-custom-pgvector.md +1 -1
- package/framework/standards/ai-agents/service-tier-flex.md +1 -1
- package/framework/standards/ai-agents/setup.md +1 -1
- package/framework/standards/ai-agents/structured-output.md +1 -1
- package/framework/standards/ai-agents/sweet-spot.md +1 -1
- package/framework/standards/ai-agents/testing-ai.md +1 -1
- package/framework/standards/ai-agents/tool-adapters.md +1 -1
- package/framework/standards/ai-agents/vector-data-extensions.md +1 -1
- package/framework/standards/ai-agents/workflows.md +1 -1
- package/framework/templates/CLAUDE.md.core.template +1 -1
- package/framework/templates/IDE-SNIPPETS.md +262 -262
- package/framework/templates/README.md +1 -1
- package/framework/templates/REGISTRY.json +0 -81
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
- package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
- package/framework/templates/docs/spec.md +19 -205
- package/framework/templates/docs/ui-components.md +52 -52
- package/framework/templates/docs/ui-design-system.md +76 -76
- package/framework/templates/docs/ui-flows.md +167 -167
- package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
- package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
- package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
- package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
- package/framework/templates/infrastructure/github/README.md +56 -56
- package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
- package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
- package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
- package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
- package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
- package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
- package/framework/templates/state.template.json +17 -17
- package/framework/templates/ui/design-system.css +226 -226
- package/package.json +2 -2
- package/src/commands/e2e/e2e.js +1 -1
- package/src/commands/project/heavy.js +1 -1
- package/src/commands/project/status.js +3 -3
- package/src/commands/state/approve.js +7 -49
- package/src/commands/state/gate-check.js +16 -106
- package/src/commands/state/gate-decision.js +1 -1
- package/src/commands/state/report-check.js +42 -17
- package/src/commands/validation/mutate.js +1 -1
- package/src/commands/validation/scout-check.js +28 -0
- package/src/commands/validation/validate-feature.js +5 -32
- package/src/commands/validation/verify.js +3 -4
- package/src/core/paths/output-schema.js +0 -2
- package/src/core/state/state-manager.js +1 -2
- package/src/core/templates/template-renderer.js +477 -477
- package/src/dashboard/app/lib/format.js +5 -0
- package/src/dashboard/app/main.jsx +13 -13
- package/src/dashboard/app/pages/FeatureDetail.jsx +16 -22
- package/src/dashboard/app/pages/Features.jsx +7 -7
- package/src/dashboard/app/pages/PhasePipeline.jsx +1 -1
- package/src/dashboard/app/pages/Rubrics.jsx +7 -11
- package/src/dashboard/scanner/docs-scanner.js +1 -2
- package/src/dashboard/scanner/features-scanner.js +3 -4
- package/src/dashboard/scanner/rubrics-scanner.js +12 -12
- package/src/dashboard/vite.config.js +24 -24
- package/src/lib/agents/output-collector.js +0 -1
- package/src/lib/detectors/design-system-detector.js +188 -188
- package/src/lib/evaluator-report.js +52 -334
- package/src/lib/generators/design-system-generator.js +508 -508
- package/src/lib/generators/handoff-generator.js +4 -5
- package/src/lib/installers/memory-installer.js +2 -2
- package/src/lib/mutation/manifest.js +8 -2
- package/src/lib/mutation/report.js +5 -3
- package/src/lib/mutation/runner.js +9 -7
- package/src/lib/risk-detector.js +60 -122
- package/src/lib/scout/scout-check.js +293 -0
- package/src/lib/tasks/task-classifier.js +30 -30
- package/src/lib/tasks/task-parser.js +209 -209
- package/src/lib/tasks/tasks-json-parser.js +7 -5
- package/src/lib/tasks/test-nodes.js +1 -1
- package/src/lib/tasks/test-runner.js +1 -1
- package/src/lib/validators/css/css-validator.js +340 -340
- package/src/lib/validators/reuse/reuse-validator.js +6 -8
- package/src/lib/validators/verify-runner.js +1 -1
- package/src/scripts/setup-infra.js +1 -1
- package/src/utils/agent-id-mapper.js +11 -11
- package/src/utils/agents-installer.js +5 -9
- package/src/utils/claude-settings-manager.js +300 -300
- package/src/utils/hooks-installer.js +3 -10
- package/src/utils/skills-installer.js +1 -1
- package/framework/evals/proof-rubrics/README.md +0 -76
- package/framework/evals/proof-rubrics/eval-de-modelo.md +0 -80
- package/framework/evals/proof-rubrics/fiacao.md +0 -54
- package/framework/evals/proof-rubrics/guard-cego.md +0 -52
- package/framework/evals/proof-rubrics/media-claims.md +0 -109
- package/framework/evals/proof-rubrics/mutation-proof.md +0 -107
- package/framework/evals/proof-rubrics/observabilidade-genai.md +0 -119
- package/framework/evals/proof-rubrics/verde-nao-e-coberto.md +0 -48
- package/framework/evals/rubrics/README.md +0 -45
- package/framework/evals/rubrics/architecture.md +0 -103
- package/framework/evals/rubrics/code-quality.md +0 -98
- package/framework/evals/rubrics/condensed.md +0 -57
- package/framework/evals/rubrics/contracts.md +0 -67
- package/framework/evals/rubrics/test-coverage.md +0 -99
- package/framework/evals/scenarios/dotnet-crud.yaml +0 -42
- package/framework/evals/scenarios/nextjs-auth.yaml +0 -38
- package/framework/evals/suites/standard.yaml +0 -5
- package/framework/hooks/claude-code/core/post-edit-typecheck.js +0 -127
- package/framework/skills/core/morph-eval/SKILL.md +0 -64
- package/framework/templates/.idea/morph-templates.xml +0 -92
- package/framework/templates/.vscode/morph-templates.code-snippets +0 -186
- package/framework/templates/docs/clarifications.md +0 -253
- package/framework/templates/docs/onboarding.md +0 -122
- package/framework/templates/docs/schema-analysis.md +0 -119
- package/framework/templates/docs/user-stories.md +0 -34
- 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.
|
|
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
|
-
- `
|
|
116
|
-
- `
|
|
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
|
|
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.
|
|
7
|
+
cliVersion: "8.45.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-review
|
|
11
11
|
|
|
12
12
|
## Objetivo
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
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
|
-
|
|
401
|
-
|
|
402
|
-
**
|
|
403
|
-
|
|
404
|
-
|
|
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: "
|
|
411
|
-
- { label: "preciso ajustar", description: "Apontar correções
|
|
412
|
-
- { label: "rollback", description: "
|
|
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
|
-
|
|
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
|
-
-
|
|
433
|
-
|
|
434
|
-
-
|
|
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
|
-
-
|
|
441
|
-
-
|
|
442
|
-
- `.morph/framework/MORPH.md` —
|
|
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.
|
|
7
|
+
cliVersion: "8.45.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-stack-scan
|