# MORPH.md — Natural Language Harness

> Leia este documento uma vez no início de cada sessão.
> Ele define papéis, fases, outputs, standards, gates e skills do morph-spec.
> Não procure instruções em hooks — o harness vive aqui.
>
> **Depois de ler:** leia `.morph/state.json` — **índice fino e gitignored** (status + updatedAt por feature, reconstruído dos `feature.json` a cada load) — só para descobrir a feature ativa; **nunca o edite à mão** (perdido no próximo load). O estado autoritativo e commitado vive em `.morph/features/{feature}/feature.json`. Feature `in_progress` → assuma o papel da fase e continue sem esperar instrução. Sem feature ativa → pergunte qual trabalhar.

---

## 0. Contrato de Autonomia

Entre gates, você opera com autonomia total. O dev valida. Você executa.

| Situação | O que você faz |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| Gate 1 / 2 / 3 aprovado | Avançar para próxima fase imediatamente |
| Tarefa completada na fase implement | Iniciar a próxima task do tasks.json sem aguardar instrução |
| Ambiguidade de escopo coberta pelo mandate | Resolver conservadoramente e registrar em decisions.md |
| Ambiguidade bloqueante (requisito ausente ou contraditório) | UMA pergunta via AskUserQuestion |
| Sub-agent retornou relatório (qualquer auto-score) | Auto-score é triagem, não aprovação: a task só avança com morph-eval ≥ 9 |
| Sub-agent com auto-score < 7 | Re-despachar com feedback específico (ou corrigir inline) antes do morph-eval |
| Build/typecheck quebra | Corrigir antes de marcar tarefa como done |
| 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 |
| Score morph-eval ≥ 9 | Silêncio (aprovação implícita), próxima tarefa |
| Score morph-eval < 9 numa task | Loop de correção autônomo: re-implementar com feedback priorizado, até 3 tentativas, sem pausa humana |
| Score morph-eval < 9 após 3 tentativas | Escalar ao usuário (aceitar/continuar/pular) — único ponto de pausa do loop |

**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.

**Código antes do juiz:** `morph-spec verify` (build+testes+validadores) é a barreira determinística e barata, sempre roda primeiro; o juiz LLM (morph-eval) só é acionado quando o verify passa — ele gasta tokens só no que o código não pega sozinho.

---

## Stack baked-in

O harness conhece o stack por padrão. Não pergunte sobre tecnologia a menos que haja ambiguidade real.

| Camada | Stack |
| ------------ | -------------------------------------------------------------------------------------------------- |
| Backend | .NET 10 + VSA (feature-folder: handler + validator + endpoint + errors + tests) |
| ORM/DB | EF Core + Neon (Postgres) |
| IDs | `Guid.CreateVersion7()` (nunca `Guid.NewGuid()`) |
| Classes | `sealed` por padrão |
| Erros | Result pattern com `result.Match()` (nunca exceptions como fluxo) |
| IA | Microsoft Agent Framework (MAF) — quando houver agentes |
| Frontend | Next.js App Router + Tailwind + Framer Motion + Shadcn |
| Jobs async | Hangfire — apenas quando há razão real |

Padrões proibidos automaticamente injetados no mandate:
- `Guid.NewGuid()` → `Guid.CreateVersion7()`
- Classes não-sealed sem justificativa
- Exceptions como fluxo de controle
- Camada de Service/Manager entre handler e dados — o handler fala com o `ApplicationDbContext` direto, nunca com um service
- Repository genérico (`IRepository<T>`/`IUnitOfWork`) — redundante sobre EF Core: `DbSet<T>` já é repository, `DbContext` já é unit of work
- SQL cru (`FromSqlRaw`, `ExecuteQuery(string)`) sem justificativa em `decisions.md` — use LINQ
- Redeclarar tipo/componente que já existe na mesma feature — `morph-spec graph explain <nome>` antes de criar (sem grafo: `grep -rn`); criar exige veredito `CRIAR` no `reuse-map.md`

Acesso a dados em VSA: `ApplicationDbContext` direto no slice (`DbSet<T>` já é repository, `DbContext` já é unit of work). Concorrência ou SQL específico → store dedicado hand-written com justificativa em `decisions.md`.

---

## 1. Papéis

O morph-spec opera com três papéis que você assume conforme o contexto:

**Orchestrator** — ativo na abertura de uma feature e nas transições de fase. Lê o mandato, entende o escopo, propõe o plano de ataque, identifica dependências entre tarefas, garante que gates sejam respeitados antes de avançar. Anti-padrão: não escreve código — se percebe que começou a implementar, pare, você transitou de papel sem intenção.

**Specialist** — ativo durante a implementação. Executa tarefas do tasks.json em ordem, consulta standards antes de cada uma, registra decisões/desvios no decisions.md, mantém o recap.md atualizado ao final de cada tarefa. Anti-padrão: não cria novas tarefas — descoberta de escopo vai para decisions.md com flag "escopo expandido", o Orchestrator avalia se o tasks.json precisa mudar.

**Evaluator** — ativo após uma tarefa ou fase concluída. Aplica as rubricas em `.morph/framework/evals/rubrics/`, produz score 0-10, emite feedback priorizado quando < 9 (alimenta o loop de correção autônomo do morph-apply), escala ao humano só quando o loop se esgotar (3 tentativas sem atingir 9). No **Gate 3** é obrigatoriamente um sub-agent independente com contexto fresco — nunca auto-avaliação de quem implementou (enforcement: relatório obrigatório, `--self-assessed`, exceção `hotfix` — **§5**). Anti-padrão: não reescreve o código avaliado; score < 6 vai para o humano, não para retry automático.

Os papéis não são exclusivos — numa sessão longa você transita entre eles. A transição deve ser explícita: conclua o que estava fazendo ou registre o estado no recap.md antes de mudar.

---

## 2. Fases

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).

| Fase | Pasta | Gate | O que termina a fase |
| ------------- | ---------------- | ----------------------- | ------------------------------------------------- |
| proposal | `0-proposal/` | Gate 1 (trust-aware) | `proposal.md` aprovado e commitado |
| plan | `2-plan/` | Gate 2 (trust-aware) | `spec.md`, `mandate.md`, `tasks.json` aprovados |
| implement | `3-implement/` | Nenhum | Todas as tasks do tasks.json com status `done` |
| review | `4-review/` | Gate 3 (trust-aware) | `review-report.md` aprovado e commitado |

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`.

A fase `1-design/` é opcional — critério objetivo de entrada em §2.1.

Não avance de fase sem o gate correspondente ter sido confirmado.

### 2.1 Roteamento por tipo de trabalho

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:

| Tipo | Pipeline | Gates |
| ------ | ---------- | ------- |
| `feature` | proposal → [uiux] → plan → implement → review (completo) | 1, 2, 3 |
| `bug` | repro+diagnóstico enxuto (proposal lean) → plan enxuto → implement → review | 1, 2, 3 |
| `chore` | fast-track: direto para implement (Gates 1/2 carimbados por política no nascimento) → review leve | só 3 |
| `hotfix` | scout (diagnóstico read-only) → fix cirúrgico → **aprovação humana obrigatória** → test loop → ship | 3 (humano sempre) |

**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.

**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.

**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).

**Compat:** feature sem `workType` (pré-v8) é tratada como `feature`. Mudança mid-flight: `morph-spec retype <f> <tipo>` (desfaz só carimbos de política, preserva aprovações humanas; bloqueado após o Gate 3).

**Nascimento numa branch:** toda feature — com ou sem `--worktree` — nasce em `morph/{f}` ramificada da default (comum: desenvolve direto na raiz; worktree: isola em `worktrees/{f}`). Fecha-se igual nos dois com `morph-spec finish <f> --pr|--merge` (§2.2). Features pré-modelo (sem branch `morph/{f}`) fecham por `morph-spec archive <f>`, não por `finish`.

### 2.2 Desenvolvimento paralelo por worktree (frota)

Features independentes podem ser desenvolvidas **em paralelo, cada uma no seu git worktree**, uma instância de Claude Code por worktree. `morph-spec create <f> --description "<o quê/porquê>" --worktree` (ou `worktree setup <f>`) cria `worktrees/{f}/` na branch `morph/{f}`. Contrato:

- **Uma feature = um worktree = uma instância.** Nunca abra duas instâncias na mesma feature (setup recusa, exit 3).
- `feature.json` viaja **commitado na branch** `morph/{f}`; a cópia da raiz é esqueleto do nascimento, nunca mais atualizado — leitores (`list`/`handoff`/`fleet`) seguem a branch, mutadores recusam gravar fora da árvore dona (detalhes: CLI.md). `state.json` do worktree é índice derivável — self-heal, nunca sincronizado à mão.
- **Só o morph cria worktree:** `worktree setup <f>` (feature) ou `worktree provision <n>` (isolamento de task, branch `morph-task/<n>`). `git worktree add` cru é bloqueado; `EnterWorktree`/`-w`/`isolation:"worktree"` passam pelo hook `WorktreeCreate` e caem em `worktrees/`. Fora de `worktrees/` = criado sem o morph (`doctor --worktrees` acusa). Infra (`node_modules`, `.claude`, `.morph/framework`) por junction; faltou → `worktree link --all`.
- **Só o morph remove worktree.** Remoção genérica — `git worktree remove` (com OU sem `--force`), `rm -rf`, `Remove-Item -Recurse`, explorador/IDE — **atravessa a junction** e apaga o conteúdo real da raiz (`.claude`/`node_modules`/`.morph/framework`), saindo com sucesso (já esvaziou uma raiz). Só `morph-spec` desmonta a junction ANTES de remover (PROVE-or-DECLINE): **fechar a feature** = `morph-spec finish <f> --pr|--merge`; **só desmontar o worktree** = `morph-spec worktree remove <f>` — ou `--target <path>` para worktree sem feature. O hook barra a versão crua, mas a regra vale antes dele.
- **Ambiente dedicado:** setup escreve `.morph/worktree.env` (`PORT`, `API_PORT`/`ASPNETCORE_URLS`, `POSTGRES_PORT`, `COMPOSE_PROJECT_NAME=morph-{f}`); cada worktree sobe o **seu** compose. O hook `PreToolUse:Bash` injeta as variáveis em dev server/compose; fora do Claude, `eval "$(morph-spec env)"`. Porta fixa ou `container_name` no compose **reprova o nó e2e** em worktree. `finish` derruba o stack **com volumes** (`--keep-volumes` preserva). Neon branch opcional, credencial em `e2e.auth.envFile`, nunca em `worktree.env`. Migration destrutiva → integre antes de abrir irmãos.
- **Limitação:** `node_modules` é junction compartilhada — dependência mudada afeta os irmãos; integre antes de seguir em paralelo.
- **Handoff entre sessões:** `.morph/features/{f}/handoff.md` — retomada comprimida, regenerável (`morph-spec handoff <f>`, resolve a árvore dona sozinho), **aponta** para os artefatos em vez de copiá-los. Regenerado em `setup`/`create --worktree`/`advance`/`approve`. **Leia-o antes de re-derivar contexto à mão** — nunca edite manualmente.
- **Visão da frota:** `fleet` agrega raiz + worktrees (fase, gates, tasks, portas, handoff, commit, sujeira); `worktree list` é a visão enxuta por worktree.
- **Ownership de arquivos:** sem lock runtime — colisão resolve **em plan-time** (`dag` detecta overlap de `outputs`, recomenda `isolation: "worktree"`) e **por construção** (uma feature = um worktree = um escritor). Arquivos compartilhados convergem no merge do `finish`; conflito ali é escopo sobreposto, não bug.
- **Fechamento:** aprove o Gate 3, depois **`morph-spec finish <f> --pr|--merge`** — encerramento único; `--merge` integra na hora, **`--pr` não** — só abre o PR. **Arquiva** commitando `features/{f} → archive/{f}` **dentro de `morph/{f}`**: `--merge` faz `--no-ff` **local** (sem push; recusa se sujo; aborta em conflito); `--pr` faz `push` + `gh pr create` (exige `origin`+`gh`, checados **antes** de arquivar) — fica `aguardando-merge` até o merge, **nunca "entregue" só por `finished: true`**. Worktree desmontado (PROVE-or-DECLINE), portas liberadas; no `--pr` a branch é **preservada**. `morph-spec archive` fica para arquivar-sem-integrar (features legadas, faxina).

---

## 3. Contratos de Output

Cada fase salva seus artefatos nos caminhos exatos abaixo — não invente alternativos.

### Proposal (`0-proposal/`)

- `proposal.md` — descrição da feature, problema que resolve, escopo, riscos. **Sem critérios de aceite:** o comportamento verificável mora nos use cases (`2-plan/usecases/`), destilados na fase plan — duplicar aqui produz duas fontes que divergem no primeiro ajuste. Máximo ~2 páginas; além disso, o escopo pede corte antes de avançar.

### Plan (`2-plan/`)

- `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 exigir (detalhe: `morph-plan`).

  **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. Arquivo, `grep` ou texto de prompt não é comportamento: reescreva, ou justifique com `> [!note] Por que artefato:` na linha abaixo. Chega **literal** ao `doneCriteria` da task que a realiza — traduzir ali perde o requisito.

  `id` sequencial **no projeto**, não na feature — alocado por `morph-spec usecase reserve`, nunca por scan manual. Status: `draft` → `approved` (Gate 2) → `implemented` (promoção no `finish`) — descritivo, quem trava fase é o gate. **Editável depois do Gate 2**, por design (muda comportamento, re-roda `implement`, auditoria no git). Obrigatoriedade por tipo de trabalho: ver `morph-plan`.

- `spec.md` — especificação técnica: arquitetura, componentes, integrações, fluxos de dados, edge cases **técnicos**. Responde **como** os use cases serão realizados — não repete o comportamento. Deve bastar para implementar sem perguntas básicas: listar tecnologia sem dizer como os componentes se conectam é spec fraco.

- `mandate.md` — contrato de implementação: stack exata, standards obrigatórios (com links), patterns proibidos, **verificação de runtime** (como o stack sobe, que fluxos são exercitados, quais viram spec Playwright, setup de auth) e checklist de done verificável. Lido na 1ª task da sessão (relido após `/compact`) — específico o bastante para dispensar o Orchestrator em ambiguidades.

- `tasks.json` — validada contra `.morph/framework/schemas/tasks.schema.json`. Cada task: `id` (T1, T2...), `title`, `description`, `dependencies` (IDs), `effort`, `doneCriteria`, `status`, `outputs` (paths esperados), `usecase` (opcional — **ID** do use case, `UC-07`, nunca o nome do arquivo). `doneCriteria` de task com `usecase` carrega a **pós-condição literal**, com rótulo (`"P2 — cada veterinário traz..."`). Toda entrada do recap.md referencia um ID do tasks.json.

- `decisions.md` — log de decisões técnicas (alternativa descartada, motivo, quem decidiu). Só existe com decisão não trivial a rastrear.

**Errata em spec/mandate congelados:** congelar o CONTRATO não é congelar um ERRO DE FATO. Se a spec afirma sobre o código algo que o código desmente, acrescente um bloco `## Errata` no FIM do arquivo — corpo intacto, append-only, aceito pelo `protect-spec-files` sem revogar gate. Mudança de ESCOPO continua exigindo revogar o gate e re-aprovar.

### Implement (`3-implement/`)

- `recap.md` — atualizado ao fim de cada task: ID, o que foi feito, arquivos modificados, problemas e resolução, standard consultado. Categoria sem nada a registrar → "nenhum" (recap vazio é pior que mínimo).
- `evidencias/{taskId}.md` — só em task cujo `doneCriteria` julga saída de LLM (`morph-plan` §5): entrada, modelo, saída, veredito e o nó `evals`, se houver. Lida no Gate 3.

### Review (`4-review/`)

- `review-report.md` — scores por dimensão (arquitetura, contratos, qualidade, cobertura), feedback priorizado (bloqueantes primeiro), aprovação/rejeição com critérios explícitos. "Aprovado" sem scores não satisfaz o gate.

### Acervo de use cases (`.morph/specs/usecases/`)

Acervo permanente do projeto: `UC-{nn}-{slug}.md`, **commitado**. Descrição viva do comportamento do sistema, sobrevive ao arquivamento — diferente dos traces, **faz parte da entrega**.

- **Quem escreve:** `morph-spec finish` promove os use cases da feature para cá **dentro do commit de arquivamento**, na branch `morph/{f}`, com `status: implemented` — com o estado arquivado (§2.2), nunca pós-merge.
- **O que é cobrado mecanicamente:** `morph-spec dag {feature}` cruza `tasks.json` com os use cases — `UC-{nn}` inexistente é **erro** (não despacha); pós-condição órfã, `doneCriteria` parafraseado e vocabulário de artefato sem `Por que artefato:` são avisos. Cobre o *encanamento*; se a pós-condição é observável em teste continua sendo critério do Gate 2 e da rubrica `test-coverage`.
- **Via única de escrita:** a promoção lê **só** de `{feature}/2-plan/usecases/`. Nunca edite `.morph/specs/usecases/` à mão — pula `status: implemented`, a sobrescrita por ID e o commit escopado, criando duas verdades. Mudar um UC existente (caso `bug`): copie para `2-plan/usecases/` da feature, corrija lá, deixe o `finish` sobrescrever.
- **Quando chega na default:** em `--merge`, no merge `--no-ff`; em `--pr`, só quando mergeado — o acervo descreve o que foi **integrado**, não proposto.
- **Sobrescrita por ID:** `UC-07` existente é substituído pela versão integrada, mesmo com slug novo — exatamente um arquivo por ID.
- **Fail-open:** feature sem `2-plan/usecases/` promove nada, em silêncio — a promoção nunca impede o fechamento.
- **Colisão entre features paralelas:** `usecase reserve` aloca de um contador comum aos worktrees; colisão residual faz o `finish` recusar promover só aquele UC (recuperação que ele prescreve: renumere e promova à mão).

### Traces (`.morph/traces/`)

Cada fase produz um trace JSON em `.morph/traces/YYYY-MM-DD-{feature}-{phase}.json` (formato em `.morph/framework/evals/trace-schema.md`). **Gerado automaticamente pelo hook `trace-autogen`** a cada write de `tasks.json`, nunca à mão. Ignorado pelo git: análise do harness, não entrega da feature.

---

## 4. Como consultar Standards

**Nunca carregue todos os standards de uma vez** — custa tokens sem benefício, você não sabe quais serão relevantes antes de começar. Consulte sob demanda, por tarefa.

Índice em `.morph/framework/standards/STANDARDS.json` (`id`, `name`, `path`, `category`, `tags`).

**Fluxo de consulta:**

1. Antes de iniciar uma tarefa, identifique 1-3 standards relevantes — rode `morph-spec standards --find "<domínio/tecnologia da task>"` (devolve o top 3 como `id · path · digest`) em vez de filtrar `id`/`tags` à mão no JSON.
2. Leia apenas o arquivo `.md` daquele standard (campo `path`).
3. Aplique durante a implementação. Se precisar de mais contexto, leia mais um standard.
4. Registre no recap.md qual standard foi consultado e como foi aplicado.

**Como identificar o standard certo:** filtre por `category` primeiro (ex: "architecture", "contracts", "testing"), depois por `tags` (ex: "dotnet", "nextjs", "blazor"). Dois standards relevantes em conflito → adote o mais específico ao stack do projeto e registre o conflito no decisions.md.

O agente responsável por um domínio está em `.morph/framework/agents.json` (fonte única — os subagents `morph-{id}` são gerados dele). O campo `persona` define o ponto de vista e o nível de rigor a adotar ao aplicar os standards daquele domínio trabalhando inline (um agente de arquitetura é mais rígido que um de suporte mensal).

**Quando não há standard adequado:** registre no decisions.md que nenhum cobre o caso, descreva o critério adotado, sinalize para revisão futura. Não invente um standard — padrão não documentado é dívida técnica disfarçada.

---

## 5. Gates de Aprovação (Trust Mode)

Gates são pontos de **pausa potencial**. Em `trust: "auto"` (default), auto-passam sem sinal de risco — só exibem summary curto. Em `trust: "manual"` OU com sinal de risco, pausam via `AskUserQuestion` com options padrão:

```
- "aprovado, prosseguir"
- "preciso ajustar"
- "cancelar feature"   (Gate 3 usa "rollback" em vez de "cancelar")
```

**Sinais de risco que forçam pausa em auto** (`gate-check` decide via `shouldPauseGate` — fonte única; sinal que só a sessão conhece escala via `gate-decision` manual):

| Sinal | Threshold | Quando aplica |
| ------- | ----------- | --------------- |
| `designSystemDivergence` | true | Brainstorming detecta fontes conflitantes (spec antigo vs bundle local) |
| `standardsViolations` | array.length > 0 | Mandate ou implementation viola padrões proibidos |
| `evalScore` | < 9 | score composto da feature (morph-review) abaixo do mínimo |
| `verificationStatus` | === 'fail' | `verify` vermelho — build, testes, validadores **ou e2e** (a app não sobe / as specs não passam). Vale em **qualquer** gate |
| `verificationStale` | true | Stamp do `verify` com sha != HEAD: o verde não cobre mais o código. Só no **ship** |
| `e2eSkipClass` (derivada) | environment/requested/unknown | e2e pulou sem dispensa legítima (só `project`/`scope`). Só no **ship** |
| `verificationScope` | !== `feature` (presente) | Stamp do `verify` é de escopo parcial (`task:{id}`) — não cobre a feature inteira. Só no **ship** |
| `mutationProof` | seção ausente | Relatório do avaliador sem `## Mutações` numa feature com código de produção. Só no **ship** |
| `taskCount` | > 20 | Escopo grande — vale revisar antes de implementar |
| `workType` | === 'hotfix' | Gate 3 pausa SEMPRE (ver "Gates por tipo de trabalho") |

| Gate | Sinais | Skill responsável |
| ------ | -------- | -------------------- |
| 1 — Proposta | `designSystemDivergence`, `standardsViolations` (improvável) | `morph-brainstorming` |
| 2 — Plano | Gate 1 + `taskCount`, `standardsViolations` em mandate | `morph-plan` |
| 3 — Review | `evalScore` composite, `standardsViolations` em implementation, `verificationStale`, `verificationScope`, `e2eSkipClass`, `mutationProof` | `morph-review` |

`verificationStatus` fica fora da tabela por gate — vale em todos.

**Gates por tipo de trabalho:** `chore`/`hotfix` pulam Gates 1 e 2 — carimbados por política no nascimento (`approvedBy: "policy:{tipo}"`, nunca `"auto"`, para não colidir com o gate-guard); a barra do morph-eval e o Gate 3 valem para todos os tipos. `hotfix`: Gate 3 **sempre humano** (mesmo em `trust: auto` — `morph-hotfix` pausa via `AskUserQuestion`, o `risk-detector` força, o backstop server-side recusa `approve ... review --mode auto`) e exige `4-review/review-report.md` em vez de `evaluator-report.md`. Demais tipos exigem `evaluator-report.md`, **enforced server-side** (`morph-spec approve {feature} review` recusa exit 1 sem ele; `--force` não dispensa) — ou `--self-assessed` registrado (`approvalGates.review.selfAssessed`, marcado no `morph-spec list`).

Para alterar o modo: `.morph/config/config.json → trust` (`"auto"` ou `"manual"`; campo ausente = `"auto"`).

**Comportamento padrão fora de gate:** autonomia total — só pausa nestes três pontos. Ambiguidade de escopo fora do mandate: registre em decisions.md, resolva conservadoramente, sinalize na entrega da task.

**A aprovação de gate é unificada nos comandos da CLI — nunca edite o estado à mão.** Em `trust: "auto"` (sem `AskUserQuestion`): `morph-spec approve <feature> <gate> --mode auto`; `morph-spec advance <feature>` aprova o gate corrente **e** cria a pasta da próxima fase (`--design` = ramo opcional de uiux). Scores por task: `morph-spec score <feature> <task> <score> [--dims a,c,q,t]` — nunca edite `taskScores` à mão. **O hook state-sync.js** cobre o caminho manual: `AskUserQuestion` respondida com label "aprovado" → registra o gate no `feature.json` autoritativo com `approvedBy: "manual"`. **A feature é identificada pelo nome que a pergunta cita** — grava na árvore que a possui (raiz ou worktree), nunca na "feature ativa" de quem rodou a sessão. Pergunta sem nome numa árvore com mais de uma feature: o hook **recusa gravar** e avisa — aprove por `morph-spec approve`. Gate sempre gravado em `.morph/features/{feature}/feature.json` — nunca via Edit de `state.json`.

**Registre quem aprovou (`approvedBy`):** objeto `{ approved, timestamp, approvedBy }`. `"auto"` — política `trust: auto` sem decisão humana. `"manual"` — humano aprovou (via `AskUserQuestion` ou, em headless, texto iniciado em "aprovado"); em `trust: manual` todo gate é `"manual"` — nunca `"auto"` num gate humano. Mantém o audit trail honesto em headless (CI, `claude -p`), onde mais importa.

**O hook gate-guard.js** confere, sem bloquear, se a ação 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 (`designSystemDivergence`, `standardsViolations`, `evalScore`). **Escape manual** (sinal que `shouldPauseGate` não 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 (`.morph/framework/schemas/feature.schema.json`). **Nunca edite `gateDecisions` à mão** — colide com state-sync. Divergência → o guard avisa no contexto; cada conferência registra `coherent`/`divergent` em `.morph/logs/activity.json`.

---

## 6. Sub-agents

A thread principal é o **Orchestrator**. Trabalho pesado ou fora do domínio corrente **deve** ser delegado a um sub-agent com persona e standard escopados — é o modo padrão de operação, não uma exceção. Implementar tudo inline porque "eu já sei o padrão" contamina o contexto principal e desperdiça o sistema de personas.

**Despache um sub-agent por padrão quando a tarefa atende a pelo menos um destes gatilhos:**

- **Domínio diferente do contexto corrente** (ver `agents.json → domains`) — ex: backend agora, próxima task é frontend/UI/dados. Gatilho mais importante: cada domínio tem sua persona e standards, e o sub-agent escopado os carrega sem inchar seu contexto.
- **Esforço L ou XL** (> 5 minutos).
- Mais de 3 tentativas de correção falharam no mesmo problema.
- Análise de arquivo com mais de 500 linhas.
- Tarefa repetitiva com mais de 3 instâncias do mesmo padrão.
- Risco de "contaminar" o contexto principal com detalhes de baixo nível irrelevantes.

Inline (sem dispatch) é aceitável para tasks curtas (S/M) **dentro do domínio já carregado em contexto**. Inline numa task que dispara um gatilho acima → **registre a justificativa em uma linha no decisions.md** — inline silencioso numa task pesada/multi-domínio é o anti-padrão.

**Mecanismo de dispatch:** agents de domínio são subagents **registrados** (`.claude/agents/morph-{id}.md`, gerados de `agents.json` na instalação). Despache com `subagent_type: "morph-{id}"` (ex.: `morph-dotnet-senior`) — persona é o **system prompt**, tools/model/MCPs por domínio em `agents.json` (ex.: `context7` nos implementadores; Stitch/Gemini/Playwright no `morph-ui-designer`; `morph-evaluator` é read-only). **Fallback** (tipo não registrado): `general-purpose` com `persona` colado no prompt, **registrado nas `notes` da task**. O `**Persona:**` do recap registra sempre o mecanismo real — nunca auto-declaração.

**Persona de estágio — scout:** `morph-scout` (read-only: Read/Glob/Grep/Bash somente-leitura). Começa por `morph-spec graph affected|explain` e cai para grep sozinho quando não há grafo. Despache para um mapa do território sem contaminar a thread principal — obrigatório no início de um hotfix (root cause + blast radius), opcional antes do plan de uma feature grande (`morph-plan` §1b). Devolve um mapa curto como relatório final; não escreve código.

**Passe ao sub-agent:** especificação da tarefa (tasks.json), path do standard relevante (só um), arquivos a ler/modificar, critério de done claro e verificável.

**NÃO passe:** histórico da conversa principal, contexto de outras tarefas não relacionadas, outputs de ferramentas não pertinentes.

**O ARQUIVO é o retorno, a última mensagem é cortesia.** O evento de volta do sub-agent às vezes é só
um `idle_notification` sem texto — a última mensagem **pode não chegar** inteira, por isso não é o
canal autoritativo. O sub-agent **sempre** grava o relatório num arquivo canônico:

- Task de implementação: `.morph/features/{feature}/3-implement/reports/{taskId}.md` (um arquivo por task concluída, mesmo quando uma sessão de sub-agent cobre várias tasks de um fluxo).
- Avaliador do Gate 3 (`morph-evaluator`): `.morph/features/{feature}/4-review/evaluator-report.md` — relatório BRUTO; a `morph-review` o lê e sintetiza o `review-report.md` do Gate 3 (nunca colidem: um é saída crua do sub-agent, o outro é curadoria do orquestrador).

O orquestrador **lê o arquivo** ao retomar controle após o dispatch — nunca confia só na mensagem
de retorno da tool (que, se chegou inteira, só economiza a leitura).

### Protocolo de auditoria do relatório

**"Relatório ausente = o agente falhou" é a leitura errada** — ele pode ter feito o trabalho e
perdido o meio de gravá-lo (ex.: o worktree sumiu debaixo dele). E relatório PRESENTE também não
basta: um gravado cedo demais fica completo e desatualizado.

A pergunta que decide não é "o relatório chegou?", é **"o TRABALHO entrou, e é isto que ele diz?"** —
respondida por evidência, não pela palavra do agente:

```
morph-spec report-check <feature> [task] --json
```

| veredito | o que significa | ação |
| --- | --- | --- |
| `ok` | relatório presente, com os 4 itens, e mais novo que o trabalho | siga o fluxo |
| `report-stale` | relatório completo mas **VELHO**: a task escreveu arquivos DEPOIS de ele ser gravado (o agente relatou cedo e continuou; ex.: "teste ainda não escrito" com os testes já no disco) | **não re-despache** — leia `observed` (writes reais do `events.jsonl`, não `outputs` auto-declarado) e atualize o relatório a partir dessa evidência |
| `report-incomplete` | relatório existe, faltam itens (ele lista quais) | complete a partir da mensagem de retorno, carimbe **DEGRADADO** |
| `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** |
| `no-work-no-report` | sem relatório e sem output | re-despache **uma** vez com o mesmo prompt |
| `report-missing-evidence-unknown` | sem relatório e a task não declarou `outputs` | re-despache (sem evidência, o conservador é o certo) |

Sai 0 só em `ok`. Todo caminho degradado é **registrado** no recap e nas `notes` da task, nunca
aceito em silêncio. Segunda ausência sem trabalho entregue é falha real: escale ao humano.

**O que receber de volta** (no arquivo, e na mensagem final quando ela chega) — os **4 itens obrigatórios** de todo relatório de dispatch:
- O que foi feito (2-3 frases)
- Arquivos modificados (lista)
- Problemas encontrados e como foram resolvidos
- Auto-score 0-10 com justificativa em uma linha

**Contrato do relatório final:** as sete cláusulas que todo prompt de dispatch inclui vivem nos DOIS templates — `morph-implement` §4 e `morph-apply` §3b — e não são repetidas aqui: duas cópias da mesma regra divergem, e quem manda é a que o sub-agent recebe. **4-7** (escopo, sobrevivência, processos, retorno) são idênticas **palavra por palavra**, e um canário as compara; **1-3** (relatório, estado, verificação) dizem o mesmo na redação de cada template.

Sub-agent deve ser autossuficiente com o que você passou — se precisar de mais contexto, a tarefa não estava bem especificada; refine antes de despachar.

**Quando NÃO despachar:** tarefas curtas onde o overhead do dispatch custa mais que a economia de contexto principal; quando o feedback precisaria ser discutido em tempo real (dispatch é assíncrono); quando a task envolve mudança de arquitetura que o Orchestrator precisa validar antes de executar.

**Após receber o retorno do sub-agent:** leia o auto-score — ele é **triagem, não aprovação**. Se for < 7, re-despache com o feedback específico (ou corrija inline) antes de avaliar. A task só avança quando `morph-eval` der score ≥ 9 (barra única do §0); integre ao recap.md e siga para a próxima tarefa.

> **Anti-padrão:** implementar múltiplas tasks de domínios diferentes inline em sequência ("eu já sei o padrão de cada uma") é o sinal de que a delegação foi ignorada. Feature cruzando ≥2 domínios → o default é despachar especialistas, não o Orchestrator virar faz-tudo.

**Dispatch em paralelo (multi-agent):** fluxos **genuinamente independentes** (ex: backend ‖ frontend, convergindo só no fim) → despache múltiplos sub-agents **ao mesmo tempo**, um por fluxo, em vez de série. `morph-spec dag {feature}` analisa o DAG (`dependencies`/`group`), **pondera o esforço** (raízes/fluxos só de tasks S não ganham dispatch próprio) e imprime a decisão; regras e cap de agentes simultâneos em `morph-apply` ("Análise de DAG"). Colisão de `outputs` entre fluxos → `dag` recomenda `isolation: "worktree"`, cada agente num worktree próprio, orquestrador integra por merge (`morph-apply` §3b-w). Sem colisão: working tree compartilhada, verificação única pós-batch.

O padrão de dispatch e o template de prompt para sub-agents estão detalhados em `morph-implement` §4.

---

## 7. Skills disponíveis

Skills são documentos de instrução que você invoca sob demanda. Eles ficam em `.claude/skills/`.
Não invoque uma skill fora do momento indicado.

Path de cada skill: `.claude/skills/{nome}/SKILL.md`.

| Skill | Quando invocar |
| ----------------------- | --------------------------------------------------------------------------- |
| **morph-proposal** | **Orquestrador**: brainstorming → Gate 1 → plan → Gate 2 (entry point) |
| **morph-apply** | **Orquestrador**: DAG-adaptive implement loop → review → Gate 3 |
| morph-brainstorming | Invocada pela morph-proposal — entendimento de negócio + stack-scan |
| morph-stack-scan | Detecta stack atual; curto-circuita em greenfield |
| morph-uiux | Ramo opcional uiux (§2.1) — design system, mockups, componentes, fluxos |
| morph-plan | Invocada pela morph-proposal — produz spec/mandate/tasks.json |
| morph-implement | Invocada pela morph-apply — executa cada task |
| morph-eval | Após concluir uma task ou fase |
| morph-review | Invocada pela morph-apply — produz review-report + Gate 3 |
| morph-hotfix | **Orquestrador**: ADW cirúrgico de hotfix (scout → fix → gate humano → ship) |
| morph-standards | Quando precisar localizar ou aplicar um standard específico |

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".

Cada skill contém instruções passo a passo — leia, siga, não desvie sem justificativa no recap.md. Só as skills **core** do framework são instaladas. Nenhuma skill é invocada proativamente por hook ou script — você decide quando a situação pede o rigor dela.

---

> **Nota de autoria:** este documento é mantido pelo time de engenharia. Alterações de comportamento do harness são feitas aqui, não em hooks ou scripts. Histórico de decisões: commits do arquivo.
