@polymorphism-tech/morph-spec 8.20.0 → 8.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +2 -2
  2. package/bin/morph-spec.js +31 -2
  3. package/claude-plugin.json +1 -1
  4. package/docs/CHEATSHEET.md +1 -1
  5. package/docs/QUICKSTART.md +1 -1
  6. package/framework/CLAUDE.md +2 -1
  7. package/framework/MORPH.md +6 -2
  8. package/framework/agents.json +3 -2
  9. package/framework/docs/CLI.md +4 -3
  10. package/framework/hooks/claude-code/core/enforce-phase-writes.js +23 -2
  11. package/framework/hooks/claude-code/core/state-sync.js +5 -0
  12. package/framework/hooks/claude-code/core/telemetry-log.js +34 -3
  13. package/framework/hooks/claude-code/core/validate-completion.js +116 -4
  14. package/framework/hooks/claude-code/core/worktree-context.js +9 -4
  15. package/framework/hooks/shared/e2e-check.js +0 -0
  16. package/framework/hooks/shared/telemetry-logger.js +64 -1
  17. package/framework/schemas/feature.schema.json +5 -3
  18. package/framework/schemas/tasks.schema.json +1 -1
  19. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  20. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  21. package/framework/skills/core/morph-apply/SKILL.md +7 -16
  22. package/framework/skills/core/morph-brainstorming/SKILL.md +2 -2
  23. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  24. package/framework/skills/core/morph-hotfix/SKILL.md +1 -1
  25. package/framework/skills/core/morph-implement/SKILL.md +1 -1
  26. package/framework/skills/core/morph-plan/SKILL.md +25 -4
  27. package/framework/skills/core/morph-proposal/SKILL.md +1 -1
  28. package/framework/skills/core/morph-review/SKILL.md +35 -8
  29. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  30. package/framework/skills/core/morph-standards/SKILL.md +29 -15
  31. package/framework/skills/core/morph-uiux/SKILL.md +3 -3
  32. package/framework/templates/infrastructure/docker/docker-compose.template.yml +29 -5
  33. package/package.json +1 -1
  34. package/src/commands/e2e/e2e.js +318 -0
  35. package/src/commands/observability/cost.js +93 -5
  36. package/src/commands/project/update.js +2 -63
  37. package/src/commands/state/finish.js +38 -0
  38. package/src/commands/state/gate-check.js +10 -3
  39. package/src/commands/validation/validate-feature.js +7 -1
  40. package/src/commands/validation/verify.js +7 -0
  41. package/src/core/templates/template-registry.js +2 -30
  42. package/src/lib/e2e/compose-env.js +74 -0
  43. package/src/lib/git/default-branch.js +44 -8
  44. package/src/lib/installers/templates-reconcile.js +81 -0
  45. package/src/lib/risk-detector.js +20 -1
  46. package/src/lib/telemetry/telemetry-reader.js +80 -4
  47. package/src/lib/validators/verify-runner.js +121 -2
  48. package/src/scripts/setup-infra.js +23 -5
@@ -39,7 +39,7 @@
39
39
  "standards": {
40
40
  "type": "array",
41
41
  "items": { "type": "string", "minLength": 1 },
42
- "description": "Standards pinned by morph-plan for this task, as paths relative to the framework root (e.g. \"standards/backend/dotnet/vsa-handler-patterns.md\"). Optional. Part of the plan contract: frozen after Gate 2."
42
+ "description": "Standards pinned by morph-plan for this task, as PATHS relative to the framework root (e.g. \"standards/backend/dotnet/vsa-handler-patterns.md\"). Optional. Part of the plan contract: frozen after Gate 2. NOT the same vocabulary as agents.json's top-level `standards` field, which lists IDs (e.g. \"backend-dotnet-vsa-handler-patterns\", no slashes/extension) — same field name, different shape; do not treat one as the other."
43
43
  }
44
44
  },
45
45
  "additionalProperties": false
@@ -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.20.0"
7
+ cliVersion: "8.22.0"
8
8
  stacks:
9
9
  - umbraco
10
10
  ---
@@ -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.20.0"
7
+ cliVersion: "8.22.0"
8
8
  stacks:
9
9
  - umbraco
10
10
  ---
@@ -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.20.0"
7
+ cliVersion: "8.22.0"
8
8
  ---
9
9
 
10
10
  # morph-apply
@@ -208,21 +208,12 @@ Quando `getPendingTasks(data).length === 0`:
208
208
  - Invocar `Skill(morph-review)` para gerar `.morph/features/{feature}/4-review/review-report.md`.
209
209
  - A skill morph-review chama `morph-eval` em escopo de feature inteira.
210
210
 
211
- ### 5. Gate 3 (trust-aware)
211
+ ### 5. Gate 3
212
212
 
213
- Rode `morph-spec gate-check {feature} review [--json]` — lê `trust`, decide via `shouldPauseGate` e persiste `gateDecisions.review` com timestamp server-side (shape canônico em `.morph/framework/schemas/feature.schema.json`), imprimindo `pause`/`reason`/`signals`. É o default — não recompute a tabela do MORPH.md §5 em linguagem natural.
214
-
215
- **`evalScore` sem override é uma PROXY** (média das `taskScores`, não o score composto real). Passe o composto do `review-report.md` (avaliador independente) e qualquer violação que ele tenha encontrado via `--signals` — as únicas chaves que este comando aceita sobrescrever:
216
- ```
217
- morph-spec gate-check {feature} review --signals '{"evalScore":9.2,"standardsViolations":[]}'
218
- ```
219
-
220
- Risco que nenhuma dessas chaves representa (julgamento do avaliador que não vira `standardsViolations`): use `gate-decision` direto em vez de `gate-check`.
221
-
222
- **Nunca edite `feature.json` à mão** (colide com o hook state-sync — erro "file modified since read"). Os caminhos acima gravam no mesmo lugar; o hook `gate-guard.js` confere depois se a ação bateu com a decisão persistida.
223
-
224
- - Pause: `AskUserQuestion` com options `["aprovado, fechar feature", "preciso ajustar", "rollback"]`.
225
- - Auto: exibir summary do review-report, aprovar via `morph-spec approve {feature} review --mode auto`, e prosseguir.
213
+ Apresentado e persistido por `morph-review` §8 (invocada no passo 4 acima) — gate-check, template
214
+ fixo nomeando a feature, aprovação registrada pós-resposta. Ao retomar o controle dela, **NÃO
215
+ re-apresente o gate**: siga direto para o encerramento (§6) conforme a decisão já persistida em
216
+ `gateDecisions.review`.
226
217
 
227
218
  ### 6. Pós Gate 3 — encerramento
228
219
 
@@ -255,7 +246,7 @@ Risco que nenhuma dessas chaves representa (julgamento do avaliador que não vir
255
246
  - `framework/skills/core/morph-review/SKILL.md`
256
247
  - `framework/skills/core/morph-plan/SKILL.md` §5a — resolve e carimba `task.agent`/`task.standards` no plano; fonte primária deste §3b
257
248
  - `morph-spec dag {feature}` — análise de DAG e decisão sequencial vs paralelo (ponderada por effort), incluindo recomendação de isolamento (`isolation.recommended: "worktree"`)
258
- - `morph-spec verify {feature} [task] --json` — cadeia determinística build+testes+validadores (código antes do juiz)
249
+ - `morph-spec verify {feature} [task] --json` — cadeia determinística build+testes+validadores+e2e (código antes do juiz)
259
250
  - `morph-spec score {feature} {task} {score} [--dims a,c,q,t]` — grava taskScores no feature.json com timestamp server-side
260
251
  - `morph-spec gate-check {feature} {gate} [--json]` — default: coleta sinais do disco, decide via `shouldPauseGate`, persiste `gateDecisions`
261
252
  - `morph-spec gate-decision {feature} {gate} --pause {bool} [--reason ...] [--signals ...]` — escape manual: risco que o `gate-check` não vê no disco (shape em `.morph/framework/schemas/feature.schema.json`)
@@ -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.20.0"
7
+ cliVersion: "8.22.0"
8
8
  ---
9
9
 
10
10
  # morph-brainstorming
@@ -147,6 +147,6 @@ options:
147
147
 
148
148
  ## Referências
149
149
  - `.morph/framework/MORPH.md` — seções 1 (Papéis), 2 (Fases), 5 (Gates), Trust Mode
150
- - `.morph/framework/standards/STANDARDS.json` — para referência de standards relevantes à stack
150
+ - `morph-spec standards --find "<query>"` — para referência de standards relevantes à stack (ver `morph-standards`)
151
151
  - `framework/skills/core/morph-stack-scan/SKILL.md` — invocada na Parte 0 (varredura), antes de qualquer pergunta
152
152
  - `.morph/framework/MORPH.md` §5 — regras de pausa do Gate 1 (trust mode)
@@ -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.20.0"
7
+ cliVersion: "8.22.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.20.0"
7
+ cliVersion: "8.22.0"
8
8
  ---
9
9
 
10
10
  # morph-hotfix
@@ -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.20.0"
7
+ cliVersion: "8.22.0"
8
8
  ---
9
9
 
10
10
  # morph-implement
@@ -4,7 +4,7 @@ description: Guia a produção dos artefatos de planejamento de uma feature (use
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.20.0"
7
+ cliVersion: "8.22.0"
8
8
  ---
9
9
 
10
10
  # morph-plan
@@ -84,10 +84,31 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
84
84
 
85
85
  4. Produza `mandate.md` em `.morph/features/{feature}/2-plan/`:
86
86
  - Stack exata do projeto (leia de `.morph/config/config.json` → `project.stack` ou do CLAUDE.md).
87
- - Standards obrigatórios: liste os IDs relevantes de `.morph/framework/standards/STANDARDS.json`.
87
+ - Standards obrigatórios: descubra-os com `morph-spec standards --find "<domínio/tecnologia>"` (top 3 `id · path · digest` — o digest decide) por domínio tocado; liste os IDs escolhidos.
88
88
  - Patterns proibidos — **copie por extenso no mandate.md** a lista canônica de `MORPH.md` § "Stack baked-in" (`Guid.NewGuid()`→`Guid.CreateVersion7()`, classes não-sealed sem justificativa, exceptions como fluxo de controle, camada de Service/Manager entre handler e dados, repository genérico `IRepository<T>`/`IUnitOfWork`, SQL cru sem justificativa) mais qualquer proibição específica da feature. Copie o texto completo — o mandate.md é lido por implementadores em contexto fresco, sem `MORPH.md` carregado, então um ponteiro sozinho não basta aqui.
89
89
  - Política de acesso a dados (registre no mandate): `ApplicationDbContext` injetado direto no slice — para CRUD e para queries específicas (joins, projeção, paginação). Para concorrência ou SQL específico, store dedicado hand-written com justificativa em `decisions.md`.
90
- - **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.
90
+ - **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 `morph-spec standards --find "<tema>" --category ai-agents`. 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.
91
+ - **Verificação de runtime** — como se PROVA que a feature funciona rodando, não só compilando.
92
+ Compilar não é subir: um serviço injetado sem registro em `Program.cs` passa no build e derruba
93
+ a aplicação no startup. Registre no mandate:
94
+ - **Como o stack sobe:** o `docker compose` do projeto (`morph-spec e2e up {feature}`). Se o
95
+ projeto containeriza mas não tem compose, **isso é uma task** — sem ele o nó `e2e` do verify
96
+ reprova (não dispensa).
97
+ - **O que precisa ser exercitado:** os fluxos desta feature que o avaliador vai navegar, em
98
+ linguagem de comportamento — os mesmos verbos das pós-condições dos use cases.
99
+ - **Quais viram spec Playwright versionada:** caminho crítico e bug corrigido merecem regressão;
100
+ exploração pontual não. O critério vai aqui; escrever a spec é tarefa da implementação.
101
+ - **Base URL vinda do ambiente:** o harness dá a cada feature um bloco de portas próprio (para
102
+ duas worktrees não brigarem pela porta 3000), então o `playwright.config.ts` **não pode**
103
+ cravar a URL — leia `process.env.PLAYWRIGHT_BASE_URL ?? \`http://localhost:${process.env.PORT ?? 3000}\``
104
+ e faça o compose publicar `"${PORT:-3000}:3000"`. Config cravada = suíte batendo em porta
105
+ vazia e `ECONNREFUSED` com cara de app quebrada. Se estiver cravado, **isso é uma task**.
106
+ - **Setup de autenticação**, se a aplicação tem login: `e2e.auth` em `config.json`
107
+ (`mode: seed|storageState|bypass|none`, `seedCommand`, `storageStatePath`, `envFile`), com as
108
+ credenciais num `.env.e2e` **gitignored** — nunca no config commitado. **Se a app tem login e
109
+ isso não existe, crie a task de setup**: sem ela a navegação para na tela de login e a
110
+ verificação de runtime vira teatro. É gap de Gate 2, não dispensa de Gate 3.
111
+ - **Quando não se aplica** (biblioteca pura, chore sem runtime), registre a dispensa e o porquê.
91
112
  - Checklist de done com critérios verificáveis por tarefa.
92
113
 
93
114
  5. Produza `tasks.json` em `.morph/features/{feature}/2-plan/` seguindo o schema em `.morph/framework/schemas/tasks.schema.json`.
@@ -199,7 +220,7 @@ Ao registrar a aprovação do Gate 2, atualize o frontmatter de cada use case de
199
220
  ## Referências
200
221
 
201
222
  - `.morph/framework/MORPH.md` — seções 2 (Fases), 3 (Contratos de Output), 5 (Gates), Trust Mode
202
- - `.morph/framework/standards/STANDARDS.json` — para identificar standards relevantes ao mandate
223
+ - `morph-spec standards --find "<query>"` — para identificar standards relevantes ao mandate (o índice inteiro só como navegação exploratória; ver `morph-standards`)
203
224
  - `.morph/framework/agents.json` — personas por domínio; lido UMA VEZ no passo 5a para carimbar `agent`/`standards` por task
204
225
  - `.morph/framework/schemas/tasks.schema.json` — schema obrigatório de tasks.json
205
226
  - `.morph/specs/usecases/` — acervo permanente de use cases do projeto (leia antes de numerar; em `bug`, é onde mora o UC a corrigir)
@@ -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.20.0"
7
+ cliVersion: "8.22.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.20.0"
7
+ cliVersion: "8.22.0"
8
8
  ---
9
9
 
10
10
  # morph-review
@@ -43,12 +43,22 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
43
43
  outro propósito. Falha aqui é bloqueante — quebra silenciosa em runtime, não em build.
44
44
 
45
45
  4. **Despache o avaliador independente** — o score do Gate 3 nunca é auto-atribuído por quem implementou:
46
- - Rode `morph-spec verify {feature} --json` (escopo feature) e capture o JSON — é a saída real de build+testes+validadores que você anexa ao prompt do avaliador independente (`morph-evaluator`).
46
+ - Rode `morph-spec verify {feature} --json` (escopo feature) e capture o JSON — é a saída real de build+testes+validadores+e2e que você anexa ao prompt do avaliador independente (`morph-evaluator`).
47
+ - **Confira o nó `e2e` do verify antes de despachar.** Ele carrega o estado do stack:
48
+ - `pass` → a aplicação subiu e está saudável; o avaliador pode navegá-la. **Passe a URL no prompt**
49
+ — cada feature roda no seu bloco de portas, não em `localhost:3000`; pegue de
50
+ `morph-spec e2e status {feature} --json` (`baseUrl`) e não deixe o avaliador adivinhar.
51
+ - `fail` → **não abra o Gate 3.** Volte ao loop de correção: a app não sobe, ou as specs quebraram.
52
+ - `skip` → leia a razão e decida se a dispensa é legítima. "não containeriza" num projeto sem UI é
53
+ legítimo; "docker indisponível no ambiente" numa feature de UI **não** é — registre você mesmo
54
+ `morph-spec gate-decision {feature} review --pause true --reason "e2e não verificado: {razão}"`.
55
+ O disco não distingue dispensa legítima de verificação que faltou; esse julgamento é seu.
47
56
  - Gere o **diff da implementação** (`git diff` do range da feature, ou a lista de arquivos do recap.md com seus conteúdos atuais).
48
- - Despache o subagent registrado `morph-evaluator` (gerado de `agents.json` — a persona do avaliador é o system prompt dele, com Read/Glob/Grep + Bash somente para verificação, sem Write/Edit), com contexto fresco:
57
+ - Despache o subagent registrado `morph-evaluator` (gerado de `agents.json` — a persona do avaliador é o system prompt dele, com Read/Glob/Grep + Bash somente para verificação + Playwright para navegar, sem Write/Edit), com contexto fresco:
49
58
  ```
50
59
  dispatch Agent (subagent_type: "morph-evaluator") with prompt:
51
60
  contexto: mandate.md + spec.md + diff da implementação + saída real dos testes
61
+ + nó e2e do verify (stack no ar? em qual URL?)
52
62
  instrução: |
53
63
  Você NÃO participou da implementação — avalie o que está no diff,
54
64
  contra o mandate. Você tem Bash: use `morph-spec verify`, testes/build
@@ -56,6 +66,16 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
56
66
  foi reportado, em vez de confiar cegamente. Aplique as rubricas em
57
67
  .morph/framework/evals/rubrics/ (architecture 30%, contracts 25%,
58
68
  code-quality 25%, test-coverage 20%) seguindo as bandas 0-10 de cada uma.
69
+ Se o nó e2e subiu o stack, NAVEGUE a aplicação com Playwright e
70
+ percorra os fluxos desta feature como um usuário faria — ler o diff
71
+ prova que o código existe, usar a aplicação prova que ela funciona.
72
+ Confira console e network atrás de erro que teste nenhum cobriu.
73
+ Registre no relatório o que você navegou e o que viu. Se um fluxo que
74
+ você exercitou merece virar regressão, RECOMENDE a spec Playwright —
75
+ recomendar é seu papel, escrever a spec não é.
76
+ NÃO suba nem derrube o stack por conta própria (`morph-spec e2e` e o
77
+ nó de verify fazem isso): stack que não sobe é achado de INFRA a
78
+ reportar, não defeito de implementação a pontuar.
59
79
  NÃO reescreva código. NÃO toque em tasks.json, feature.json nem no board
60
80
  de sessão — Bash é só para verificação, nunca para mudar estado.
61
81
  Contrato do relatório final: GRAVE seu relatório em
@@ -71,8 +91,9 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
71
91
  contracts×0.25 + quality×0.25 + tests×0.20) gravado TAMBÉM como a
72
92
  linha literal `**Composite-Score:** {n.n}` (machine-readable — o
73
93
  `morph-spec gate-check` lê o score real daí em vez do proxy de
74
- taskScores), e feedback priorizado (bloqueantes primeiro) para
75
- qualquer dimensão < 9. Relatório ausente, oco, ou sem esses itens,
94
+ taskScores), feedback priorizado (bloqueantes primeiro) para
95
+ qualquer dimensão < 9, e — quando o stack estava no ar — o que você
96
+ navegou e o que observou. Relatório ausente, oco, ou sem esses itens,
76
97
  é falha de protocolo.
77
98
  ```
78
99
  - **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).
@@ -87,6 +108,10 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
87
108
  uma regra de negócio, e ainda dizendo `976/976` quando eram 982).
88
109
  - Scores por dimensão (arquitetura, contratos, qualidade, cobertura)
89
110
  - Score composto final
111
+ - **Verificação de runtime** — o resultado do nó `e2e` (`pass`/`fail`/`skip` + razão), e o que o
112
+ avaliador navegou. Dispensa (`skip`) entra aqui **por extenso**: o valor de um gate está tanto
113
+ no que ele provou quanto no que ele deixou de provar, e uma dispensa silenciosa se lê como
114
+ aprovação. Se houver spec Playwright recomendada pelo avaliador, liste-a como melhoria.
90
115
  - Lista de itens bloqueantes (se houver) — com descrição e critério de resolução
91
116
  - Lista de melhorias recomendadas (não bloqueantes)
92
117
  - Recomendação final: Aprovado / Rejeitar com condições / Reprovar
@@ -98,7 +123,8 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
98
123
 
99
124
  7. **NÃO finalize o trace manualmente.** O hook `trace-autogen` gera e finaliza `.morph/traces/YYYY-MM-DD-{feature}-implement.json` automaticamente (incl. `phase_summary` e `completed_at`) no último write de `tasks.json` — quando a última task sai de `pending`/`in_progress`. Se o trace parecer desatualizado, a causa é um `morph-spec score` faltante ou um recap sem o bloco da task — corrija a fonte, não o trace.
100
125
 
101
- 8. Apresente o Gate 3 segundo trust mode.
126
+ 8. Apresente o Gate 3 segundo trust mode — **única apresentação do gate**: `morph-apply` §5 aponta
127
+ para cá em vez de duplicar; ao devolver o controle a ela, o gate já está decidido.
102
128
 
103
129
  Rode `morph-spec gate-check {feature} review [--json]` — lê `trust` de `.morph/config/config.json`, decide via `shouldPauseGate` e persiste `gateDecisions.review` com timestamp server-side, imprimindo `pause`/`reason`/`signals`. É o default — não recompute a tabela do MORPH.md §5 em linguagem natural.
104
130
 
@@ -109,7 +135,7 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
109
135
 
110
136
  Julgamento do revisor que nenhuma dessas chaves representa: use `gate-decision` direto em vez de `gate-check`.
111
137
 
112
- **Nunca edite `feature.json` à mão** (colide com o hook state-sync). Os caminhos acima gravam no mesmo lugar; o hook `gate-guard.js` confere depois se a ação bateu com a decisão persistida.
138
+ **Nunca edite `feature.json` à mão** (colide com o hook state-sync — erro "file modified since read"). Os caminhos acima gravam no mesmo lugar; o hook `gate-guard.js` confere depois se a ação bateu com a decisão persistida.
113
139
 
114
140
  **Se `pause === true`**, use `AskUserQuestion`:
115
141
 
@@ -129,6 +155,7 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
129
155
 
130
156
  **Composite score:** {score}/10
131
157
  **Dimensões:** arquitetura={X} contratos={Y} qualidade={Z} cobertura={W}
158
+ **Runtime:** e2e={pass|skip} {razão, quando skip}
132
159
  **Bloqueantes:** {N (zero esperado em auto-aprovação)}
133
160
  **Recomendação:** Aprovado
134
161
  ```
@@ -146,7 +173,7 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
146
173
  - Gate 3 registrado aprovado em `.morph/features/{feature}/feature.json` (autoritativo), na forma canônica `{ approved, timestamp, approvedBy }` — via `morph-spec approve` em auto, ou pelo hook state-sync no caminho manual
147
174
 
148
175
  ## Referências
149
- - `morph-spec verify {feature} [task] --json` — cadeia determinística build+testes+validadores anexada ao prompt do avaliador (passo 4)
176
+ - `morph-spec verify {feature} [task] --json` — cadeia determinística build+testes+validadores+e2e anexada ao prompt do avaliador (passo 4)
150
177
  - `.morph/framework/MORPH.md` — seção 5 (Gate 3 + regras de pausa), seção 1 (papel Evaluator), Trust Mode
151
178
  - `.claude/agents/morph-evaluator.md` — subagent do avaliador (gerado de `.morph/framework/agents.json`), despachado no passo 4
152
179
  - `framework/skills/core/morph-eval/SKILL.md` — rubricas e bandas que o avaliador aplica
@@ -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.20.0"
7
+ cliVersion: "8.22.0"
8
8
  ---
9
9
 
10
10
  # morph-stack-scan
@@ -1,17 +1,18 @@
1
1
  ---
2
2
  name: morph-standards
3
- description: Localiza e carrega um standard específico do STANDARDS.json sob demanda
3
+ description: Localiza um standard específico via busca server-side (morph-spec standards --find) e carrega só o necessário
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.20.0"
7
+ cliVersion: "8.22.0"
8
8
  ---
9
9
 
10
10
  # morph-standards
11
11
 
12
12
  ## Objetivo
13
- Encontrar o standard certo para a situação atual e carregar apenas esse arquivo no contexto.
14
- Nunca carregue todos os standards — o custo de token não compensa.
13
+ Encontrar o standard certo para a situação atual e carregar apenas o necessário no contexto.
14
+ Nunca abra o `STANDARDS.json` inteiro (65 KB) — a busca server-side já devolve o suficiente
15
+ para aplicar o standard na maioria dos casos.
15
16
 
16
17
  ## Quando invocar
17
18
  Quando durante a implementação surgir uma dúvida de padrão arquitetural, de contrato, de qualidade
@@ -19,21 +20,33 @@ ou de teste — e o mandate.md não for suficiente para resolver.
19
20
 
20
21
  ## O que fazer
21
22
 
22
- 1. Abra `framework/standards/STANDARDS.json`.
23
+ 1. Rode a busca server-side — é O caminho, não uma opção entre várias:
24
+ ```
25
+ morph-spec standards --find "<domínio/tecnologia da task>" [--category <cat>] [--tags <a,b>] [--json]
26
+ ```
27
+ Devolve o **top 3** como `id · path · digest` — o `digest` é o texto completo do standard;
28
+ na maioria dos casos ele já basta para aplicar o padrão, sem abrir o `.md`.
23
29
 
24
- 2. Filtre por `category` primeiro (valores típicos: "architecture", "contracts", "testing", "frontend", "backend").
30
+ 2. Se dois resultados parecerem relevantes e houver conflito, adote o mais específico ao stack
31
+ do projeto. Registre o conflito no `decisions.md` da feature.
25
32
 
26
- 3. Dentro da categoria, filtre por `tags` que correspondam ao stack do projeto
27
- (ex: "dotnet", "nextjs", "blazor", "typescript").
33
+ 3. Abra o arquivo `.md` do standard (campo `path`) só quando o `digest` não bastar para resolver
34
+ a dúvida — ex.: precisa de um exemplo de código completo ou de uma seção que o resumo não cobre.
28
35
 
29
- 4. Se dois standards parecerem relevantes e houver conflito, adote o mais específico ao stack.
30
- Registre o conflito no `decisions.md` da feature.
36
+ 4. Aplique o standard na tarefa atual.
31
37
 
32
- 5. Leia o arquivo `.md` do standard selecionado — o path está no campo `path` do JSON.
38
+ 5. Registre no `recap.md`: qual standard foi consultado (via `--find`, ou navegação — item abaixo)
39
+ e como foi aplicado.
33
40
 
34
- 6. Aplique o standard na tarefa atual.
41
+ ## Fallback — navegação exploratória
35
42
 
36
- 7. Registre no `recap.md`: qual standard foi consultado e como foi aplicado.
43
+ `--find` exige uma query. Quando a necessidade é genuinamente exploratória (ex.: "o que existe
44
+ pra categoria X?", sem um termo de busca claro), nesta ordem:
45
+
46
+ 1. `morph-spec standards` sem `--find` — lista categorias + contagem, custo mínimo, o suficiente
47
+ pra decidir qual `--category` usar num `--find` em seguida.
48
+ 2. Só se isso não bastar, abra `framework/standards/STANDARDS.json` inteiro — último recurso,
49
+ nunca o primeiro passo.
37
50
 
38
51
  ## Quando não há standard adequado
39
52
  Registre no `decisions.md` que nenhum standard cobre o caso.
@@ -41,10 +54,11 @@ Descreva o critério adotado e sinalize para revisão futura.
41
54
  Não invente um standard — padrões não documentados são dívida técnica.
42
55
 
43
56
  ## Output esperado
44
- - Standard identificado e lido no contexto
57
+ - Standard identificado (via `--find`/digest, ou `.md` completo quando necessário) no contexto
45
58
  - Critério de implementação claro para a tarefa atual
46
59
  - Entrada no recap.md registrando o standard consultado
47
60
 
48
61
  ## Referências
49
- - `framework/standards/STANDARDS.json` — índice completo com id, name, path, category, tags
62
+ - `morph-spec standards --find "<query>" [--category] [--tags] [--json]` — busca server-side, top 3 `id · path · digest`
63
+ - `framework/standards/STANDARDS.json` — índice completo; abrir só como fallback exploratório (ver acima)
50
64
  - `framework/MORPH.md` — seção 4 (Como consultar Standards)
@@ -4,7 +4,7 @@ description: Conduz a fase opcional de UI/UX — design system, mockups, compone
4
4
  version: core
5
5
  when-to-invoke: ao tomar o ramo uiux (morph-spec advance --design), depois do Gate 1 e antes do morph-plan
6
6
  user-invokable: true
7
- cliVersion: "8.20.0"
7
+ cliVersion: "8.22.0"
8
8
  ---
9
9
 
10
10
  # morph-uiux
@@ -33,7 +33,7 @@ Ao tomar o ramo opcional uiux: feature/bug cuja mudança cria ou altera superfí
33
33
 
34
34
  3. **Despache `morph-ui-designer`** para o trabalho visual — dispatch é o default aqui (domínio diferente do Orchestrator, MORPH.md §6). `morph-ui-designer` tem `Read/Write/Edit/Glob/Grep` + MCPs `stitch`/`gemini-image`/`playwright`/`context7`, mas **não tem Bash** — não peça build, testes nem `morph-spec` a ele; isso é do orquestrador.
35
35
 
36
- **Fallback — caminho normal fora de stack Next.js** (`ui-designer.stack = ["nextjs"]` em `agents.json`, então em qualquer outro stack o subagent não está registrado): `general-purpose` colando o campo `persona` (Read em `.morph/framework/agents.json`) no prompt, registrando o fallback no relatório. Isto não é uma exceção rara — é o caminho normal para projetos não-Next.js.
36
+ **Persona universal** (`ui-designer.stack = ["*"]` em `agents.json`, mesmo mecanismo de `evaluator`/`scout`): UI/UX importa sempre que há superfície de UI, então o subagent está registrado em **todo** projeto — .NET/Blazor incluído, não só Next.js. **Fallback** (caso raro: instalação anterior a essa mudança, `.claude/agents/morph-ui-designer.md` ainda não regenerado): `general-purpose` colando o campo `persona` (Read em `.morph/framework/agents.json`) no prompt, registrando o fallback no relatório — resolvido rodando `morph-spec setup-infra --reinstall`.
37
37
 
38
38
  Template do prompt (contrato do relatório em forma curta — copia o padrão de `morph-implement` §4, sem a cláusula de build/isolamento, que não se aplica a um agente sem Bash):
39
39
  ```
@@ -93,7 +93,7 @@ Ao tomar o ramo opcional uiux: feature/bug cuja mudança cria ou altera superfí
93
93
 
94
94
  Aguardar resposta. Se "preciso ajustar", aplicar e reapresentar.
95
95
 
96
- **Divergência do hook state-sync — só neste gate:** ao contrário de Gate 1/2/3, o hook `state-sync.js` (`gateFromQuestion`) não reconhece o texto "Gate uiux" — uma resposta "aprovado" aqui **não** grava o gate sozinha. Depois do "aprovado", grave explicitamente:
96
+ **Hook state-sync reconhece este gate, como os demais.** Igual a Gate 1/2/3, o hook `state-sync.js` (`gateFromQuestion`) reconhece o texto "Gate uiux" — uma resposta "aprovado" ao template acima grava sozinha `approvalGates.uiux = { approved: true, timestamp, approvedBy: "manual" }` no `feature.json` autoritativo, atribuído pelo nome da feature que a pergunta cita (MORPH.md §5). Sem nome na pergunta, ou fora de `AskUserQuestion` (headless/CI): aprove explicitamente:
97
97
  ```
98
98
  morph-spec approve {feature} uiux --approver <quem respondeu>
99
99
  # ou, para já aprovar e criar 2-plan/ num passo só:
@@ -1,7 +1,19 @@
1
1
  # Docker Compose for Local Development
2
2
  # Next.js + Neon Stack
3
-
4
- version: '3.8'
3
+ #
4
+ # Ports come from variables with sane defaults so `morph-spec e2e up` can hand
5
+ # each feature worktree its own port block (see env-allocator.js). Hardcode
6
+ # "3000:3000" here and two features running side by side collide on the host,
7
+ # no matter what the harness injects — the container names would be distinct
8
+ # and the ports would not.
9
+ #
10
+ # Healthchecks are what make `up --wait` meaningful: without them Compose
11
+ # reports "started" the moment the process launches, and the e2e node would
12
+ # navigate an application that is not serving yet.
13
+ #
14
+ # The harness also exports PLAYWRIGHT_BASE_URL for the same allocated port, so
15
+ # `playwright.config.ts` must read it instead of hardcoding a URL:
16
+ # baseURL: process.env.PLAYWRIGHT_BASE_URL ?? `http://localhost:${process.env.PORT ?? 3000}`
5
17
 
6
18
  services:
7
19
  # Next.js Application
@@ -11,7 +23,7 @@ services:
11
23
  dockerfile: Dockerfile.dev
12
24
  container_name: {{kebabCase FEATURE_NAME}}-app
13
25
  ports:
14
- - "3000:3000"
26
+ - "${PORT:-3000}:3000"
15
27
  environment:
16
28
  - NODE_ENV=development
17
29
  - DATABASE_URL=${DATABASE_URL}
@@ -20,7 +32,14 @@ services:
20
32
  - /app/node_modules
21
33
  - /app/.next
22
34
  depends_on:
23
- - postgres
35
+ postgres:
36
+ condition: service_healthy
37
+ healthcheck:
38
+ test: ["CMD-SHELL", "node -e \"fetch('http://localhost:3000/').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\""]
39
+ interval: 10s
40
+ timeout: 5s
41
+ retries: 12
42
+ start_period: 20s
24
43
  networks:
25
44
  - app-network
26
45
 
@@ -30,7 +49,7 @@ services:
30
49
  container_name: {{kebabCase FEATURE_NAME}}-postgres
31
50
  restart: unless-stopped
32
51
  ports:
33
- - "5432:5432"
52
+ - "${POSTGRES_PORT:-5432}:5432"
34
53
  environment:
35
54
  POSTGRES_USER: postgres
36
55
  POSTGRES_PASSWORD: postgres
@@ -38,6 +57,11 @@ services:
38
57
  volumes:
39
58
  - postgres-data:/var/lib/postgresql/data
40
59
  - ./migrations:/docker-entrypoint-initdb.d
60
+ healthcheck:
61
+ test: ["CMD-SHELL", "pg_isready -U postgres -d {{snakeCase FEATURE_NAME}}"]
62
+ interval: 5s
63
+ timeout: 5s
64
+ retries: 10
41
65
  networks:
42
66
  - app-network
43
67
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polymorphism-tech/morph-spec",
3
- "version": "8.20.0",
3
+ "version": "8.22.0",
4
4
  "description": "MORPH-SPEC: NLH (Natural Language Harness) for spec-driven development with Claude Code",
5
5
  "keywords": [
6
6
  "claude-code",