@polymorphism-tech/morph-spec 8.4.0 → 8.5.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 (32) hide show
  1. package/README.md +8 -5
  2. package/bin/morph-spec.js +13 -10
  3. package/claude-plugin.json +1 -1
  4. package/docs/CHEATSHEET.md +7 -4
  5. package/docs/QUICKSTART.md +7 -4
  6. package/framework/CLAUDE.md +6 -5
  7. package/framework/MORPH.md +3 -1
  8. package/framework/commands/morph-archive.md +11 -4
  9. package/framework/schemas/feature.schema.json +2 -2
  10. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  11. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  12. package/framework/skills/core/morph-apply/SKILL.md +8 -5
  13. package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
  14. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  15. package/framework/skills/core/morph-hotfix/SKILL.md +3 -3
  16. package/framework/skills/core/morph-implement/SKILL.md +1 -1
  17. package/framework/skills/core/morph-plan/SKILL.md +1 -1
  18. package/framework/skills/core/morph-proposal/SKILL.md +1 -1
  19. package/framework/skills/core/morph-review/SKILL.md +4 -2
  20. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  21. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  22. package/package.json +1 -1
  23. package/src/commands/project/worktree.js +154 -357
  24. package/src/commands/state/archive.js +148 -70
  25. package/src/commands/state/create.js +46 -2
  26. package/src/commands/state/finish.js +422 -0
  27. package/src/core/state/state-manager.js +2 -2
  28. package/src/dashboard/scanner/state-scanner.js +1 -1
  29. package/src/lib/generators/handoff-generator.js +2 -2
  30. package/src/lib/git/default-branch.js +73 -0
  31. package/src/lib/worktree/env-allocator.js +1 -1
  32. package/src/utils/file-copier.js +2 -2
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.4.0
6
+ **Version:** 8.5.0
7
7
  **Requires:** Node.js 22+, Claude Code
8
8
 
9
9
  ---
@@ -140,7 +140,7 @@ These commands are available inside Claude Code after init.
140
140
  | `/morph-apply {feature}` | Autonomous execution + review (Gate 3) |
141
141
  | `/morph-hotfix {feature}` | Surgical hotfix ADW — scout → fix → human Gate 3 → ship |
142
142
  | `/morph-status [feature]` | Status of the active (or specified) feature |
143
- | `/morph-archive {feature}` | Archive a completed feature (after Gate 3) |
143
+ | `/morph-archive {feature}` | Archive **without integrating** (legacy feature / cleanup); normal close is `morph-spec finish --pr\|--merge` |
144
144
  | `/morph-preflight` | Pre-deploy validation (specs, contracts, tests, infra) |
145
145
  | `/morph-troubleshoot [error]` | Root-cause diagnosis for .NET/Next.js errors |
146
146
 
@@ -167,9 +167,12 @@ morph-spec status {feature} # Feature status dashboard
167
167
  morph-spec approve {feature} {gate} # Approve a phase gate (proposal, plan, review)
168
168
  morph-spec advance {feature} # Approve the current gate and scaffold the next phase folder
169
169
  morph-spec approval-status {feature} # Show approval status for all gates
170
- morph-spec archive {feature} # Archive a completed feature (after Gate 3)
170
+ morph-spec finish {feature} --pr|--merge # Close a feature: archive + integrate (PR or local merge) + teardown
171
+ morph-spec archive {feature} # Archive WITHOUT integrating (legacy feature / cleanup)
171
172
  ```
172
173
 
174
+ `finish` is the normal close for both flows: it archives (committing the move inside `morph/{feature}`), then integrates — `--merge` merges `--no-ff` into the default branch locally; `--pr` pushes the branch and runs `gh pr create` (needs `origin` + authenticated `gh`) — and tears down the worktree if there is one. Plain `archive` is reserved for legacy features (born before every feature had a `morph/{feature}` branch) and cleanup.
175
+
173
176
  Task progress within a feature is tracked with the native `TaskCreate`/`TaskUpdate` tools, persisted to `tasks.json` — there is no separate CLI command for starting or completing a task.
174
177
 
175
178
  ### Validation
@@ -196,8 +199,8 @@ morph-spec dag {feature} [--mermaid] # DAG dispatch d
196
199
  morph-spec create {feature} --description "<what/why>" --worktree # Birth the feature already isolated in its own worktree
197
200
  morph-spec worktree setup {feature} # Create .worktrees/{feature}/ on branch morph/{feature}
198
201
  morph-spec worktree link [--all] # Relink shared infra (node_modules, .claude, .morph/framework)
199
- morph-spec worktree finish {feature} # Merge --no-ff back to the primary root, clean up (requires Gate 3)
200
202
  morph-spec worktree list [--json] # List active feature worktrees with phase/gate status
203
+ # Close a worktree feature with `morph-spec finish {feature} --pr|--merge` (see Feature workflow) — it absorbed `worktree finish`.
201
204
  ```
202
205
 
203
206
  ---
@@ -365,4 +368,4 @@ Code generated by morph-spec (contracts, templates, implementation output) belon
365
368
 
366
369
  ---
367
370
 
368
- *morph-spec v8.4.0 by [Polymorphism Tech](https://polymorphism.tech)*
371
+ *morph-spec v8.5.0 by [Polymorphism Tech](https://polymorphism.tech)*
package/bin/morph-spec.js CHANGED
@@ -23,13 +23,14 @@ import { installPluginCommand } from '../src/commands/project/install-plugin-cmd
23
23
  import { updateCommand } from '../src/commands/project/update.js';
24
24
  import { doctorCommand } from '../src/commands/project/doctor.js';
25
25
  import { statusCommand } from '../src/commands/project/status.js';
26
- import { worktreeSetupCommand, worktreeLinkCommand, worktreeFinishCommand, worktreeListCommand } from '../src/commands/project/worktree.js';
26
+ import { worktreeSetupCommand, worktreeLinkCommand, worktreeListCommand } from '../src/commands/project/worktree.js';
27
27
  import { fleetCommand } from '../src/commands/project/fleet.js';
28
28
 
29
29
  // === Approval gates (human-only) ===
30
30
  import { approveCommand, approvalStatusCommand, unapproveCommand } from '../src/commands/state/approve.js';
31
31
  import { advanceCommand } from '../src/commands/state/advance.js';
32
32
  import { archiveCommand } from '../src/commands/state/archive.js';
33
+ import { finishCommand } from '../src/commands/state/finish.js';
33
34
  import { scoreCommand } from '../src/commands/state/score.js';
34
35
  import { gateDecisionCommand } from '../src/commands/state/gate-decision.js';
35
36
  import { createCommand } from '../src/commands/state/create.js';
@@ -158,11 +159,21 @@ program
158
159
 
159
160
  program
160
161
  .command('archive <feature>')
161
- .description('Archive a completed feature (atomic, git-aware): move folder + update state')
162
+ .description('Archive a completed feature (atomic, git-aware): move folder + update state. Archive WITHOUT integrating (legacy features, cleanup) — the close path is `finish`')
162
163
  .option('--no-git', 'Skip git staging of the move')
163
164
  .option('--force', 'Archive even if Gate 3 (review) is not approved')
164
165
  .action((feature, options) => archiveCommand(feature, options));
165
166
 
167
+ program
168
+ .command('finish <feature>')
169
+ .description('Close a feature: archive → integrate. --merge merges morph/{f} into the default (local); --pr pushes it + opens a PR. Works with and without a worktree')
170
+ .option('--pr', 'Push morph/{feature} and open a PR against the default branch (no local merge)')
171
+ .option('--merge', 'Merge morph/{feature} into the default branch locally (no push)')
172
+ .option('--keep', 'Keep the worktree/branch after integrating (worktree flow only)')
173
+ .option('--force', 'Skip the Gate-3-approved precondition')
174
+ .option('--discard-ignored', 'Allow removing the worktree even though it holds gitignored files that exist nowhere else (e.g. .env) — they are destroyed')
175
+ .action((feature, options) => finishCommand(feature, options));
176
+
166
177
  program
167
178
  .command('delete <feature>')
168
179
  .description('Delete a feature (hard by default; --archive marks it abandoned). Refuses if a gate is approved unless --force')
@@ -341,14 +352,6 @@ worktreeCommand
341
352
  .option('--all', 'Link all shared dirs, not just node_modules')
342
353
  .action((options) => worktreeLinkCommand(options));
343
354
 
344
- worktreeCommand
345
- .command('finish <feature>')
346
- .description('Merge the feature branch back into the primary root and clean up the worktree (requires Gate 3 approved)')
347
- .option('--keep', 'Keep the worktree and branch after merging')
348
- .option('--force', 'Skip the Gate-3-approved precondition')
349
- .option('--discard-ignored', 'Allow removing the worktree even though it holds gitignored files that exist nowhere else (e.g. .env) — they are destroyed')
350
- .action((feature, options) => worktreeFinishCommand(feature, options));
351
-
352
355
  worktreeCommand
353
356
  .command('list')
354
357
  .description('List active feature worktrees with their phase and gate status')
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "morph-spec",
3
- "version": "8.4.0",
3
+ "version": "8.5.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",
@@ -46,7 +46,7 @@ proposal → [uiux] → plan → implement → review
46
46
  | `/morph-hotfix {feature}` | Surgical hotfix ADW (scout → fix → human gate → ship) |
47
47
  | `/morph-apply {feature}` | Autonomous execution + review (Gate 3) |
48
48
  | `/morph-status [feature]` | Status of the active (or specified) feature |
49
- | `/morph-archive {feature}` | Archive a completed feature (after Gate 3) |
49
+ | `/morph-archive {feature}` | Archive **without integrating** (legacy feature / cleanup) — normal close is `morph-spec finish --pr\|--merge` |
50
50
  | `/morph-preflight` | Pre-deploy validation (specs, contracts, tests, infra) |
51
51
  | `/morph-troubleshoot [error]` | Root-cause diagnosis for .NET/Next.js errors |
52
52
 
@@ -59,9 +59,12 @@ morph-spec approve {feature} {gate} [--mode auto] [--approver name] [--notes tex
59
59
  morph-spec advance {feature} [--design] # approve current gate + scaffold next phase folder in one step
60
60
  morph-spec approval-status {feature} [--json]
61
61
  morph-spec unapprove {feature} {gate} [--reason text] # recovery only
62
- morph-spec archive {feature} [--force] [--no-git]
62
+ morph-spec finish {feature} --pr|--merge [--keep] [--force] [--discard-ignored] # normal close: archive + integrate + teardown
63
+ morph-spec archive {feature} [--force] [--no-git] # archive WITHOUT integrating (legacy feature / cleanup)
63
64
  ```
64
65
 
66
+ `finish` is the normal way to close a feature (both the worktree flow and the common flow): it archives (committing the move inside `morph/{feature}`), then integrates — `--merge` merges `--no-ff` into the default branch locally (no push); `--pr` pushes `morph/{feature}` + `gh pr create` (needs `origin` + authenticated `gh`). It then tears down the worktree and releases the port block. `archive` alone is reserved for legacy features (no `morph/{feature}` branch) and cleanup.
67
+
65
68
  ---
66
69
 
67
70
  ## CLI — feature birth & work-type routing
@@ -116,8 +119,8 @@ One feature = one git worktree = one Claude Code instance. Each worktree gets it
116
119
  morph-spec create {feature} --description "<what/why>" --worktree # birth the feature already isolated in its own worktree
117
120
  morph-spec worktree setup {feature} # create .worktrees/{feature}/ on branch morph/{feature}
118
121
  morph-spec worktree link [--all] # relink shared infra (node_modules[, .claude, .morph/framework])
119
- morph-spec worktree finish {feature} # merge --no-ff back to the primary root, clean up + release ports (requires Gate 3)
120
122
  morph-spec worktree list [--json] # active feature worktrees with phase/gate status
123
+ # Close a worktree feature with `morph-spec finish {feature} --pr|--merge` (see above) — it absorbed `worktree finish`.
121
124
  morph-spec handoff {feature} [--json] # regenerate the compressed session-handoff doc (pointers, not copies)
122
125
  morph-spec fleet [--json] # every active feature (root + worktrees) with phase/gates/ports/handoff/activity
123
126
  ```
@@ -182,4 +185,4 @@ Never edited directly — go through CLI commands or `morph-spec update` instead
182
185
 
183
186
  ---
184
187
 
185
- *morph-spec v8.4.0 by Polymorphism Tech*
188
+ *morph-spec v8.5.0 by Polymorphism Tech*
@@ -168,13 +168,16 @@ morph-spec create my-feature --description "what & why" --worktree # birth the
168
168
  morph-spec worktree setup my-feature # creates .worktrees/my-feature/ on branch morph/my-feature
169
169
  ```
170
170
 
171
- Open the new worktree directory in its own Claude Code instance and work normally — a SessionStart hook injects the worktree's feature identity into context automatically. When the feature is done:
171
+ Open the new worktree directory in its own Claude Code instance and work normally — a SessionStart hook injects the worktree's feature identity into context automatically. When the feature is done (Gate 3 approved), close it in one step:
172
172
 
173
173
  ```bash
174
- morph-spec worktree finish my-feature # merges --no-ff back into the primary root, then cleans up
175
- morph-spec archive my-feature # run at the primary root afterward
174
+ morph-spec finish my-feature --merge # archive + merge --no-ff into the default branch (local), tear down the worktree
175
+ # or, to open a PR instead of merging locally:
176
+ morph-spec finish my-feature --pr # archive + push morph/my-feature + gh pr create (keeps the branch the PR needs)
176
177
  ```
177
178
 
179
+ `finish` archives the feature (committing the move inside `morph/my-feature`) *and* integrates *and* tears down the worktree in one step — it replaces the old `worktree finish` + separate `archive`. The same command closes features developed **without** a worktree (they're born on `morph/{feature}` too).
180
+
178
181
  List every active worktree with its phase and gate status:
179
182
 
180
183
  ```bash
@@ -246,4 +249,4 @@ morph-spec doctor
246
249
 
247
250
  ---
248
251
 
249
- *morph-spec v8.4.0 by Polymorphism Tech*
252
+ *morph-spec v8.5.0 by Polymorphism Tech*
@@ -36,23 +36,24 @@ Se não houver feature ativa, pergunte ao usuário qual feature trabalhar.
36
36
  | `/morph-hotfix {feature}` | ADW cirúrgico de hotfix (scout → fix → gate humano → ship) |
37
37
  | `/morph-apply {feature}` | Execução autônoma + review (Gate 3) |
38
38
  | `/morph-status [feature]` | Status da feature ativa (ou a especificada) |
39
- | `/morph-archive {feature}` | Arquiva feature concluída (após Gate 3) — wrapper de `morph-spec archive` (atômico, git-aware) |
39
+ | `/morph-archive {feature}` | Arquiva-**sem-integrar** (features legadas/faxina) — wrapper de `morph-spec archive`. Fechamento normal = `morph-spec finish --pr\|--merge` |
40
40
  | `/morph-preflight` | Validação pré-deploy (specs, contratos, testes, infra) |
41
41
  | `/morph-troubleshoot [erro]` | Diagnóstico de erros .NET/Next.js com root-cause analysis |
42
42
 
43
43
  **Comandos CLI de gate e de estado** (a LLM os usa em vez de editar o estado à mão):
44
44
  - `morph-spec approve <feature> <gate> --mode auto` — aprova um gate (`proposal`/`plan`/`review`) em `trust: auto`.
45
45
  - `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).
46
- - `morph-spec archive <feature>` — arquiva a feature (atômico, git-aware); é o que `/morph-archive` chama.
46
+ - `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.
47
+ - `morph-spec finish <feature> --pr|--merge` — o **encerramento único** da feature (worktree ou comum): **arquiva** commitando `features/{f} → archive/{f}` dentro de `morph/{f}`, 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.
47
48
  - `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).
48
49
  - `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.
49
50
  - `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.
50
- - `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.
51
+ - `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.
51
52
  - `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).
52
53
  - `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).
53
54
  - `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.
54
55
  - `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.
55
- - `morph-spec worktree setup|link|finish|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; `finish` faz merge `--no-ff`, limpa e libera o bloco; `list` mostra fase/gate de cada worktree ativo).
56
+ - `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).
56
57
  - `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`.
57
58
  - `morph-spec fleet` — visão da frota: toda feature ativa (raiz + worktrees) com fase, gates pendentes, tasks, portas, handoff e atividade. Use entre sessões para decidir onde atuar.
58
59
  - `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.
@@ -74,7 +75,7 @@ Se não houver feature ativa, pergunte ao usuário qual feature trabalhar.
74
75
 
75
76
  Toda feature nasce com um `workType` (`morph-spec create <f> --description "<o quê/porquê>" --type <tipo>` ou classificado de `--request "<pedido>"`, que também semeia a descrição obrigatória) que dimensiona o pipeline: `feature` roda o fluxo completo (proposal → [uiux] → plan → implement → review); `bug` roda uma versão enxuta (proposal/plan lean); `chore` pula direto para implement (Gates 1/2 carimbados por política no nascimento); `hotfix` roda scout → fix cirúrgico → test loop → ship. O Gate 3 do `hotfix` **pausa sempre para um humano**, mesmo em `trust: auto` — o CLI recusa `morph-spec approve <f> review --mode auto` nesse tipo. Detalhes em `.morph/framework/MORPH.md` §2.1 e §5.
76
77
 
77
- Features independentes podem rodar em paralelo, cada uma isolada num git worktree (`morph-spec create <f> --description "<o quê/porquê>" --worktree` ou `morph-spec worktree setup <f>`) — uma feature por worktree, uma instância de Claude Code por worktree. Cada worktree tem seu **bloco de portas** próprio (`.morph/worktree.env` — suba dev servers SEMPRE nelas, nunca nas portas padrão) e seu **handoff.md** de retomada. `feature.json` viaja commitado na branch `morph/{f}`; ao fechar, aprove o Gate 3 dentro do worktree e rode `morph-spec worktree finish <f>` seguido de `morph-spec archive <f>` na raiz. Visão agregada: `morph-spec fleet`. Detalhes em `.morph/framework/MORPH.md` §2.2.
78
+ Features independentes podem rodar em paralelo, cada uma isolada num git worktree (`morph-spec create <f> --description "<o quê/porquê>" --worktree` ou `morph-spec worktree setup <f>`) — uma feature por worktree, uma instância de Claude Code por worktree. Cada worktree tem seu **bloco de portas** próprio (`.morph/worktree.env` — suba dev servers SEMPRE nelas, nunca nas portas padrão) e seu **handoff.md** de retomada. `feature.json` viaja commitado na branch `morph/{f}`; ao fechar, aprove o Gate 3 e rode `morph-spec finish <f> --pr|--merge` (arquiva dentro da branch, integra e desmonta o worktree num passo só). Visão agregada: `morph-spec fleet`. Detalhes em `.morph/framework/MORPH.md` §2.2.
78
79
 
79
80
  ## Personas (em `.claude/agents/`)
80
81
 
@@ -112,6 +112,8 @@ Nem todo trabalho merece o pipeline completo. Cada feature nasce com **identidad
112
112
 
113
113
  **Compat:** uma feature sem `workType` (criada antes do v8) é tratada como `feature`. Mudança de tipo mid-flight: `morph-spec retype <f> <tipo>` (desfaz só carimbos de política, preserva aprovações humanas; bloqueado após o Gate 3).
114
114
 
115
+ **Nascimento numa branch:** toda feature — **com ou sem `--worktree`** — nasce numa branch `morph/{f}` ramificada da default. O fluxo comum (sem worktree) desenvolve direto em `morph/{f}` na raiz; o fluxo worktree isola em `.worktrees/{f}`. Por construção o fechamento é simétrico: `morph-spec finish <f> --pr|--merge` (§2.2) fecha os dois do mesmo jeito. Features criadas **antes** deste modelo (sem branch `morph/{f}`) fecham por `morph-spec archive <f>` (arquivar-sem-integrar), não por `finish`.
116
+
115
117
  ### 2.2 Desenvolvimento paralelo por worktree (frota)
116
118
 
117
119
  Features independentes podem ser desenvolvidas **em paralelo, cada uma no seu git worktree**, com uma instância de Claude Code por worktree. `morph-spec create <f> --description "<o quê/porquê>" --worktree` (ou `morph-spec worktree setup <f>`) cria `.worktrees/{f}/` na branch `morph/{f}`. Contrato:
@@ -125,7 +127,7 @@ Features independentes podem ser desenvolvidas **em paralelo, cada uma no seu gi
125
127
  - **Handoff entre sessões:** `.morph/features/{f}/handoff.md` é o documento de retomada — comprimido, derivado e regenerável (`morph-spec handoff <f>`), ele **aponta** para os artefatos em vez de copiá-los. É regenerado automaticamente no `worktree setup`, `create --worktree` e `advance`; o hook de SessionStart aponta para ele. **Ao abrir uma sessão numa feature em andamento, leia o handoff antes de re-derivar contexto à mão.** Nunca o edite manualmente (é git-invisível e sobrescrito na próxima regeneração).
126
128
  - **Visão da frota:** `morph-spec fleet` agrega raiz + worktrees (fase, gates pendentes, tasks, portas, handoff, último commit, sujeira) — use entre sessões para decidir onde atuar. `morph-spec worktree list` continua sendo a visão enxuta por worktree.
127
129
  - **Ownership de arquivos:** não há lock em runtime, por design — a colisão de escrita se resolve **em plan-time** (`morph-spec dag` detecta overlap de `outputs` e recomenda `isolation: "worktree"`) e **por construção** (uma feature = um worktree = um escritor). Entre features, arquivos compartilhados convergem no merge do `finish` — conflito ali é o sinal honesto de escopo sobreposto, não um bug.
128
- - **Fechamento:** aprove o Gate 3 dentro do worktree, depois `morph-spec worktree finish <f>` (merge `--no-ff` da branch na raiz primária limpa; recusa se worktree ou raiz estiverem sujos; aborta em conflito; libera o bloco de portas) e por fim `morph-spec archive <f>` na raiz.
130
+ - **Fechamento:** aprove o Gate 3, depois **`morph-spec finish <f> --pr|--merge`** — o encerramento único e simétrico (mesmo comando nos dois fluxos, worktree e comum). Ele **arquiva** a feature commitando o move `features/{f} → archive/{f}` **dentro da branch `morph/{f}`** (o estado arquivado viaja na própria integração, não num commit à parte) e então integra: `--merge` faz o merge `--no-ff` **local** na branch default (sem push; recusa se worktree/raiz estiverem sujos; aborta em conflito) e `--pr` faz `push` de `morph/{f}` + `gh pr create` (sem merge local; exige `origin` + `gh` autenticado — as pré-condições rodam **antes** de arquivar, então um `--pr` recusado não deixa meio-estado). Em ambos o worktree é desmontado (PROVE-or-DECLINE) e o bloco de portas liberado; no `--pr` a branch é **preservada** (o PR aberto precisa dela) e a sessão permanece em `morph/{f}`. Não há mais `worktree finish` nem `archive` separado no caminho feliz — `morph-spec archive` fica reservado a arquivar-sem-integrar (features legadas, faxina).
129
131
 
130
132
  ---
131
133
 
@@ -6,12 +6,18 @@ allowed-tools: Read, Bash
6
6
 
7
7
  # Archive MORPH Feature
8
8
 
9
- Archive a feature that has cleared Gate 3 (review). Use when the work is shipped and you want the
10
- feature out of the active set in `.morph/features/`.
9
+ Archive-**without-integrate**: move a feature out of the active set in `.morph/features/` without
10
+ merging or opening a PR. This is the **reserved** path — for **legacy** features (born before the
11
+ "every feature is born on a `morph/{f}` branch" model, so there's no branch to integrate) and for
12
+ **cleanup**. The **normal close** of a feature is `morph-spec finish {feature} --pr|--merge`, which
13
+ archives *and* integrates *and* tears down the worktree in one step (see `MORPH.md` §2.2 and
14
+ `morph-apply` §6). Reach for `/morph-archive` only when integration is not wanted.
11
15
 
12
16
  This is a thin wrapper over the atomic, git-aware CLI command — do **not** move folders or edit state
13
17
  by hand. The command moves the folder, stamps the feature `completed` + `archivedAt` in its
14
- `feature.json`, stages the move in git, and cleans the derivable root index, all-or-nothing.
18
+ `feature.json`, **commits the move scoped to the feature's own pathspec** (`.morph/features/{f}` +
19
+ `.morph/archive/{f}`, never `commit -a`), and cleans the derivable root index, all-or-nothing. Re-running
20
+ is idempotent: an already-archived feature is reported, not re-moved.
15
21
 
16
22
  ## Workflow
17
23
 
@@ -28,7 +34,8 @@ by hand. The command moves the folder, stamps the feature `completed` + `archive
28
34
  ```
29
35
  The command refuses if Gate 3 isn't approved (override with `--force` only when the user asks).
30
36
  It moves `.morph/features/{feature}/` → `.morph/archive/{feature}/` (via `git mv` when possible),
31
- sets `status: "completed"` + `archivedAt`, and drops the feature from the thin index.
37
+ sets `status: "completed"` + `archivedAt`, commits that move scoped to the feature's pathspec, and
38
+ drops the feature from the thin index.
32
39
 
33
40
  3. **Report** the new path (`.morph/archive/{feature}/`). Do not invent metrics not recorded in
34
41
  `feature.json` or `recap.md`.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "title": "MORPH-SPEC feature.json",
4
- "description": "Canonical shape of the authoritative, committed per-feature state at .morph/features/{feature}/feature.json (v5 per-feature state model). Born via `morph-spec create` (explicit) or the state-sync hook (implicit fallback). Server-side writers: `morph-spec approve/advance` (approvalGates), `morph-spec score` (taskScores), `morph-spec gate-decision` (gateDecisions), `morph-spec archive` (status/archivedAt). Never hand-edit the CLI-owned fields — manual Edits collide with the state-sync hook. This schema is documentational: additionalProperties stays true so older/newer CLIs interoperate.",
4
+ "description": "Canonical shape of the authoritative, committed per-feature state at .morph/features/{feature}/feature.json (v5 per-feature state model). Born via `morph-spec create` (explicit) or the state-sync hook (implicit fallback). Server-side writers: `morph-spec approve/advance` (approvalGates), `morph-spec score` (taskScores), `morph-spec gate-decision` (gateDecisions), `morph-spec archive`/`finish` (status/archivedAt — `finish` archives internally before integrating). Never hand-edit the CLI-owned fields — manual Edits collide with the state-sync hook. This schema is documentational: additionalProperties stays true so older/newer CLIs interoperate.",
5
5
  "type": "object",
6
6
  "required": ["status", "approvalGates"],
7
7
  "properties": {
@@ -200,7 +200,7 @@
200
200
  },
201
201
  "worktree": {
202
202
  "type": "object",
203
- "description": "Bookkeeping do worktree ativo desta feature no ROOT feature.json, gravado por `morph-spec worktree setup` (via `create --worktree` ou standalone). Removido por `worktree finish`.",
203
+ "description": "Bookkeeping do worktree ativo desta feature no ROOT feature.json, gravado por `morph-spec worktree setup` (via `create --worktree` ou standalone). Removido no fechamento por `morph-spec finish` (que absorveu o antigo `worktree finish`).",
204
204
  "properties": {
205
205
  "path": { "type": "string" },
206
206
  "branch": { "type": "string" },
@@ -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.4.0"
7
+ cliVersion: "8.5.0"
8
8
  ---
9
9
 
10
10
  # create-umbraco-lp
@@ -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.4.0"
7
+ cliVersion: "8.5.0"
8
8
  ---
9
9
 
10
10
  # 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.4.0"
7
+ cliVersion: "8.5.0"
8
8
  ---
9
9
 
10
10
  # morph-apply
@@ -218,11 +218,14 @@ O comando grava `gateDecisions.review = { pause, reason, signals, trust, decided
218
218
  - Pause: `AskUserQuestion` com options `["aprovado, fechar feature", "preciso ajustar", "rollback"]`.
219
219
  - Auto: exibir summary do review-report, aprovar via `morph-spec approve {feature} review --mode auto`, e prosseguir.
220
220
 
221
- ### 6. Pós Gate 3
221
+ ### 6. Pós Gate 3 — encerramento
222
222
 
223
223
  - 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. O gate fica gravado no `feature.json` autoritativo da feature — nunca via Edit à mão de `state.json`.
224
- - Sinalizar: "Feature {nome} concluída. Rode `/morph-archive {feature}` para arquivar."
225
- - Não arquivar automaticamente.
224
+ - **Fechar a feature** com `morph-spec finish {feature} --pr|--merge` — um passo só: arquiva commitando `features/{f} → archive/{f}` dentro de `morph/{f}`, integra e desmonta o worktree (se houver). Escolha o modo com `AskUserQuestion` (header `"Integração"`):
225
+ - **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}`.
226
+ - **Merge local** (`--merge`): merge `--no-ff` na default **localmente**, sem push — para o fluxo single-user direto. Remove a branch e o worktree.
227
+ - 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.
228
+ - 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.
226
229
 
227
230
  ## Anti-padrões
228
231
 
@@ -240,7 +243,7 @@ O comando grava `gateDecisions.review = { pause, reason, signals, trust, decided
240
243
  - `.morph/features/{feature}/3-implement/recap.md` produzido por morph-implement.
241
244
  - `.morph/features/{feature}/4-review/review-report.md` produzido por morph-review.
242
245
  - Gate 3 registrado aprovado em `.morph/features/{feature}/feature.json` (autoritativo) — via `morph-spec approve` em auto, ou pelo hook state-sync no caminho manual.
243
- - Feature com Gate 3 aprovado e pronta para `morph-spec archive` (que carimba `status: "completed"` + `archivedAt`).
246
+ - Feature com Gate 3 aprovado e **fechada** por `morph-spec finish --pr|--merge` (arquiva carimbando `status: "completed"` + `archivedAt`, integra e desmonta num passo) — ou, se legada, por `morph-spec archive`.
244
247
 
245
248
  ## Referências
246
249
 
@@ -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.4.0"
7
+ cliVersion: "8.5.0"
8
8
  ---
9
9
 
10
10
  # morph-brainstorming
@@ -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.4.0"
7
+ cliVersion: "8.5.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.4.0"
7
+ cliVersion: "8.5.0"
8
8
  ---
9
9
 
10
10
  # morph-hotfix
@@ -103,8 +103,8 @@ options:
103
103
  ### 8. Pós-gate (o "test loop → ship" de `MORPH.md` §2.1)
104
104
 
105
105
  - Rode a suíte completa uma vez: `morph-spec verify {feature}` (sem escopo de task — cobertura da feature inteira, agora que o Gate 3 está aprovado).
106
- - Sinalize ao usuário: commit do fix e `morph-spec archive {feature}` (ou `morph-spec worktree finish {feature}` se a feature nasceu em worktree — ver `MORPH.md` §2.2) estão prontos.
107
- - Não arquive automaticamente — usuário decide quando.
106
+ - Feche com `morph-spec finish {feature} --pr|--merge` — o mesmo encerramento único das demais features (arquiva commitando dentro de `morph/{f}`, integra, desmonta). Num hotfix urgente o `--merge` (local, direto na default) costuma ser o caminho; use `--pr` quando o fix precisa passar por CI/review antes do merge. Ver `MORPH.md` §2.2.
107
+ - Não integre automaticamente — o usuário decide quando e por qual modo (`finish` toca a default ou o remoto). Feature legada sem `morph/{f}`: `finish` roteia para `morph-spec archive {feature}`.
108
108
 
109
109
  ## Anti-padrões
110
110
 
@@ -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.4.0"
7
+ cliVersion: "8.5.0"
8
8
  ---
9
9
 
10
10
  # morph-implement
@@ -4,7 +4,7 @@ description: Guia a produção dos três artefatos de planejamento de uma featur
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.4.0"
7
+ cliVersion: "8.5.0"
8
8
  ---
9
9
 
10
10
  # morph-plan
@@ -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.4.0"
7
+ cliVersion: "8.5.0"
8
8
  ---
9
9
 
10
10
  # morph-proposal
@@ -4,7 +4,7 @@ description: Conduz a fase de revisão e produz o review-report.md para o Gate 3
4
4
  version: core
5
5
  when-to-invoke: ao iniciar a fase review, após todas as tasks de tasks.json estarem com status `done`
6
6
  user-invokable: true
7
- cliVersion: "8.4.0"
7
+ cliVersion: "8.5.0"
8
8
  ---
9
9
 
10
10
  # morph-review
@@ -102,7 +102,7 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
102
102
  question: "Gate 3 — Review de {feature} aprovado?{ reason ? ' Sinal: ' + reason : '' }"
103
103
  header: "Gate 3"
104
104
  options:
105
- - { label: "aprovado, fechar feature", description: "Marcar feature como completed, habilitar /morph-archive" }
105
+ - { label: "aprovado, fechar feature", description: "Marcar review aprovado; próximo passo é fechar com morph-spec finish --pr|--merge (ver morph-apply §6)" }
106
106
  - { label: "preciso ajustar", description: "Apontar correções necessárias antes de fechar" }
107
107
  - { label: "rollback", description: "Desfazer e voltar para implement" }
108
108
  ```
@@ -120,6 +120,8 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
120
120
 
121
121
  No caminho manual, o hook state-sync detecta a aprovação em answers de AskUserQuestion e grava `approvalGates.review = { approved: true, timestamp, approvedBy: "manual" }` no `feature.json` autoritativo da feature. Em auto sem AskUserQuestion, aprove via `morph-spec approve {feature} review --mode auto` — nunca via Edit à mão de state.json.
122
122
 
123
+ **Próximo passo (não é desta skill):** com o Gate 3 aprovado, a feature fecha por `morph-spec finish {feature} --pr|--merge` — a `morph-apply` §6 conduz a escolha PR vs merge. Não arquive nem integre aqui.
124
+
123
125
  ## Output esperado
124
126
  - `.morph/features/{feature}/4-review/evaluator-report.md` — relatório bruto e autoritativo do
125
127
  `morph-evaluator` despachado no passo 4 (canal durável, ver MORPH.md §6)
@@ -4,7 +4,7 @@ description: Varre o codebase existente, detecta stack atual, compara com o stac
4
4
  version: core
5
5
  when-to-invoke: ao iniciar uma feature em projeto brownfield (codebase já existente)
6
6
  user-invokable: true
7
- cliVersion: "8.4.0"
7
+ cliVersion: "8.5.0"
8
8
  ---
9
9
 
10
10
  # morph-stack-scan
@@ -4,7 +4,7 @@ description: Localiza e carrega um standard específico do STANDARDS.json sob de
4
4
  version: core
5
5
  when-to-invoke: quando precisar consultar um standard específico durante a implementação
6
6
  user-invokable: true
7
- cliVersion: "8.4.0"
7
+ cliVersion: "8.5.0"
8
8
  ---
9
9
 
10
10
  # morph-standards
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polymorphism-tech/morph-spec",
3
- "version": "8.4.0",
3
+ "version": "8.5.0",
4
4
  "description": "MORPH-SPEC: NLH (Natural Language Harness) for spec-driven development with Claude Code",
5
5
  "keywords": [
6
6
  "claude-code",