spec-first-copilot 0.6.0-beta.9 → 0.7.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 (57) hide show
  1. package/README.md +252 -167
  2. package/bin/cli.js +70 -70
  3. package/lib/init.js +92 -92
  4. package/lib/update.js +132 -132
  5. package/package.json +1 -1
  6. package/templates/.ai/memory/napkin.md +68 -68
  7. package/templates/.github/CHANGELOG.md +121 -0
  8. package/templates/.github/adapters/SETUP.md +314 -314
  9. package/templates/.github/adapters/confluence.md +295 -295
  10. package/templates/.github/adapters/errors.md +234 -234
  11. package/templates/.github/adapters/filesystem.md +353 -353
  12. package/templates/.github/adapters/interface.md +301 -301
  13. package/templates/.github/adapters/naming.md +241 -241
  14. package/templates/.github/adapters/registry.md +244 -244
  15. package/templates/.github/agents/backend-coder.md +14 -14
  16. package/templates/.github/agents/db-coder.md +165 -165
  17. package/templates/.github/agents/doc-writer.md +66 -53
  18. package/templates/.github/agents/frontend-coder.md +5 -5
  19. package/templates/.github/agents/infra-coder.md +341 -341
  20. package/templates/.github/agents/reviewer.md +6 -6
  21. package/templates/.github/agents/security-reviewer.md +153 -153
  22. package/templates/.github/copilot-instructions.md +272 -262
  23. package/templates/.github/instructions/docs.instructions.md +147 -145
  24. package/templates/.github/instructions/sensitive-files.instructions.md +32 -32
  25. package/templates/.github/rules.md +229 -229
  26. package/templates/.github/scripts/bootstrap-confluence.js +289 -223
  27. package/templates/.github/skills/sf-design/SKILL.md +161 -216
  28. package/templates/.github/skills/sf-dev/SKILL.md +204 -351
  29. package/templates/.github/skills/sf-discovery/SKILL.md +415 -414
  30. package/templates/.github/skills/sf-extract/SKILL.md +225 -249
  31. package/templates/.github/skills/sf-load/SKILL.md +296 -295
  32. package/templates/.github/skills/sf-mcp/SKILL.md +386 -385
  33. package/templates/.github/skills/sf-merge-docs/SKILL.md +152 -100
  34. package/templates/.github/skills/sf-plan/SKILL.md +152 -128
  35. package/templates/.github/skills/sf-publish/SKILL.md +144 -143
  36. package/templates/.github/skills/sf-session-finish/SKILL.md +93 -120
  37. package/templates/.github/skills/sf-start/SKILL.md +192 -145
  38. package/templates/.github/templates/estrutura/apiContracts.template.md +160 -159
  39. package/templates/.github/templates/estrutura/architecture.template.md +169 -168
  40. package/templates/.github/templates/estrutura/conventions.template.md +214 -212
  41. package/templates/.github/templates/estrutura/decisions.template.md +107 -107
  42. package/templates/.github/templates/estrutura/domain.template.md +161 -160
  43. package/templates/.github/templates/feature/PRD.template.md +279 -286
  44. package/templates/.github/templates/feature/Progresso.template.md +141 -141
  45. package/templates/.github/templates/feature/TRD.template.md +358 -0
  46. package/templates/.github/templates/feature/context.template.md +89 -48
  47. package/templates/.github/templates/feature/extract-log.template.md +49 -39
  48. package/templates/.github/templates/feature/projetos.template.yaml +79 -79
  49. package/templates/.github/templates/global/progresso_global.template.md +59 -57
  50. package/templates/.github/templates/specs/brief.template.md +66 -59
  51. package/templates/.github/templates/specs/contracts.template.md +147 -141
  52. package/templates/.github/templates/specs/scenarios.template.md +125 -117
  53. package/templates/.github/templates/specs/tasks.template.md +65 -63
  54. package/templates/_gitignore +35 -35
  55. package/templates/sfw.config.yml.example +147 -147
  56. package/templates/.github/templates/feature/backlog-extraido.template.md +0 -156
  57. package/templates/.github/templates/feature/sdd.template.md +0 -559
@@ -1,143 +1,144 @@
1
- # /sf-publish <nome> <tipo>
2
-
3
- Publica um artefato gerado localmente no(s) backend(s) configurado(s) como `output.targets[]` no `sfw.config.yml`.
4
-
5
- ## Argumentos
6
-
7
- - `<nome>` = scope do artefato (ex: `app_barbearia`, `feat_login`)
8
- - `<tipo>` = tipo do artefato: `PRD` | `SDD` | `Progresso`
9
-
10
- ## Quando é chamado
11
-
12
- Automaticamente pelos commands:
13
- - `/sf-extract` → publica `PRD` no fim
14
- - `/sf-design` → publica `SDD` no fim
15
- - `/sf-plan` → publica `Progresso` no fim
16
-
17
- Manualmente: quando o usuário quer re-publicar um artefato após editar local.
18
-
19
- ## Modo (`mode` no sfw.config.yml)
20
-
21
- | Mode | Comportamento |
22
- |------|---------------|
23
- | `auto` | Publica sem perguntar (default) |
24
- | `manual` | Gera artefato local, pergunta "Publicar no {target.name}? (s/n)" |
25
- | `off` | Ignora o target completamente |
26
-
27
- ## Pré-condições
28
-
29
- | # | Validação | Se falhar |
30
- |---|-----------|-----------|
31
- | 1 | `sfw.config.yml` existe | Parar → "Sem sfw.config.yml, publish desabilitado. Artefato local está em workspace/Output/{nome}/{tipo}.md" |
32
- | 2 | Tipo está na `publishes` do target | Pular target, informar |
33
- | 3 | Arquivo local existe em `workspace/Output/{nome}/{tipo}.md` (ou .lower) | Parar "Arquivo não encontrado" |
34
-
35
- ## Execução
36
-
37
- ### 1. Carregar configuração
38
-
39
- - Ler `sfw.config.yml`
40
- - Para cada target em `output.targets[]`:
41
- - Verificar `mode` (se `off` → pular)
42
- - Verificar `publishes` inclui `<tipo>` (se não → pular)
43
- - Se `mode: manual` perguntar ao usuário
44
-
45
- ### 2. Ler artefato local
46
-
47
- Ler `workspace/Output/{nome}/{arquivo}` onde arquivo depende do tipo:
48
- - `PRD` `PRD.md`
49
- - `SDD` → `sdd.md`
50
- - `Progresso` → `Progresso.md`
51
-
52
- ### 3. Aplicar naming
53
-
54
- Usar templates do `naming` no `sfw.config.yml`:
55
- - `containerTitle = applyNaming(naming.output_container, {scope: nome})`
56
- - Ex: `"out_app_barbearia"`
57
- - `artifactTitle = applyNaming(naming.output_artifact, {scope: nome, type: tipo})`
58
- - Ex: `"app_barbearia - PRD"`
59
-
60
- ### 4. Para cada target ativo — publicar
61
-
62
- **Confluence**:
63
-
64
- 1. Listar filhos de `target.config.parent_page_id` (Output)
65
- 2. Buscar container pelo `containerTitle`:
66
- - **Não existe** `mcp__atlassian__confluence_create_page` como filho de Output
67
- - **Existe** → pegar `container.id`
68
- 3. Listar filhos do container
69
- 4. Buscar artefato pelo `artifactTitle`:
70
- - **Não existe** `mcp__atlassian__confluence_create_page` com `content=markdown local`
71
- - **Existe** → precisa atualizar (próximo passo)
72
-
73
- ### 5. Conflict detection (update)
74
-
75
- Se artefato existe no backend:
76
-
77
- 1. Ler `.ai/sf-publish-log.md` pra pegar a última `version` publicada desse artefato
78
- 2. Chamar `mcp__atlassian__confluence_get_page(page_id=artifact.id)` pega `currentVersion`
79
- 3. **Se `currentVersion != lastPublishedVersion`** DRIFT detectado
80
- - Alguém editou no Confluence depois do último publish
81
- - Mostrar ao usuário:
82
- ```
83
- CONFLITO: "{artifactTitle}" foi editada no Confluence desde o último publish.
84
-
85
- Última version publicada por nós: {last}
86
- Version atual no Confluence: {current}
87
-
88
- Opções:
89
- 1. Sobrescrever (perde edição manual)
90
- 2. Abortar (edita local depois)
91
- 3. Ver diff
92
- ```
93
- - Esperar decisão
94
- 4. Se sem drift → `mcp__atlassian__confluence_update_page(page_id, content)`
95
- 5. Ler nova `version` retornada
96
-
97
- ### 6. Registrar em `.ai/sf-publish-log.md`
98
-
99
- Formato append-only:
100
-
101
- ```markdown
102
- ## Publish: {nome} {tipo} — {ISO_DATETIME}
103
-
104
- | Target | Container | Artifact ID | Version | Status |
105
- |--------|-----------|-------------|---------|--------|
106
- | confluence-mirror | out_app_barbearia (393220) | 393238 | 3 | UPDATED |
107
- ```
108
-
109
- Status: `CREATED`, `UPDATED`, `SKIPPED` (se INALTERADO), `CONFLICT` (se drift não resolvido)
110
-
111
- ### 7. Informar o usuário
112
-
113
- ```
114
- Publicado: {nome} {tipo}
115
-
116
- confluence-mirror: app_barbearia - PRD (v3) — UPDATED
117
-
118
- Link: https://empresa.atlassian.net/wiki/spaces/ST/pages/393238
119
- ```
120
-
121
- ## Erros
122
-
123
- | Erro | Ação |
124
- |------|------|
125
- | `sfw.config.yml` não existe | Skippa todos os targets, só salva local |
126
- | Target MCP não disponível | Avisar, pular target |
127
- | Sem permissão de escrita | Avisar, pular target |
128
- | Conflict não resolvido | Não publicar, salvar como CONFLICT no log |
129
- | Container Output não existe | Criar automaticamente como filho de `output.parent_page_id` |
130
-
131
- ## Notas
132
-
133
- - O `/sf-publish` é **idempotente** pra content sem mudanças — detecta hash igual e marca `SKIPPED`
134
- - `naming.output_container` e `naming.output_artifact` são aplicados em TODOS os targets
135
- - Cada target pode ter `publishes: []` diferente (permite segmentar: Confluence recebe 4 artefatos, filesystem recebe todos)
136
- - `.ai/sf-publish-log.md` é essencial pro conflict detection funcionar
137
- - Nunca publica tasks.md, docs/, specs/, projetos.yaml esses são LOCAL ONLY
138
-
139
- ## Referências
140
-
141
- - Adapter interface: `.github/adapters/interface.md`
142
- - Confluence adapter: `.github/adapters/confluence.md`
143
- - Naming engine: `.github/adapters/naming.md`
1
+
2
+ # /sf-publish <nome> <tipo>
3
+
4
+ Publica um artefato gerado localmente no(s) backend(s) configurado(s) como `output.targets[]` no `sfw.config.yml`.
5
+
6
+ ## Argumentos
7
+
8
+ - `<nome>` = scope do artefato (ex: `app_barbearia`, `feat_login`)
9
+ - `<tipo>` = tipo do artefato: `PRD` | `TRD` | `Progresso`
10
+
11
+ ## Quando é chamado
12
+
13
+ Automaticamente pelos commands:
14
+ - `/sf-extract` → publica `PRD` (se `prd_existe=true`) E `TRD` (se `trd_existe=true`)
15
+ - `/sf-plan` → publica `Progresso` no fim
16
+ - `/sf-design` → **não publica** (gera apenas artefatos locais: docs/, specs/, projetos.yaml)
17
+
18
+ Manualmente: quando o usuário quer re-publicar um artefato após editar local.
19
+
20
+ ## Modo (`mode` no sfw.config.yml)
21
+
22
+ | Mode | Comportamento |
23
+ |------|---------------|
24
+ | `auto` | Publica sem perguntar (default) |
25
+ | `manual` | Gera artefato local, pergunta "Publicar no {target.name}? (s/n)" |
26
+ | `off` | Ignora o target completamente |
27
+
28
+ ## Pré-condições
29
+
30
+ | # | Validação | Se falhar |
31
+ |---|-----------|-----------|
32
+ | 1 | `sfw.config.yml` existe | Parar → "Sem sfw.config.yml, publish desabilitado. Artefato local está em workspace/Output/{nome}/{tipo}.md" |
33
+ | 2 | Tipo está na `publishes` do target | Pular target, informar |
34
+ | 3 | Arquivo local existe em `workspace/Output/{nome}/{tipo}.md` (ou .lower) | Parar → "Arquivo não encontrado" |
35
+
36
+ ## Execução
37
+
38
+ ### 1. Carregar configuração
39
+
40
+ - Ler `sfw.config.yml`
41
+ - Para cada target em `output.targets[]`:
42
+ - Verificar `mode` (se `off` → pular)
43
+ - Verificar `publishes` inclui `<tipo>` (se não → pular)
44
+ - Se `mode: manual` → perguntar ao usuário
45
+
46
+ ### 2. Ler artefato local
47
+
48
+ Ler `workspace/Output/{nome}/{arquivo}` onde arquivo depende do tipo:
49
+ - `PRD` → `PRD.md`
50
+ - `TRD` → `TRD.md`
51
+ - `Progresso` → `Progresso.md`
52
+
53
+ ### 3. Aplicar naming
54
+
55
+ Usar templates do `naming` no `sfw.config.yml`:
56
+ - `containerTitle = applyNaming(naming.output_container, {scope: nome})`
57
+ - Ex: `"out_app_barbearia"`
58
+ - `artifactTitle = applyNaming(naming.output_artifact, {scope: nome, type: tipo})`
59
+ - Ex: `"app_barbearia - PRD"`
60
+
61
+ ### 4. Para cada target ativo — publicar
62
+
63
+ **Confluence**:
64
+
65
+ 1. Listar filhos de `target.config.parent_page_id` (Output)
66
+ 2. Buscar container pelo `containerTitle`:
67
+ - **Não existe** → `mcp__atlassian__confluence_create_page` como filho de Output
68
+ - **Existe** pegar `container.id`
69
+ 3. Listar filhos do container
70
+ 4. Buscar artefato pelo `artifactTitle`:
71
+ - **Não existe** → `mcp__atlassian__confluence_create_page` com `content=markdown local`
72
+ - **Existe** → precisa atualizar (próximo passo)
73
+
74
+ ### 5. Conflict detection (update)
75
+
76
+ Se artefato existe no backend:
77
+
78
+ 1. Ler `.ai/publish-log.md` pra pegar a última `version` publicada desse artefato
79
+ 2. Chamar `mcp__atlassian__confluence_get_page(page_id=artifact.id)`pega `currentVersion`
80
+ 3. **Se `currentVersion != lastPublishedVersion`** DRIFT detectado
81
+ - Alguém editou no Confluence depois do último publish
82
+ - Mostrar ao usuário:
83
+ ```
84
+ CONFLITO: "{artifactTitle}" foi editada no Confluence desde o último publish.
85
+
86
+ Última version publicada por nós: {last}
87
+ Version atual no Confluence: {current}
88
+
89
+ Opções:
90
+ 1. Sobrescrever (perde edição manual)
91
+ 2. Abortar (edita local depois)
92
+ 3. Ver diff
93
+ ```
94
+ - Esperar decisão
95
+ 4. Se sem drift → `mcp__atlassian__confluence_update_page(page_id, content)`
96
+ 5. Ler nova `version` retornada
97
+
98
+ ### 6. Registrar em `.ai/publish-log.md`
99
+
100
+ Formato append-only:
101
+
102
+ ```markdown
103
+ ## Publish: {nome} {tipo} — {ISO_DATETIME}
104
+
105
+ | Target | Container | Artifact ID | Version | Status |
106
+ |--------|-----------|-------------|---------|--------|
107
+ | confluence-mirror | out_app_barbearia (393220) | 393238 | 3 | UPDATED |
108
+ ```
109
+
110
+ Status: `CREATED`, `UPDATED`, `SKIPPED` (se INALTERADO), `CONFLICT` (se drift não resolvido)
111
+
112
+ ### 7. Informar o usuário
113
+
114
+ ```
115
+ Publicado: {nome} {tipo}
116
+
117
+ confluence-mirror: app_barbearia - PRD (v3) — UPDATED
118
+
119
+ Link: https://empresa.atlassian.net/wiki/spaces/ST/pages/393238
120
+ ```
121
+
122
+ ## Erros
123
+
124
+ | Erro | Ação |
125
+ |------|------|
126
+ | `sfw.config.yml` não existe | Skippa todos os targets, salva local |
127
+ | Target MCP não disponível | Avisar, pular target |
128
+ | Sem permissão de escrita | Avisar, pular target |
129
+ | Conflict não resolvido | Não publicar, salvar como CONFLICT no log |
130
+ | Container Output não existe | Criar automaticamente como filho de `output.parent_page_id` |
131
+
132
+ ## Notas
133
+
134
+ - O `/sf-publish` é **idempotente** pra content sem mudanças detecta hash igual e marca `SKIPPED`
135
+ - `naming.output_container` e `naming.output_artifact` são aplicados em TODOS os targets
136
+ - Cada target pode ter `publishes: []` diferente (permite segmentar: Confluence recebe 4 artefatos, filesystem recebe todos)
137
+ - `.ai/publish-log.md` é essencial pro conflict detection funcionar
138
+ - Nunca publica tasks.md, docs/, specs/, projetos.yaml — esses são LOCAL ONLY
139
+
140
+ ## Referências
141
+
142
+ - Adapter interface: `.github/adapters/interface.md`
143
+ - Confluence adapter: `.github/adapters/confluence.md`
144
+ - Naming engine: `.github/adapters/naming.md`
@@ -1,120 +1,93 @@
1
- ---
2
- name: sf-session-finish
3
- description: |
4
- Encerrar sessão. Salva estado, atualiza napkin, gera retomada.md.
5
- Trigger: /sf-session-finish
6
- author: GustavoMaritan
7
- version: 1.0.0
8
- date: 2026-04-08
9
- ---
10
-
11
- # Skill: /sf-session-finish
12
-
13
- > Encerra a sessão de trabalho de forma organizada.
14
- > Consolida estado, atualiza memória, gera ponto de retomada para a próxima sessão.
15
-
16
- ## Tipo
17
- Utilitária — roda a qualquer momento
18
-
19
- ## Uso
20
- ```
21
- /sf-session-finish
22
- ```
23
-
24
- ---
25
-
26
- ## Passos
27
-
28
- ### 1. Levantar estado atual de cada feature/setup
29
-
30
- Para cada `.context.md` em `workspace/Output/*/`:
31
- - Ler status atual
32
- - Ler Progresso.md (se existir)% concluído, fase atual
33
- - Identificar tasks em andamento (`- [ ]` com dependências resolvidas)
34
-
35
- ### 2. Verificar working tree dos repos
36
-
37
- Para cada repo em `projetos/`:
38
- ```bash
39
- cd projetos/{repo}
40
- git status --short
41
- git log --oneline -3
42
- ```
43
- - Listar mudanças não commitadas
44
- - Listar branches ativas
45
- - Se working tree sujo → avisar (sugerir commit antes de pausar)
46
-
47
- ### 3. Atualizar `.ai/memory/napkin.md`
48
-
49
- Adicionar/atualizar seção `## Sessão Atual` com:
50
- - Data da sessão
51
- - O que foi feito (tasks concluídas, fases entregues)
52
- - O que estava em andamento (task atual, bloqueios)
53
- - Decisões tomadas durante a sessão
54
- - Armadilhas encontradas (se houver novos aprendizados)
55
-
56
- ### 4. Gerar resumo de retomada
57
-
58
- Criar/atualizar `workspace/Output/retomada.md`:
59
-
60
- ```markdown
61
- # Ponto de Retomada {{DATA}}
62
-
63
- > Gerado pelo /sf-session-finish. Leia este arquivo ao iniciar a próxima sessão.
64
-
65
- ## Estado geral
66
-
67
- | Feature/Setup | Status | Fase atual | % | Próxima ação |
68
- |---------------|--------|------------|---|-------------|
69
- | {{nome}} | {{status}} | Fase {{N}} | {{%}} | {{ação}} |
70
-
71
- ## Reposestado do git
72
-
73
- | Repo | Branch ativa | Working tree | Último commit |
74
- |------|-------------|-------------|---------------|
75
- | {{repo}} | {{branch}} | limpo/sujo | {{commit msg}} |
76
-
77
- ## O que estava em andamento
78
-
79
- - Task: {{AREA-NNN}} — {{descrição}}
80
- - Bloqueios: {{se houver}}
81
- - Decisões pendentes: {{se houver}}
82
-
83
- ## Para retomar
84
-
85
- 1. {{Passo 1 — ex: "Subir infra: docker compose up -d"}}
86
- 2. {{Passo 2 — ex: "Continuar /sf-dev feat_mvp --fase 2"}}
87
- 3. {{Passo 3 ex: "Resolver ambiguidade X do PRD"}}
88
-
89
- ## Aprendizados desta sessão
90
-
91
- - {{Decisão ou armadilha que vale registrar}}
92
- ```
93
-
94
- ### 5. Informar ao usuário
95
-
96
- ```
97
- ✅ Sessão encerrada. Estado salvo em:
98
- - `.ai/memory/napkin.md` — memória atualizada
99
- - `workspace/Output/retomada.md` — ponto de retomada
100
-
101
- Para retomar na próxima sessão:
102
- 1. Ler retomada.md
103
- 2. Seguir os passos listados em "Para retomar"
104
- ```
105
-
106
- ---
107
-
108
- ## Saídas
109
-
110
- | Arquivo | Descrição |
111
- |---------|-----------|
112
- | `.ai/memory/napkin.md` | Sessão atual atualizada |
113
- | `workspace/Output/retomada.md` | Ponto de retomada com estado completo |
114
-
115
- ## Notas
116
-
117
- - Não modifica .context.md (o status da pipeline não muda ao pausar)
118
- - Não faz commit automático — se tem working tree sujo, avisa mas não força
119
- - Pode ser chamada a qualquer momento, não só no final do dia
120
- - O arquivo `retomada.md` é sobrescrito a cada /sf-session-finish (é ponto atual, não histórico)
1
+ ---
2
+ name: sf-session-finish
3
+ description: |
4
+ Encerrar sessão. Salva estado, atualiza napkin, gera retomada.md.
5
+ Trigger: /sf-session-finish
6
+ author: GustavoMaritan
7
+ version: 1.0.0
8
+ date: 2026-04-08
9
+ ---
10
+
11
+ # /sf-session-finish
12
+
13
+ Encerra a sessão de trabalho de forma organizada.
14
+ Consolida estado, atualiza memória, gera ponto de retomada para a próxima sessão.
15
+
16
+ ## Passos
17
+
18
+ ### 1. Levantar estado atual
19
+
20
+ Para cada `.context.md` em `workspace/Output/*/`:
21
+ - Status atual + Progresso.md (% concluído, fase atual)
22
+ - Tasks em andamento
23
+
24
+ ### 2. Verificar working tree dos repos
25
+
26
+ Para cada repo em `projetos/`:
27
+ ```bash
28
+ cd projetos/{repo}
29
+ git status --short
30
+ git log --oneline -3
31
+ ```
32
+ - Se working tree sujoavisar (sugerir commit antes de pausar)
33
+
34
+ ### 3. Atualizar `.ai/memory/napkin.md`
35
+
36
+ Atualizar seção `## Sessão Atual` com:
37
+ - Data, o que foi feito, o que estava em andamento
38
+ - Decisões tomadas, armadilhas encontradas
39
+
40
+ ### 4. Gerar resumo de retomada
41
+
42
+ Criar/atualizar `workspace/Output/retomada.md`:
43
+
44
+ ```markdown
45
+ # Ponto de Retomada {{DATA}}
46
+
47
+ > Gerado pelo /sf-session-finish. Leia este arquivo ao iniciar a próxima sessão.
48
+
49
+ ## Estado geral
50
+
51
+ | Feature/Setup | Status | Fase atual | % | Próxima ação |
52
+ |---------------|--------|------------|---|-------------|
53
+ | {{nome}} | {{status}} | Fase {{N}} | {{%}} | {{ação}} |
54
+
55
+ ## Repos — estado do git
56
+
57
+ | Repo | Branch ativa | Working tree | Último commit |
58
+ |------|-------------|-------------|---------------|
59
+ | {{repo}} | {{branch}} | limpo/sujo | {{commit msg}} |
60
+
61
+ ## O que estava em andamento
62
+
63
+ - Task: {{AREA-NNN}} {{descrição}}
64
+ - Bloqueios: {{se houver}}
65
+ - Decisões pendentes: {{se houver}}
66
+
67
+ ## Para retomar
68
+
69
+ 1. {{Passo 1 ex: "Subir infra: docker compose up -d"}}
70
+ 2. {{Passo 2 — ex: "Continuar /sf-dev feat_mvp --fase 2"}}
71
+ 3. {{Passo 3 ex: "Resolver ambiguidade X do PRD"}}
72
+
73
+ ## Aprendizados desta sessão
74
+
75
+ - {{Decisão ou armadilha que vale registrar}}
76
+ ```
77
+
78
+ ### 5. Informar ao usuário
79
+
80
+ ```
81
+ Sessão encerrada. Estado salvo em:
82
+ - `.ai/memory/napkin.md` — memória atualizada
83
+ - `workspace/Output/retomada.md` — ponto de retomada
84
+
85
+ Para retomar:
86
+ 1. Ler retomada.md
87
+ 2. Seguir os passos listados
88
+ ```
89
+
90
+ ## Notas
91
+ - Não modifica .context.md (status da pipeline não muda)
92
+ - Não faz commit automático — avisa se working tree sujo
93
+ - `retomada.md` é sobrescrito a cada /sf-session-finish (ponto atual, não histórico)