@polymorphism-tech/morph-spec 8.18.0 → 8.20.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/bin/morph-spec.js +9 -0
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +8 -15
- package/framework/MORPH.md +56 -58
- package/framework/commands/morph-hotfix.md +1 -1
- package/framework/docs/CLI.md +3 -2
- package/framework/hooks/shared/phase-utils.js +0 -2
- package/framework/phases.json +2 -2
- package/framework/rules/morph-workflow.md +1 -1
- package/framework/schemas/feature.schema.json +12 -0
- package/framework/skills/README.md +1 -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 +10 -14
- package/framework/skills/core/morph-brainstorming/SKILL.md +11 -22
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +4 -4
- package/framework/skills/core/morph-implement/SKILL.md +1 -1
- package/framework/skills/core/morph-plan/SKILL.md +14 -20
- package/framework/skills/core/morph-proposal/SKILL.md +12 -15
- package/framework/skills/core/morph-review/SKILL.md +15 -8
- package/framework/skills/core/morph-stack-scan/SKILL.md +9 -13
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/skills/core/morph-uiux/SKILL.md +135 -0
- package/package.json +1 -1
- package/src/commands/project/status.js +2 -2
- package/src/commands/state/gate-check.js +223 -0
- package/src/commands/state/gate-decision.js +46 -10
- package/src/commands/validation/verify.js +18 -1
- package/src/core/paths/output-schema.js +0 -1
- package/src/lib/agents/output-collector.js +0 -1
- package/src/lib/git/default-branch.js +65 -0
- package/src/lib/risk-detector.js +13 -0
- package/src/lib/standards/digest-builder.js +0 -72
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.20.0
|
|
7
7
|
**Requires:** Node.js 22+, Claude Code
|
|
8
8
|
|
|
9
9
|
---
|
|
@@ -368,4 +368,4 @@ Code generated by morph-spec (contracts, templates, implementation output) belon
|
|
|
368
368
|
|
|
369
369
|
---
|
|
370
370
|
|
|
371
|
-
*morph-spec v8.
|
|
371
|
+
*morph-spec v8.20.0 by [Polymorphism Tech](https://polymorphism.tech)*
|
package/bin/morph-spec.js
CHANGED
|
@@ -36,6 +36,7 @@ import { archiveCommand } from '../src/commands/state/archive.js';
|
|
|
36
36
|
import { finishCommand } from '../src/commands/state/finish.js';
|
|
37
37
|
import { scoreCommand } from '../src/commands/state/score.js';
|
|
38
38
|
import { gateDecisionCommand } from '../src/commands/state/gate-decision.js';
|
|
39
|
+
import { gateCheckCommand } from '../src/commands/state/gate-check.js';
|
|
39
40
|
import { createCommand } from '../src/commands/state/create.js';
|
|
40
41
|
import { retypeCommand } from '../src/commands/state/retype.js';
|
|
41
42
|
import { handoffCommand } from '../src/commands/state/handoff.js';
|
|
@@ -205,6 +206,14 @@ program
|
|
|
205
206
|
.option('--reason <reason>', 'Reason for revocation')
|
|
206
207
|
.action((feature, gate, options) => unapproveCommand(feature, gate, options));
|
|
207
208
|
|
|
209
|
+
program
|
|
210
|
+
.command('gate-check <feature> <gate>')
|
|
211
|
+
.description('Decide + record a gate\'s trust decision from disk-derived signals (shouldPauseGate) — the deterministic default; see gate-decision for the manual escape hatch')
|
|
212
|
+
.option('--signals <json>', 'Override ONLY standardsViolations/designSystemDivergence/evalScore (not derivable from disk) — everything else is read from feature.json/tasks.json/git and cannot be overridden here')
|
|
213
|
+
.option('--trust <mode>', 'Trust mode to decide with (default: config.json → trust, or "auto")')
|
|
214
|
+
.option('--json', 'Output as JSON')
|
|
215
|
+
.action((feature, gateArg, options) => gateCheckCommand(feature, gateArg, options));
|
|
216
|
+
|
|
208
217
|
program
|
|
209
218
|
.command('gate-decision <feature> <gate>')
|
|
210
219
|
.description('Record the trust decision for a gate in feature.json (gateDecisions, server-side timestamp)')
|
package/claude-plugin.json
CHANGED
package/docs/CHEATSHEET.md
CHANGED
package/docs/QUICKSTART.md
CHANGED
package/framework/CLAUDE.md
CHANGED
|
@@ -20,7 +20,7 @@ Se não houver feature ativa, pergunte ao usuário qual feature trabalhar.
|
|
|
20
20
|
- Editar `.morph/specs/usecases/` à mão — só o `finish` escreve lá (lê de `2-plan/usecases/`, carimba `status: implemented`, sobrescreve por ID). Mudar um UC existente (caso `bug`): copie para `2-plan/usecases/` da feature e corrija lá.
|
|
21
21
|
- Listar perguntas em texto simples — sempre `AskUserQuestion` (1-4 perguntas por chamada).
|
|
22
22
|
- Usar `Guid.NewGuid()`, 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`), ou SQL cru sem justificativa.
|
|
23
|
-
- Editar `taskScores`, `gateDecisions` ou gates de `feature.json` à mão — sempre via `morph-spec score`/`gate-
|
|
23
|
+
- Editar `taskScores`, `gateDecisions` ou gates de `feature.json` à mão — sempre via `morph-spec score`/`gate-check`/`approve` (timestamps server-side; Edit manual colide com o hook `state-sync`).
|
|
24
24
|
|
|
25
25
|
**SEMPRE:**
|
|
26
26
|
- Auto-advance entre tarefas durante a fase implement — não pause sem ambiguidade bloqueante.
|
|
@@ -51,8 +51,9 @@ Se não houver feature ativa, pergunte ao usuário qual feature trabalhar.
|
|
|
51
51
|
|---------|-----------|
|
|
52
52
|
| `approve <f> <gate> --mode auto` | Aprova gate em `trust:auto`. Gate 3 exige `evaluator-report.md` (ou `--self-assessed`); `hotfix` nunca aceita `--mode auto` — use `--approver` |
|
|
53
53
|
| `advance <f>` | Aprova o gate corrente + já cria a pasta da próxima fase |
|
|
54
|
-
| `score <f> <task> <n> [--dims a,c,q,t]` | Grava `taskScores` server-side
|
|
55
|
-
| `gate-
|
|
54
|
+
| `score <f> <task> <n> [--dims a,c,q,t]` | Grava `taskScores` server-side (nunca à mão) |
|
|
55
|
+
| `gate-check <f> <gate> [--json]` | Default: decide via sinais do disco (`shouldPauseGate`) |
|
|
56
|
+
| `gate-decision <f> <gate> --pause <bool>` | Escape manual: risco que o disco não vê |
|
|
56
57
|
| `create <f> --description "..." --type <t>` | Nasce a feature + `feature.json`; `--worktree` já isola |
|
|
57
58
|
| `list [--all] [--json]` | Quadro de auditoria: feature × workType × status × gates |
|
|
58
59
|
| `delete <f> [--archive] [--force]` | Remove feature; recusa se gate aprovado sem `--force` |
|
|
@@ -70,7 +71,7 @@ Se não houver feature ativa, pergunte ao usuário qual feature trabalhar.
|
|
|
70
71
|
| `telemetry [--feature] [--limit]` | Caminho de execução da sessão a partir de `events.jsonl` |
|
|
71
72
|
| `cost [f] [--by task\|phase]` | Custo (bytes/duração) a partir do mesmo log |
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
Prefixo de todo comando: `morph-spec`. Flags/exemplos: `.morph/framework/CLI.md`.
|
|
74
75
|
|
|
75
76
|
## Skills core (em `.claude/skills/`)
|
|
76
77
|
|
|
@@ -78,6 +79,7 @@ Todo comando é `morph-spec <comando>`. Referência completa (flags, semântica,
|
|
|
78
79
|
|-------|-------------|
|
|
79
80
|
| `morph-brainstorming` | Entender negócio, escanear stack, produzir proposal.md |
|
|
80
81
|
| `morph-stack-scan` | Detectar desvios de stack em projeto brownfield |
|
|
82
|
+
| `morph-uiux` | Ramo opcional uiux — design system, mockups, componentes, fluxos |
|
|
81
83
|
| `morph-plan` | Destilar use cases e produzir spec.md + mandate.md + tasks.json |
|
|
82
84
|
| `morph-implement` | Executar uma tarefa com auto-advance entre tasks |
|
|
83
85
|
| `morph-eval` | Aplicar rubricas e produzir score 0-10 |
|
|
@@ -87,7 +89,7 @@ Todo comando é `morph-spec <comando>`. Referência completa (flags, semântica,
|
|
|
87
89
|
|
|
88
90
|
## Roteamento por tipo de trabalho
|
|
89
91
|
|
|
90
|
-
`workType` (`create --type <tipo>` ou classificado de `--request`) dimensiona o pipeline: `feature` completo, `bug` enxuto, `chore` fast-track (Gates 1/2 por política), `hotfix` scout→fix→gate humano→ship. Canônico: `MORPH.md` §2.1/§5.
|
|
92
|
+
`workType` (`create --type <tipo>` ou classificado de `--request`) dimensiona o pipeline: `feature` completo (+ ramo uiux quando há superfície de UI), `bug` enxuto, `chore` fast-track (Gates 1/2 por política), `hotfix` scout→fix→gate humano→ship. Canônico: `MORPH.md` §2.1/§5.
|
|
91
93
|
|
|
92
94
|
Features independentes rodam em paralelo, uma por git worktree (`create --worktree`/`worktree setup`), bloco de portas próprio + handoff.md. Fechamento: `finish <f> --pr|--merge`; agregado: `fleet`. Canônico: `MORPH.md` §2.2.
|
|
93
95
|
|
|
@@ -103,15 +105,6 @@ Drift entre `agents.json` e os `.md` gerados é detectado por `morph-spec doctor
|
|
|
103
105
|
|
|
104
106
|
## Regra de precedência de skills
|
|
105
107
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
| Em vez de | Use |
|
|
109
|
-
|-----------|-----|
|
|
110
|
-
| `superpowers:brainstorming` | `morph-brainstorming` |
|
|
111
|
-
| `superpowers:writing-plans` | `morph-plan` |
|
|
112
|
-
| `superpowers:executing-plans` | `morph-apply` |
|
|
113
|
-
| `superpowers:test-driven-development` | seguir `mandate.md` (TDD está embutido) |
|
|
114
|
-
|
|
115
|
-
As skills `morph-*` aplicam Gates e leem/produzem outputs nos paths corretos de `.morph/`. As `superpowers:*` são genéricas e não conhecem o contexto morph-spec.
|
|
108
|
+
Prefira `morph-*` a `superpowers:*` equivalentes (`brainstorming`→`morph-brainstorming`, `writing-plans`→`morph-plan`, `executing-plans`→`morph-apply`, `test-driven-development`→seguir `mandate.md`, TDD embutido): `morph-*` aplica Gates e paths corretos de `.morph/`; `superpowers:*` é genérico, sem esse contexto.
|
|
116
109
|
|
|
117
110
|
*MORPH-SPEC v5 by Polymorphism Tech*
|
package/framework/MORPH.md
CHANGED
|
@@ -12,19 +12,19 @@
|
|
|
12
12
|
|
|
13
13
|
Entre gates, você opera com autonomia total. O dev valida. Você executa.
|
|
14
14
|
|
|
15
|
-
| Situação
|
|
16
|
-
|
|
17
|
-
| Gate 1 / 2 / 3 aprovado
|
|
18
|
-
| Tarefa completada na fase implement
|
|
19
|
-
| Ambiguidade de escopo coberta pelo mandate
|
|
20
|
-
| Ambiguidade bloqueante (requisito ausente ou contraditório)
|
|
21
|
-
| Sub-agent retornou relatório (qualquer auto-score)
|
|
22
|
-
| Sub-agent com auto-score < 7
|
|
23
|
-
| Build/typecheck quebra
|
|
24
|
-
| Task implementada (código escrito)
|
|
25
|
-
| Score morph-eval ≥ 9
|
|
26
|
-
| Score morph-eval < 9 numa task
|
|
27
|
-
| Score morph-eval < 9 após 3 tentativas
|
|
15
|
+
| Situação | O que você faz |
|
|
16
|
+
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
|
|
17
|
+
| Gate 1 / 2 / 3 aprovado | Avançar para próxima fase imediatamente |
|
|
18
|
+
| Tarefa completada na fase implement | Iniciar a próxima task do tasks.json sem aguardar instrução |
|
|
19
|
+
| Ambiguidade de escopo coberta pelo mandate | Resolver conservadoramente e registrar em decisions.md |
|
|
20
|
+
| Ambiguidade bloqueante (requisito ausente ou contraditório) | UMA pergunta via AskUserQuestion |
|
|
21
|
+
| Sub-agent retornou relatório (qualquer auto-score) | Auto-score é triagem, não aprovação: a task só avança com morph-eval ≥ 9 |
|
|
22
|
+
| Sub-agent com auto-score < 7 | Re-despachar com feedback específico (ou corrigir inline) antes do morph-eval |
|
|
23
|
+
| Build/typecheck quebra | Corrigir antes de marcar tarefa como done |
|
|
24
|
+
| Task implementada (código escrito) | `morph-spec verify <feature> <task>` ANTES do juiz: vermelho = feedback ao loop sem gastar o morph-eval; verde → morph-eval avalia o que o código não pega |
|
|
25
|
+
| Score morph-eval ≥ 9 | Silêncio (aprovação implícita), próxima tarefa |
|
|
26
|
+
| Score morph-eval < 9 numa task | Loop de correção autônomo: re-implementar com feedback priorizado, até 3 tentativas, sem pausa humana |
|
|
27
|
+
| Score morph-eval < 9 após 3 tentativas | Escalar ao usuário (aceitar/continuar/pular) — único ponto de pausa do loop |
|
|
28
28
|
|
|
29
29
|
**Regra de ouro:** dúvida que não bloqueia → resolver e registrar; dúvida que bloqueia → uma pergunta, máximo. Vale **entre gates** (plan/implement/review) — **não** vale na abertura da feature: a fase proposal pode rodar em **modo entrevista** (escolhido na pergunta de abertura, `morph-brainstorming` Parte 2), onde perguntar até fechar o entendimento é o comportamento desejado.
|
|
30
30
|
|
|
@@ -36,16 +36,16 @@ Entre gates, você opera com autonomia total. O dev valida. Você executa.
|
|
|
36
36
|
|
|
37
37
|
O harness conhece o stack por padrão. Não pergunte sobre tecnologia a menos que haja ambiguidade real.
|
|
38
38
|
|
|
39
|
-
| Camada
|
|
40
|
-
|
|
41
|
-
| Backend
|
|
42
|
-
| ORM/DB
|
|
43
|
-
| IDs
|
|
44
|
-
| Classes
|
|
45
|
-
| Erros
|
|
46
|
-
| IA
|
|
47
|
-
| Frontend
|
|
48
|
-
| Jobs async | Hangfire — apenas quando há razão real
|
|
39
|
+
| Camada | Stack |
|
|
40
|
+
| ------------ | -------------------------------------------------------------------------------------------------- |
|
|
41
|
+
| Backend | .NET 10 + VSA (feature-folder: handler + validator + endpoint + errors + tests) |
|
|
42
|
+
| ORM/DB | EF Core + Neon (Postgres) |
|
|
43
|
+
| IDs | `Guid.CreateVersion7()` (nunca `Guid.NewGuid()`) |
|
|
44
|
+
| Classes | `sealed` por padrão |
|
|
45
|
+
| Erros | Result pattern com `result.Match()` (nunca exceptions como fluxo) |
|
|
46
|
+
| IA | Microsoft Agent Framework (MAF) — quando houver agentes |
|
|
47
|
+
| Frontend | Next.js App Router + Tailwind + Framer Motion + Shadcn |
|
|
48
|
+
| Jobs async | Hangfire — apenas quando há razão real |
|
|
49
49
|
|
|
50
50
|
Padrões proibidos automaticamente injetados no mandate:
|
|
51
51
|
- `Guid.NewGuid()` → `Guid.CreateVersion7()`
|
|
@@ -77,16 +77,16 @@ Os papéis não são exclusivos — numa sessão longa você transita entre eles
|
|
|
77
77
|
|
|
78
78
|
O fluxo padrão de uma feature tem quatro fases, cada uma com pasta dedicada em `.morph/features/{feature}/`. Estado autoritativo e commitado: `.morph/features/{feature}/feature.json` (status, approvalGates, outputs, tasks, gateDecisions, taskScores, archivedAt); `.morph/state.json` na raiz é só índice fino gitignored derivado dele; identidade do projeto em `.morph/config/config.json` (commitado).
|
|
79
79
|
|
|
80
|
-
| Fase
|
|
81
|
-
|
|
82
|
-
| proposal
|
|
83
|
-
| plan
|
|
84
|
-
| implement
|
|
85
|
-
| review
|
|
80
|
+
| Fase | Pasta | Gate | O que termina a fase |
|
|
81
|
+
| ------------- | ---------------- | ----------------------- | ------------------------------------------------- |
|
|
82
|
+
| proposal | `0-proposal/` | Gate 1 (trust-aware) | `proposal.md` aprovado e commitado |
|
|
83
|
+
| plan | `2-plan/` | Gate 2 (trust-aware) | `spec.md`, `mandate.md`, `tasks.json` aprovados |
|
|
84
|
+
| implement | `3-implement/` | Nenhum | Todas as tasks do tasks.json com status `done` |
|
|
85
|
+
| review | `4-review/` | Gate 3 (trust-aware) | `review-report.md` aprovado e commitado |
|
|
86
86
|
|
|
87
87
|
A fase `proposal` tem dois **modos de descoberta**, escolhidos pelo usuário na abertura (só `workType: feature`/`bug` — `chore`/`hotfix` nascem em `implement`): **entrevista** (uma pergunta por vez até a árvore de decisões abertas zerar; Gate 1 pausa sempre) e **automático** (até 4 perguntas em lote; Gate 1 trust-aware). Nos dois modos a varredura do ambiente roda **antes** de qualquer pergunta — fato que `morph-stack-scan` ou o acervo de use cases responde não vira pergunta. Detalhes em `morph-brainstorming`.
|
|
88
88
|
|
|
89
|
-
A fase `1-design/`
|
|
89
|
+
A fase `1-design/` é opcional — critério objetivo de entrada em §2.1.
|
|
90
90
|
|
|
91
91
|
Não avance de fase sem o gate correspondente ter sido confirmado.
|
|
92
92
|
|
|
@@ -95,12 +95,14 @@ Não avance de fase sem o gate correspondente ter sido confirmado.
|
|
|
95
95
|
Nem todo trabalho merece o pipeline completo. Cada feature nasce com **identidade** (`name` = slug + `description` obrigatória) e um **workType** (`morph-spec create <f> --description "<o quê/porquê>" --type <tipo>`, ou classificado de `--request "<pedido>"`, que também semeia a descrição) que dimensiona o pipeline:
|
|
96
96
|
|
|
97
97
|
| Tipo | Pipeline | Gates |
|
|
98
|
-
|
|
98
|
+
| ------ | ---------- | ------- |
|
|
99
99
|
| `feature` | proposal → [uiux] → plan → implement → review (completo) | 1, 2, 3 |
|
|
100
100
|
| `bug` | repro+diagnóstico enxuto (proposal lean) → plan enxuto → implement → review | 1, 2, 3 |
|
|
101
101
|
| `chore` | fast-track: direto para implement (Gates 1/2 carimbados por política no nascimento) → review leve | só 3 |
|
|
102
102
|
| `hotfix` | scout (diagnóstico read-only) → fix cirúrgico → **aprovação humana obrigatória** → test loop → ship | 3 (humano sempre) |
|
|
103
103
|
|
|
104
|
+
**Ramo uiux (critério objetivo):** feature/bug que cria ou altera superfície de UI (componente, página, tela, estilo, fluxo de navegação) toma o ramo `1-design/` via `morph-spec advance {feature} --design`; sem superfície de UI, direto para plan. Skill: `morph-uiux`. Avaliado por `morph-proposal`/`morph-brainstorming` no fecho do Gate 1 — não redecida em nenhum outro ponto do pipeline.
|
|
105
|
+
|
|
104
106
|
**Como classificar (router):** sinais determinísticos primeiro — `morph-spec create --request "<texto>"` roda o detector por keywords (hotfix: "produção caiu/urgente/incident/p0"; bug: "bug/corrigir/exception/regressão"; chore: "typo/rename/bump/config/docs/cleanup"). As keywords casam como **palavra inteira** ("group0" não é `p0`, "prefix" não é `fix`, "debug" não é `bug`) — casar demais pularia gates num pedido inócuo; por isso plural e flexão são listados explicitamente ("bugs", "incidentes", "configs"). Confiança `high` → usa o tipo. Empate (`tie`) ou nenhum sinal (`none`) → o comando sai com código 2 e os candidatos; **você decide como roteador** e re-roda com `--type`. Só vale uma `AskUserQuestion` quando o pedido é genuinamente indeterminado.
|
|
105
107
|
|
|
106
108
|
**Como o skip funciona:** `chore`/`hotfix` têm os gates `proposal`/`plan` carimbados no nascimento com `approvedBy: "policy:{tipo}"`. Como `derivePhase` é gate-aware, o trabalho já nasce em `implement` — sem tocar `phases.json`. Artefatos reutilizam os nomes canônicos (hotfix escreve brief curto em `proposal.md`; ambos escrevem `2-plan/tasks.json` mínimo de 1-3 tasks para ligar trace/score/dag).
|
|
@@ -138,7 +140,7 @@ Não invente caminhos alternativos.
|
|
|
138
140
|
|
|
139
141
|
### Plan (`2-plan/`)
|
|
140
142
|
|
|
141
|
-
- `usecases/UC-{nn}-{slug}.md` — **um arquivo por use case**, o artefato de comportamento da feature. Frontmatter (`id`, `title`, `actor`, `status`, `entities`) mais as seções `Pré-condições`, `Cenário principal
|
|
143
|
+
- `usecases/UC-{nn}-{slug}.md` — **um arquivo por use case**, o artefato de comportamento da feature. Frontmatter (`id`, `title`, `actor`, `status`, `entities`) mais as seções obrigatórias `Pré-condições`, `Cenário principal` (curto) e `Pós-condições` (P1, P2…). `Fluxos alternativos` (A1, A2…) e `Delta de domínio` são **opcionais** — só quando o comportamento não-trivial exigir (detalhe: `morph-plan`).
|
|
142
144
|
|
|
143
145
|
**Pós-condição precisa ser observável em teste** — a regra que sustenta a camada. "O sistema fica consistente" não passa; "a resposta contém todos os veterinários não arquivados" passa. Chega **literal** ao `doneCriteria` da task que a realiza — tradução manual nesse ponto é o que hoje perde o requisito.
|
|
144
146
|
|
|
@@ -209,10 +211,10 @@ Gates são pontos de **pausa potencial**. Em `trust: "auto"` (default), auto-pas
|
|
|
209
211
|
- "cancelar feature" (Gate 3 usa "rollback" em vez de "cancelar")
|
|
210
212
|
```
|
|
211
213
|
|
|
212
|
-
**Sinais de risco que forçam pausa em auto** (
|
|
214
|
+
**Sinais de risco que forçam pausa em auto** (`gate-check` aplica esta tabela via `shouldPauseGate` — fonte única; sinal que só a sessão conhece escala via `gate-decision` manual):
|
|
213
215
|
|
|
214
216
|
| Sinal | Threshold | Quando aplica |
|
|
215
|
-
|
|
217
|
+
| ------- | ----------- | --------------- |
|
|
216
218
|
| `designSystemDivergence` | true | Brainstorming detecta fontes conflitantes (spec antigo vs bundle local) |
|
|
217
219
|
| `standardsViolations` | array.length > 0 | Mandate ou implementation viola padrões proibidos |
|
|
218
220
|
| `evalScore` | < 9 | score composto da feature (via morph-review) abaixo do mínimo |
|
|
@@ -220,7 +222,7 @@ Gates são pontos de **pausa potencial**. Em `trust: "auto"` (default), auto-pas
|
|
|
220
222
|
| `workType` | === 'hotfix' | Gate 3 pausa SEMPRE (detalhe abaixo, "Gates por tipo de trabalho") |
|
|
221
223
|
|
|
222
224
|
| Gate | Sinais | Skill responsável |
|
|
223
|
-
|
|
225
|
+
| ------ | -------- | -------------------- |
|
|
224
226
|
| 1 — Proposta | `designSystemDivergence`, `standardsViolations` (improvável) | `morph-brainstorming` |
|
|
225
227
|
| 2 — Plano | Gate 1 + `taskCount`, `standardsViolations` em mandate | `morph-plan` |
|
|
226
228
|
| 3 — Review | `evalScore` composite, `standardsViolations` em implementation | `morph-review` |
|
|
@@ -235,7 +237,7 @@ Para alterar o modo: editar `.morph/config/config.json → trust` (`"auto"` ou `
|
|
|
235
237
|
|
|
236
238
|
**Registre quem aprovou (`approvedBy`):** objeto `{ approved, timestamp, approvedBy }`. `"auto"` — política `trust: auto` sem decisão humana. `"manual"` — humano aprovou explicitamente (via `AskUserQuestion`, ou, sem ela em headless, via texto começando em "aprovado"); em `trust: manual` todo gate é `"manual"` — nunca grave `"auto"` num gate que um humano aprovou. Mantém o audit trail honesto nos contextos headless (CI, `claude -p`) onde mais importa.
|
|
237
239
|
|
|
238
|
-
**O hook gate-guard.js** confere, sem bloquear, se a ação tomada num gate (pausar vs auto-aprovar) bateu com a decisão
|
|
240
|
+
**O hook gate-guard.js** confere, sem bloquear, se a ação tomada num gate (pausar vs auto-aprovar) bateu com a decisão persistida. **Default:** `gate-check <feature> <gate> [--signals <json>] [--json]` decide via `shouldPauseGate`; `--signals` sobrescreve só o que o disco não expõe sozinho (`designSystemDivergence`, `standardsViolations`, `evalScore`). **Escape manual** (sinal que `shouldPauseGate` nem representa, ex.: modo de descoberta): `gate-decision <feature> <gate> --pause <bool> [--reason <txt>] [--signals <json>]`. Ambos gravam `gateDecisions[gate] = { pause, reason, signals, trust, decidedAt }` server-side (shape em `framework/schemas/feature.schema.json`). **Nunca edite `gateDecisions` à mão** — colide com state-sync. Divergência → o guard injeta aviso no contexto; cada conferência registra `coherent`/`divergent` em `.morph/logs/activity.json` — nunca bloqueia.
|
|
239
241
|
|
|
240
242
|
---
|
|
241
243
|
|
|
@@ -287,7 +289,7 @@ morph-spec report-check <feature> [task] --json
|
|
|
287
289
|
```
|
|
288
290
|
|
|
289
291
|
| veredito | o que significa | ação |
|
|
290
|
-
|
|
292
|
+
| --- | --- | --- |
|
|
291
293
|
| `ok` | relatório presente e com os 4 itens | siga o fluxo |
|
|
292
294
|
| `report-incomplete` | relatório existe, faltam itens (ele lista quais) | complete a partir da mensagem de retorno, carimbe **DEGRADADO** |
|
|
293
295
|
| `work-landed-report-missing` | sem relatório, mas os `outputs` da task estão no disco | **não re-despache** — grave você mesmo o relatório canônico a partir da mensagem de retorno, carimbado **DEGRADADO** |
|
|
@@ -330,27 +332,23 @@ Não invoque uma skill fora do momento indicado.
|
|
|
330
332
|
|
|
331
333
|
Path de cada skill: `framework/skills/core/{nome}/SKILL.md`.
|
|
332
334
|
|
|
333
|
-
| Skill
|
|
334
|
-
|
|
335
|
-
| **morph-proposal**
|
|
336
|
-
| **morph-apply**
|
|
337
|
-
| morph-brainstorming
|
|
338
|
-
| morph-stack-scan
|
|
339
|
-
| morph-
|
|
340
|
-
| morph-
|
|
341
|
-
| morph-
|
|
342
|
-
| morph-
|
|
343
|
-
| morph-
|
|
344
|
-
| morph-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
Slash commands são atalhos: o agente pode chamar `Skill(morph-proposal)` diretamente quando o usuário pede "use /morph-proposal".
|
|
352
|
-
|
|
353
|
-
Cada skill contém instruções passo a passo. Leia, siga, não desvie sem justificativa no recap.md. Apenas `framework/skills/core/` é instalado. Nenhuma skill deve ser invocada proativamente por um hook ou script — skills são instrumentos do modelo, você decide quando a situação pede o rigor que a skill fornece.
|
|
335
|
+
| Skill | Quando invocar |
|
|
336
|
+
| ----------------------- | --------------------------------------------------------------------------- |
|
|
337
|
+
| **morph-proposal** | **Orquestrador**: brainstorming → Gate 1 → plan → Gate 2 (entry point) |
|
|
338
|
+
| **morph-apply** | **Orquestrador**: DAG-adaptive implement loop → review → Gate 3 |
|
|
339
|
+
| morph-brainstorming | Invocada pela morph-proposal — entendimento de negócio + stack-scan |
|
|
340
|
+
| morph-stack-scan | Detecta stack atual; curto-circuita em greenfield |
|
|
341
|
+
| morph-uiux | Ramo opcional uiux (§2.1) — design system, mockups, componentes, fluxos |
|
|
342
|
+
| morph-plan | Invocada pela morph-proposal — produz spec/mandate/tasks.json |
|
|
343
|
+
| morph-implement | Invocada pela morph-apply — executa cada task |
|
|
344
|
+
| morph-eval | Após concluir uma task ou fase |
|
|
345
|
+
| morph-review | Invocada pela morph-apply — produz review-report + Gate 3 |
|
|
346
|
+
| morph-hotfix | **Orquestrador**: ADW cirúrgico de hotfix (scout → fix → gate humano → ship) |
|
|
347
|
+
| morph-standards | Quando precisar localizar ou aplicar um standard específico |
|
|
348
|
+
|
|
349
|
+
Slash commands (`/morph-proposal`, `/morph-apply`, `/morph-hotfix` — linhas acima) são atalhos que invocam a `Skill()` correspondente; o agente pode chamá-la direto quando o usuário pede "use /morph-proposal".
|
|
350
|
+
|
|
351
|
+
Cada skill contém instruções passo a passo — leia, siga, não desvie sem justificativa no recap.md. Só `framework/skills/core/` é instalado. Nenhuma skill é invocada proativamente por hook ou script — você decide quando a situação pede o rigor dela.
|
|
354
352
|
|
|
355
353
|
---
|
|
356
354
|
|
|
@@ -21,7 +21,7 @@ Resolve uma queda ou bug crítico de produção com prioridade máxima em veloci
|
|
|
21
21
|
3. **Hotfix brief:** escreve `0-proposal/proposal.md` curto (sintoma/root cause/blast radius/plano do fix) e `2-plan/tasks.json` mínimo (T1 fix, T2 verify/regressão).
|
|
22
22
|
4. **Fix cirúrgico:** implementa a mudança mínima que resolve o sintoma — sem refatoração, sem hardening fora de escopo.
|
|
23
23
|
5. **Test loop:** `morph-spec verify {feature-name} {task} --json` focado no blast radius até verde; evidência real capturada no `recap.md`.
|
|
24
|
-
6. **Gate 3 sempre humano:** `morph-spec gate-
|
|
24
|
+
6. **Gate 3 sempre humano:** `morph-spec gate-check {feature-name} review` (força a pausa via `workType: hotfix`, lido do disco) → `4-review/review-report.md` → `AskUserQuestion` sempre. **Nunca** `morph-spec approve {feature-name} review --mode auto` — o CLI recusa essa combinação num hotfix.
|
|
25
25
|
7. **Pós-gate:** `morph-spec verify {feature-name}` (suíte completa da feature) e sinaliza commit/archive — não arquiva automaticamente.
|
|
26
26
|
|
|
27
27
|
## Anti-padrões
|
package/framework/docs/CLI.md
CHANGED
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
## Gates e estado
|
|
8
8
|
|
|
9
|
-
- **`morph-spec approve <feature> <gate> --mode auto`** — aprova um gate (`proposal`/`plan`/`review`) em `trust: auto`. **O Gate 3 exige `4-review/evaluator-report.md`**: sem o relatório do avaliador independente o comando recusa (exit 1). Se o dispatch do avaliador for impossível nesta sessão, aprove com `--self-assessed` — a degradação é gravada em `approvalGates.review.selfAssessed` e aparece marcada no `morph-spec list`. `--force` **não** dispensa esta regra (é só para ordem de gate). **Exceção `hotfix`:** esse tipo nunca despacha o avaliador (`morph-hotfix` §7); o Gate 3 exige `4-review/review-report.md` no lugar do `evaluator-report.md`, e a assinatura humana continua obrigatória via `--approver` (o backstop de `--mode auto` acima permanece recusando).
|
|
9
|
+
- **`morph-spec approve <feature> <gate> --mode auto`** — aprova um gate (`proposal`/`uiux`/`plan`/`review`) em `trust: auto`. **`uiux`** é o único gate cujo `AskUserQuestion` o hook `state-sync.js` não reconhece por texto (só casa "Gate 1/2/3") — aprove-o sempre explicitamente por este comando ou por `advance`, nunca contando com o hook. **O Gate 3 exige `4-review/evaluator-report.md`**: sem o relatório do avaliador independente o comando recusa (exit 1). Se o dispatch do avaliador for impossível nesta sessão, aprove com `--self-assessed` — a degradação é gravada em `approvalGates.review.selfAssessed` e aparece marcada no `morph-spec list`. `--force` **não** dispensa esta regra (é só para ordem de gate). **Exceção `hotfix`:** esse tipo nunca despacha o avaliador (`morph-hotfix` §7); o Gate 3 exige `4-review/review-report.md` no lugar do `evaluator-report.md`, e a assinatura humana continua obrigatória via `--approver` (o backstop de `--mode auto` acima permanece recusando).
|
|
10
10
|
- **`morph-spec advance <feature>`** — aprova o gate da fase corrente **e** cria a pasta da próxima fase num passo só (`--design` toma o ramo opcional de uiux a partir da proposta).
|
|
11
11
|
- **`morph-spec score <feature> <task> <score> [--dims a,c,q,t]`** — grava `taskScores` no feature.json com timestamp server-side; **nunca edite taskScores à mão**. Em PowerShell, cite o valor de `--dims` entre aspas (`--dims "9.5,9,9,9"`) — sem aspas, a lista pode chegar como tokens separados; o parser aceita ambas as formas, mas citar evita qualquer ambiguidade.
|
|
12
|
-
- **`morph-spec gate-
|
|
12
|
+
- **`morph-spec gate-check <feature> <gate> [--signals <json>] [--trust <mode>] [--json]`** — o caminho **default**: coleta do disco os sinais que `shouldPauseGate` (risk-detector.js) já sabe avaliar (`workType`, `taskCount`, verificação, sha/diffstat), decide a pausa e persiste `gateDecisions.{gate}`. `--signals` aceita só as chaves que o disco genuinamente não expõe sozinho — `designSystemDivergence`, `standardsViolations`, `evalScore` — qualquer outra chave é ignorada com aviso. No **review**, o `evalScore` real vem do token `**Composite-Score:** {n.n}` do `evaluator-report.md` (o avaliador o grava por contrato); sem o token, cai no proxy (média das `taskScores`); `--signals` vence ambos. Um stamp de `verification` com status `fail` (último `morph-spec verify` vermelho) **força pausa** em qualquer gate.
|
|
13
|
+
- **`morph-spec gate-decision <feature> <gate> --pause <bool> [--reason <txt>] [--signals <json>]`** — o **escape manual**: registra uma decisão já tomada pela sessão (ex.: `discoveryMode: "interview"`, sinal que `shouldPauseGate` nem representa). Mesmo write path do `gate-check` — grava `gateDecisions` no feature.json com timestamp server-side (shape em `framework/schemas/feature.schema.json`); **nunca edite gateDecisions à mão** — o Edit manual colide com o hook state-sync.
|
|
13
14
|
|
|
14
15
|
## Features
|
|
15
16
|
|
|
@@ -24,7 +24,6 @@ export const PHASE_DIRS = {
|
|
|
24
24
|
export const OUTPUT_PHASE_MAP = {
|
|
25
25
|
proposal: 'proposal',
|
|
26
26
|
stackScan: 'proposal',
|
|
27
|
-
migrationPlan: 'proposal',
|
|
28
27
|
uiDesignSystem: 'uiux',
|
|
29
28
|
uiMockups: 'uiux',
|
|
30
29
|
uiComponents: 'uiux',
|
|
@@ -43,7 +42,6 @@ export const OUTPUT_PHASE_MAP = {
|
|
|
43
42
|
export const FILENAME_TO_OUTPUT = {
|
|
44
43
|
'proposal.md': 'proposal',
|
|
45
44
|
'stack-scan.md': 'stackScan',
|
|
46
|
-
'migration-plan.md': 'migrationPlan',
|
|
47
45
|
'design-system.md': 'uiDesignSystem',
|
|
48
46
|
'mockups.md': 'uiMockups',
|
|
49
47
|
'components.md': 'uiComponents',
|
package/framework/phases.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"Produce proposal.md and reach Gate 1"
|
|
13
13
|
],
|
|
14
14
|
"requiredOutputs": ["proposal"],
|
|
15
|
-
"optionalOutputs": ["
|
|
15
|
+
"optionalOutputs": ["stackScan"],
|
|
16
16
|
"pausePoints": [
|
|
17
17
|
{ "id": "proposal", "label": "Gate 1 — Approve proposal" }
|
|
18
18
|
],
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"pausePoints": [
|
|
34
34
|
{ "id": "uiux", "label": "Approve UI/UX" }
|
|
35
35
|
],
|
|
36
|
-
"skill":
|
|
36
|
+
"skill": "morph-uiux"
|
|
37
37
|
},
|
|
38
38
|
"plan": {
|
|
39
39
|
"id": "plan",
|
|
@@ -64,7 +64,7 @@ All outputs go in `.morph/features/{feature}/`:
|
|
|
64
64
|
|
|
65
65
|
| Phase | Path |
|
|
66
66
|
|-------|------|
|
|
67
|
-
| Proposal | `0-proposal/proposal.md`, `stack-scan.md
|
|
67
|
+
| Proposal | `0-proposal/proposal.md`, `stack-scan.md` |
|
|
68
68
|
| Design (optional) | `1-design/design-system.md`, `mockups.md`, `components.md`, `flows.md` |
|
|
69
69
|
| Plan | `2-plan/spec.md`, `mandate.md`, `tasks.json`, `decisions.md` |
|
|
70
70
|
| Implement | `3-implement/recap.md` + source code |
|
|
@@ -145,6 +145,18 @@
|
|
|
145
145
|
},
|
|
146
146
|
"additionalProperties": false
|
|
147
147
|
},
|
|
148
|
+
"verification": {
|
|
149
|
+
"type": "object",
|
|
150
|
+
"description": "The single latest deterministic verify stamp (any scope), written ONLY by `morph-spec verify`. Distinct from `verifications`/`taskVerifications` above (per-scope history with attempts/nodes): this is overwritten by every verify call regardless of scope, carrying just enough to correlate a pass/fail with the exact commit it covers. Primary consumer: `morph-spec gate-check`, which surfaces it as a signal (informational — no shouldPauseGate rule keys on it directly).",
|
|
151
|
+
"required": ["status", "sha", "ts", "scope"],
|
|
152
|
+
"properties": {
|
|
153
|
+
"status": { "type": "string", "enum": ["pass", "fail"] },
|
|
154
|
+
"sha": { "type": ["string", "null"], "description": "HEAD commit SHA at verify time (git rev-parse HEAD); null when not in a git repo or no commits yet." },
|
|
155
|
+
"ts": { "type": "string", "format": "date-time", "description": "Server-side timestamp, same instant as the corresponding verifications/taskVerifications entry's updatedAt." },
|
|
156
|
+
"scope": { "type": "string", "description": "'feature', or 'task:<id>' for a task-scoped verify." }
|
|
157
|
+
},
|
|
158
|
+
"additionalProperties": false
|
|
159
|
+
},
|
|
148
160
|
"tasks": {
|
|
149
161
|
"type": "object",
|
|
150
162
|
"description": "Aggregate task counters (informational — the source of truth is 2-plan/tasks.json).",
|
|
@@ -13,7 +13,7 @@ These are the only skills the harness needs. MORPH.md references them by path.
|
|
|
13
13
|
| Skill | Purpose | User-invocable |
|
|
14
14
|
|----------------------|----------------------------------------------------------------------|----------------|
|
|
15
15
|
| `morph-brainstorming` | Business understanding + brownfield scan → proposal.md (Gate 1) | yes |
|
|
16
|
-
| `morph-stack-scan` | Detect stack drift in existing projects,
|
|
16
|
+
| `morph-stack-scan` | Detect stack drift in existing projects, report in stack-scan.md | yes |
|
|
17
17
|
| `morph-plan` | Produce spec.md + mandate.md + tasks.json (Gate 2) | yes |
|
|
18
18
|
| `morph-implement` | Execute each task with standard + persona, auto-advance between tasks| no |
|
|
19
19
|
| `morph-eval` | Score work 0-10 across 4 dimensions, silence on score >= 9 | no |
|
|
@@ -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.20.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.
|
|
7
|
+
cliVersion: "8.20.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.
|
|
7
|
+
cliVersion: "8.20.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-apply
|
|
@@ -210,21 +210,16 @@ Quando `getPendingTasks(data).length === 0`:
|
|
|
210
210
|
|
|
211
211
|
### 5. Gate 3 (trust-aware)
|
|
212
212
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
- Score médio < 9 no review-report.
|
|
216
|
-
- Presença de erros não resolvidos.
|
|
217
|
-
- Mudanças incidentais em standards/.morph/framework/.
|
|
218
|
-
|
|
219
|
-
Mesma lógica do Gate 1/Gate 2 (regras da tabela do MORPH.md §5, aplicadas em linguagem natural — sem scripts): `trust: manual` → pausa sempre; `standardsViolations` não-vazio → pausa; `evalScore < 9` → pausa; caso contrário → auto-passa.
|
|
220
|
-
|
|
221
|
-
**Persista a decisão ANTES de apresentar ou auto-aprovar — via CLI, nunca editando feature.json à mão** (o Edit manual colide com o hook state-sync — erro "file modified since read"):
|
|
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.
|
|
222
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:
|
|
223
216
|
```
|
|
224
|
-
morph-spec gate-
|
|
217
|
+
morph-spec gate-check {feature} review --signals '{"evalScore":9.2,"standardsViolations":[]}'
|
|
225
218
|
```
|
|
226
219
|
|
|
227
|
-
|
|
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.
|
|
228
223
|
|
|
229
224
|
- Pause: `AskUserQuestion` com options `["aprovado, fechar feature", "preciso ajustar", "rollback"]`.
|
|
230
225
|
- Auto: exibir summary do review-report, aprovar via `morph-spec approve {feature} review --mode auto`, e prosseguir.
|
|
@@ -242,7 +237,7 @@ O comando grava `gateDecisions.review = { pause, reason, signals, trust, decided
|
|
|
242
237
|
- Não dispachar mais que 4 agentes em paralelo (sobrecarga de contexto + custo).
|
|
243
238
|
- Não dispachar um agente inteiro para uma raiz de effort S — overhead > trabalho; o `morph-spec dag` já as marca como `inline`.
|
|
244
239
|
- Não deixar sub-agent tocar `tasks.json`, `feature.json` ou o board de sessão — estado é do orquestrador (cláusula 2 do protocolo).
|
|
245
|
-
- Não editar `feature.json` à mão para gravar scores ou decisões de gate — use `morph-spec score` e `morph-spec gate-decision` (timestamps server-side; o Edit manual colide com o hook state-sync — "file modified since read").
|
|
240
|
+
- Não editar `feature.json` à mão para gravar scores ou decisões de gate — use `morph-spec score` e `morph-spec gate-check`/`gate-decision` (timestamps server-side; o Edit manual colide com o hook state-sync — "file modified since read").
|
|
246
241
|
|
|
247
242
|
## Output esperado
|
|
248
243
|
|
|
@@ -262,5 +257,6 @@ O comando grava `gateDecisions.review = { pause, reason, signals, trust, decided
|
|
|
262
257
|
- `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"`)
|
|
263
258
|
- `morph-spec verify {feature} [task] --json` — cadeia determinística build+testes+validadores (código antes do juiz)
|
|
264
259
|
- `morph-spec score {feature} {task} {score} [--dims a,c,q,t]` — grava taskScores no feature.json com timestamp server-side
|
|
265
|
-
- `morph-spec gate-
|
|
260
|
+
- `morph-spec gate-check {feature} {gate} [--json]` — default: coleta sinais do disco, decide via `shouldPauseGate`, persiste `gateDecisions`
|
|
261
|
+
- `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`)
|
|
266
262
|
- `.morph/framework/MORPH.md` §5 — regras de pausa de gate (trust mode)
|
|
@@ -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.20.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-brainstorming
|
|
@@ -40,7 +40,7 @@ Fato não se pergunta. Antes de levar a primeira pergunta ao usuário, levante o
|
|
|
40
40
|
|
|
41
41
|
3. Reconciliação de design-system (se aplicável): comparar `.morph/context/design-system.md` (se existir) com o que foi detectado no stack-scan e com bundles/mocks recentes do usuário. Se houver **divergência** (tokens diferentes, framework version mismatch, fonte aprovada distinta), marque `signals.designSystemDivergence = true` — a escolha da fonte vira uma **decisão da árvore** (Parte 1), não uma pergunta solta. Resolvida, atualize `.morph/context/design-system.md` com a fonte escolhida + entrada de changelog (data, motivo).
|
|
42
42
|
|
|
43
|
-
4. Desvio de stack detectado
|
|
43
|
+
4. Desvio de stack detectado (`stack-scan.md`, seção Desvios): "a migração entra nesta feature ou vira feature separada?" — pergunta feita pelo `morph-stack-scan` ao fim da varredura — também é decisão da árvore; a resposta vai para a seção "Compliance de stack" do `proposal.md` (Parte 4).
|
|
44
44
|
|
|
45
45
|
### Parte 1 — Árvore de decisões abertas
|
|
46
46
|
|
|
@@ -88,7 +88,7 @@ options:
|
|
|
88
88
|
|
|
89
89
|
1. Produza `proposal.md` em `.morph/features/{feature}/0-proposal/` com:
|
|
90
90
|
- **Problema:** o que está sendo resolvido e para quem (máx. 2 parágrafos)
|
|
91
|
-
- **Escopo:** o que está incluído e o que está explicitamente excluído
|
|
91
|
+
- **Escopo:** o que está incluído e o que está explicitamente excluído — registre se a mudança cria ou altera superfície de UI (componente, página, tela, estilo, fluxo de navegação): é o fato que decide o roteamento para o ramo uiux na `morph-proposal` (critério objetivo em `MORPH.md` §2.1)
|
|
92
92
|
- **Usuários e fluxos críticos:** quem usa e qual é o caminho principal
|
|
93
93
|
- **Stack:** confirme o stack padrão ou documente desvios aprovados
|
|
94
94
|
- **Riscos e dependências:** o que pode dar errado, o que esta feature depende
|
|
@@ -102,27 +102,17 @@ options:
|
|
|
102
102
|
|
|
103
103
|
2. Apresente o Gate 1 segundo o modo de descoberta e o trust mode.
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
- `discoveryMode` = `"interview"` ou `"auto"`, conforme a resposta da Parte 2.
|
|
108
|
-
- `designSystemDivergence` = detectado na Parte 0 (fontes de design conflitantes).
|
|
109
|
-
- `standardsViolations` = lista de violações detectadas.
|
|
110
|
-
|
|
111
|
-
**Decisão de pausa** (regras da tabela do MORPH.md §5): **modo entrevista → pausa sempre** ("não aja até eu confirmar" é literalmente o Gate 1: a confirmação do entendimento compartilhado é o gate); `trust: manual` → pausa sempre; `designSystemDivergence` → pausa; `standardsViolations` não-vazio → pausa; caso contrário → auto-passa (`pause: false`). Monte `reason` com o sinal que disparou.
|
|
112
|
-
|
|
113
|
-
**Persista a decisão ANTES de apresentar ou auto-aprovar — via CLI, nunca editando feature.json à mão** (o Edit manual colide com o hook state-sync, que reescreve o arquivo entre o seu Read e o Edit — erro "file modified since read"):
|
|
114
|
-
|
|
105
|
+
**Modo entrevista** (Parte 2) é a única exceção genuína: pausa sempre, e `shouldPauseGate` não tem esse conceito — `discoveryMode` não está entre as chaves que `gate-check --signals` aceita sobrescrever. Registre direto, sem `gate-check`:
|
|
115
106
|
```
|
|
116
|
-
|
|
117
|
-
morph-spec gate-decision {feature} proposal --pause true --reason "modo entrevista — entendimento compartilhado confirmado pelo usuário" --signals '{"discoveryMode":"interview","designSystemDivergence":false,"standardsViolations":[]}'
|
|
118
|
-
|
|
119
|
-
# modo automático, sem sinais de risco
|
|
120
|
-
morph-spec gate-decision {feature} proposal --pause false --reason "nenhum sinal de risco" --signals '{"discoveryMode":"auto","designSystemDivergence":false,"standardsViolations":[]}'
|
|
107
|
+
morph-spec gate-decision {feature} proposal --pause true --reason "modo entrevista — entendimento compartilhado confirmado pelo usuário" --signals '{"discoveryMode":"interview"}'
|
|
121
108
|
```
|
|
122
109
|
|
|
123
|
-
|
|
110
|
+
**Fora do modo entrevista** (o caminho comum), rode `morph-spec gate-check {feature} proposal [--json]` — lê `trust` de `.morph/config/config.json`, decide via `shouldPauseGate` e persiste `gateDecisions.proposal` com timestamp server-side, imprimindo `pause`/`reason`/`signals`. Se a Parte 0 detectou divergência de design-system (leitura semântica — o `gate-check` não a vê sozinho no disco), repasse-a: `designSystemDivergence` é uma das poucas chaves que `--signals` aceita sobrescrever aqui:
|
|
111
|
+
```
|
|
112
|
+
morph-spec gate-check {feature} proposal --signals '{"designSystemDivergence":true}'
|
|
113
|
+
```
|
|
124
114
|
|
|
125
|
-
|
|
115
|
+
**Nunca edite `feature.json` à mão** (o Edit manual colide com o hook state-sync — erro "file modified since read"). Os dois comandos gravam `gateDecisions.proposal = { pause, reason, signals, trust, decidedAt }` no mesmo lugar (shape canônico em `.morph/framework/schemas/feature.schema.json`); o hook `gate-guard.js` confere depois se a ação (pausar vs auto-aprovar) bateu com a decisão persistida.
|
|
126
116
|
|
|
127
117
|
**Se `pause === true`** (manual mode OU risco detectado em auto), use `AskUserQuestion`:
|
|
128
118
|
|
|
@@ -152,8 +142,7 @@ options:
|
|
|
152
142
|
No caminho manual, o hook state-sync.js detecta a aprovação automaticamente (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} proposal`). Em modo auto sem AskUserQuestion, aprove via `morph-spec approve {feature} proposal --mode auto` (ou `morph-spec advance {feature}` para já criar a pasta 2-plan/) — nunca via Edit à mão de state.json.
|
|
153
143
|
|
|
154
144
|
## Output esperado
|
|
155
|
-
- `.morph/features/{feature}/0-proposal/proposal.md` — proposta aprovada
|
|
156
|
-
- `.morph/features/{feature}/0-proposal/migration-plan.md` — apenas se houver desvio de stack
|
|
145
|
+
- `.morph/features/{feature}/0-proposal/proposal.md` — proposta aprovada, com desvios de stack (se houver) resolvidos na seção "Compliance de stack"
|
|
157
146
|
- Gate 1 apresentado e aprovado
|
|
158
147
|
|
|
159
148
|
## Referências
|