@polymorphism-tech/morph-spec 8.0.0 → 8.1.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 +2 -2
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +1 -1
- package/framework/MORPH.md +5 -5
- package/framework/agents.json +1 -1
- package/framework/hooks/README.md +0 -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 +12 -21
- package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +2 -4
- package/framework/skills/core/morph-implement/SKILL.md +10 -19
- package/framework/skills/core/morph-plan/SKILL.md +1 -1
- package/framework/skills/core/morph-proposal/SKILL.md +1 -1
- package/framework/skills/core/morph-review/SKILL.md +11 -15
- 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/utils/hooks-installer.js +3 -24
- package/framework/hooks/claude-code/core/subagent-report-guard.js +0 -95
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> Spec-driven development framework for multi-stack projects. Turns feature requests into implementation-ready code through structured, AI-orchestrated phases.
|
|
4
4
|
|
|
5
5
|
**Package:** `@polymorphism-tech/morph-spec`
|
|
6
|
-
**Version:** 8.
|
|
6
|
+
**Version:** 8.1.0
|
|
7
7
|
**Requires:** Node.js 22+, Claude Code
|
|
8
8
|
|
|
9
9
|
---
|
|
@@ -394,4 +394,4 @@ Code generated by morph-spec (contracts, templates, implementation output) belon
|
|
|
394
394
|
|
|
395
395
|
---
|
|
396
396
|
|
|
397
|
-
*morph-spec v8.
|
|
397
|
+
*morph-spec v8.1.0 by [Polymorphism Tech](https://polymorphism.tech)*
|
package/claude-plugin.json
CHANGED
package/docs/CHEATSHEET.md
CHANGED
package/docs/QUICKSTART.md
CHANGED
package/framework/CLAUDE.md
CHANGED
|
@@ -25,7 +25,7 @@ Se não houver feature ativa, pergunte ao usuário qual feature trabalhar.
|
|
|
25
25
|
- Apresentar gates com o template fixo definido em MORPH.md / morph-plan.
|
|
26
26
|
- Registrar decisões não triviais em `decisions.md`.
|
|
27
27
|
- Aplicar `morph-eval` após cada tarefa; silêncio em score ≥ 9 é o sinal correto. Score < 9 dispara o loop de correção autônomo (re-implementa, sem pausa), não escala ao humano entre tarefas. No Gate 3, o score composto da feature vem do **avaliador independente** despachado pela `morph-review` (persona `evaluator`, contexto fresco) — nunca de auto-avaliação de quem implementou.
|
|
28
|
-
- Incluir as 3 cláusulas
|
|
28
|
+
- Incluir as 3 cláusulas do contrato do relatório final em todo dispatch de sub-agent (**ato final = o relatório é a ÚLTIMA MENSAGEM DE TEXTO do sub-agent, com os 4 itens obrigatórios (o quê / arquivos / problemas / auto-score 0-10) — ela é o valor de retorno e chega inteira ao orquestrador; não chamar `SendMessage`, que gera um evento a mais e custa um turno inútil**; não tocar tasks.json/feature.json/board; sem build/test da suíte compartilhada em batch paralelo) — templates em `morph-implement` §4 e `morph-apply` §3b.
|
|
29
29
|
|
|
30
30
|
## Slash commands
|
|
31
31
|
|
package/framework/MORPH.md
CHANGED
|
@@ -250,7 +250,7 @@ Inline (sem dispatch) é aceitável para tasks curtas (effort S/M) **dentro do d
|
|
|
250
250
|
|
|
251
251
|
**Mecanismo de dispatch:** os agents de domínio são subagents **registrados** (`.claude/agents/morph-{id}.md`, gerados de `agents.json` — a fonte única — na instalação). Despache com `subagent_type: "morph-{id}"` (ex.: `morph-dotnet-senior`): a persona é o **system prompt** do subagent, com tools, model e MCPs definidos por domínio no próprio `agents.json` (ex.: `context7` para docs vivas nos implementadores; Stitch/Gemini/Playwright no `morph-ui-designer`; o `morph-evaluator` é read-only). **Fallback** quando o tipo não está registrado (stack não instalado neste projeto): `general-purpose` com o campo `persona` de `agents.json` colado no prompt, **registrado nas `notes` da task**. O `**Persona:**` do recap registra sempre o mecanismo real usado — nunca uma auto-declaração.
|
|
252
252
|
|
|
253
|
-
**Persona de estágio — scout:** além das personas de domínio, existe o `morph-scout` (read-only: Read/Glob/Grep/Bash somente-leitura). Despache-o quando precisar de um mapa do território sem contaminar a thread principal — obrigatoriamente no início de um hotfix (localizar root cause + blast radius) e opcionalmente antes do plan de uma feature grande (buscar código, docs e specs anteriores relevantes). Ele devolve um mapa curto
|
|
253
|
+
**Persona de estágio — scout:** além das personas de domínio, existe o `morph-scout` (read-only: Read/Glob/Grep/Bash somente-leitura). Despache-o quando precisar de um mapa do território sem contaminar a thread principal — obrigatoriamente no início de um hotfix (localizar root cause + blast radius) e opcionalmente antes do plan de uma feature grande (buscar código, docs e specs anteriores relevantes). Ele devolve um mapa curto como relatório final e encerra; não escreve código.
|
|
254
254
|
|
|
255
255
|
**O que passar ao sub-agent:**
|
|
256
256
|
- Especificação da tarefa (do tasks.json)
|
|
@@ -269,10 +269,10 @@ Inline (sem dispatch) é aceitável para tasks curtas (effort S/M) **dentro do d
|
|
|
269
269
|
- Problemas encontrados e como foram resolvidos
|
|
270
270
|
- Auto-score 0-10 com justificativa em uma linha
|
|
271
271
|
|
|
272
|
-
**
|
|
273
|
-
1. **ATO FINAL:
|
|
272
|
+
**Contrato do relatório final** (cláusulas que todo prompt de dispatch inclui — ver templates em `morph-implement` §4 e `morph-apply` §3b):
|
|
273
|
+
1. **ATO FINAL: o seu relatório é a sua ÚLTIMA MENSAGEM DE TEXTO** — ela é o valor de retorno do sub-agent e chega inteira ao orquestrador. **Não chame `SendMessage`**: ele gera um evento a mais (o teammate-message) além da notificação de término, custando um turno inútil ao orquestrador. Conteúdo obrigatório: (1) o que foi feito em 2-3 frases, (2) arquivos modificados, (3) problemas encontrados e como foram resolvidos, (4) auto-score 0-10 com justificativa em uma linha. Relatório oco ou sem os 4 itens é **falha de protocolo** — registrada no recap.
|
|
274
274
|
2. Não tocar em `tasks.json`, `feature.json`, `state.json` nem no board de sessão (TaskCreate/TaskUpdate) — todo estado é gravado exclusivamente pelo orquestrador.
|
|
275
|
-
3. **Verificação em batch paralelo — condicional ao isolamento:** em batch **sem isolamento** (agentes na mesma working tree), não rode build/test da suíte compartilhada — a verificação (`morph-spec verify`) é do orquestrador, uma vez, pós-batch. Em batch **com `isolation: "worktree"`** (quando o `morph-spec dag` recomenda, por colisão de `outputs` entre fluxos), a regra se inverte: rode build/test **dentro do seu worktree**, commite o trabalho na branch do worktree como
|
|
275
|
+
3. **Verificação em batch paralelo — condicional ao isolamento:** em batch **sem isolamento** (agentes na mesma working tree), não rode build/test da suíte compartilhada — a verificação (`morph-spec verify`) é do orquestrador, uma vez, pós-batch. Em batch **com `isolation: "worktree"`** (quando o `morph-spec dag` recomenda, por colisão de `outputs` entre fluxos), a regra se inverte: rode build/test **dentro do seu worktree**, commite o trabalho na branch do worktree como último ato antes do relatório, reporte a branch + status de build, e **nunca** faça merge nem toque na árvore principal — a integração é do orquestrador.
|
|
276
276
|
|
|
277
277
|
O sub-agent deve ser autossuficiente com o que você passou. Se precisar de mais contexto para começar, a tarefa não estava bem especificada — refine antes de despachar.
|
|
278
278
|
|
|
@@ -281,7 +281,7 @@ O sub-agent deve ser autossuficiente com o que você passou. Se precisar de mais
|
|
|
281
281
|
- Quando o feedback do sub-agent precisaria ser discutido em tempo real — dispatch é assíncrono.
|
|
282
282
|
- Quando a tarefa envolve mudanças de arquitetura que o Orchestrator precisa validar antes de executar.
|
|
283
283
|
|
|
284
|
-
**Após receber o retorno do sub-agent:** leia o auto-score — ele é **triagem, não aprovação**. Se for < 7, re-despache com o feedback específico (ou corrija inline) antes de avaliar. Em qualquer caso, a task só avança quando `morph-eval` der score ≥ 9 (a barra única do §0); integre o resultado ao recap.md e siga para a próxima tarefa.
|
|
284
|
+
**Após receber o retorno do sub-agent:** leia o auto-score — ele é **triagem, não aprovação**. Se for < 7, re-despache com o feedback específico (ou corrija inline) antes de avaliar. Em qualquer caso, a task só avança quando `morph-eval` der score ≥ 9 (a barra única do §0); integre o resultado ao recap.md e siga para a próxima tarefa.
|
|
285
285
|
|
|
286
286
|
> **Anti-padrão a evitar:** implementar múltiplas tasks de domínios diferentes inline, em sequência, na thread principal — "eu já sei o padrão de cada uma". Isso é exatamente o sinal de que o sistema de delegação foi ignorado. Quando uma feature cruza ≥2 domínios, o caminho default é o Orchestrator despachando especialistas, não o Orchestrator virando faz-tudo.
|
|
287
287
|
|
package/framework/agents.json
CHANGED
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"standards": [],
|
|
156
156
|
"tools": "Read, Glob, Grep, Bash",
|
|
157
157
|
"model": "haiku",
|
|
158
|
-
"persona": "Você é um scout read-only: mapeia o território sem escrever código. Dado um sintoma ou uma feature, localiza os arquivos relevantes, o root cause provável e o blast radius (o que mais é afetado). Usa Read/Glob/Grep e Bash SOMENTE-LEITURA (git log/diff/show, ls, cat) — nunca Write/Edit, nunca comandos que mudam estado. Devolve um mapa curto e acionável (arquivos com paths, hipótese de causa, áreas de impacto)
|
|
158
|
+
"persona": "Você é um scout read-only: mapeia o território sem escrever código. Dado um sintoma ou uma feature, localiza os arquivos relevantes, o root cause provável e o blast radius (o que mais é afetado). Usa Read/Glob/Grep e Bash SOMENTE-LEITURA (git log/diff/show, ls, cat) — nunca Write/Edit, nunca comandos que mudam estado. Devolve um mapa curto e acionável (arquivos com paths, hipótese de causa, áreas de impacto) como relatório final e encerra. Não implementa, não corrige — ilumina o caminho para quem vai."
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
}
|
|
@@ -53,7 +53,6 @@ framework/hooks/
|
|
|
53
53
|
| **PostToolUse** (Write\|Edit\|AskUserQuestion) | gate-guard.js | Advisory | Warns (never blocks) when a gate action disagrees with the persisted gateDecisions; logs one `coherent`/`divergent` line per check in `.morph/logs/activity.json` (issue #63) |
|
|
54
54
|
| **PostToolUse** (all tools) | loop-detect.js | Advisory | Warns when the last 8 actions collapse to ≤2 unique signatures |
|
|
55
55
|
| **Stop** | validate-completion.js | Advisory | Warns about incomplete tasks/missing outputs/recap drift; build check; session snapshot |
|
|
56
|
-
| **Stop** / **SubagentStop** | subagent-report-guard.js | Block (once) | Blocks a dispatched sub-agent stopping without SendMessage (clause 1 of the dispatch protocol) and injects the exact instruction; `stop_hook_active` prevents loops; inert in the orchestrator's session |
|
|
57
56
|
|
|
58
57
|
## Design Principles
|
|
59
58
|
|
|
@@ -4,7 +4,7 @@ description: Guia a criação de uma landing page nova ponta-a-ponta a partir do
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao iniciar um novo projeto de LP com o template Umbraco genérico
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.1.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# create-umbraco-lp
|
|
@@ -4,7 +4,7 @@ description: Migra uma landing page existente (React/Vite, Next.js estático ou
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao receber instrução "use /migrate-lp-to-umbraco {projeto}" do usuário, ou quando o usuário descrever necessidade de migrar uma LP para Umbraco
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.1.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# migrate-lp-to-umbraco
|
|
@@ -4,7 +4,7 @@ description: Orquestra a execução autônoma de tasks de uma feature morph-spec
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: após Gate 2 aprovado, ao receber instrução "use /morph-apply" ou "implementar feature"
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.1.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-apply
|
|
@@ -134,21 +134,12 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
|
|
|
134
134
|
Implemente esta task (ou cadeia de tasks do fluxo) isoladamente.
|
|
135
135
|
Não modifique spec.md, mandate.md.
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
1. ATO FINAL
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
confirmação" — o SendMessage É o encerramento, não um passo
|
|
144
|
-
intermediário.
|
|
145
|
-
Exemplo literal (última chamada de tool da sua sessão, sem nada depois):
|
|
146
|
-
SendMessage({ to: "main", content: "Fluxo backend concluído (T2→T7).
|
|
147
|
-
Sumário: ... Arquivos: src/... Standards: vsa-handler-patterns.
|
|
148
|
-
Auto-score: 9/10" })
|
|
149
|
-
Terminar idle sem SendMessage, ou continuar agindo depois dele, é
|
|
150
|
-
falha de protocolo — cada segundo entre o SendMessage e o fim real do
|
|
151
|
-
turno é cauda que o orquestrador espera sem necessidade.
|
|
137
|
+
Contrato do relatório final:
|
|
138
|
+
1. ATO FINAL — o seu relatório é a sua ÚLTIMA MENSAGEM DE TEXTO: ela é o
|
|
139
|
+
valor de retorno desta sessão e chega inteira ao orquestrador. NÃO chame
|
|
140
|
+
SendMessage: ele gera um evento a mais além da notificação de término,
|
|
141
|
+
custando um turno inútil ao orquestrador. Escreva o relatório e encerre.
|
|
142
|
+
Relatório oco, ou sem os itens abaixo, é falha de protocolo.
|
|
152
143
|
2. NÃO toque em tasks.json, feature.json, state.json nem no board de sessão
|
|
153
144
|
(TaskCreate/TaskUpdate) — todo estado (status de task, scores, gates) é
|
|
154
145
|
gravado exclusivamente pelo orquestrador.
|
|
@@ -158,21 +149,21 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
|
|
|
158
149
|
a verificação é do orquestrador, uma vez, pós-batch (`morph-spec verify`).
|
|
159
150
|
- Batch COM isolamento (você recebeu `isolation: "worktree"`): rode build/test
|
|
160
151
|
DENTRO do seu worktree; commite seu trabalho na branch do worktree como
|
|
161
|
-
|
|
152
|
+
último ato antes do relatório; reporte a branch + status de build no
|
|
162
153
|
relatório; NUNCA faça merge nem toque na árvore principal.
|
|
163
154
|
|
|
164
|
-
|
|
155
|
+
Seu relatório final deve conter:
|
|
165
156
|
- sumário das mudanças
|
|
166
157
|
- arquivos modificados (paths)
|
|
167
158
|
- standard(s) consultado(s)
|
|
168
159
|
- auto-score 0-10 (rubric: completeness, correctness, mandate compliance)
|
|
169
160
|
```
|
|
170
161
|
|
|
171
|
-
> Este template é deliberadamente paritário com o template sequencial em `morph-implement` §4: ambos despacham o **subagent registrado do domínio (`morph-{id}`)** com standard escopado e as mesmas cláusulas
|
|
162
|
+
> Este template é deliberadamente paritário com o template sequencial em `morph-implement` §4: ambos despacham o **subagent registrado do domínio (`morph-{id}`)** com standard escopado e as mesmas cláusulas do contrato do relatório final. A única diferença é que aqui múltiplos agentes rodam ao mesmo tempo, um por fluxo independente.
|
|
172
163
|
|
|
173
164
|
> **Alternativa quando os fluxos tocam os mesmos projetos/arquivos** (ex.: o mesmo csproj de testes compartilhado): siga a §3b-w abaixo em vez desta seção — despache com `isolation: "worktree"`, cada agente trabalha numa working tree própria e o orquestrador integra ao final.
|
|
174
165
|
|
|
175
|
-
Aguardar todos os agentes terminarem
|
|
166
|
+
Aguardar todos os agentes terminarem — o relatório de cada um chega como o resultado do seu dispatch. Se um relatório vier oco ou sem os itens da cláusula 1, registre a falha de protocolo no recap. Depois, sequencialmente:
|
|
176
167
|
- **Rodar `morph-spec verify {feature} --json` uma única vez, pós-batch** (escopo feature) — os agentes não a rodaram (cláusula 3). Vermelho: use `verify.feedback` para corrigir/redespachar ANTES de qualquer morph-eval. (Com isolamento por worktree, cada agente já rodou o verify dentro do seu worktree; o orquestrador roda o verify compartilhado UMA vez após o merge — ver §3b-w.)
|
|
177
168
|
- Para cada relatório retornado:
|
|
178
169
|
- Aplicar `Skill(morph-eval)`.
|
|
@@ -187,7 +178,7 @@ Depois do batch paralelo, executar o restante em modo sequencial (passo 3a).
|
|
|
187
178
|
Quando o `morph-spec dag {feature}` reporta `isolation.recommended: "worktree"` (dois fluxos paralelos planejam escrever no mesmo path — colisão de `outputs`), despache cada fluxo com o parâmetro `isolation: "worktree"` do tool Agent. Cada agente trabalha numa working tree própria; build/test rodam lá dentro sem colidir.
|
|
188
179
|
|
|
189
180
|
1. **Dispatch:** mesmo `subagent_type: "morph-{id}"` e standards de §3b, mais `isolation: "worktree"`. Se a stack for Node e faltar `node_modules` no worktree, o agente roda `morph-spec worktree link` (fail-open) antes de testar; se ainda impossível, reporta "verificação: não executada" (o verify pós-merge cobre). O agente commita na branch do worktree e reporta a branch.
|
|
190
|
-
2. **Integração (orquestrador, após todos os relatórios
|
|
181
|
+
2. **Integração (orquestrador, após todos os relatórios):** faça o merge de cada branch reportada, uma por vez, na ordem de chegada — `git merge --no-ff <branch>`. Conflito → `git merge --abort`, marque a task de volta a `pending` com nota "merge conflict — reexecutar sequencial", siga para a próxima branch. Os paths em conflito são exatamente os de `isolation.collisions` do dag.
|
|
191
182
|
3. **Pós-merge:** rode `morph-spec verify {feature} --json` UMA vez (o merge é o novo ponto de integração — verificação compartilhada obrigatória), depois `morph-eval` + `morph-spec score` por relatório, como em §3b.
|
|
192
183
|
4. **Cleanup:** `git worktree remove` + `git branch -d` das branches integradas + `git worktree prune` (fail-open). Branches não integradas ficam e são registradas no recap com o motivo.
|
|
193
184
|
5. **Agente morto no meio:** se commitou, a branch sobrevive (retomável); senão, a task volta a `pending` na lane sequencial. Registre a falha de protocolo no recap.
|
|
@@ -4,7 +4,7 @@ description: Entende o negócio, os usuários e a arquitetura antes de qualquer
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao receber um novo request de feature, antes de morph-plan
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.1.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-brainstorming
|
|
@@ -4,7 +4,7 @@ description: Avalia a qualidade de uma tarefa ou fase com rubricas graduadas 0-1
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao completar uma tarefa ou ao finalizar uma fase de implementação
|
|
6
6
|
user-invokable: false
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.1.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-eval
|
|
@@ -4,7 +4,7 @@ description: ADW cirúrgico de hotfix — resolve uma queda/bug crítico de prod
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao receber "/morph-hotfix {feature}", quando a morph-proposal classifica o pedido como workType hotfix (Passo 0), ou o usuário diz "produção caiu / hotfix / urgente"
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.1.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-hotfix
|
|
@@ -43,9 +43,7 @@ subagent_type: "morph-scout"
|
|
|
43
43
|
|
|
44
44
|
**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, **registrando o fallback nas notes da task**.
|
|
45
45
|
|
|
46
|
-
Peça ao scout: localizar o root cause provável, os arquivos afetados e o blast radius (o que mais pode quebrar). Ele é read-only (Read/Glob/Grep/Bash somente-leitura) — não escreve código. Inclua as 3 cláusulas
|
|
47
|
-
|
|
48
|
-
Ao receber o mapa via `SendMessage`, **libere a sessão imediatamente**: `TaskStop(task_id: <id/nome retornado pelo dispatch>)` (trate falha como não-fatal).
|
|
46
|
+
Peça ao scout: localizar o root cause provável, os arquivos afetados e o blast radius (o que mais pode quebrar). Ele é read-only (Read/Glob/Grep/Bash somente-leitura) — não escreve código. Inclua as 3 cláusulas do contrato do relatório final no prompt (template literal em `morph-implement` §4 / `morph-apply` §3b): ato final = o relatório é a última mensagem de texto, sem `SendMessage`; não tocar `tasks.json`/`feature.json`/`state.json` nem o board de sessão; sem build/test da suíte compartilhada em batch paralelo.
|
|
49
47
|
|
|
50
48
|
### 3. Hotfix brief (`0-proposal/proposal.md`)
|
|
51
49
|
|
|
@@ -4,7 +4,7 @@ description: Guia a execução de cada tarefa de implementação com standard e
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao iniciar cada task de implementação listada em tasks.json
|
|
6
6
|
user-invokable: false
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.1.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-implement
|
|
@@ -58,21 +58,12 @@ Ao iniciar cada task de `tasks.json` — antes de escrever qualquer código. Nor
|
|
|
58
58
|
Arquivos relevantes: [lista de paths]
|
|
59
59
|
Done quando: [doneCriteria do tasks.json]
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
1. ATO FINAL
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
confirmação" — o SendMessage É o encerramento, não um passo
|
|
68
|
-
intermediário antes de um encerramento "de verdade".
|
|
69
|
-
Exemplo literal (última chamada de tool da sua sessão, sem nada depois):
|
|
70
|
-
SendMessage({ to: "main", content: "T{N} concluída. (1) O que foi feito:
|
|
71
|
-
handler + validator do slice X. (2) Arquivos: src/Features/X/Handler.cs,
|
|
72
|
-
tests/X/HandlerTests.cs. (3) Problemas: nenhum. (4) Auto-score: 9/10" })
|
|
73
|
-
Terminar idle sem SendMessage, ou continuar agindo depois dele, é
|
|
74
|
-
falha de protocolo — cada segundo entre o SendMessage e o fim real do
|
|
75
|
-
turno é cauda que o orquestrador espera sem necessidade.
|
|
61
|
+
Contrato do relatório final:
|
|
62
|
+
1. ATO FINAL — o seu relatório é a sua ÚLTIMA MENSAGEM DE TEXTO: ela é o
|
|
63
|
+
valor de retorno desta sessão e chega inteira ao orquestrador. NÃO chame
|
|
64
|
+
SendMessage: ele gera um evento a mais além da notificação de término,
|
|
65
|
+
custando um turno inútil ao orquestrador. Escreva o relatório e encerre.
|
|
66
|
+
Relatório oco, ou sem os 4 itens abaixo, é falha de protocolo.
|
|
76
67
|
2. NÃO toque em tasks.json, feature.json, state.json nem no board de sessão
|
|
77
68
|
(TaskCreate/TaskUpdate) — todo estado é gravado exclusivamente pelo
|
|
78
69
|
orquestrador.
|
|
@@ -80,14 +71,14 @@ Ao iniciar cada task de `tasks.json` — antes de escrever qualquer código. Nor
|
|
|
80
71
|
NÃO rode build/test da suíte compartilhada — a verificação
|
|
81
72
|
(`morph-spec verify`) é do orquestrador, uma vez, pós-batch. Em batch
|
|
82
73
|
COM `isolation: "worktree"`, rode build/test dentro do seu worktree,
|
|
83
|
-
commite na branch do worktree como
|
|
74
|
+
commite na branch do worktree como último ato antes do relatório
|
|
84
75
|
e reporte a branch — nunca faça merge.
|
|
85
76
|
|
|
86
|
-
|
|
77
|
+
Seu relatório final deve conter APENAS: (1) o que foi feito em 2-3 frases,
|
|
87
78
|
(2) arquivos modificados, (3) problemas encontrados e como foram resolvidos,
|
|
88
79
|
(4) auto-score 0-10.
|
|
89
80
|
```
|
|
90
|
-
Após receber o retorno: o auto-score é **triagem, não aprovação** — se < 7, re-despache com o feedback específico (ou corrija inline) antes de prosseguir. Em qualquer caso, a task só avança quando `morph-eval` der score ≥ 9 (barra única do MORPH.md §0).
|
|
81
|
+
Após receber o retorno: o auto-score é **triagem, não aprovação** — se < 7, re-despache com o feedback específico (ou corrija inline) antes de prosseguir. Em qualquer caso, a task só avança quando `morph-eval` der score ≥ 9 (barra única do MORPH.md §0). Integre o relatório ao recap.md e vá para o passo 7.
|
|
91
82
|
|
|
92
83
|
**Se não — siga para o passo 5.**
|
|
93
84
|
|
|
@@ -4,7 +4,7 @@ description: Guia a produção dos três artefatos de planejamento de uma featur
|
|
|
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.1.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-plan
|
|
@@ -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.1.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.1.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-review
|
|
@@ -56,22 +56,18 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
|
|
|
56
56
|
seguindo as bandas 0-10 de cada uma.
|
|
57
57
|
NÃO reescreva código. NÃO toque em tasks.json, feature.json nem no board
|
|
58
58
|
de sessão.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
falha de protocolo.
|
|
69
|
-
Retorne no content: score 0-10 por dimensão, score composto (arch×0.30 +
|
|
70
|
-
contracts×0.25 + quality×0.25 + tests×0.20), e feedback priorizado
|
|
71
|
-
(bloqueantes primeiro) para qualquer dimensão < 9.
|
|
59
|
+
Contrato do relatório final — ATO FINAL: o seu relatório é a sua
|
|
60
|
+
ÚLTIMA MENSAGEM DE TEXTO; ela é o valor de retorno desta sessão e
|
|
61
|
+
chega inteira ao orquestrador. NÃO chame SendMessage: ele gera um
|
|
62
|
+
evento a mais além da notificação de término, custando um turno
|
|
63
|
+
inútil ao orquestrador. Escreva o relatório e encerre.
|
|
64
|
+
Seu relatório final deve conter: score 0-10 por dimensão, score
|
|
65
|
+
composto (arch×0.30 + contracts×0.25 + quality×0.25 + tests×0.20), e
|
|
66
|
+
feedback priorizado (bloqueantes primeiro) para qualquer dimensão < 9.
|
|
67
|
+
Relatório oco, ou sem esses itens, é falha de protocolo.
|
|
72
68
|
```
|
|
73
69
|
- **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).
|
|
74
|
-
- Os scores por dimensão e o composto do review-report vêm **desse retorno**, não da sua auto-avaliação.
|
|
70
|
+
- Os scores por dimensão e o composto do review-report vêm **desse retorno**, não da sua auto-avaliação. Se o relatório vier 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.
|
|
75
71
|
|
|
76
72
|
5. Produza `review-report.md` em `.morph/features/{feature}/4-review/` com:
|
|
77
73
|
- Scores por dimensão (arquitetura, contratos, qualidade, cobertura)
|
|
@@ -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.1.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.1.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-standards
|
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@ import { homedir } from 'os';
|
|
|
15
15
|
import { execSync } from 'child_process';
|
|
16
16
|
|
|
17
17
|
/** Current hooks schema version — bump when hook definitions change */
|
|
18
|
-
const HOOKS_VERSION = '3.
|
|
18
|
+
const HOOKS_VERSION = '3.3.0';
|
|
19
19
|
|
|
20
20
|
/** Marker for old dispatch.js (v1) */
|
|
21
21
|
const OLD_DISPATCH_COMMAND = 'node framework/hooks/agent-teams/dispatch.js';
|
|
@@ -176,34 +176,13 @@ const MORPH_HOOKS = [
|
|
|
176
176
|
}]
|
|
177
177
|
},
|
|
178
178
|
|
|
179
|
-
// === Stop — build check + session snapshot
|
|
180
|
-
// subagent-report-guard blocks (once) a dispatched sub-agent stopping
|
|
181
|
-
// without SendMessage — clause 1 of the dispatch protocol. In the
|
|
182
|
-
// orchestrator's session it is inert (marker never in a user message).
|
|
179
|
+
// === Stop — build check + session snapshot ===
|
|
183
180
|
{
|
|
184
181
|
event: 'Stop',
|
|
185
182
|
matcher: null,
|
|
186
|
-
hooks: [
|
|
187
|
-
{
|
|
188
|
-
type: 'command',
|
|
189
|
-
command: 'node framework/hooks/claude-code/core/validate-completion.js'
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
type: 'command',
|
|
193
|
-
command: 'node framework/hooks/claude-code/core/subagent-report-guard.js',
|
|
194
|
-
timeout: 5000
|
|
195
|
-
}
|
|
196
|
-
]
|
|
197
|
-
},
|
|
198
|
-
|
|
199
|
-
// === SubagentStop — dispatch-report guard for Task-tool subagents ===
|
|
200
|
-
{
|
|
201
|
-
event: 'SubagentStop',
|
|
202
|
-
matcher: null,
|
|
203
183
|
hooks: [{
|
|
204
184
|
type: 'command',
|
|
205
|
-
command: 'node framework/hooks/claude-code/core/
|
|
206
|
-
timeout: 5000
|
|
185
|
+
command: 'node framework/hooks/claude-code/core/validate-completion.js'
|
|
207
186
|
}]
|
|
208
187
|
}
|
|
209
188
|
];
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* subagent-report-guard.js — Stop / SubagentStop hook
|
|
4
|
-
*
|
|
5
|
-
* Enforces clause 1 of the morph-spec dispatch protocol: a dispatched
|
|
6
|
-
* sub-agent's FINAL act is SendMessage to the orchestrator (main). Plain text
|
|
7
|
-
* in the last message never reaches the orchestrator, and an idle agent forces
|
|
8
|
-
* the costly nag-and-wait cycle (observed 2/2 in real apply sessions —
|
|
9
|
-
* MORPH_GHLBrain 2026-07-11).
|
|
10
|
-
*
|
|
11
|
-
* Detection: the session transcript (JSONL) contains the dispatch-protocol
|
|
12
|
-
* marker ("Protocolo obrigatório") inside a USER message — that is how the
|
|
13
|
-
* dispatch prompt arrives in the sub-agent's own transcript. In the
|
|
14
|
-
* ORCHESTRATOR's transcript the marker only appears inside assistant tool_use
|
|
15
|
-
* input (the Agent call that did the dispatch), so the orchestrator is never
|
|
16
|
-
* blocked by this guard. A SendMessage tool_use anywhere in an assistant
|
|
17
|
-
* message counts as the report.
|
|
18
|
-
*
|
|
19
|
-
* Action: block the stop ONCE ({"decision":"block"}) with the exact
|
|
20
|
-
* instruction to call SendMessage — the agent continues and reports.
|
|
21
|
-
* stop_hook_active guards against blocking loops. Fail-open on any error.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
import { readFileSync, existsSync } from 'fs';
|
|
25
|
-
import { stateExists } from '../../shared/state-reader.js';
|
|
26
|
-
import { block, pass } from '../../shared/hook-response.js';
|
|
27
|
-
import { logHookActivity } from '../../shared/activity-logger.js';
|
|
28
|
-
|
|
29
|
-
const PROTOCOL_MARKER = 'Protocolo obrigatório';
|
|
30
|
-
|
|
31
|
-
function readStdin() {
|
|
32
|
-
try {
|
|
33
|
-
return JSON.parse(readFileSync(0, 'utf8') || '{}');
|
|
34
|
-
} catch {
|
|
35
|
-
return {};
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function projectDir() {
|
|
40
|
-
return process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Scan a transcript for the dispatch-protocol marker (user messages only) and
|
|
45
|
-
* for a SendMessage tool call (assistant messages).
|
|
46
|
-
*
|
|
47
|
-
* @param {string} path - JSONL transcript path
|
|
48
|
-
* @returns {{ dispatched: boolean, reported: boolean }}
|
|
49
|
-
*/
|
|
50
|
-
function scanTranscript(path) {
|
|
51
|
-
const raw = readFileSync(path, 'utf8');
|
|
52
|
-
let dispatched = false;
|
|
53
|
-
let reported = false;
|
|
54
|
-
for (const line of raw.split('\n')) {
|
|
55
|
-
if (!line.trim()) continue;
|
|
56
|
-
let role = null;
|
|
57
|
-
try {
|
|
58
|
-
const entry = JSON.parse(line);
|
|
59
|
-
role = entry?.message?.role ?? entry?.type ?? null;
|
|
60
|
-
} catch {
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
if (!dispatched && role === 'user' && line.includes(PROTOCOL_MARKER)) dispatched = true;
|
|
64
|
-
if (!reported && role === 'assistant' && line.includes('"name":"SendMessage"')) reported = true;
|
|
65
|
-
}
|
|
66
|
-
return { dispatched, reported };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
try {
|
|
70
|
-
if (!stateExists(projectDir())) pass();
|
|
71
|
-
|
|
72
|
-
const input = readStdin();
|
|
73
|
-
|
|
74
|
-
// Never loop: a previous block already forced one continuation — let this
|
|
75
|
-
// stop through even if the agent still failed to report.
|
|
76
|
-
if (input.stop_hook_active) pass();
|
|
77
|
-
|
|
78
|
-
const transcriptPath = input.transcript_path;
|
|
79
|
-
if (!transcriptPath || !existsSync(transcriptPath)) pass();
|
|
80
|
-
|
|
81
|
-
const { dispatched, reported } = scanTranscript(transcriptPath);
|
|
82
|
-
if (!dispatched || reported) pass();
|
|
83
|
-
|
|
84
|
-
logHookActivity('subagent-report-guard', input.hook_event_name || 'Stop', 'blocked', projectDir());
|
|
85
|
-
block(
|
|
86
|
-
'[morph-spec] PROTOCOLO DE RETORNO — você foi despachado com o protocolo obrigatório ' +
|
|
87
|
-
'mas ainda não chamou SendMessage. Sua última mensagem em texto NÃO chega ao orquestrador. ' +
|
|
88
|
-
'Antes de encerrar, chame a tool SendMessage com to:"main" e o relatório completo no content: ' +
|
|
89
|
-
'(1) o que foi feito em 2-3 frases, (2) arquivos modificados, (3) problemas encontrados e ' +
|
|
90
|
-
'como foram resolvidos, (4) auto-score 0-10. O SendMessage é o seu ato final.'
|
|
91
|
-
);
|
|
92
|
-
} catch {
|
|
93
|
-
// Fail-open
|
|
94
|
-
process.exit(0);
|
|
95
|
-
}
|