@polymorphism-tech/morph-spec 8.17.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.
- 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 +46 -43
- package/framework/MORPH.md +120 -168
- package/framework/commands/morph-hotfix.md +1 -1
- package/framework/docs/CLI.md +41 -0
- package/framework/hooks/shared/phase-utils.js +0 -2
- package/framework/phases.json +1 -1
- 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 +3 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +3 -1
- package/framework/skills/core/morph-apply/SKILL.md +12 -20
- package/framework/skills/core/morph-brainstorming/SKILL.md +11 -32
- 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 +13 -27
- package/framework/skills/core/morph-proposal/SKILL.md +3 -15
- package/framework/skills/core/morph-review/SKILL.md +15 -8
- package/framework/skills/core/morph-stack-scan/SKILL.md +10 -26
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/package.json +1 -1
- package/src/commands/project/doctor.js +11 -4
- package/src/commands/project/init.js +1 -1
- package/src/commands/project/status.js +2 -2
- package/src/commands/project/update.js +91 -7
- 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/stack-filter.js +7 -2
- package/src/scripts/setup-infra.js +27 -8
- package/src/utils/skills-installer.js +28 -15
- package/src/lib/standards/digest-builder.js +0 -72
|
@@ -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
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# morph-spec CLI — Referência Completa
|
|
2
|
+
|
|
3
|
+
> Referência completa (flags, semântica, exemplos) dos comandos `morph-spec` usados pela LLM em vez de editar o estado à mão. Resumo rápido em `.morph/framework/CLAUDE.md`; racional dos gates em `.morph/framework/MORPH.md` §5, dispatch de sub-agents em §6, worktree/fleet em §2.2.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Gates e estado
|
|
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).
|
|
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
|
+
- **`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-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.
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- **`morph-spec create <feature> --description "<o quê/porquê>" --type <feature|bug|chore|hotfix> [--request "<txt>"] [--name "<nome>"] [--worktree]`** — cria a estrutura da feature + `feature.json` canônico explicitamente (nascimento explícito no início da proposal; o hook state-sync continua cobrindo o caminho implícito como fallback). **Identidade no nascimento:** `name` (default = slug) e `description` são carimbados; a `--description` é **obrigatória** numa feature nova (ou `--request`, que a semeia) — sem nenhuma das duas o `create` recusa (fim dos scaffolds anônimos). `--type` classifica direto; `--request "<pedido>"` roda o detector determinístico (empate/sem sinal sai com exit 2 e candidatos — a LLM decide e re-roda com `--type` + `--request`/`--description`); `--worktree` já nasce a feature no seu worktree próprio. **Toda feature nasce numa branch `morph/{f}`** (ramificada da default) mesmo sem `--worktree` — por isso o fechamento por `morph-spec finish` é idêntico nos dois fluxos.
|
|
18
|
+
- **`morph-spec list [--all] [--json]`** — o quadro de auditoria: uma linha por feature × workType × status × fase × gates G1/G2/G3 × descrição, com `⚠` para inconsistências (sem descrição, ordem de gate). `--all` inclui as arquivadas; `--json` para scripting. É o complemento do `delete` (enxergar o que está morto antes de remover).
|
|
19
|
+
- **`morph-spec delete <feature> [--archive] [--force]`** — remove uma feature. Hard por padrão (pasta apagada, git-aware, + entrada podada do índice raiz para não ressuscitar); `--archive` move para `.morph/archive` com status `abandoned` em vez de apagar. Recusa se algum gate estiver aprovado, a menos que `--force`. Use para faxina de scaffolds mortos e drafts abandonados (`archive` é para trabalho concluído; `delete` é para trabalho morto).
|
|
20
|
+
- **`morph-spec retype <feature> <newType>`** — muda o tipo de trabalho mid-flight; desfaz só os gates carimbados por política, preserva aprovações humanas; bloqueado após o Gate 3.
|
|
21
|
+
|
|
22
|
+
## Worktree / Fleet
|
|
23
|
+
|
|
24
|
+
- **`morph-spec finish <feature> --pr|--merge`** — o **encerramento único** da feature (worktree ou comum): **arquiva** commitando `features/{f} → archive/{f}` dentro de `morph/{f}` — promovendo junto, no mesmo commit, os use cases da feature para o acervo permanente `.morph/specs/usecases/` com `status: implemented` (fail-open: sem `2-plan/usecases/`, no-op silencioso) — depois integra. `--merge` faz merge `--no-ff` **local** na default (sem push); `--pr` faz `push` + `gh pr create` (exige `origin` + `gh`, checados **antes** de arquivar — um `--pr` recusado não deixa meio-estado). Desmonta o worktree (PROVE-or-DECLINE) e libera o bloco de portas; no `--pr` **preserva** a branch (o PR precisa dela) e fica em `morph/{f}`. Flags: `--keep` mantém o worktree, `--force` dispensa o Gate 3, `--discard-ignored` consente descartar gitignored no teardown. Substitui o antigo `worktree finish` + `archive` separados.
|
|
25
|
+
- **`morph-spec archive <feature>`** — arquiva-**sem-integrar** (atômico, git-aware, commita o move escopado por pathspec): reservado a features legadas (sem branch `morph/{f}`) e faxina. O fechamento normal (arquiva **e** integra num passo) é `morph-spec finish`. É o que `/morph-archive` chama.
|
|
26
|
+
- **`morph-spec worktree setup|link|list`** — gerencia o ciclo do worktree por feature (`setup` cria `worktrees/{f}/` na branch `morph/{f}`, aloca o bloco de portas e escreve `.morph/worktree.env`; `link` religa infra compartilhada; `list` mostra fase/gate de cada worktree ativo). O fechamento saiu daqui — use `morph-spec finish` (acima).
|
|
27
|
+
- **`morph-spec handoff <feature>`** — regenera o documento de retomada (`.morph/features/{f}/handoff.md`): comprimido, derivado, aponta para os artefatos em vez de copiá-los. Gerado automaticamente em `setup`/`create --worktree`/`advance`.
|
|
28
|
+
- **`morph-spec fleet`** — visão da frota: toda feature ativa (raiz + worktrees) com fase, gates pendentes, tasks, **remoto** (`local`/`pushed`/`PR #N`), **claim** (que sessão está na feature), portas, handoff e atividade. Use entre sessões para decidir onde atuar.
|
|
29
|
+
- **`morph-spec claim [feature] [--release] [--list] [--json]`** — posse **advisory** de feature. Cada sessão reclama sua feature ativa automaticamente (hook SessionStart) e renova o heartbeat a cada tool call; o registro vive em `<git-common-dir>/morph-spec/claims.json`, compartilhado por todos os worktrees. **`morph-spec claim <feature>` (sem flags) ADQUIRE** — se esta árvore já tinha claim vivo em outra feature, ele é liberado no mesmo passo (o CLI reporta "movido de X para Y"); é o jeito de trocar de feature no meio da tarefa sem a dança de dois passos `--release` + reclamar. `--list` força a leitura sem adquirir mesmo passando uma feature. **Claims avisam, nunca bloqueiam** — mas se o SessionStart avisar que outra sessão tem claim vivo, **confirme antes de `finish`/`archive`/`delete`**: duas sessões na mesma feature já custaram um recap.md inteiro e um sub-agent (o worktree sumiu debaixo dele). Claim órfão de sessão morta: `morph-spec claim <f> --release`.
|
|
30
|
+
|
|
31
|
+
## Validação
|
|
32
|
+
|
|
33
|
+
- **`morph-spec dag <feature>`** — análise do DAG de tasks.json com decisão sequencial vs paralelo **ponderada por effort** (raízes S vão inline, nunca ganham agente próprio). Também cruza `tasks.json` com os use cases: `usecase` apontando para um `UC-{nn}` inexistente é **erro** (exit 1, não despacha); pós-condição órfã e `doneCriteria` que parafraseou em vez de copiar são avisos. `--mermaid` nunca é bloqueado.
|
|
34
|
+
- **`morph-spec verify <feature> [task] [--json]`** — cadeia determinística build+testes+validadores (código antes do juiz LLM); escopo de task quando informado, senão a feature inteira.
|
|
35
|
+
- **`morph-spec doctor --worktrees [--prune] [--json]`** — reconcilia o registro do git × as pastas em disco × as features conhecidas. Worktrees órfãos acumulavam **invisíveis**: o `fleet` só reporta worktrees em branch `morph/*`, então um worktree em outra branch (resíduo de finish anterior) não aparecia em lugar nenhum. `--prune` roda o único reparo seguro (`git worktree prune` — registros de pastas que já sumiram); apagar pasta que ainda existe é reportado com o comando exato, nunca executado.
|
|
36
|
+
- **`morph-spec report-check <feature> [task] [--json]`** — audita os relatórios de sub-agent contra o trabalho que realmente entrou. **Relatório ausente NÃO quer dizer que o agente falhou** — ele pode ter feito tudo e perdido o meio de gravar. O comando responde a pergunta certa (`work-landed-report-missing` → aceite degradado, NÃO re-despache; `no-work-no-report` → re-despache uma vez). Protocolo completo em MORPH.md §6.
|
|
37
|
+
|
|
38
|
+
## Observabilidade
|
|
39
|
+
|
|
40
|
+
- **`morph-spec telemetry [--json] [--feature <f>] [--limit <n>]`** — reconstrói o caminho de execução da sessão a partir de `.morph/logs/events.jsonl` (skills invocadas, personas despachadas + prompts, standards/base de conhecimento lidos, mix de tools, prompts do usuário). Capturado silenciosamente pelo hook `telemetry-log` em todo tool call e todo UserPromptSubmit.
|
|
41
|
+
- **`morph-spec cost [feature] [--by task|phase] [--json]`** — custo da execução a partir do mesmo `events.jsonl`: duração por task (TaskStart→TaskEnd), bytes de contexto re-ingerido por tipo (`rubric`/`standard`/`skill`/`agents`/`plan-artifact`/`code`), dispatches + tamanho de prompt e mix de tools. Bytes re-ingeridos são **proxy determinística** de custo de token (tokens reais não são observáveis por hook). Use antes/depois de mudar skill ou fluxo para medir o efeito.
|
|
@@ -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
|
],
|
|
@@ -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,9 @@ 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.19.0"
|
|
8
|
+
stacks:
|
|
9
|
+
- umbraco
|
|
8
10
|
---
|
|
9
11
|
|
|
10
12
|
# create-umbraco-lp
|
|
@@ -4,7 +4,9 @@ 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.19.0"
|
|
8
|
+
stacks:
|
|
9
|
+
- umbraco
|
|
8
10
|
---
|
|
9
11
|
|
|
10
12
|
# migrate-lp-to-umbraco
|
|
@@ -4,7 +4,7 @@ description: Orquestra a execução autônoma de tasks de uma feature morph-spec
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: após Gate 2 aprovado, ao receber instrução "use /morph-apply" ou "implementar feature"
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.19.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-apply
|
|
@@ -210,33 +210,24 @@ 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.
|
|
231
226
|
|
|
232
227
|
### 6. Pós Gate 3 — encerramento
|
|
233
228
|
|
|
234
|
-
- Aprovar o Gate 3: em auto, `morph-spec approve {feature} review --mode auto`; em manual, o hook state-sync registra a resposta "aprovado" em AskUserQuestion — **desde que a pergunta nomeie a feature** (
|
|
235
|
-
- **Fechar a feature** com `morph-spec finish {feature} --pr|--merge
|
|
236
|
-
- **Abrir PR** (`--pr`): faz `push` de `morph/{f}` + `gh pr create` com base na default — para review por outro humano/CI antes do merge. Exige `origin` + `gh` autenticado (checados **antes** de arquivar; se faltarem, `finish` recusa sem efeito colateral — caia para `--merge`). A branch é preservada e a sessão fica em `morph/{f}`.
|
|
237
|
-
- **Merge local** (`--merge`): merge `--no-ff` na default **localmente**, sem push — para o fluxo single-user direto. Remove a branch e o worktree.
|
|
238
|
-
- Não integre automaticamente sem a escolha do modo: `finish` toca o remoto (`--pr`) ou a branch default (`--merge`) — é uma ação de saída que pede confirmação.
|
|
239
|
-
- Feature **legada** (criada antes do modelo "nasce numa branch", sem `morph/{f}`): `finish` recusa e roteia para `morph-spec archive {feature}` (arquivar-sem-integrar); nesse caso, arquive.
|
|
229
|
+
- Aprovar o Gate 3: em auto, `morph-spec approve {feature} review --mode auto`; em manual, o hook state-sync registra a resposta "aprovado" em `AskUserQuestion` — **desde que a pergunta nomeie a feature** (senão aprove via `morph-spec approve`).
|
|
230
|
+
- **Fechar a feature** com `morph-spec finish {feature} --pr|--merge`, modo escolhido via `AskUserQuestion` (header `"Integração"`): `--pr` (push + PR, review antes do merge) vs `--merge` (integra local, single-user direto). Não integre automaticamente sem essa escolha. Mecânica completa (o que cada modo faz, feature legada sem `morph/{f}`): `MORPH.md` §2.1/§2.2.
|
|
240
231
|
|
|
241
232
|
## Anti-padrões
|
|
242
233
|
|
|
@@ -246,7 +237,7 @@ O comando grava `gateDecisions.review = { pause, reason, signals, trust, decided
|
|
|
246
237
|
- Não dispachar mais que 4 agentes em paralelo (sobrecarga de contexto + custo).
|
|
247
238
|
- Não dispachar um agente inteiro para uma raiz de effort S — overhead > trabalho; o `morph-spec dag` já as marca como `inline`.
|
|
248
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).
|
|
249
|
-
- 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").
|
|
250
241
|
|
|
251
242
|
## Output esperado
|
|
252
243
|
|
|
@@ -266,5 +257,6 @@ O comando grava `gateDecisions.review = { pause, reason, signals, trust, decided
|
|
|
266
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"`)
|
|
267
258
|
- `morph-spec verify {feature} [task] --json` — cadeia determinística build+testes+validadores (código antes do juiz)
|
|
268
259
|
- `morph-spec score {feature} {task} {score} [--dims a,c,q,t]` — grava taskScores no feature.json com timestamp server-side
|
|
269
|
-
- `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`)
|
|
270
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.19.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-brainstorming
|
|
@@ -17,17 +17,7 @@ Ao iniciar uma nova feature — antes de qualquer especificação técnica ou pl
|
|
|
17
17
|
|
|
18
18
|
## Stack padrão (baked in)
|
|
19
19
|
|
|
20
|
-
O harness conhece o stack por padrão. Não pergunte sobre tecnologia a menos que haja ambiguidade real.
|
|
21
|
-
|
|
22
|
-
| Camada | Stack |
|
|
23
|
-
|--------|-------|
|
|
24
|
-
| Backend | .NET 10, VSA (feature-folder: handler + validator + endpoint + errors + tests) |
|
|
25
|
-
| ORM | EF Core + Neon (Postgres), `Guid.CreateVersion7()`, `sealed` classes, `result.Match()` |
|
|
26
|
-
| IA | Microsoft Agent Framework (MAF) — quando a feature envolve agentes |
|
|
27
|
-
| Frontend | Next.js App Router + Tailwind + Framer Motion + Shadcn |
|
|
28
|
-
| Jobs async | Hangfire — apenas se a feature requer processamento em background |
|
|
29
|
-
|
|
30
|
-
**Padrões proibidos:** `Guid.NewGuid()`, classes não-sealed sem justificativa, exceptions sem result pattern, camada de Service/Manager entre handler e dados, repository genérico (`IRepository<T>`/`IUnitOfWork`), SQL cru sem justificativa. Acesso a dados em VSA: `ApplicationDbContext` direto no slice (`DbSet<T>` já é repository, `DbContext` já é unit of work); para concorrência ou SQL específico, store dedicado hand-written com justificativa em `decisions.md`.
|
|
20
|
+
O harness conhece o stack por padrão (backend .NET 10 + VSA + EF Core/Neon, IA via MAF, frontend Next.js/Tailwind/Shadcn) e a lista de padrões proibidos (`Guid.NewGuid()`, classes não-sealed, Service/Manager layer, repository genérico, SQL cru). **Não pergunte sobre tecnologia a menos que haja ambiguidade real** — stack nunca entra na árvore de decisões. Regra canônica: `MORPH.md` § "Stack baked-in".
|
|
31
21
|
|
|
32
22
|
## Modo bug-lean (`workType: bug`)
|
|
33
23
|
|
|
@@ -50,7 +40,7 @@ Fato não se pergunta. Antes de levar a primeira pergunta ao usuário, levante o
|
|
|
50
40
|
|
|
51
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).
|
|
52
42
|
|
|
53
|
-
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).
|
|
54
44
|
|
|
55
45
|
### Parte 1 — Árvore de decisões abertas
|
|
56
46
|
|
|
@@ -112,27 +102,17 @@ options:
|
|
|
112
102
|
|
|
113
103
|
2. Apresente o Gate 1 segundo o modo de descoberta e o trust mode.
|
|
114
104
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
- `discoveryMode` = `"interview"` ou `"auto"`, conforme a resposta da Parte 2.
|
|
118
|
-
- `designSystemDivergence` = detectado na Parte 0 (fontes de design conflitantes).
|
|
119
|
-
- `standardsViolations` = lista de violações detectadas.
|
|
120
|
-
|
|
121
|
-
**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.
|
|
122
|
-
|
|
123
|
-
**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"):
|
|
124
|
-
|
|
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`:
|
|
125
106
|
```
|
|
126
|
-
|
|
127
|
-
morph-spec gate-decision {feature} proposal --pause true --reason "modo entrevista — entendimento compartilhado confirmado pelo usuário" --signals '{"discoveryMode":"interview","designSystemDivergence":false,"standardsViolations":[]}'
|
|
128
|
-
|
|
129
|
-
# modo automático, sem sinais de risco
|
|
130
|
-
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"}'
|
|
131
108
|
```
|
|
132
109
|
|
|
133
|
-
|
|
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
|
+
```
|
|
134
114
|
|
|
135
|
-
|
|
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.
|
|
136
116
|
|
|
137
117
|
**Se `pause === true`** (manual mode OU risco detectado em auto), use `AskUserQuestion`:
|
|
138
118
|
|
|
@@ -162,8 +142,7 @@ options:
|
|
|
162
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.
|
|
163
143
|
|
|
164
144
|
## Output esperado
|
|
165
|
-
- `.morph/features/{feature}/0-proposal/proposal.md` — proposta aprovada
|
|
166
|
-
- `.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"
|
|
167
146
|
- Gate 1 apresentado e aprovado
|
|
168
147
|
|
|
169
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.
|
|
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.
|
|
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`.
|
|
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-
|
|
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-
|
|
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.
|
|
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.
|
|
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
|
-
##
|
|
58
|
-
-
|
|
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
|
|
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
|
|
|
@@ -88,13 +85,7 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
|
|
|
88
85
|
4. Produza `mandate.md` em `.morph/features/{feature}/2-plan/`:
|
|
89
86
|
- Stack exata do projeto (leia de `.morph/config/config.json` → `project.stack` ou do CLAUDE.md).
|
|
90
87
|
- Standards obrigatórios: liste os IDs relevantes de `.morph/framework/standards/STANDARDS.json`.
|
|
91
|
-
- Patterns proibidos —
|
|
92
|
-
- `Guid.NewGuid()` → usar `Guid.CreateVersion7()`
|
|
93
|
-
- Classes não-sealed sem justificativa documentada
|
|
94
|
-
- Exceptions como fluxo de controle → usar result pattern com `result.Match()`
|
|
95
|
-
- Camada de Service/Manager entre handler e dados → handler usa `ApplicationDbContext` direto no slice
|
|
96
|
-
- Repository genérico (`IRepository<T>`/`IUnitOfWork`) → redundante sobre EF Core: `DbSet<T>` já é repository, `DbContext` já é unit of work
|
|
97
|
-
- SQL cru (`FromSqlRaw`, `ExecuteQuery(string)`) sem justificativa em `decisions.md` → usar LINQ
|
|
88
|
+
- Patterns proibidos — **copie por extenso no mandate.md** a lista canônica de `MORPH.md` § "Stack baked-in" (`Guid.NewGuid()`→`Guid.CreateVersion7()`, classes não-sealed sem justificativa, exceptions como fluxo de controle, camada de Service/Manager entre handler e dados, repository genérico `IRepository<T>`/`IUnitOfWork`, SQL cru sem justificativa) mais qualquer proibição específica da feature. Copie o texto completo — o mandate.md é lido por implementadores em contexto fresco, sem `MORPH.md` carregado, então um ponteiro sozinho não basta aqui.
|
|
98
89
|
- Política de acesso a dados (registre no mandate): `ApplicationDbContext` injetado direto no slice — para CRUD e para queries específicas (joins, projeção, paginação). Para concorrência ou SQL específico, store dedicado hand-written com justificativa em `decisions.md`.
|
|
99
90
|
- **Features com agentes de IA (MAF):** se a feature envolve um agente (Microsoft Agent Framework), **use a tool Read** nos standards relevantes de `framework/standards/ai-agents/*.md` (ex.: `setup`, `agent-session`, `middleware-patterns`, `mcp-server`, `mcp-tools`, `multi-agent-patterns`, `production`) — filtre pelo que a feature exige via STANDARDS.json. Esses standards carregam as **convenções de projeto** (single-agent por padrão — Workflows só para fan-in/out real; provider, caching, observability, A2A) que uma fonte externa de docs (ex.: context7) não conhece. Padrão de divisão: **superfície da API** pode vir de docs ao vivo/context7 (mais frescas para um SDK em evolução), mas **as convenções vêm dos standards** — registre ambas no mandate. Não pule os `ai-agents/*.md` só porque o STANDARDS.json index lista que eles existem.
|
|
100
91
|
- Checklist de done com critérios verificáveis por tarefa.
|
|
@@ -157,21 +148,16 @@ Ao iniciar a fase plan — após o `proposal.md` ser aprovado e antes de qualque
|
|
|
157
148
|
|
|
158
149
|
Você pode embutir o diagrama do DAG do plano via `morph-spec dag {feature} --mermaid` (flowchart Mermaid) para visualização no gate.
|
|
159
150
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
- `taskCount` = número de tasks do tasks.json.
|
|
163
|
-
- `designSystemDivergence` = herdado do brainstorming.
|
|
164
|
-
- `standardsViolations` = violações detectadas no mandate.
|
|
165
|
-
|
|
166
|
-
**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`).
|
|
167
|
-
|
|
168
|
-
**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.
|
|
169
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):
|
|
170
154
|
```
|
|
171
|
-
morph-spec gate-
|
|
155
|
+
morph-spec gate-check {feature} plan --signals '{"designSystemDivergence":true,"standardsViolations":["<id>"]}'
|
|
172
156
|
```
|
|
173
157
|
|
|
174
|
-
|
|
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.
|
|
175
161
|
|
|
176
162
|
**Se `pause === true`**, use `AskUserQuestion`:
|
|
177
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.
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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)
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
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
|
-
|
|
103
|
-
|
|
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
|
-
**
|
|
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
|
|