@polymorphism-tech/morph-spec 8.18.0 → 8.19.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 (36) hide show
  1. package/README.md +2 -2
  2. package/bin/morph-spec.js +9 -0
  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 +5 -4
  7. package/framework/MORPH.md +3 -3
  8. package/framework/commands/morph-hotfix.md +1 -1
  9. package/framework/docs/CLI.md +2 -1
  10. package/framework/hooks/shared/phase-utils.js +0 -2
  11. package/framework/phases.json +1 -1
  12. package/framework/rules/morph-workflow.md +1 -1
  13. package/framework/schemas/feature.schema.json +12 -0
  14. package/framework/skills/README.md +1 -1
  15. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  16. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  17. package/framework/skills/core/morph-apply/SKILL.md +10 -14
  18. package/framework/skills/core/morph-brainstorming/SKILL.md +10 -21
  19. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  20. package/framework/skills/core/morph-hotfix/SKILL.md +4 -4
  21. package/framework/skills/core/morph-implement/SKILL.md +1 -1
  22. package/framework/skills/core/morph-plan/SKILL.md +12 -20
  23. package/framework/skills/core/morph-proposal/SKILL.md +3 -15
  24. package/framework/skills/core/morph-review/SKILL.md +15 -8
  25. package/framework/skills/core/morph-stack-scan/SKILL.md +9 -13
  26. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  27. package/package.json +1 -1
  28. package/src/commands/project/status.js +2 -2
  29. package/src/commands/state/gate-check.js +223 -0
  30. package/src/commands/state/gate-decision.js +46 -10
  31. package/src/commands/validation/verify.js +18 -1
  32. package/src/core/paths/output-schema.js +0 -1
  33. package/src/lib/agents/output-collector.js +0 -1
  34. package/src/lib/git/default-branch.js +65 -0
  35. package/src/lib/risk-detector.js +13 -0
  36. 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.18.0
6
+ **Version:** 8.19.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.18.0 by [Polymorphism Tech](https://polymorphism.tech)*
371
+ *morph-spec v8.19.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)')
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "morph-spec",
3
- "version": "8.18.0",
3
+ "version": "8.19.0",
4
4
  "displayName": "MORPH-SPEC Framework",
5
5
  "description": "Spec-driven development with 38 agents and 8-phase workflow for .NET/Blazor/Next.js/Azure",
6
6
  "publisher": "polymorphism-tech",
@@ -185,4 +185,4 @@ Never edited directly — go through CLI commands or `morph-spec update` instead
185
185
 
186
186
  ---
187
187
 
188
- *morph-spec v8.18.0 by Polymorphism Tech*
188
+ *morph-spec v8.19.0 by Polymorphism Tech*
@@ -249,4 +249,4 @@ morph-spec doctor
249
249
 
250
250
  ---
251
251
 
252
- *morph-spec v8.18.0 by Polymorphism Tech*
252
+ *morph-spec v8.19.0 by Polymorphism Tech*
@@ -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-decision`/`approve` (timestamps server-side; Edit manual colide com o hook `state-sync`).
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 — nunca edite à mão |
55
- | `gate-decision <f> <gate> --pause <bool>` | Grava `gateDecisions` server-side — nunca edite à mão |
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
- Todo comando é `morph-spec <comando>`. Referência completa (flags, semântica, exemplos): `.morph/framework/CLI.md`.
74
+ Prefixo de todo comando: `morph-spec`. Flags/exemplos: `.morph/framework/CLI.md`.
74
75
 
75
76
  ## Skills core (em `.claude/skills/`)
76
77
 
@@ -138,7 +138,7 @@ Não invente caminhos alternativos.
138
138
 
139
139
  ### Plan (`2-plan/`)
140
140
 
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`, `Fluxos alternativos` (A1, A2… — cada alternativa aproxima uma user story), `Pós-condições` (P1, P2…) e `Delta de domínio` (**só o que muda** — o domínio completo continua sendo o código EF Core mais as migrations).
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 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
142
 
143
143
  **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
144
 
@@ -209,7 +209,7 @@ Gates são pontos de **pausa potencial**. Em `trust: "auto"` (default), auto-pas
209
209
  - "cancelar feature" (Gate 3 usa "rollback" em vez de "cancelar")
210
210
  ```
211
211
 
212
- **Sinais de risco que forçam pausa em auto** (as skills aplicam estas regras em linguagem natural — a tabela abaixo é a fonte única):
212
+ **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
213
 
214
214
  | Sinal | Threshold | Quando aplica |
215
215
  |-------|-----------|---------------|
@@ -235,7 +235,7 @@ Para alterar o modo: editar `.morph/config/config.json → trust` (`"auto"` ou `
235
235
 
236
236
  **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
237
 
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 de trust via `shouldPauseGate`. A skill **persiste** essa decisão antes de agir — via `morph-spec gate-decision <feature> <gate> --pause <bool> [--reason <txt>] [--signals <json>]`, gravando `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.
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 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
239
 
240
240
  ---
241
241
 
@@ -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-decision {feature-name} review --pause true ...` → `4-review/review-report.md` → `AskUserQuestion` sempre. **Nunca** `morph-spec approve {feature-name} review --mode auto` — o CLI recusa essa combinação num hotfix.
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
@@ -9,7 +9,8 @@
9
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).
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-decision <feature> <gate> --pause <bool> [--reason <txt>] [--signals <json>]`** — 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.
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',
@@ -12,7 +12,7 @@
12
12
  "Produce proposal.md and reach Gate 1"
13
13
  ],
14
14
  "requiredOutputs": ["proposal"],
15
- "optionalOutputs": ["migrationPlan", "stackScan"],
15
+ "optionalOutputs": ["stackScan"],
16
16
  "pausePoints": [
17
17
  { "id": "proposal", "label": "Gate 1 — Approve proposal" }
18
18
  ],
@@ -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`, `migration-plan.md` (optional) |
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, generate migration-plan.md | yes |
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.18.0"
7
+ cliVersion: "8.19.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.18.0"
7
+ cliVersion: "8.19.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.18.0"
7
+ cliVersion: "8.19.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
- Sinais de risco para Gate 3:
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-decision {feature} review --pause false --reason "score 9.2, sem violações" --signals '{"evalScore":9.2,"standardsViolations":[]}'
217
+ morph-spec gate-check {feature} review --signals '{"evalScore":9.2,"standardsViolations":[]}'
225
218
  ```
226
219
 
227
- O comando grava `gateDecisions.review = { pause, reason, signals, trust, decidedAt }` no `feature.json` autoritativo com timestamp server-side (o `signals.evalScore` aqui é o score composto do review-report; shape canônico em `.morph/framework/schemas/feature.schema.json`). O hook `gate-guard.js` confere depois se a ação bateu. Sem o registro o guard não verifica.
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-decision {feature} {gate} --pause {bool} [--reason ...] [--signals ...]` — grava gateDecisions no feature.json com timestamp server-side (shape em `.morph/framework/schemas/feature.schema.json`)
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.18.0"
7
+ cliVersion: "8.19.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: gere `migration-plan.md` em `.morph/features/{feature}/0-proposal/`. "A migração entra nesta feature ou vira feature separada?" também é decisão da árvore.
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
 
@@ -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
- Ler `.morph/config/config.json → trust` (default `"auto"`). Calcular os sinais de risco em linguagem natural — sem scripts:
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
- # modo entrevista — o gate pausa sempre
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
- `signals` é free-form no `feature.schema.json` — `discoveryMode` não exige mudança de schema, e deixa o modo escolhido auditável no `feature.json` commitado.
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
- O comando grava `gateDecisions.proposal = { pause, reason, signals, trust, decidedAt }` no `feature.json` autoritativo com timestamp server-side (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 esta decisão e avisa em divergência. Sem o registro o guard não verifica — não pule.
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
@@ -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.18.0"
7
+ cliVersion: "8.19.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.18.0"
7
+ cliVersion: "8.19.0"
8
8
  ---
9
9
 
10
10
  # morph-hotfix
@@ -81,10 +81,10 @@ Use `--skip-tests`/`--skip-build` quando fizer sentido para velocidade (ex.: ite
81
81
 
82
82
  ### 7. Gate 3 — SEMPRE humano
83
83
 
84
- O hotfix tem `forcedPauseGates: ['review']` (`src/core/work-types.js`) — o Gate 3 pausa **sempre**, mesmo em `trust: auto`. Persista a decisão antes de apresentar:
84
+ O hotfix tem `forcedPauseGates: ['review']` (`src/core/work-types.js`) — o Gate 3 pausa **sempre**, mesmo em `trust: auto`. `gate-check` já sabe disso: lê `workType` do disco e `shouldPauseGate` força a pausa antes de checar qualquer outro sinal — rode direto, sem `--signals`:
85
85
 
86
86
  ```
87
- morph-spec gate-decision {feature} review --pause true --reason "hotfix: aprovação humana obrigatória" --signals '{"workType":"hotfix","evalScore":X}'
87
+ morph-spec gate-check {feature} review [--json]
88
88
  ```
89
89
 
90
90
  Escreva `4-review/review-report.md` curto: diff do fix + evidência real de teste (saída do `verify` do passo 6). Depois, **`AskUserQuestion` SEMPRE**:
@@ -137,4 +137,4 @@ morph-spec approve {feature} review --approver "<nome de quem aprovou>"
137
137
  - `src/core/work-types.js` — `scaffold`/`skippedGates`/`forcedPauseGates` do tipo `hotfix`
138
138
  - `morph-spec create {feature} --type hotfix` — nascimento com política de gates
139
139
  - `morph-spec verify {feature} [task] --json` — cadeia determinística build+testes+validadores
140
- - `morph-spec gate-decision {feature} review --pause true [--reason ...] [--signals ...]` — persiste a decisão de pausa antes do Gate 3
140
+ - `morph-spec gate-check {feature} review [--json]` — persiste a decisão de pausa (forçada por `workType: hotfix`) antes do Gate 3
@@ -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.18.0"
7
+ cliVersion: "8.19.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.18.0"
7
+ cliVersion: "8.19.0"
8
8
  ---
9
9
 
10
10
  # morph-plan
@@ -45,25 +45,22 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
45
45
  2. Sistema retorna os veterinários ordenados por sobrenome
46
46
  3. Sistema exibe, para cada um, nome e especialidades
47
47
 
48
- ## Fluxos alternativos
49
- - **A1** — Nenhum veterinário cadastrado → sistema exibe estado vazio
50
- - **A2** — Veterinário sem especialidade → sistema exibe "sem especialidade"
51
-
52
48
  ## Pós-condições
53
49
  - **P1** — A resposta contém todos os veterinários não arquivados
54
50
  - **P2** — Cada veterinário traz suas especialidades em lista, nunca string concatenada
55
51
  - **P3** — A ordenação por sobrenome é estável para nomes repetidos
56
52
 
57
- ## Delta de domínio
58
- - `Vet.archivedAt` (novo, nullable) — habilita P1
59
- - Nenhuma relação nova
53
+ ## Fluxos alternativos (opcional)
54
+ - **A1** — Nenhum veterinário cadastrado → sistema exibe estado vazio
60
55
  ```
61
56
 
62
57
  **A regra que sustenta a camada inteira: pós-condição precisa ser observável em teste.** "O sistema fica consistente" não passa. "A resposta contém todos os veterinários não arquivados" passa. Antes de escrever cada pós-condição, pergunte: *que asserção eu escreveria para verificar isto?* Se não há resposta, a pós-condição está mal formulada — reescreva ou descarte. Sem esse filtro a camada vira prosa e não chega ao `doneCriteria`.
63
58
 
64
59
  **Identificador sequencial no projeto, não na feature.** Antes de numerar, leia o acervo `.morph/specs/usecases/` (se existir) mais os use cases das features ativas em `.morph/features/*/2-plan/usecases/`; tome o maior `UC-{nn}` e some um. Numerar por feature garante colisão no momento da promoção.
65
60
 
66
- **Seções:** `Pré-condições` (o que já é verdade antes), `Cenário principal` (o caminho feliz, numerado), `Fluxos alternativos` (**A1**, **A2**… — cada alternativa aproxima uma user story; edge case de *comportamento* mora aqui, edge case *técnico* fica no `spec.md`), `Pós-condições` (**P1**, **P2**… — o que passa a ser verdade, cada uma testável) e `Delta de domínio` (**só o que muda**: campo novo, relação nova, invariante nova — o modelo completo continua sendo o código EF Core mais as migrations; se a feature não altera o domínio, escreva "nenhum").
61
+ **Seções obrigatórias:** `Pré-condições` (o que já é verdade antes), `Cenário principal` (o caminho feliz, numerado, **curto** — não é o lugar para exaustão de casos) e `Pós-condições` (**P1**, **P2**… — o que passa a ser verdade, cada uma testável; é a seção que viaja **literal** ao `doneCriteria`, ver abaixo).
62
+
63
+ **Seções opcionais** — inclua só quando o comportamento não-trivial exigir, não por padrão: `Fluxos alternativos` (**A1**, **A2**… — um desvio do caminho feliz que precisa de pós-condição própria; edge case de *comportamento* mora aqui, edge case *técnico* fica no `spec.md`) e `Delta de domínio` (**só quando a feature muda o modelo**: campo novo, relação nova, invariante nova — sem delta, omita a seção em vez de escrever "nenhum"). Nenhuma das duas é consumida por `dag`/`finish` — existem para o leitor humano quando o caso pede, não para preencher o template.
67
64
 
68
65
  **Quando é obrigatório** (ver MORPH.md §2.1 para o roteamento por tipo):
69
66
 
@@ -151,21 +148,16 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
151
148
 
152
149
  Você pode embutir o diagrama do DAG do plano via `morph-spec dag {feature} --mermaid` (flowchart Mermaid) para visualização no gate.
153
150
 
154
- Ler `.morph/config/config.json → trust` (default `"auto"`). Calcular os sinais de risco em linguagem natural — sem scripts:
155
-
156
- - `taskCount` = número de tasks do tasks.json.
157
- - `designSystemDivergence` = herdado do brainstorming.
158
- - `standardsViolations` = violações detectadas no mandate.
159
-
160
- **Decisão de pausa** (regras da tabela do MORPH.md §5): `trust: manual` → pausa sempre; `designSystemDivergence` → pausa; `standardsViolations` não-vazio → pausa; `taskCount > 20` → pausa; caso contrário → auto-passa (`pause: false`).
161
-
162
- **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"):
151
+ Rode `morph-spec gate-check {feature} plan [--json]` — lê `trust` de `.morph/config/config.json`, conta `taskCount` do `tasks.json` (disco), decide via `shouldPauseGate` e persiste `gateDecisions.plan` 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.
163
152
 
153
+ `gate-check` **não herda** `designSystemDivergence` do Gate 1 automaticamente — é recomputado a cada chamada. Se a divergência do Gate 1 segue sem resolução, ou o mandate introduziu uma violação de standard, repasse via `--signals` (as únicas chaves que este comando aceita sobrescrever):
164
154
  ```
165
- morph-spec gate-decision {feature} plan --pause false --reason "nenhum sinal de risco" --signals '{"taskCount":12,"standardsViolations":[]}'
155
+ morph-spec gate-check {feature} plan --signals '{"designSystemDivergence":true,"standardsViolations":["<id>"]}'
166
156
  ```
167
157
 
168
- O comando grava `gateDecisions.plan = { pause, reason, signals, trust, decidedAt }` no `feature.json` autoritativo com timestamp server-side (shape canônico em `.morph/framework/schemas/feature.schema.json`). Isso deixa o raciocínio de trust auditável no disco: o hook `gate-guard.js` confere depois se a ação tomada (pausar vs auto-aprovar) bateu com esta decisão e avisa em caso de divergência. Sem este registro o guard não tem como verificar — não pule.
158
+ Risco que nenhuma dessas chaves representa (julgamento desta sessão, não fato de disco): use `gate-decision` direto em vez de `gate-check`.
159
+
160
+ **Nunca edite `feature.json` à mão** (colide com o hook state-sync — erro "file modified since read"). Os caminhos acima gravam no mesmo lugar; o hook `gate-guard.js` confere depois se a ação tomada (pausar vs auto-aprovar) bateu com a decisão persistida.
169
161
 
170
162
  **Se `pause === true`**, use `AskUserQuestion`:
171
163
 
@@ -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.18.0"
7
+ cliVersion: "8.19.0"
8
8
  ---
9
9
 
10
10
  # morph-proposal
@@ -65,13 +65,7 @@ No **modo entrevista** o Gate 1 pausa sempre — a confirmação do entendimento
65
65
 
66
66
  ### 3. Gate 1 (trust-aware)
67
67
 
68
- Ler `.morph/config/config.json → trust` (default `"auto"`). Calcular sinais de risco:
69
-
70
- - `discoveryMode` — `"interview"` ou `"auto"`, decidido na pergunta de abertura da morph-brainstorming.
71
- - `designSystemDivergence` — detectado pela morph-brainstorming.
72
- - `standardsViolations` — violações de mandate listadas na proposal (não deveria, mas verifica).
73
-
74
- **Decisão de pausa** (regras da tabela do MORPH.md §5, aplicadas em linguagem natural — sem scripts): `discoveryMode: "interview"` → `pause: true` sempre; `trust: manual` → `pause: true` sempre; `designSystemDivergence` → pausa; `standardsViolations` não-vazio → pausa; caso contrário → `pause: false` (auto-passa). Monte `reason` com o sinal que disparou.
68
+ A decisão de pausa já foi tomada e persistida pela `morph-brainstorming` (Parte 4): `morph-spec gate-check {feature} proposal` no caminho comum (`shouldPauseGate`; divergência de design-system detectada entra via `--signals`), ou `gate-decision` manual quando `discoveryMode: "interview"` — o único sinal que `shouldPauseGate` não representa. Leia `gateDecisions.proposal` em `feature.json` (ou o output do comando) para `pause`/`reason`.
75
69
 
76
70
  **Se `pause === true`**, apresentar via `AskUserQuestion`:
77
71
 
@@ -118,13 +112,7 @@ A skill lê `proposal.md` e produz:
118
112
 
119
113
  ### 6. Gate 2 (trust-aware)
120
114
 
121
- Sinais de risco para Gate 2 incluem **mais** do que Gate 1:
122
-
123
- - Todos os do Gate 1.
124
- - `taskCount` — count(tasks.json.tasks). Threshold: 20.
125
- - `standardsViolations` detectadas no mandate (improvável, mas verificar).
126
-
127
- Lógica idêntica ao passo 3 (`shouldPauseGate` + AskUserQuestion ou auto-aprovação).
115
+ Mesma mecânica do passo 3: a decisão já foi tomada e persistida pela `morph-plan` (passo 6) — `morph-spec gate-check {feature} plan` no caminho comum (`shouldPauseGate` sobre `taskCount` do disco; `designSystemDivergence`/`standardsViolations` via `--signals` quando aplicável — não são herdados automaticamente entre gates), ou `gate-decision` manual para risco que nenhuma dessas chaves representa. Leia `gateDecisions.plan` para `pause`/`reason` e apresente com o mesmo template (AskUserQuestion ou auto-aprovação) do passo 3.
128
116
 
129
117
  ### 7. Conclusão
130
118
 
@@ -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.18.0"
7
+ cliVersion: "8.19.0"
8
8
  ---
9
9
 
10
10
  # morph-review
@@ -68,9 +68,12 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
68
68
  um turno inútil ao orquestrador.
69
69
  Seu relatório (no arquivo, e na mensagem final quando ela chega)
70
70
  deve conter: score 0-10 por dimensão, score composto (arch×0.30 +
71
- contracts×0.25 + quality×0.25 + tests×0.20), e feedback priorizado
72
- (bloqueantes primeiro) para qualquer dimensão < 9. Relatório
73
- ausente, oco, ou sem esses itens, é falha de protocolo.
71
+ contracts×0.25 + quality×0.25 + tests×0.20) gravado TAMBÉM como a
72
+ linha literal `**Composite-Score:** {n.n}` (machine-readable — o
73
+ `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,
76
+ é falha de protocolo.
74
77
  ```
75
78
  - **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).
76
79
  - **Leia primeiro** `.morph/features/{feature}/4-review/evaluator-report.md` — é o valor de retorno autoritativo, não a mensagem de texto do dispatch (que é cortesia, útil só quando chega inteira). Os scores por dimensão e o composto do review-report vêm **desse arquivo**, não da sua auto-avaliação. Se o arquivo vier ausente, 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.
@@ -97,12 +100,16 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
97
100
 
98
101
  8. Apresente o Gate 3 segundo trust mode.
99
102
 
100
- Ler `.morph/config/config.json → trust` (default `"auto"`). Calcular os sinais de risco em linguagem natural — sem scripts:
103
+ 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.
101
104
 
102
- - `evalScore` = score composto retornado pelo **avaliador independente** (passo 4).
103
- - `standardsViolations` = ids dos itens bloqueantes de standard encontrados no passo 3.
105
+ **`evalScore` sem override é uma PROXY** (média das `taskScores`, não o composto real). Passe o composto retornado pelo **avaliador independente** (passo 4) e qualquer item bloqueante encontrado nas **verificações mecânicas sempre-rodar** do passo 3 via `--signals` — as únicas chaves que este comando aceita sobrescrever:
106
+ ```
107
+ morph-spec gate-check {feature} review --signals '{"evalScore":9.2,"standardsViolations":[]}'
108
+ ```
109
+
110
+ Julgamento do revisor que nenhuma dessas chaves representa: use `gate-decision` direto em vez de `gate-check`.
104
111
 
105
- **Decisão de pausa** (mesmas regras da tabela do MORPH.md §5): `trust: manual` → `pause: true` sempre; `standardsViolations` não-vazio → `pause: true`; `evalScore < 9` → `pause: true`; caso contrário → `pause: false` (auto-passa).
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.
106
113
 
107
114
  **Se `pause === true`**, use `AskUserQuestion`:
108
115