@polymorphism-tech/morph-spec 8.4.0 → 8.6.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/README.md +8 -5
- package/bin/morph-spec.js +13 -10
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +7 -4
- package/docs/QUICKSTART.md +7 -4
- package/framework/CLAUDE.md +11 -8
- package/framework/MORPH.md +24 -4
- package/framework/commands/morph-archive.md +11 -4
- package/framework/evals/rubrics/test-coverage.md +4 -1
- package/framework/hooks/shared/phase-utils.js +1 -0
- package/framework/rules/morph-workflow.md +2 -2
- package/framework/schemas/feature.schema.json +2 -2
- package/framework/schemas/tasks.schema.json +6 -1
- 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 +8 -5
- package/framework/skills/core/morph-brainstorming/SKILL.md +4 -3
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +3 -3
- package/framework/skills/core/morph-implement/SKILL.md +1 -1
- package/framework/skills/core/morph-plan/SKILL.md +83 -13
- package/framework/skills/core/morph-proposal/SKILL.md +1 -1
- package/framework/skills/core/morph-review/SKILL.md +4 -2
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/package.json +1 -1
- package/src/commands/project/worktree.js +154 -357
- package/src/commands/state/archive.js +186 -69
- package/src/commands/state/create.js +46 -2
- package/src/commands/state/finish.js +433 -0
- package/src/commands/tasks/dag.js +25 -2
- package/src/commands/validation/validate-feature.js +9 -2
- package/src/core/paths/output-schema.js +66 -6
- package/src/core/state/state-manager.js +2 -2
- package/src/dashboard/scanner/state-scanner.js +1 -1
- package/src/lib/agents/output-collector.js +5 -0
- package/src/lib/generators/handoff-generator.js +6 -4
- package/src/lib/git/default-branch.js +73 -0
- package/src/lib/specs/usecase-check.js +173 -0
- package/src/lib/specs/usecase-promoter.js +120 -0
- package/src/lib/tasks/tasks-json-parser.js +8 -0
- package/src/lib/worktree/env-allocator.js +1 -1
- package/src/utils/file-copier.js +2 -2
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: morph-plan
|
|
3
|
-
description: Guia a produção dos
|
|
3
|
+
description: Guia a produção dos artefatos de planejamento de uma feature (use cases, spec.md, mandate.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.6.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-plan
|
|
11
11
|
|
|
12
12
|
## Objetivo
|
|
13
13
|
|
|
14
|
-
Produzir `spec.md`, `mandate.md` e `tasks.json` com qualidade suficiente para abrir o Gate 2.
|
|
15
|
-
Os três artefatos
|
|
14
|
+
Produzir os **use cases**, `spec.md`, `mandate.md` e `tasks.json` com qualidade suficiente para abrir o Gate 2.
|
|
15
|
+
Os use cases definem o **comportamento**; os três artefatos seguintes definem o como e o quanto da feature.
|
|
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.
|
|
16
18
|
|
|
17
19
|
## Quando invocar
|
|
18
20
|
|
|
@@ -20,14 +22,70 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
|
|
|
20
22
|
|
|
21
23
|
## O que fazer
|
|
22
24
|
|
|
23
|
-
1. **Garanta que `proposal.md` e `stack-scan.md` estão no seu contexto antes de planejar.** Se não tem o conteúdo atual em contexto (sessão fresca, ou conteúdo possivelmente desatualizado), **use a tool Read para carregá-los** — não confie em cache de turnos anteriores. Na dúvida, Read. `.morph/features/{feature}/0-proposal/proposal.md` (escopo,
|
|
25
|
+
1. **Garanta que `proposal.md` e `stack-scan.md` estão no seu contexto antes de planejar.** Se não tem o conteúdo atual em contexto (sessão fresca, ou conteúdo possivelmente desatualizado), **use a tool Read para carregá-los** — não confie em cache de turnos anteriores. Na dúvida, Read. `.morph/features/{feature}/0-proposal/proposal.md` (problema, escopo, riscos — o comportamento é destilado aqui no passo 2, não vem pronto do proposal) e `.morph/features/{feature}/0-proposal/stack-scan.md` (contexto técnico detectado: greenfield vs brownfield, stack atual, drift). Em brownfield, o stack-scan informa decisões de spec/mandate — não invente padrões que conflitam com o detectado.
|
|
26
|
+
|
|
27
|
+
2. **Destile os use cases — ANTES de escrever `spec.md` e `tasks.json`.**
|
|
28
|
+
|
|
29
|
+
Um arquivo por use case em `.morph/features/{feature}/2-plan/usecases/UC-{nn}-{slug}.md`:
|
|
30
|
+
|
|
31
|
+
```markdown
|
|
32
|
+
---
|
|
33
|
+
id: UC-07
|
|
34
|
+
title: Listar veterinários com suas especialidades
|
|
35
|
+
actor: Visitante
|
|
36
|
+
status: draft
|
|
37
|
+
entities: [Vet, Specialty]
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Pré-condições
|
|
41
|
+
- Existe ao menos um veterinário cadastrado
|
|
42
|
+
|
|
43
|
+
## Cenário principal
|
|
44
|
+
1. Visitante acessa a listagem de veterinários
|
|
45
|
+
2. Sistema retorna os veterinários ordenados por sobrenome
|
|
46
|
+
3. Sistema exibe, para cada um, nome e especialidades
|
|
47
|
+
|
|
48
|
+
## Fluxos alternativos
|
|
49
|
+
- **A1** — Nenhum veterinário cadastrado → sistema exibe estado vazio
|
|
50
|
+
- **A2** — Veterinário sem especialidade → sistema exibe "sem especialidade"
|
|
51
|
+
|
|
52
|
+
## Pós-condições
|
|
53
|
+
- **P1** — A resposta contém todos os veterinários não arquivados
|
|
54
|
+
- **P2** — Cada veterinário traz suas especialidades em lista, nunca string concatenada
|
|
55
|
+
- **P3** — A ordenação por sobrenome é estável para nomes repetidos
|
|
56
|
+
|
|
57
|
+
## Delta de domínio
|
|
58
|
+
- `Vet.archivedAt` (novo, nullable) — habilita P1
|
|
59
|
+
- Nenhuma relação nova
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**A regra que sustenta a camada inteira: pós-condição precisa ser observável em teste.** "O sistema fica consistente" não passa. "A resposta contém todos os veterinários não arquivados" passa. Antes de escrever cada pós-condição, pergunte: *que asserção eu escreveria para verificar isto?* Se não há resposta, a pós-condição está mal formulada — reescreva ou descarte. Sem esse filtro a camada vira prosa e não chega ao `doneCriteria`.
|
|
24
63
|
|
|
25
|
-
|
|
64
|
+
**Identificador sequencial no projeto, não na feature.** Antes de numerar, leia o acervo `.morph/specs/usecases/` (se existir) mais os use cases das features ativas em `.morph/features/*/2-plan/usecases/`; tome o maior `UC-{nn}` e some um. Numerar por feature garante colisão no momento da promoção.
|
|
65
|
+
|
|
66
|
+
**Seções:** `Pré-condições` (o que já é verdade antes), `Cenário principal` (o caminho feliz, numerado), `Fluxos alternativos` (**A1**, **A2**… — cada alternativa aproxima uma user story; edge case de *comportamento* mora aqui, edge case *técnico* fica no `spec.md`), `Pós-condições` (**P1**, **P2**… — o que passa a ser verdade, cada uma testável) e `Delta de domínio` (**só o que muda**: campo novo, relação nova, invariante nova — o modelo completo continua sendo o código EF Core mais as migrations; se a feature não altera o domínio, escreva "nenhum").
|
|
67
|
+
|
|
68
|
+
**Quando é obrigatório** (ver MORPH.md §2.1 para o roteamento por tipo):
|
|
69
|
+
|
|
70
|
+
| Tipo | Use case |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `feature` | Obrigatório quando há comportamento observável. Feature puramente técnica (refactor, infra, migração) dispensa — **registre a dispensa em `decisions.md`**. |
|
|
73
|
+
| `bug` | Não cria novo: **copie** o `UC-{nn}-*.md` do acervo para `2-plan/usecases/` e **corrija ou adicione a pós-condição** lá — o bug é a pós-condição que faltava. |
|
|
74
|
+
| `chore` | Nenhum (já pula a fase plan por política). |
|
|
75
|
+
| `hotfix` | Não bloqueia. Referencia se existir; o pós-mortem pode virar pós-condição numa feature posterior. |
|
|
76
|
+
|
|
77
|
+
**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.
|
|
78
|
+
|
|
79
|
+
O use case fica **editável depois do Gate 2**, por design — é o que permite mudar o comportamento e re-rodar `implement`. A trilha de auditoria fica no git.
|
|
80
|
+
|
|
81
|
+
3. Produza `spec.md` em `.morph/features/{feature}/2-plan/`:
|
|
26
82
|
- Arquitetura da solução: quais componentes, como se conectam, fluxos de dados principais.
|
|
27
|
-
- Edge cases
|
|
83
|
+
- Edge cases **técnicos** e como serão tratados (os de comportamento estão nos fluxos alternativos dos use cases).
|
|
28
84
|
- Integrações externas e contratos esperados.
|
|
29
85
|
|
|
30
|
-
|
|
86
|
+
O `spec.md` responde **como** os use cases do passo 2 serão realizados. Não repita o comportamento aqui.
|
|
87
|
+
|
|
88
|
+
4. Produza `mandate.md` em `.morph/features/{feature}/2-plan/`:
|
|
31
89
|
- Stack exata do projeto (leia de `.morph/config/config.json` → `project.stack` ou do CLAUDE.md).
|
|
32
90
|
- Standards obrigatórios: liste os IDs relevantes de `.morph/framework/standards/STANDARDS.json`.
|
|
33
91
|
- Patterns proibidos — inclua sempre os defaults abaixo mais qualquer específico da feature:
|
|
@@ -41,7 +99,7 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
|
|
|
41
99
|
- **Features com agentes de IA (MAF):** se a feature envolve um agente (Microsoft Agent Framework), **use a tool Read** nos standards relevantes de `framework/standards/ai-agents/*.md` (ex.: `setup`, `agent-session`, `middleware-patterns`, `mcp-server`, `mcp-tools`, `multi-agent-patterns`, `production`) — filtre pelo que a feature exige via STANDARDS.json. Esses standards carregam as **convenções de projeto** (single-agent por padrão — Workflows só para fan-in/out real; provider, caching, observability, A2A) que uma fonte externa de docs (ex.: context7) não conhece. Padrão de divisão: **superfície da API** pode vir de docs ao vivo/context7 (mais frescas para um SDK em evolução), mas **as convenções vêm dos standards** — registre ambas no mandate. Não pule os `ai-agents/*.md` só porque o STANDARDS.json index lista que eles existem.
|
|
42
100
|
- Checklist de done com critérios verificáveis por tarefa.
|
|
43
101
|
|
|
44
|
-
|
|
102
|
+
5. Produza `tasks.json` em `.morph/features/{feature}/2-plan/` seguindo o schema em `.morph/framework/schemas/tasks.schema.json`.
|
|
45
103
|
|
|
46
104
|
**Formato obrigatório** (schema em `.morph/framework/schemas/tasks.schema.json` — o hook `tasks-json-guard` valida cada write):
|
|
47
105
|
|
|
@@ -56,10 +114,11 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
|
|
|
56
114
|
"description": "Detalhes — o que esta task realiza e por quê",
|
|
57
115
|
"dependencies": [],
|
|
58
116
|
"effort": "S",
|
|
59
|
-
"doneCriteria": "
|
|
117
|
+
"doneCriteria": "P2 — Cada veterinário traz suas especialidades em lista, nunca string concatenada",
|
|
60
118
|
"status": "pending",
|
|
61
119
|
"outputs": [],
|
|
62
|
-
"group": "backend"
|
|
120
|
+
"group": "backend",
|
|
121
|
+
"usecase": "UC-07"
|
|
63
122
|
}
|
|
64
123
|
]
|
|
65
124
|
}
|
|
@@ -72,12 +131,19 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
|
|
|
72
131
|
- `status` inicia sempre como `pending`.
|
|
73
132
|
- `group` (opcional): backend, frontend, tests, infra, docs. Default backend.
|
|
74
133
|
- `outputs` (opcional): array de paths que serão criados/modificados.
|
|
134
|
+
- `usecase` (opcional): o **ID** do use case que a task realiza — `UC-07`, nunca o nome do arquivo. Task puramente técnica (build, config, migração) não tem.
|
|
135
|
+
|
|
136
|
+
**O `doneCriteria` carrega a pós-condição LITERAL.** Este é o elo que amarra a cadeia inteira: a pós-condição escrita em linguagem de negócio chega **sem tradução** ao critério que o `morph-spec verify` e o `morph-eval` cobram. Copie o texto da pós-condição, prefixado pelo seu rótulo (`"P2 — Cada veterinário traz..."`). Reescrever com outras palavras aqui é exatamente o ponto em que o requisito se perde hoje.
|
|
137
|
+
|
|
138
|
+
**`morph-spec dag {feature}` cobra o encanamento.** Ele lê os use cases junto com o `tasks.json` e reporta: referência a um `UC-{nn}` inexistente (**erro** — trava), pós-condição que nenhuma task cita (aviso) e task que referencia um UC mas parafraseou em vez de copiar (aviso). A comparação normaliza caixa e espaço, então prefixar o rótulo não quebra o casamento — mas a redação e os acentos precisam bater. O que o `dag` **não** julga é se a pós-condição é observável em teste: isso é semântico e continua sendo trabalho seu no Gate 2 e do evaluator.
|
|
139
|
+
|
|
140
|
+
Cada pós-condição de cada use case deve estar coberta por **pelo menos uma** task. Antes de fechar o `tasks.json`, percorra os `UC-*.md` e confira: sobrou pós-condição sem task? Ou o plano está incompleto, ou a pós-condição não era necessária — resolva antes do Gate 2, não depois.
|
|
75
141
|
|
|
76
142
|
**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).
|
|
77
143
|
|
|
78
144
|
Antes de retornar, valide rodando `morph-spec dag {feature}` — o comando parseia e valida o schema do tasks.json (ids únicos `T\d+`, enums de `status`/`effort`, `dependencies` válidas) e já imprime a análise de DAG que a `/morph-apply` vai usar. Erros de schema abortam com a lista do que corrigir.
|
|
79
145
|
|
|
80
|
-
|
|
146
|
+
6. Apresente o Gate 2 segundo trust mode.
|
|
81
147
|
|
|
82
148
|
Você pode embutir o diagrama do DAG do plano via `morph-spec dag {feature} --mermaid` (flowchart Mermaid) para visualização no gate.
|
|
83
149
|
|
|
@@ -124,16 +190,20 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
|
|
|
124
190
|
|
|
125
191
|
## Output esperado
|
|
126
192
|
|
|
193
|
+
- `.morph/features/{feature}/2-plan/usecases/UC-{nn}-{slug}.md` — um arquivo por use case, com pós-condições testáveis
|
|
127
194
|
- `.morph/features/{feature}/2-plan/spec.md` — especificação técnica completa
|
|
128
195
|
- `.morph/features/{feature}/2-plan/mandate.md` — contrato de implementação
|
|
129
|
-
- `.morph/features/{feature}/2-plan/tasks.json` — task list estruturada válida contra schema
|
|
196
|
+
- `.morph/features/{feature}/2-plan/tasks.json` — task list estruturada válida contra schema, com o `doneCriteria` carregando a pós-condição literal
|
|
130
197
|
- Gate 2 registrado aprovado em `.morph/features/{feature}/feature.json` (autoritativo)
|
|
131
198
|
|
|
199
|
+
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`. O status é **descritivo** — quem trava fase é o gate, não este campo.
|
|
200
|
+
|
|
132
201
|
## Referências
|
|
133
202
|
|
|
134
203
|
- `.morph/framework/MORPH.md` — seções 2 (Fases), 3 (Contratos de Output), 5 (Gates), Trust Mode
|
|
135
204
|
- `.morph/framework/standards/STANDARDS.json` — para identificar standards relevantes ao mandate
|
|
136
205
|
- `.morph/framework/schemas/tasks.schema.json` — schema obrigatório de tasks.json
|
|
206
|
+
- `.morph/specs/usecases/` — acervo permanente de use cases do projeto (leia antes de numerar; em `bug`, é onde mora o UC a corrigir)
|
|
137
207
|
- `.morph/features/{feature}/0-proposal/proposal.md` — escopo da feature
|
|
138
208
|
- `.morph/features/{feature}/0-proposal/stack-scan.md` — contexto técnico detectado
|
|
139
209
|
- `.morph/framework/schemas/tasks.schema.json` — schema e enums de tasks.json
|
|
@@ -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.6.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-proposal
|
|
@@ -4,7 +4,7 @@ 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.6.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-review
|
|
@@ -102,7 +102,7 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
|
|
|
102
102
|
question: "Gate 3 — Review de {feature} aprovado?{ reason ? ' Sinal: ' + reason : '' }"
|
|
103
103
|
header: "Gate 3"
|
|
104
104
|
options:
|
|
105
|
-
- { label: "aprovado, fechar feature", description: "Marcar
|
|
105
|
+
- { label: "aprovado, fechar feature", description: "Marcar review aprovado; próximo passo é fechar com morph-spec finish --pr|--merge (ver morph-apply §6)" }
|
|
106
106
|
- { label: "preciso ajustar", description: "Apontar correções necessárias antes de fechar" }
|
|
107
107
|
- { label: "rollback", description: "Desfazer e voltar para implement" }
|
|
108
108
|
```
|
|
@@ -120,6 +120,8 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
|
|
|
120
120
|
|
|
121
121
|
No caminho manual, o hook state-sync detecta a aprovação em answers de AskUserQuestion e grava `approvalGates.review = { approved: true, timestamp, approvedBy: "manual" }` no `feature.json` autoritativo da feature. Em auto sem AskUserQuestion, aprove via `morph-spec approve {feature} review --mode auto` — nunca via Edit à mão de state.json.
|
|
122
122
|
|
|
123
|
+
**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.
|
|
124
|
+
|
|
123
125
|
## Output esperado
|
|
124
126
|
- `.morph/features/{feature}/4-review/evaluator-report.md` — relatório bruto e autoritativo do
|
|
125
127
|
`morph-evaluator` despachado no passo 4 (canal durável, ver MORPH.md §6)
|
|
@@ -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.6.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-stack-scan
|
|
@@ -4,7 +4,7 @@ description: Localiza e carrega um standard específico do STANDARDS.json sob de
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: quando precisar consultar um standard específico durante a implementação
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.6.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-standards
|