@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
|
@@ -1,80 +1,67 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: morph-plan
|
|
3
|
-
description: Guia a produção dos artefatos de planejamento de uma feature (use cases, spec.md,
|
|
3
|
+
description: Guia a produção dos artefatos de planejamento de uma feature (use cases, spec.md, tasks.json) e apresenta o Gate 2 trust-aware.
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao iniciar a fase plan de uma feature, após o Gate 1 (proposal aprovado)
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.45.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-plan
|
|
11
11
|
|
|
12
12
|
## Objetivo
|
|
13
13
|
|
|
14
|
-
Produzir os **use cases**, `spec.md
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
A ordem importa e não é negociável: **comportamento antes de solução técnica**. Um `spec.md` escrito antes dos use cases resolve um problema que ainda não foi enunciado.
|
|
14
|
+
Produzir os **use cases**, o `spec.md` e o `tasks.json` com qualidade para abrir o Gate 2. Os use
|
|
15
|
+
cases definem o **comportamento**; o spec diz **como**; as tasks dizem **em que ordem** e **quando
|
|
16
|
+
cada uma está pronta**. Comportamento antes de solução técnica — sempre nessa ordem.
|
|
18
17
|
|
|
19
18
|
## Quando invocar
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
Fase plan, depois do Gate 1. Normalmente chamada pela `morph-proposal`.
|
|
22
21
|
|
|
23
22
|
## O que fazer
|
|
24
23
|
|
|
25
|
-
1. **Garanta que `proposal.md` e `stack-scan.md` estão no seu contexto antes de planejar
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
uiux (wireframes, decisões de layout, componentes propostos). Leia TODOS os `.md` de lá: eles
|
|
29
|
-
descrevem comportamento de interface que o `proposal.md` não carrega, e um plano que os ignora
|
|
30
|
-
dimensiona a feature pela metade. **Diretório ausente NÃO é erro** — a fase uiux é opcional
|
|
31
|
-
(MORPH.md §2.1) e a maioria das features não a toma; nesse caso não há passo nenhum a rodar e o
|
|
32
|
-
plano segue idêntico ao de hoje.
|
|
24
|
+
1. **Garanta que `proposal.md` e `stack-scan.md` estão no seu contexto antes de planejar** (Read se
|
|
25
|
+
a sessão é fresca). Em brownfield, o stack-scan manda: não invente padrão que conflita com o
|
|
26
|
+
detectado.
|
|
33
27
|
|
|
34
|
-
|
|
28
|
+
**E `.morph/features/{feature}/1-design/*.md`, quando o diretório existe** — leia todos os `.md`:
|
|
29
|
+
descrevem comportamento de interface que o proposal não carrega. **Diretório ausente NÃO é erro**
|
|
30
|
+
— a fase uiux é opcional (MORPH.md §2.1) e o plano segue igual.
|
|
35
31
|
|
|
32
|
+
1b. **Scout — mapa do território (default em feature grande ou brownfield).**
|
|
33
|
+
Despache `subagent_type: "morph-scout"`: os arquivos que a feature vai tocar, o blast radius dos símbolos centrais e o que
|
|
34
|
+
quebra junto. O scout começa por `morph-spec graph affected|explain` e **cai para grep sozinho
|
|
35
|
+
quando não há grafo**. Não registrado: `general-purpose` com o campo `persona` do `scout`.
|
|
36
|
+
Grave a resposta em `2-plan/scout-map.md` e audite:
|
|
36
37
|
```
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Peça: os arquivos que a feature vai tocar, o blast radius dos símbolos centrais dessa área e o que quebra junto. O scout começa por `morph-spec graph affected|explain` e **cai para grep sozinho quando não há grafo** — nunca trate a ausência de grafo como impedimento para planejar.
|
|
41
|
-
|
|
42
|
-
**Fallback** (se `morph-scout` não estiver registrado nos subagent types deste projeto): `general-purpose` com o campo `persona` do agente `scout` colado no prompt (Read em `.morph/framework/agents.json`), registrando o fallback no `decisions.md`.
|
|
43
|
-
|
|
44
|
-
Pular o scout é aceitável em feature pequena dentro de domínio já carregado — nesse caso **registre a decisão em uma linha no `decisions.md`**.
|
|
45
|
-
|
|
46
|
-
1c. **Mapa de reuso — o que desta feature JÁ EXISTE no codebase.** Antes de destilar os use cases, responda por conceito: *isto já está implementado?* É o passo que falta hoje e cujo efeito é medido — 17 duplicações intra-feature no ProspectPRO, `SimpleBuilding` redefinido em cinco arquivos da MESMA pasta, um deles já sem um campo. Sem este passo, quem implementa não tem como saber, e o framework nunca pergunta.
|
|
47
|
-
|
|
48
|
-
**Insumos, nesta ordem:**
|
|
49
|
-
0. **O estado do grafo** — `morph-spec graph status --json`. Stale com `refresh.running: true`: espere o refresh terminar (ele roda em background, só na raiz) ou trate cada "não existe" como possivelmente velho; stale sem refresh em andamento — e sempre numa worktree (`refresh.auto: false`), cujo grafo é o semeado da raiz e não anda sozinho: `morph-spec graph refresh`. O resultado vai para a linha de método do mapa.
|
|
50
|
-
1. **O grafo** — para cada conceito central (entidade, DTO, componente, hook, serviço, helper — e o dublê ou a fixture de teste, que também estão no grafo, com `test: true`) que a feature vai introduzir: `morph-spec graph explain <nome-candidato> --json` (existe? onde?) e `morph-spec graph affected <conceito> --uses-only --json` (quem usa de verdade, sem contar quem só implementa). **O mapa nasce dessa saída**, não de memória nem de grep por conta própria.
|
|
51
|
-
2. **O inventário do projeto** — `.morph/context/README.md` (gerado por `morph-spec context refresh`): entidades, endpoints com método e rota, páginas e **componentes com path**. É a granularidade de *conceito* que o grafo, que casa por símbolo, não dá. **Este passo é o consumidor declarado desse arquivo** — se ele não existir, rode `morph-spec context refresh` ou siga sem ele.
|
|
52
|
-
3. **Sem grafo** (`no-graph`, projeto sem Python), ou o grafo não respondeu (`not-found` num grafo stale, `ambiguous` sem opção que sirva) — **caia para `grep -rn "<nome-candidato>"` no diretório de código e siga**; a ausência de grafo nunca bloqueia o plano (ADR-002). Registre a queda no `decisions.md`.
|
|
53
|
-
|
|
54
|
-
**Produza `.morph/features/{feature}/2-plan/reuse-map.md`** — artefato, não prosa solta, com a saída do grafo **citada**:
|
|
55
|
-
|
|
56
|
-
```markdown
|
|
57
|
-
Método: `morph-spec graph status --json` → fresh, built_at_commit 1a2b3c4d = HEAD
|
|
58
|
-
|
|
59
|
-
| Conceito | Já existe? | Onde | Fonte | Decisão |
|
|
60
|
-
|---|---|---|---|---|
|
|
61
|
-
| SimpleBuilding | SIM (5×) | features/roulette/types/roulette.types.ts:L12 | `graph explain SimpleBuilding` → ambiguous, 5 opções | REUSAR |
|
|
62
|
-
| FilterValues | SIM (ambíguo) | dashboard + leads + store | `graph affected FilterValues --uses-only` → 7 consumidores | ESTENDER o de dashboard |
|
|
63
|
-
| RouletteScore | NÃO | — | `graph explain RouletteScore` → not-found; `grep -rn RouletteScore` → 0 | CRIAR — nenhum tipo cobre pontuação por sorteio |
|
|
38
|
+
morph-spec scout-check .morph/features/{feature}/2-plan/scout-map.md --json
|
|
64
39
|
```
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
40
|
+
Exit ≠ 0 → o mapa é descartado; re-despache **uma** vez com as `failures` coladas. Segunda
|
|
41
|
+
reprovação: faça você o grep dos fatos que o plano precisa. Mapa aprovado prova que as citações
|
|
42
|
+
existem, não que a conclusão está certa — confira com grep próprio o Inferido que muda o plano.
|
|
43
|
+
Pular o scout em feature pequena no domínio carregado: uma linha em `decisions.md`.
|
|
44
|
+
|
|
45
|
+
1c. **Reuso — o que desta feature JÁ EXISTE.** Para cada conceito central que a feature introduz
|
|
46
|
+
(entidade, DTO, componente, hook, serviço, helper, dublê de teste): `morph-spec graph explain
|
|
47
|
+
<nome> --json` (existe? onde?) e `morph-spec graph affected <conceito> --uses-only --json` (quem
|
|
48
|
+
usa de verdade). Antes, `morph-spec graph status --json`: stale numa worktree, ou sem refresh em
|
|
49
|
+
andamento, `morph-spec graph refresh`. O inventário `.morph/context/README.md` (`morph-spec context
|
|
50
|
+
refresh`) dá componentes e endpoints por path. **Sem grafo** (`no-graph`, `not-found` num grafo
|
|
51
|
+
stale), caia para `grep -rn "<nome>"` e siga — a ausência de grafo nunca bloqueia.
|
|
52
|
+
|
|
53
|
+
O veredito vai direto para a task que realiza o conceito (passo 5b): `REUSAR`, `ESTENDER` ou
|
|
54
|
+
`CRIAR`. **`CRIAR` exige `why`** — uma linha com a consulta que respondeu "não existe" (`graph
|
|
55
|
+
explain X → not-found; grep -rn X → 0`). Conceito de duas features vai para um módulo comum, nunca
|
|
56
|
+
import cruzado entre slices. O validador `reuse` do `verify` cobra o resultado: símbolo novo
|
|
57
|
+
homônimo de um existente reprova na mesma feature e avisa entre features; `CRIAR` declarado no
|
|
58
|
+
plano rebaixa o achado a aviso.
|
|
59
|
+
|
|
60
|
+
1d. **O que esta feature supera no acervo.** Insumos: `Conflitos com o acervo` do `proposal.md`,
|
|
61
|
+
`.morph/specs/usecases/` e o índice `.morph/specs/adrs/`. UC `status: superseded` não é o
|
|
62
|
+
comportamento vigente — o `superseded_by` é. Cada conflito decidido vira uma linha na seção de
|
|
63
|
+
revogação do `spec.md` (passo 3) e um ADR em `decisions.md`; ADR que vale além desta feature leva
|
|
64
|
+
`**Alcance:** projeto` (é por ela que o `finish` o copia para o índice):
|
|
78
65
|
```markdown
|
|
79
66
|
## ADR-{nnn}: {a regra que vale no projeto}
|
|
80
67
|
|
|
@@ -101,66 +88,53 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
|
|
|
101
88
|
## Cenário principal
|
|
102
89
|
1. Visitante acessa a listagem de veterinários
|
|
103
90
|
2. Sistema retorna os veterinários ordenados por sobrenome
|
|
104
|
-
3. Sistema exibe, para cada um, nome e especialidades
|
|
105
91
|
|
|
106
92
|
## Pós-condições
|
|
107
93
|
- **P1** — A resposta contém todos os veterinários não arquivados
|
|
108
94
|
- **P2** — Cada veterinário traz suas especialidades em lista, nunca string concatenada
|
|
109
|
-
- **P3** — A ordenação por sobrenome é estável para nomes repetidos
|
|
110
95
|
|
|
111
96
|
## Fluxos alternativos (opcional)
|
|
112
97
|
- **A1** — Nenhum veterinário cadastrado → sistema exibe estado vazio
|
|
113
98
|
```
|
|
114
99
|
|
|
115
|
-
**A regra que sustenta a camada inteira: pós-condição precisa ser observável em teste.**
|
|
100
|
+
**A regra que sustenta a camada inteira: pós-condição precisa ser observável em teste.** Pergunte:
|
|
101
|
+
*que asserção eu escreveria para verificar isto?* Sem resposta, reescreva ou descarte.
|
|
116
102
|
|
|
117
103
|
**Artefato não é comportamento.** Pós-condição que cita arquivo, pasta, `grep`, "contém a
|
|
118
|
-
string" ou "o binário" descreve o
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
o texto está errado ("publicar tenant com `criterion_overrides` é recusado, nomeando a
|
|
122
|
-
chave", não "nenhum arquivo em `tenants/**` contém a chave").
|
|
123
|
-
2. **Se o artefato É o entregável** (standard, faxina sem efeito de runtime), justifique
|
|
124
|
-
**na linha logo abaixo** da pós-condição:
|
|
104
|
+
string" ou "o binário" descreve o texto do repositório, não o que o sistema faz. Primeiro tente
|
|
105
|
+
o efeito observável em runtime ("publicar tenant com `criterion_overrides` é recusado, nomeando a
|
|
106
|
+
chave"). Se o artefato É o entregável, justifique **na linha logo abaixo**:
|
|
125
107
|
|
|
126
108
|
```markdown
|
|
127
109
|
- **P4** — Nenhum arquivo em `tenants/**` contém a chave `criterion_overrides`
|
|
128
110
|
> [!note] Por que artefato: a chave saiu do contrato; nenhum leitor de runtime a consulta.
|
|
129
111
|
```
|
|
130
112
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
Pós-condição sobre o que um **modelo** responde ("o texto pode nomear a pior campanha") é
|
|
136
|
-
observável — em runtime, nunca no texto do prompt. O passo 5 diz que forma a task toma.
|
|
137
|
-
|
|
138
|
-
**Identificador sequencial, reservado — nunca leia o disco à mão.** Rode `morph-spec usecase reserve --count {n} --feature {feature}` (`n` = quantos UCs esta feature vai criar; pode reservar de novo se descobrir mais no meio do plano). Um scan manual do maior `UC-{nn}` só enxerga a ÁRVORE CORRENTE — cada worktree tem a própria cópia de `.morph/features/`, então dois worktrees planejando ao mesmo tempo calculam o mesmo maior número e mintam o MESMO `UC-{nn}` sem saber um do outro; na promoção do `finish`, o segundo a fechar sobrescreve por ID e **apaga o use case do primeiro** — já causou perda de dados em produção. `usecase reserve` aloca atomicamente a partir de um contador compartilhado em `<git-common-dir>/morph-spec/uc-registry.json` (visível a todo worktree do repo, mesmo mecanismo do `claim`/fleet), semeado do maior número já visto no acervo + nas features da árvore corrente + no próprio contador — nunca regride. Fora de um repositório git, cai para o scan local antigo e avisa que o paralelismo entre worktrees não está protegido.
|
|
113
|
+
Nunca na mesma linha: a pós-condição viaja literal ao `doneCriteria`. Task sem `usecase`
|
|
114
|
+
justifica no próprio `doneCriteria` (`… — Por que artefato: …`). Pós-condição sobre o que um
|
|
115
|
+
**modelo** responde é observável em runtime, nunca no texto do prompt (passo 5).
|
|
139
116
|
|
|
140
|
-
**
|
|
117
|
+
**Numeração:** `morph-spec usecase reserve --count {n} --feature {feature}` — nunca o maior
|
|
118
|
+
`UC-{nn}` do disco: cada worktree vê só a sua cópia, e dois planos paralelos mintariam o mesmo id.
|
|
141
119
|
|
|
142
|
-
**Seções
|
|
143
|
-
|
|
144
|
-
**Quando é obrigatório** (ver MORPH.md §2.1 para o roteamento por tipo):
|
|
120
|
+
**Seções:** obrigatórias `Pré-condições`, `Cenário principal` (curto) e `Pós-condições` (**P1**,
|
|
121
|
+
**P2**…). Opcionais, só quando pedem: `Fluxos alternativos` (**A1**…) e `Delta de domínio`.
|
|
145
122
|
|
|
146
123
|
| Tipo | Use case |
|
|
147
124
|
|---|---|
|
|
148
|
-
| `feature` | Obrigatório
|
|
149
|
-
| `bug` |
|
|
150
|
-
| `chore` | Nenhum
|
|
151
|
-
| `hotfix` |
|
|
152
|
-
|
|
153
|
-
**Nunca edite `.morph/specs/usecases/` à mão.** A única via de escrita no acervo é a promoção do `finish`, que lê **só** de `2-plan/usecases/`: é ela que carimba `status: implemented`, sobrescreve por ID (mesmo com slug novo) e leva o arquivo no commit de arquivamento. Editar o acervo direto pula os três e cria uma segunda verdade fora do mecanismo. Mudar um UC existente = copiar para o `2-plan/usecases/` da feature, corrigir lá, e deixar o `finish` sobrescrever. Aposentar um UC (todo ou em parte) também não é edição à mão: é a seção de revogação do `spec.md` (passo 3), que o `finish` aplica.
|
|
154
|
-
|
|
155
|
-
**Backstop de colisão na promoção.** Se, apesar da reserva, duas features chegarem à promoção com o MESMO `UC-{nn}` e slugs diferentes — registro de reserva aponta para uma feature diferente da que já está no acervo —, o `finish`/`archive` **recusa promover esse UC específico** (nunca recusa fechar a feature: fail-open, só aquele use case fica de fora) e imprime onde o arquivo ficou e como recuperar. Se acontecer: renumere com `usecase reserve` e promova manualmente, ou — se for mesmo o caso `bug` — confira se o slug bate com o publicado.
|
|
125
|
+
| `feature` | Obrigatório com comportamento observável; feature puramente técnica dispensa (registre em `decisions.md`). |
|
|
126
|
+
| `bug` | Copie o `UC-{nn}-*.md` do acervo para `2-plan/usecases/` **com o mesmo nome de arquivo** e corrija ou adicione a pós-condição — não reserve número novo. |
|
|
127
|
+
| `chore` | Nenhum. |
|
|
128
|
+
| `hotfix` | Referencia se existir. |
|
|
156
129
|
|
|
157
|
-
|
|
130
|
+
**Nunca edite `.morph/specs/usecases/` à mão** — a única escrita no acervo é a promoção do
|
|
131
|
+
`finish`, que lê de `2-plan/usecases/`. O use case segue editável depois do Gate 2.
|
|
158
132
|
|
|
159
|
-
3. Produza `spec.md` em
|
|
160
|
-
- Arquitetura
|
|
161
|
-
|
|
162
|
-
-
|
|
163
|
-
|
|
133
|
+
3. Produza `spec.md` em `2-plan/`:
|
|
134
|
+
- Arquitetura: componentes, como se conectam, fluxos de dados. Edge cases **técnicos** (os de
|
|
135
|
+
comportamento estão nos use cases) e integrações externas. Não repita o comportamento.
|
|
136
|
+
- **UCs e ADRs que esta feature altera ou revoga** — seção obrigatória com este título; `Nenhum.`
|
|
137
|
+
quando nada muda, senão:
|
|
164
138
|
|
|
165
139
|
```markdown
|
|
166
140
|
## UCs e ADRs que esta feature altera ou revoga
|
|
@@ -171,75 +145,41 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
|
|
|
171
145
|
| {feature}/ADR-{nnn} | total | — | — |
|
|
172
146
|
```
|
|
173
147
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
isso não existe, crie a task de setup**: sem ela a navegação para na tela de login e a
|
|
210
|
-
verificação de runtime vira teatro. É gap de Gate 2, não dispensa de Gate 3.
|
|
211
|
-
- **Baseline de contagem de testes é um COMANDO aqui também:** se o projeto declara
|
|
212
|
-
`project.tests[]`, o `expectedCount` de cada suíte é gravado por `morph-spec verify {feature}
|
|
213
|
-
--record-baseline` a partir de uma execução verde — **nunca digitado no config**. Um número
|
|
214
|
-
inventado **alto demais** deixa o verify vermelho por `count-drop` e trava o próprio comando que
|
|
215
|
-
o consertaria (só sai rebaixando/apagando o número à mão). Forma de `project.tests[]`:
|
|
216
|
-
`.morph/framework/CLI.md`, seção "Suítes de teste".
|
|
217
|
-
- **Quando não se aplica** (biblioteca pura, chore sem runtime), registre a dispensa e o porquê.
|
|
218
|
-
- Checklist de done com critérios verificáveis por tarefa.
|
|
219
|
-
- **Orçamento de teste e comentário — copie no mandate**, pelo mesmo motivo dos patterns
|
|
220
|
-
proibidos: o orçamento por task do passo 5 (um teste por pós-condição + um de regressão por
|
|
221
|
-
bug, justificativa acima disso, tabela antes de cópia, nenhum teste que só fixa texto);
|
|
222
|
-
fixture compartilhada antes de helper novo; TDD onde paga (bug: regressão primeiro; lógica
|
|
223
|
-
pura), teste depois aceito em UI e integração; comentário: o padrão é nenhum (nome, tipo e teste
|
|
224
|
-
explicam), só o porquê que o código não mostra, nunca `///`/JSDoc que repete a assinatura
|
|
225
|
-
nem história de task/UC/ADR. Nos standards obrigatórios, liste
|
|
226
|
-
`architecture-code-comments` e o standard de teste do stack (seção *Test budget*).
|
|
227
|
-
- **Baseline é um COMANDO, nunca um número.** O mandate congela no Gate 2 e é lido por
|
|
228
|
-
implementadores durante dias — todo número cravado nele (`Suíte: 2366 passando`, cobertura,
|
|
229
|
-
contagem de arquivos) está errado a partir da primeira task, e um agente que confia nele
|
|
230
|
-
"conserta" um baseline que nunca esteve quebrado. Registre **como medir** (`npm test`,
|
|
231
|
-
`dotnet test`) e mande comparar com o resultado do momento, não com um valor histórico.
|
|
232
|
-
Aconteceu de verdade: mandate afirmando 2366 quando já eram 2375, e um ADR escrito só para
|
|
233
|
-
desmentir o próprio mandate.
|
|
234
|
-
- **Pré-requisito é um PREDICADO, nunca um SHA literal.** "`git merge-base --is-ancestor
|
|
235
|
-
origin/main HEAD` sai 0" ou "a branch da feature X está integrada" — não "confirme que
|
|
236
|
-
origin/master contém `49dfba2`". SHA cravado envelhece na primeira rebase/squash: o merge sai
|
|
237
|
-
com outro hash e o sub-agent mandado verificá-lo ou queima turnos procurando o que não existe,
|
|
238
|
-
ou declara que verificou sem ter verificado.
|
|
239
|
-
|
|
240
|
-
5. Produza `tasks.json` em `.morph/features/{feature}/2-plan/` seguindo o schema em `.morph/framework/schemas/tasks.schema.json`.
|
|
241
|
-
|
|
242
|
-
**Formato obrigatório** (schema em `.morph/framework/schemas/tasks.schema.json` — o hook `tasks-json-guard` valida cada write):
|
|
148
|
+
`Id` é `UC-{nn}` ou `{feature}/ADR-{nnn}`. UC revogado exige `Substituto`; `parcial` exige
|
|
149
|
+
`Escopo`. O `finish` aplica as linhas válidas e devolve as malformadas em `revocationProblems`.
|
|
150
|
+
**Rode `morph-spec usecase check {feature}` logo depois de escrever a seção** — o spec congela no
|
|
151
|
+
Gate 2.
|
|
152
|
+
|
|
153
|
+
4. **Seção `## Contrato de implementação` do `spec.md`** — o que quem implementa precisa saber e o
|
|
154
|
+
código não diz. Curta; o resto já está nos standards que cada task carrega.
|
|
155
|
+
- **Standards:** `morph-spec standards --find "<domínio>"` por domínio tocado (o digest decide);
|
|
156
|
+
liste os ids. Inclua `architecture-code-comments` e o standard de teste do stack. Feature com
|
|
157
|
+
agente MAF: os `standards/ai-agents/*.md` que ela exige (`--category ai-agents`) — convenção de
|
|
158
|
+
projeto vem deles; superfície da API pode vir do context7.
|
|
159
|
+
- **Proibições desta feature** além das de `MORPH.md` § "Stack baked-in", quando houver.
|
|
160
|
+
- **Verificação de runtime** — como se prova que a feature funciona rodando:
|
|
161
|
+
- O stack sobe pelo `docker compose` do projeto (`morph-spec e2e up {feature}`). Projeto que
|
|
162
|
+
containeriza sem compose: **isso é uma task**.
|
|
163
|
+
- Os fluxos que o avaliador vai navegar, nos verbos das pós-condições; quais viram spec
|
|
164
|
+
Playwright (caminho crítico e bug corrigido).
|
|
165
|
+
- Base URL do ambiente: `process.env.PLAYWRIGHT_BASE_URL ?? \`http://localhost:${process.env.PORT ?? 3000}\``,
|
|
166
|
+
compose publicando `"${PORT:-3000}:3000"` e sem `container_name` (standard
|
|
167
|
+
`infrastructure/docker/local-compose-isolation`). Cravado: **isso é uma task**.
|
|
168
|
+
- App com login: `e2e.auth` em `config.json` (`mode: seed|storageState|bypass|none`,
|
|
169
|
+
`seedCommand`, `storageStatePath`, `envFile`), credenciais num `.env.e2e` gitignored.
|
|
170
|
+
**`mode` é obrigatório sempre que houver `seedCommand`** — sem ele o seed fica inerte. Sem setup de
|
|
171
|
+
login, crie a task.
|
|
172
|
+
- Não se aplica (biblioteca pura): registre a dispensa e o porquê.
|
|
173
|
+
- **Baseline é um COMANDO, nunca um número.** O spec congela no Gate 2 e é lido por dias: número
|
|
174
|
+
cravado (`2366 passando`) está errado na primeira task, e quem confia nele "conserta" o que não
|
|
175
|
+
quebrou. Registre como medir (`npm test`, `dotnet test`); o `expectedCount` de `project.tests[]`
|
|
176
|
+
é gravado por `morph-spec verify {feature} --record-baseline`, nunca digitado.
|
|
177
|
+
- **Pré-requisito é um PREDICADO, nunca um SHA literal**: "`git merge-base --is-ancestor
|
|
178
|
+
origin/main HEAD` sai 0", não "confirme que main contém `49dfba2`" — o SHA muda no primeiro
|
|
179
|
+
squash.
|
|
180
|
+
|
|
181
|
+
5. Produza `tasks.json` em `.morph/features/{feature}/2-plan/` seguindo o schema
|
|
182
|
+
`.morph/framework/schemas/tasks.schema.json` (o hook `tasks-json-guard` valida cada write):
|
|
243
183
|
|
|
244
184
|
```json
|
|
245
185
|
{
|
|
@@ -249,175 +189,119 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
|
|
|
249
189
|
{
|
|
250
190
|
"id": "T1",
|
|
251
191
|
"title": "Título curto",
|
|
252
|
-
"description": "
|
|
192
|
+
"description": "O que esta task realiza e por quê",
|
|
253
193
|
"dependencies": [],
|
|
254
194
|
"effort": "S",
|
|
255
195
|
"doneCriteria": "P2 — Cada veterinário traz suas especialidades em lista, nunca string concatenada",
|
|
256
196
|
"status": "pending",
|
|
257
|
-
"outputs": [],
|
|
197
|
+
"outputs": ["src/Vets/ListVets.cs", "tests/Vets/ListVetsTests.cs"],
|
|
258
198
|
"group": "backend",
|
|
259
199
|
"usecase": "UC-07",
|
|
260
200
|
"agent": "dotnet-senior",
|
|
261
201
|
"standards": ["standards/backend/dotnet/vsa-handler-patterns.md"],
|
|
262
|
-
"reuse": [{ "concept": "
|
|
202
|
+
"reuse": [{ "concept": "VetDto", "verdict": "CRIAR", "why": "graph explain VetDto → not-found; grep -rn VetDto → 0" }]
|
|
263
203
|
}
|
|
264
204
|
]
|
|
265
205
|
}
|
|
266
206
|
```
|
|
267
207
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
- `
|
|
271
|
-
- `
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
**
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
`description` (é ela que chega ao sub-agente). O orçamento conta comportamentos, não cenários:
|
|
301
|
-
os cenários do mesmo comportamento são linhas de uma tabela (`[Theory]`/`it.each`), não N
|
|
302
|
-
testes. **Nenhum teste que só fixa texto** (copy de UI, config de tenant, prosa): a checagem
|
|
303
|
-
vira analyzer, lint ou validação no publish e fica fora da contagem da suíte. A regra de
|
|
304
|
-
critério sobre saída de LLM, abaixo, é o caso de prompt desta. A prova de mutação do Gate 3
|
|
305
|
-
continua no caminho crítico: mutante sobrevivente se mata apertando uma asserção ou somando uma
|
|
306
|
-
linha de tabela, nunca com um teste novo por mutante. O `morph-spec verify` avisa quando as
|
|
307
|
-
linhas de teste adicionadas passam de 1,5× as de produção (validador `code-budget`).
|
|
308
|
-
|
|
309
|
-
**Preencha `outputs` (paths planejados) em cada task** — o `morph-spec dag` usa os outputs para detectar colisão de arquivos entre fluxos paralelos e recomendar `isolation: "worktree"`. Task sem `outputs` entra como footprint desconhecido (não força isolamento, mas o dag não consegue protegê-la de colisão).
|
|
310
|
-
|
|
311
|
-
**Tamanho da task: no máximo 8 `outputs`** (testes incluídos). Uma task inteira cabe num
|
|
312
|
-
dispatch; acima disso o sub-agente bate no teto de turnos e a retomada recomeça fria. Fatie por
|
|
313
|
-
pós-condição (uma task por pós-condição ou par delas, com a dependência explícita). Antes do
|
|
314
|
-
Gate 2, o `morph-spec dag` recusa (exit 1) e o `gate-check plan` pausa com `oversizedTasks`;
|
|
315
|
-
depois do Gate 2 é só aviso.
|
|
316
|
-
|
|
317
|
-
**Critério sobre saída de LLM vira eval de runtime — nunca "suíte estrutural".** Duas etapas,
|
|
318
|
-
como na `morph-review`: (1) **filtro mecânico** — o `mandate.md` cita ao menos um standard
|
|
319
|
-
`ai-agents`; senão, a regra não se aplica. (2) **determinação sua, por task** — o
|
|
320
|
-
`doneCriteria` julga o que o modelo *responde* (conteúdo, tom, escolha)? Se sim:
|
|
321
|
-
- a prova é um **eval de runtime**; a evidência (entrada, modelo, saída, veredito) vai em
|
|
208
|
+
- `id` `T\d+`; `dependencies` com ids Tn; `effort` S (≤30min) | M (≤1h) | L (≤2h) | XL (>2h);
|
|
209
|
+
`status` nasce `pending`; `group` backend | frontend | tests | infra | docs.
|
|
210
|
+
- `usecase`: o **id** (`UC-07`), nunca o nome do arquivo.
|
|
211
|
+
- `outputs`: paths planejados — o `dag` detecta colisão entre fluxos paralelos por eles.
|
|
212
|
+
**No máximo 8 `outputs` por task** (testes incluídos): acima disso o sub-agente bate no teto de
|
|
213
|
+
turnos; o `dag` recusa antes do Gate 2.
|
|
214
|
+
|
|
215
|
+
**5a. Carimbe `agent` e `standards`** com UMA leitura de `.morph/framework/agents.json`: `agent` é
|
|
216
|
+
o id da persona (sem `morph-`) cujo `domains` cobre o domínio da task; `standards`, o array dela
|
|
217
|
+
mais o que a task exige. **Persona com `surfaces`** (a `ui-designer`): some a lista da superfície
|
|
218
|
+
que o checklist de tela do `1-design/mockups.md` declara em `Superfície`, nunca de outra; sem
|
|
219
|
+
mockup, escolha pela tela e registre em `decisions.md`. Task que cria ou altera UI carimba
|
|
220
|
+
`agent: "ui-designer"` mesmo sem o ramo uiux. Task sem persona clara (config, docs) fica sem `agent`.
|
|
221
|
+
|
|
222
|
+
**5b. Carimbe `reuse`** na task que escreve cada conceito do passo 1c: `concept`, `verdict`,
|
|
223
|
+
`target` (o que reusar ou estender) e, em `CRIAR`, `why`. Conceito sem task: falta task ou o
|
|
224
|
+
conceito não é desta feature — resolva antes do Gate 2.
|
|
225
|
+
|
|
226
|
+
**O `doneCriteria` carrega a pós-condição LITERAL**, prefixada pelo rótulo (`"P2 — Cada
|
|
227
|
+
veterinário traz..."`). Reescrever com outras palavras é onde o requisito se perde. Toda
|
|
228
|
+
pós-condição de todo UC tem ao menos uma task.
|
|
229
|
+
|
|
230
|
+
**`morph-spec dag {feature}` cobra o encanamento.** Ele reporta UC inexistente (erro), pós-condição sem task e `doneCriteria` parafraseado (avisos), e `doneCriteria` com vocabulário de artefato (`grep`, "contém a string", "o binário", "nenhum arquivo", "arquivo/pasta/diretório em", glob `**/`) sem `Por que artefato:` (aviso). Também aponta task sobre UC `superseded` e linha de revogação que o `finish` não aplicaria.
|
|
231
|
+
|
|
232
|
+
**Orçamento de teste por task.** Cada pós-condição compra **um** teste, cada bug corrigido **um** de
|
|
233
|
+
regressão; acima disso, uma linha de justificativa na `description`. Cenários do mesmo
|
|
234
|
+
comportamento são linhas de tabela (`[Theory]`/`it.each`). **Nenhum teste que só fixa texto**
|
|
235
|
+
(copy, config, prosa). O `verify` avisa quando o teste adicionado passa de 1,5× a produção.
|
|
236
|
+
|
|
237
|
+
**Critério sobre saída de LLM vira eval de runtime — nunca "suíte estrutural".** Vale quando a seção
|
|
238
|
+
de contrato cita um standard `ai-agents` e o `doneCriteria` julga o que o modelo *responde*:
|
|
239
|
+
- a prova é um **eval de runtime**; a evidência vai em
|
|
322
240
|
`.morph/features/{feature}/3-implement/evidencias/{taskId}.md`, e esse path entra em
|
|
323
241
|
`outputs` — é por ele que implementador e avaliador sabem que ela é devida. Com nó
|
|
324
|
-
`runner: "evals"` (standard `ai-agents-evals-with-cache`), o cenário mora no dataset do
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
- escreva as duas coisas na `description` da task: é ela que chega ao sub-agente.
|
|
242
|
+
`runner: "evals"` (standard `ai-agents-evals-with-cache`), o cenário mora no dataset do nó;
|
|
243
|
+
- **no máximo 1 teste de estrutura** da fonte do prompt — nunca vocabulário do que o modelo
|
|
244
|
+
deveria dizer;
|
|
245
|
+
- as duas coisas vão na `description` da task.
|
|
329
246
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
**5c. Cross-check do `1-design/` — todo aviso de capacidade tem destino.** Se o diretório existe,
|
|
334
|
-
rode antes de fechar o array `tasks`:
|
|
247
|
+
**5c. Cross-check do `1-design/` — todo aviso de capacidade tem destino.** Com o diretório
|
|
248
|
+
presente, antes de fechar o array `tasks`:
|
|
335
249
|
|
|
336
250
|
```bash
|
|
337
251
|
grep -riE "capacidade nova|precisa de backend|dimensionar junto" .morph/features/{feature}/1-design/
|
|
338
252
|
```
|
|
339
253
|
|
|
340
|
-
Cada ocorrência
|
|
341
|
-
|
|
342
|
-
sem destino**. Medido em campo: duas ocorrências dessas passaram batidas em features reais e
|
|
343
|
-
viraram trabalho descoberto na fase implement, quando o escopo já estava aprovado no Gate 2.
|
|
344
|
-
Sem hits, ou sem `1-design/`, o passo é um no-op silencioso.
|
|
254
|
+
Cada ocorrência vira **task irmã** ou exclusão registrada em `decisions.md` com o motivo —
|
|
255
|
+
**nunca fica sem destino**. Sem hits, ou sem `1-design/`, o passo é um no-op.
|
|
345
256
|
|
|
346
|
-
**5d. O checklist de tela vira critério.**
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
no Gate 3 (`morph-review` §4). Item marcado "não se aplica" não vira critério.
|
|
257
|
+
**5d. O checklist de tela vira critério.** A task que entrega uma `## Tela:` do
|
|
258
|
+
`1-design/mockups.md` carrega no `doneCriteria` as decisões do `### Checklist de tela` (volume,
|
|
259
|
+
paginação, ordenação, filtro, os três estados, mobile, abas), citando a seção por path
|
|
260
|
+
(`1-design/mockups.md#tela-…`) — "lista pagina no servidor, 25 por página" é critério; "conforme
|
|
261
|
+
o mockup" não é. Item "não se aplica" não vira critério.
|
|
352
262
|
|
|
353
|
-
Antes de retornar, valide rodando `morph-spec dag {feature}` —
|
|
263
|
+
Antes de retornar, valide rodando `morph-spec dag {feature}` — schema do tasks.json (ids, enums,
|
|
264
|
+
dependências) e a análise de DAG que a `/morph-apply` vai usar.
|
|
354
265
|
|
|
355
266
|
6. Apresente o Gate 2 segundo trust mode.
|
|
356
267
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
`gate-check` **não herda** `designSystemDivergence` do Gate 1 automaticamente — é recomputado a cada chamada. Se a divergência do Gate 1 segue sem resolução, ou o mandate introduziu uma violação de standard, repasse via `--signals` (as únicas chaves que este comando aceita sobrescrever):
|
|
268
|
+
Rode `morph-spec gate-check {feature} plan [--json]` — decide pelos sinais do disco e persiste
|
|
269
|
+
`gateDecisions.plan`. Divergência de design system do Gate 1 sem resolução, ou violação de
|
|
270
|
+
standard, entram por `--signals` (as únicas chaves aceitas):
|
|
362
271
|
```
|
|
363
272
|
morph-spec gate-check {feature} plan --signals '{"designSystemDivergence":true,"standardsViolations":["<id>"]}'
|
|
364
273
|
```
|
|
274
|
+
Risco que nenhuma chave representa: `gate-decision` direto. Nunca edite `feature.json` à mão.
|
|
275
|
+
`morph-spec dag {feature} --mermaid` dá o diagrama do plano para o gate.
|
|
365
276
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
**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 tomada (pausar vs auto-aprovar) bateu com a decisão persistida.
|
|
369
|
-
|
|
370
|
-
**Se `pause === true`**, use `AskUserQuestion`:
|
|
277
|
+
**Se `pause === true`**, `AskUserQuestion`:
|
|
371
278
|
|
|
372
279
|
```
|
|
373
280
|
question: "Gate 2 — Plano de {feature} aprovado?{ reason ? ' Sinal: ' + reason : '' }"
|
|
374
281
|
header: "Gate 2"
|
|
375
282
|
options:
|
|
376
|
-
- { label: "aprovado, prosseguir", description: "Aceitar spec
|
|
283
|
+
- { label: "aprovado, prosseguir", description: "Aceitar use cases, spec e tasks e habilitar /morph-apply" }
|
|
377
284
|
- { label: "preciso ajustar", description: "Apontar mudanças no plano antes de prosseguir" }
|
|
378
285
|
- { label: "cancelar feature", description: "Abortar" }
|
|
379
286
|
```
|
|
380
287
|
|
|
381
|
-
|
|
288
|
+
**Se `pause === false`**: resumo de 3 linhas (problema → solução; tasks e esforço; caminho
|
|
289
|
+
crítico) e `morph-spec approve {feature} plan --mode auto` (ou `advance {feature}`). A pergunta
|
|
290
|
+
nomeia a feature — é por ela que o hook `state-sync` grava a aprovação.
|
|
382
291
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
```
|
|
386
|
-
## Gate 2 (auto-aprovado)
|
|
387
|
-
|
|
388
|
-
**Spec:** {1 frase} → {1 frase da solução}
|
|
389
|
-
**Mandate:** Stack: {stack} | Standards: {N obrigatórios} | Proibido: {N padrões}
|
|
390
|
-
**Tasks:** {N} | Esforço total: {soma} | Caminho crítico: {IDs sem deps paralelas}
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
No caminho manual, o hook state-sync registra a aprovação automaticamente em answers de AskUserQuestion (grava o gate no `feature.json` autoritativo, `approvedBy: "manual"`) — **atribuindo pela feature nomeada na pergunta**; sem o nome, e com mais de uma feature na árvore, ele recusa a gravar e avisa (aprove então por `morph-spec approve {feature} plan`). Em auto sem AskUserQuestion, aprove via `morph-spec approve {feature} plan --mode auto` (ou `morph-spec advance {feature}` para já criar a pasta da próxima fase) — nunca via Edit à mão de state.json.
|
|
292
|
+
Aprovado o Gate 2, o frontmatter de cada use case passa de `status: draft` a `status: approved`.
|
|
293
|
+
O `finish` os promove ao acervo com `status: implemented`.
|
|
394
294
|
|
|
395
295
|
## Output esperado
|
|
396
296
|
|
|
397
|
-
-
|
|
398
|
-
-
|
|
399
|
-
-
|
|
400
|
-
-
|
|
401
|
-
-
|
|
402
|
-
- Gate 2 registrado aprovado em `.morph/features/{feature}/feature.json` (autoritativo)
|
|
403
|
-
|
|
404
|
-
Ao registrar a aprovação do Gate 2, atualize o frontmatter de cada use case de `status: draft` para `status: approved`. O ciclo fecha na integração: `morph-spec finish` promove os use cases para o acervo permanente `.morph/specs/usecases/` já com `status: implemented` — até que uma feature posterior o revogue (passo 3) e ele passe a `status: superseded`, com `superseded_by` e, se parcial, `scope`. O status é **descritivo** — quem trava fase é o gate, não este campo.
|
|
297
|
+
- `2-plan/usecases/UC-{nn}-{slug}.md` — pós-condições testáveis
|
|
298
|
+
- `2-plan/spec.md` — arquitetura, seção de revogação e `## Contrato de implementação`
|
|
299
|
+
- `2-plan/tasks.json` — válido contra o schema, `doneCriteria` literal, `agent`/`standards`/`reuse`
|
|
300
|
+
carimbados, `3-implement/evidencias/{taskId}.md` em `outputs` nas tasks de critério sobre LLM
|
|
301
|
+
- Gate 2 registrado em `feature.json`
|
|
405
302
|
|
|
406
303
|
## Referências
|
|
407
304
|
|
|
408
|
-
- `.morph/framework/MORPH.md` —
|
|
409
|
-
- `morph-spec standards --find
|
|
410
|
-
- `.morph/framework/
|
|
411
|
-
- `.morph/framework/schemas/tasks.schema.json` — schema obrigatório de tasks.json
|
|
412
|
-
- `morph-spec graph explain|affected --uses-only` — "isto já existe?" e "quem usa de verdade" (passo 1c); **sem grafo, o fallback é `grep -rn`**
|
|
413
|
-
- `.morph/context/README.md` — inventário do projeto (entidades, endpoints, componentes com path); insumo declarado do passo 1c, atualizado por `morph-spec context refresh`
|
|
414
|
-
- `.morph/specs/usecases/` — acervo permanente de use cases do projeto (`usecase reserve` já lê antes de numerar; em `bug`, é onde mora o UC a corrigir; `status: superseded` não é comportamento vigente)
|
|
415
|
-
- `.morph/specs/adrs/` — índice dos ADRs que valem no projeto, um arquivo por ADR, mantido pelo `finish` (passo 1d); os `decisions.md` arquivados são história
|
|
416
|
-
- `morph-spec usecase check {feature}` — o ciclo de vida do acervo contra esta feature (revogações do `spec.md`, task sobre UC `superseded`), antes do Gate 2
|
|
417
|
-
- `.morph/features/{feature}/1-design/` — artefatos da fase uiux, insumo do passo 1 e do cross-check do passo 5c (ausente não é erro)
|
|
418
|
-
- `.morph/features/{feature}/0-proposal/proposal.md` — escopo da feature
|
|
419
|
-
- `.morph/features/{feature}/0-proposal/stack-scan.md` — contexto técnico detectado
|
|
420
|
-
- `.morph/framework/schemas/tasks.schema.json` — schema e enums de tasks.json
|
|
421
|
-
- `.morph/framework/standards/ai-agents/evals-with-cache.md` e `.morph/framework/standards/ai-agents/testing-ai.md` — o nó `runner: "evals"` e a fronteira eval × unit; insumos da regra de critério sobre saída de LLM (passo 5)
|
|
422
|
-
- `morph-spec dag {feature}` — valida o tasks.json e imprime a análise de DAG
|
|
423
|
-
- `.morph/framework/MORPH.md` §5 — regras de pausa de gate (trust mode)
|
|
305
|
+
- `.morph/framework/MORPH.md` — §2 (fases), §3 (contratos de output), §5 (gates)
|
|
306
|
+
- `morph-spec standards --find|graph explain|graph affected --uses-only|usecase reserve|usecase check|dag` — `.morph/framework/CLI.md`
|
|
307
|
+
- `.morph/framework/schemas/tasks.schema.json`
|