spec-first-copilot 0.5.0-beta.17 → 0.5.0-beta.19
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/package.json +1 -1
- package/templates/.github/copilot-instructions.md +4 -2
- package/templates/.github/skills/sf-design/SKILL.md +132 -209
- package/templates/.github/skills/sf-extract/SKILL.md +99 -237
- package/templates/.github/skills/sf-load/SKILL.md +22 -2
- package/templates/.github/skills/sf-plan/SKILL.md +104 -180
- package/templates/.github/skills/sf-publish/SKILL.md +144 -0
package/package.json
CHANGED
|
@@ -20,12 +20,13 @@
|
|
|
20
20
|
|
|
21
21
|
### 2. Validar acesso a todas skills
|
|
22
22
|
|
|
23
|
-
Verificar que TODAS as
|
|
23
|
+
Verificar que TODAS as 12 skills estão acessíveis:
|
|
24
24
|
|
|
25
25
|
| Skill | Caminho |
|
|
26
26
|
|-------|---------|
|
|
27
27
|
| `/sf-mcp` | `.github/skills/sf-mcp/SKILL.md` |
|
|
28
28
|
| `/sf-load` | `.github/skills/sf-load/SKILL.md` |
|
|
29
|
+
| `/sf-publish` | `.github/skills/sf-publish/SKILL.md` |
|
|
29
30
|
| `/sf-new-project` | `.github/skills/sf-new-project/SKILL.md` |
|
|
30
31
|
| `/sf-feature` | `.github/skills/sf-feature/SKILL.md` |
|
|
31
32
|
| `/sf-extract` | `.github/skills/sf-extract/SKILL.md` |
|
|
@@ -98,7 +99,8 @@ Nenhum código é escrito sem especificação aprovada (SDD).
|
|
|
98
99
|
| Skill | Tipo | O que faz |
|
|
99
100
|
|-------|------|-----------|
|
|
100
101
|
| `/sf-mcp <provider>` | Setup | Configura backend externo interativamente. Cria .mcp.json + sfw.config.yml + ajusta .gitignore |
|
|
101
|
-
| `/sf-load <nome
|
|
102
|
+
| `/sf-load <nome> \| --all` | Utilitária | Puxa Input + Output do backend. Incremental |
|
|
103
|
+
| `/sf-publish <nome> <tipo>` | Utilitária | Publica artefato (PRD/TRD/SDD/Progresso) nos output.targets[]. Chamado auto por extract/design/plan |
|
|
102
104
|
| `/sf-new-project <nome>` | Orquestrador | Bootstrap técnico: cria .context.md tipo TRD, chama /sf-extract, para no checkpoint |
|
|
103
105
|
| `/sf-feature <nome>` | Orquestrador | Feature: cria .context.md tipo PRD, chama /sf-extract, para no checkpoint |
|
|
104
106
|
| `/sf-extract <nome>` | Atômica | Lê workspace/Input/{nome}/ → gera PRD ou TRD. Re-executável para novos insumos |
|
|
@@ -1,209 +1,132 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
|
40
|
-
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
- Se
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
**Regras de geração:**
|
|
135
|
-
1. SDD deve ser **auto-contido** — o coder lê APENAS o SDD + task, nunca PRD/PM
|
|
136
|
-
2. Toda regra/entidade referencia seção do PRD/TRD (rastreabilidade)
|
|
137
|
-
3. Seções não aplicáveis marcadas `N/A — [motivo]` (ex: §6 em setup sem UI)
|
|
138
|
-
4. Contratos de API com JSON schema completo (request, response, erros)
|
|
139
|
-
5. Modelo de dados com tipos exatos, não genéricos (varchar(255), não "string")
|
|
140
|
-
6. Critérios de aceite testáveis — Given/When/Then, não frases vagas
|
|
141
|
-
7. Delta Specs sempre preenchida, mesmo que vazia (ADDED: nenhum)
|
|
142
|
-
|
|
143
|
-
### 6. Complementar decisions.md (setup — complemento do passo 3)
|
|
144
|
-
Após gerar SDD §2, popular `decisions.md` com as decisões iniciais de arquitetura
|
|
145
|
-
(stack principal, padrões de design, trade-offs significativos).
|
|
146
|
-
|
|
147
|
-
### 7. Projetar SDD em `specs/{nome}/` (sempre)
|
|
148
|
-
|
|
149
|
-
Após gerar/atualizar o SDD, criar/sobrescrever os 4 arquivos de spec estruturado
|
|
150
|
-
em `specs/{nome}/` como **projeções do SDD** pro coder consumir:
|
|
151
|
-
|
|
152
|
-
| Arquivo | Projeção de |
|
|
153
|
-
|---------|-------------|
|
|
154
|
-
| `brief.md` | SDD §1 Visão + §2 Decisões + §10 Fora do escopo |
|
|
155
|
-
| `contracts.md` | SDD §3 Modelo de dados + §4 Regras/validações + §5 Endpoints + §8 Integrações |
|
|
156
|
-
| `scenarios.md` | SDD §6 Componentes/telas + §7 Fluxos + §9 Estratégia de testes + Critérios de aceite |
|
|
157
|
-
| `tasks.md` | (stub vazio — será preenchido pelo /sf-plan) |
|
|
158
|
-
|
|
159
|
-
**Regras:**
|
|
160
|
-
- Os 4 arquivos são **projeções regeneráveis** — re-rodar /sf-design sobrescreve
|
|
161
|
-
- NÃO editar direto em `specs/` — fonte de verdade é o SDD em `workspace/Output/`
|
|
162
|
-
- Templates em `.github/templates/specs/` (brief/contracts/scenarios/tasks)
|
|
163
|
-
- Coders e Reviewer leem daqui, NUNCA do SDD direto
|
|
164
|
-
- Se o SDD tem seções N/A, refletir N/A nas projeções também
|
|
165
|
-
|
|
166
|
-
**Criação:**
|
|
167
|
-
- Criar diretório `specs/{nome}/` se não existir
|
|
168
|
-
- Para cada arquivo, ler template correspondente → preencher com projeção do SDD → remover bloco `<!-- INSTRUÇÕES -->`
|
|
169
|
-
- `tasks.md` é apenas stub na saída do /sf-design — o /sf-plan preenche
|
|
170
|
-
|
|
171
|
-
### 8. Atualizar `.context.md`
|
|
172
|
-
```yaml
|
|
173
|
-
status: "design_done"
|
|
174
|
-
ultima_skill: "/sf-design"
|
|
175
|
-
atualizado_em: "{{ISO_DATETIME}}"
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
---
|
|
179
|
-
|
|
180
|
-
## Saídas
|
|
181
|
-
|
|
182
|
-
| Arquivo | Descrição |
|
|
183
|
-
|---------|-----------|
|
|
184
|
-
| `workspace/Output/{nome}/sdd.md` | Especificação técnica narrativa (para humano) |
|
|
185
|
-
| `specs/{nome}/brief.md` | Projeção do SDD — Problema/Solução/Escopo (para agent) |
|
|
186
|
-
| `specs/{nome}/contracts.md` | Projeção do SDD — Dados, API, Integrações, Regras (para agent) |
|
|
187
|
-
| `specs/{nome}/scenarios.md` | Projeção do SDD — Fluxos, UI, CAs (para agent) |
|
|
188
|
-
| `specs/{nome}/tasks.md` | Stub — preenchido pelo /sf-plan |
|
|
189
|
-
| `projetos.yaml` | (setup) Manifesto de repos — mapeamento serviço → repo → áreas |
|
|
190
|
-
| `docs/*.md` | (setup) 5 docs globais preenchidos do TRD (architecture, domain, conventions, apiContracts, decisions) |
|
|
191
|
-
| `.context.md` | Atualizado: `approved` → `design_done` |
|
|
192
|
-
|
|
193
|
-
## Pós-condições
|
|
194
|
-
- SDD (humano, em `workspace/Output/`) é fonte única narrativa
|
|
195
|
-
- `specs/{nome}/` é projeção estruturada pro agent — nunca editado manualmente
|
|
196
|
-
- Coder/Reviewer leem exclusivamente `specs/{nome}/`, não o SDD
|
|
197
|
-
- Rastreabilidade: specs → SDD → PRD/TRD → insumos
|
|
198
|
-
|
|
199
|
-
## Erros
|
|
200
|
-
|
|
201
|
-
| Erro | Ação |
|
|
202
|
-
|------|------|
|
|
203
|
-
| Nome não informado | Parar, mostrar exemplo |
|
|
204
|
-
| Status anterior a extract_done | Parar, sugerir /sf-extract |
|
|
205
|
-
| Status posterior a approved | Informar que SDD já foi gerado |
|
|
206
|
-
| Ambiguidades pendentes no PRD/TRD | Parar, listar ambiguidades |
|
|
207
|
-
| PRD/TRD não encontrado | Parar, sugerir /sf-extract |
|
|
208
|
-
| docs/ vazio (em features) | Parar, sugerir /sf-setup-projeto |
|
|
209
|
-
| Informação insuficiente no PRD/TRD para gerar seção | NÃO inventar — marcar seção como incompleta, reportar ao usuário |
|
|
1
|
+
# /sf-design $ARGUMENTS
|
|
2
|
+
|
|
3
|
+
Skill atômica de design. Lê PRD/TRD aprovado e gera SDD.
|
|
4
|
+
$ARGUMENTS = nome (ex: setup_projeto, feat_cadastro_cliente)
|
|
5
|
+
|
|
6
|
+
## Agente: Architect (Opus)
|
|
7
|
+
Técnico e preciso. Gera contratos completos. Toda decisão tem justificativa.
|
|
8
|
+
|
|
9
|
+
## Pré-condições
|
|
10
|
+
|
|
11
|
+
| # | Validação | Se falhar |
|
|
12
|
+
|---|-----------|-----------|
|
|
13
|
+
| 1 | $ARGUMENTS informado | Parar |
|
|
14
|
+
| 2 | `.context.md` existe com status `extract_done` ou `approved` | Se anterior → "/sf-extract primeiro". Se posterior → "SDD já gerado" |
|
|
15
|
+
| 3 | PRD.md ou TRD.md existe | Parar → "/sf-extract primeiro" |
|
|
16
|
+
| 4 | `docs/` populado (para features) | Parar → "/setup-projeto primeiro" (não aplica para tipo=setup) |
|
|
17
|
+
|
|
18
|
+
## Passos
|
|
19
|
+
|
|
20
|
+
### 1. Checkpoint de aprovação
|
|
21
|
+
Se status é `extract_done`:
|
|
22
|
+
- Perguntar: "O PRD/TRD foi revisado e está aprovado? (s/n)"
|
|
23
|
+
- Se SIM → atualizar .context.md para `approved` → continuar
|
|
24
|
+
- Se NÃO → parar
|
|
25
|
+
|
|
26
|
+
### 2. Verificar ambiguidades
|
|
27
|
+
- Ler seção de ambiguidades (§13 PRD / §9 TRD)
|
|
28
|
+
- Se há perguntas sem resposta → PARAR, listar pendentes
|
|
29
|
+
|
|
30
|
+
### 3. Gerar docs/ (APENAS para setup)
|
|
31
|
+
|
|
32
|
+
> Este passo só executa quando tipo=setup. Para features, docs/ já existe.
|
|
33
|
+
|
|
34
|
+
Ler TRD e gerar os 5 docs de `docs/` usando os templates correspondentes:
|
|
35
|
+
|
|
36
|
+
| Doc gerado | Fontes (TRD) | Template |
|
|
37
|
+
|-----------|--------------|---------|
|
|
38
|
+
| architecture.md | §3 Arquitetura + §2 Stack + §6 Infra (ambientes, deploy, CI/CD, rollback) | `.claude/templates/estrutura/architecture.template.md` |
|
|
39
|
+
| domain.md | §1 Visão + §4 Modelo de Dados | `.claude/templates/estrutura/domain.template.md` |
|
|
40
|
+
| conventions.md | §7 Segurança + §6 Infra (env vars, domínios, monitoramento) + §5 API (códigos de erro de domínio) + §2 Stack (alternativas, versionamento) | `.claude/templates/estrutura/conventions.template.md` |
|
|
41
|
+
| apiContracts.md | §5 API (padrão geral, rotas, paginação, filtros, erros, catálogo) | `.claude/templates/estrutura/apiContracts.template.md` |
|
|
42
|
+
| decisions.md | SDD §2 Decisões (após gerar) + decisões iniciais de stack/arquitetura | `.claude/templates/estrutura/decisions.template.md` |
|
|
43
|
+
|
|
44
|
+
Regras:
|
|
45
|
+
- Ler template → preencher TODAS seções com dados do TRD
|
|
46
|
+
- Remover bloco `<!-- INSTRUÇÕES -->` do doc gerado
|
|
47
|
+
- Changelog inicia vazio (primeira geração)
|
|
48
|
+
- Se TRD não tem dados pra uma seção → marcar "A definir"
|
|
49
|
+
- decisions.md é gerado APÓS o SDD (usa §2 Decisões de Design como ponto de partida)
|
|
50
|
+
- TRD §8 Módulos NÃO vira doc de Estrutura — vai para backlog faseado
|
|
51
|
+
|
|
52
|
+
### 3b. Gerar `projetos.yaml` (APENAS para setup)
|
|
53
|
+
|
|
54
|
+
Mapeia a arquitetura do TRD §3 para repositórios independentes.
|
|
55
|
+
Cada serviço = 1 repo. Os repos serão criados/clonados pelo /sf-dev (INFRA-001).
|
|
56
|
+
|
|
57
|
+
1. Identificar serviços separados no TRD §3 (api, worker, web, mobile, etc.)
|
|
58
|
+
2. Perguntar ao usuário:
|
|
59
|
+
- Organização/usuário do GitHub (ex: `empresa`)
|
|
60
|
+
- Nome base do projeto (ex: `meu-projeto`)
|
|
61
|
+
- Se algum repo já existe (para clonar em vez de criar)
|
|
62
|
+
3. Gerar `projetos.yaml` na raiz usando template `projetos.template.yaml`
|
|
63
|
+
4. Mapear áreas de task para repos:
|
|
64
|
+
- BACK → api (ou worker, se separado)
|
|
65
|
+
- BANCO → api (se usa EF migrations) ou repo próprio
|
|
66
|
+
- FRONT → web
|
|
67
|
+
- MOBILE → mobile
|
|
68
|
+
- INFRA → todos (cross-repo)
|
|
69
|
+
5. Validar: cada área DEVE mapear para exatamente 1 repo
|
|
70
|
+
|
|
71
|
+
**Regra**: Se o TRD indica API e Worker como serviços separados, DEVEM ser repos separados.
|
|
72
|
+
Nunca juntar serviços que o TRD definiu como distintos.
|
|
73
|
+
|
|
74
|
+
### 4. Carregar contexto
|
|
75
|
+
- PRD.md ou TRD.md completo
|
|
76
|
+
- `docs/` (agora já populado, mesmo no setup)
|
|
77
|
+
- `.claude/rules.md`
|
|
78
|
+
- Template `sdd.template.md`
|
|
79
|
+
|
|
80
|
+
### 5. Gerar SDD
|
|
81
|
+
11 seções obrigatórias (usar template). Para cada seção:
|
|
82
|
+
- §1 Visão geral — escopo claro
|
|
83
|
+
- §2 Decisões de design — mini-ADRs com justificativa
|
|
84
|
+
- §3 Modelo de dados — tipos EXATOS, constraints, índices
|
|
85
|
+
- §4 Regras e validações — ref PRD §N RN-NNN, mensagens de erro
|
|
86
|
+
- §5 Endpoints API — contratos JSON completos, erros com códigos
|
|
87
|
+
- §6 Componentes e telas — estados (loading/empty/error/success)
|
|
88
|
+
- §7 Fluxos de dados — sequências front→back
|
|
89
|
+
- §8 Integrações externas — timeout, retry, fallback
|
|
90
|
+
- §9 Estratégia de testes — framework, estrutura, CAs mapeados
|
|
91
|
+
- §10 Fora do escopo — lista explícita
|
|
92
|
+
- §11 Delta Specs — ADDED/MODIFIED/REMOVED
|
|
93
|
+
|
|
94
|
+
**Setup**: §4-§8 podem ser N/A (normal).
|
|
95
|
+
**Feature**: todas seções aplicáveis preenchidas.
|
|
96
|
+
|
|
97
|
+
### 6. Complementar decisions.md (setup — complemento do passo 3)
|
|
98
|
+
Após gerar SDD §2, popular `decisions.md` com as decisões iniciais de arquitetura.
|
|
99
|
+
|
|
100
|
+
### 7. Projetar SDD em `specs/{nome}/` (sempre)
|
|
101
|
+
|
|
102
|
+
Após gerar/atualizar o SDD, criar/sobrescrever os 4 arquivos em `specs/{nome}/`
|
|
103
|
+
como projeções do SDD pro agent consumir:
|
|
104
|
+
|
|
105
|
+
| Arquivo | Projeção de |
|
|
106
|
+
|---------|-------------|
|
|
107
|
+
| `brief.md` | SDD §1 + §2 + §10 |
|
|
108
|
+
| `contracts.md` | SDD §3 + §4 + §5 + §8 |
|
|
109
|
+
| `scenarios.md` | SDD §6 + §7 + §9 + CAs |
|
|
110
|
+
| `tasks.md` | stub (preenchido pelo /sf-plan) |
|
|
111
|
+
|
|
112
|
+
Regras:
|
|
113
|
+
- São projeções REGENERÁVEIS — ao re-rodar /sf-design, sobrescreve
|
|
114
|
+
- NUNCA editar direto em specs/ — SDD é a fonte
|
|
115
|
+
- Templates em `.claude/templates/specs/`
|
|
116
|
+
- Coders e Reviewer leem daqui, NUNCA do SDD direto
|
|
117
|
+
|
|
118
|
+
### 8. Atualizar `.context.md`
|
|
119
|
+
```yaml
|
|
120
|
+
status: "design_done"
|
|
121
|
+
ultima_skill: "/sf-design"
|
|
122
|
+
atualizado_em: "{{ISO_DATETIME}}"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 9. Publicar SDD no(s) backend(s)
|
|
126
|
+
|
|
127
|
+
Se existe `sfw.config.yml` com `output.targets[]` ativo:
|
|
128
|
+
- Executar `/sf-publish $ARGUMENTS SDD`
|
|
129
|
+
- O `/sf-publish` respeita o `mode` (auto/manual/off) de cada target
|
|
130
|
+
- Se não existe `sfw.config.yml` → pular silenciosamente
|
|
131
|
+
|
|
132
|
+
Ver `.github/skills/sf-publish.md`.
|
|
@@ -1,211 +1,94 @@
|
|
|
1
|
-
|
|
2
|
-
name: sf-extract
|
|
3
|
-
description: |
|
|
4
|
-
Extração de insumos. Lê workspace/Input/ e gera PRD ou TRD estruturado.
|
|
5
|
-
Trigger: /sf-extract
|
|
6
|
-
author: GustavoMaritan
|
|
7
|
-
version: 1.0.0
|
|
8
|
-
date: 2026-04-08
|
|
9
|
-
---
|
|
1
|
+
# /sf-extract $ARGUMENTS
|
|
10
2
|
|
|
11
|
-
|
|
3
|
+
Skill atômica de extração. Lê insumos brutos do PM/ e gera PRD ou TRD.
|
|
4
|
+
$ARGUMENTS = nome (ex: setup_projeto, feat_cadastro_cliente)
|
|
12
5
|
|
|
13
|
-
|
|
14
|
-
> Chamada via orquestrador (/feature, /sf-setup-projeto) ou diretamente para re-extração.
|
|
6
|
+
## Multi-agent
|
|
15
7
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
/sf-extract <nome>
|
|
22
|
-
```
|
|
23
|
-
Exemplo: `/sf-extract feat_cadastro_cliente`
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## Agentes
|
|
28
|
-
|
|
29
|
-
| Agente | Papel | Modelo | Input | Output |
|
|
30
|
-
|--------|-------|--------|-------|--------|
|
|
31
|
-
| **Reader** | Lê e cataloga 1 arquivo de insumo | Sonnet | 1 arquivo bruto + formato esperado | Resumo estruturado por seção do template |
|
|
32
|
-
| **Analyzer** | Cruza fontes, detecta gaps, gera documento final | Opus | Outputs de todos os Readers + template + contexto do projeto | PRD/TRD completo + extract-log |
|
|
33
|
-
|
|
34
|
-
### Orquestração
|
|
35
|
-
```
|
|
36
|
-
1. Ler .context.md e .extract-log.md (se existir)
|
|
37
|
-
2. Ler discovery.md (se existir) — análise profunda prévia dos insumos
|
|
38
|
-
3. Inventariar arquivos em workspace/Input/{nome}/ → filtrar NOVOS e MODIFICADOS
|
|
39
|
-
4. Spawn 1 Reader por arquivo NOVO/MODIFICADO (paralelo)
|
|
40
|
-
5. Aguardar todos os Readers
|
|
41
|
-
6. Spawn Analyzer com:
|
|
42
|
-
- Outputs concatenados dos Readers
|
|
43
|
-
- discovery.md (se existir) — mapa do sistema pré-validado
|
|
44
|
-
- PRD/TRD existente (se re-extração)
|
|
45
|
-
- Template (PRD.template.md ou TRD.template.md)
|
|
46
|
-
- docs/ (contexto do projeto)
|
|
47
|
-
7. Analyzer gera documento final + extract-log
|
|
48
|
-
8. Atualizar .context.md → status: extract_done
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
> **Se discovery.md existir**: O Analyzer usa o mapa do sistema, perguntas já respondidas
|
|
52
|
-
> e pontos críticos como contexto enriquecido. Resultado: menos ambiguidades, melhor estruturação.
|
|
53
|
-
> **Se não existir**: O Analyzer trabalha normalmente com os outputs dos Readers.
|
|
54
|
-
|
|
55
|
-
### Agent: Reader (Sonnet)
|
|
56
|
-
|
|
57
|
-
**Papel**: Especialista em leitura e catalogação de um único arquivo de insumo.
|
|
58
|
-
|
|
59
|
-
**Comportamento**:
|
|
60
|
-
- Lê 1 arquivo por vez
|
|
61
|
-
- Extrai informações seguindo as categorias do template alvo
|
|
62
|
-
- Não interpreta, não infere — apenas cataloga o que encontra
|
|
63
|
-
- Marca cada informação com a seção do template onde se encaixa
|
|
64
|
-
|
|
65
|
-
**Formatos e o que extrair:**
|
|
66
|
-
|
|
67
|
-
| Formato | Extensões | O que extrair |
|
|
68
|
-
|---------|-----------|---------------|
|
|
69
|
-
| Texto/Requisitos | `.md`, `.txt` | Requisitos, regras de negócio, contexto, restrições |
|
|
70
|
-
| Banco de dados | `.sql` | Entidades, campos, tipos, constraints, índices, relações |
|
|
71
|
-
| Protótipos | `.html` | Telas, campos (`data-field`), ações (`data-action`), validações (`data-validation`), rotas (`data-route`), permissões (`data-permission`), estados (`data-state`) |
|
|
72
|
-
| Diagramas | `.xml` (drawio), `.json` | Fluxos, decisões, atores, sequências |
|
|
73
|
-
| Planilhas | `.csv` | Dados tabulares, mapeamentos, configurações |
|
|
74
|
-
| Imagens | `.png`, `.jpg`, `.pdf` | Wireframes, mockups, fluxogramas (análise visual) |
|
|
75
|
-
| Outros | qualquer | Extrair o que for relevante — nunca ignorar um arquivo |
|
|
76
|
-
|
|
77
|
-
**Output do Reader** (por arquivo):
|
|
78
|
-
```markdown
|
|
79
|
-
## Reader Output: {nome_arquivo}
|
|
80
|
-
- Hash: {sha256_8chars}
|
|
81
|
-
- Formato: {tipo}
|
|
82
|
-
- Status: extraído | parcial | não identificado
|
|
83
|
-
|
|
84
|
-
### Seções alimentadas:
|
|
85
|
-
- §1 Contexto: ...
|
|
86
|
-
- §3 Entidades: ...
|
|
87
|
-
- §5 Regras: RN-XXX: "descrição"
|
|
88
|
-
- §13 Ambiguidades: "campo X definido mas sem tipo especificado"
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
**Quando o Reader NÃO consegue extrair conteúdo:**
|
|
92
|
-
- Status: `não identificado` — arquivo binário desconhecido, corrompido, ou sem conteúdo relevante
|
|
93
|
-
- Status: `parcial` — conseguiu extrair algo mas o formato limita (ex: imagem sem OCR, PDF escaneado)
|
|
94
|
-
- O Reader NUNCA ignora o arquivo — sempre registra no output com o status
|
|
95
|
-
- O Analyzer inclui arquivo não identificado no extract-log com classificação `NÃO IDENTIFICADO`
|
|
96
|
-
- O Analyzer gera ambiguidade: "Arquivo {nome} não pôde ser processado — verifique conteúdo e formato"
|
|
97
|
-
|
|
98
|
-
### Agent: Analyzer (Opus)
|
|
99
|
-
|
|
100
|
-
**Papel**: Especialista em análise cruzada, detecção de gaps e geração de documento estruturado.
|
|
101
|
-
|
|
102
|
-
**Comportamento**:
|
|
103
|
-
- Nunca assume — se não está explícito nos insumos, vira pergunta bloqueante
|
|
104
|
-
- Busca contradições ativamente entre fontes diferentes
|
|
105
|
-
- Rastreia tudo — cada informação aponta para o arquivo fonte
|
|
106
|
-
- Prefere estrutura a narrativa — tabelas e listas, nunca texto livre
|
|
107
|
-
- Pessimista construtivo — melhor uma ambiguidade a mais do que uma regra inventada
|
|
108
|
-
|
|
109
|
-
**Responsabilidades**:
|
|
110
|
-
1. Consolidar outputs dos Readers em visão unificada
|
|
111
|
-
2. Detectar contradições entre fontes → gerar ambiguidade com os dois arquivos citados
|
|
112
|
-
3. Detectar gaps — seções do template sem informação → gerar ambiguidade
|
|
113
|
-
4. **Validar Checklist de Temas Críticos** (ver abaixo) — temas ausentes viram ambiguidades obrigatórias
|
|
114
|
-
5. Nunca inferir regra de negócio — se não está explícito, é ambiguidade
|
|
115
|
-
6. Manter IDs estáveis (RN-001 nunca renumera, novos continuam sequência)
|
|
116
|
-
7. Gerar rastreabilidade completa (§14 PRD / §10 TRD)
|
|
117
|
-
8. Na re-extração: merge ADITIVO com documento existente, marcar seções atualizadas
|
|
118
|
-
|
|
119
|
-
### Checklist de Temas Críticos (Analyzer)
|
|
120
|
-
|
|
121
|
-
Após consolidar os Readers, o Analyzer DEVE verificar se os insumos cobrem os temas abaixo.
|
|
122
|
-
Se um tema **não foi mencionado em nenhum insumo**, gera **ambiguidade obrigatória** pedindo ao usuário.
|
|
123
|
-
|
|
124
|
-
#### Para TRD (setup):
|
|
125
|
-
|
|
126
|
-
| # | Tema | O que verificar | Se ausente |
|
|
127
|
-
|---|------|-----------------|------------|
|
|
128
|
-
| 1 | **Autenticação** | Qual mecanismo? JWT, OAuth, API Key, Session? | Ambiguidade: "Nenhum mecanismo de autenticação definido nos insumos" |
|
|
129
|
-
| 2 | **Autorização / Roles** | Quais perfis? RBAC, ABAC? Quem acessa o quê? | Ambiguidade: "Perfis de acesso e regras de autorização não definidos" |
|
|
130
|
-
| 3 | **Separação de serviços** | É monolito, microserviços, modular? API e Worker são separados? | Ambiguidade: "Arquitetura de serviços não definida (monolito vs separados)" |
|
|
131
|
-
| 4 | **Ambientes** | Dev, staging, prod? Docker? CI/CD? | Ambiguidade: "Estratégia de ambientes e deploy não definida" |
|
|
132
|
-
| 5 | **Dados sensíveis** | PII, LGPD, criptografia, masking? | Ambiguidade: "Tratamento de dados sensíveis / LGPD não mencionado" |
|
|
133
|
-
|
|
134
|
-
#### Para PRD (feature):
|
|
135
|
-
|
|
136
|
-
| # | Tema | O que verificar | Se ausente |
|
|
137
|
-
|---|------|-----------------|------------|
|
|
138
|
-
| 1 | **Autenticação requerida** | Feature exige login? Quais endpoints são públicos vs autenticados? | Ambiguidade: "Não definido quais operações exigem autenticação" |
|
|
139
|
-
| 2 | **Permissões / Roles** | Quais perfis podem executar cada ação? | Ambiguidade: "Não definido quais perfis têm acesso a cada operação" |
|
|
140
|
-
| 3 | **Validações de entrada** | Regras de validação dos campos? Limites? Formatos? | Ambiguidade: "Validações de entrada não detalhadas" |
|
|
141
|
-
| 4 | **Tratamento de erros** | O que acontece quando dá errado? Mensagens ao usuário? | Ambiguidade: "Cenários de erro e mensagens ao usuário não definidos" |
|
|
142
|
-
| 5 | **Impacto em dados existentes** | A feature altera dados existentes? Migração necessária? | Ambiguidade: "Impacto em dados existentes não avaliado" |
|
|
143
|
-
|
|
144
|
-
> **Regra**: O Analyzer NÃO inventa respostas para esses temas. Se não está nos insumos, PERGUNTA.
|
|
145
|
-
> Esses temas são os mais comuns de serem esquecidos pelo usuário e os mais caros de corrigir depois.
|
|
146
|
-
|
|
147
|
-
---
|
|
8
|
+
| Agente | Modelo | Papel |
|
|
9
|
+
|--------|--------|-------|
|
|
10
|
+
| **Reader** (1 por arquivo) | Sonnet | Lê e cataloga 1 arquivo. Não interpreta, apenas cataloga |
|
|
11
|
+
| **Analyzer** | Opus | Cruza fontes, detecta gaps/contradições, gera documento final |
|
|
148
12
|
|
|
149
13
|
## Pré-condições
|
|
150
14
|
|
|
151
15
|
| # | Validação | Se falhar |
|
|
152
16
|
|---|-----------|-----------|
|
|
153
|
-
| 1 |
|
|
154
|
-
| 2 | `workspace/Input
|
|
155
|
-
| 3 |
|
|
156
|
-
| 4 | Status
|
|
17
|
+
| 1 | $ARGUMENTS informado | Parar → "Informe o nome" |
|
|
18
|
+
| 2 | `workspace/Input/$ARGUMENTS/` existe com arquivos | Parar → "Pasta vazia ou inexistente" |
|
|
19
|
+
| 3 | `.context.md` existe | Parar → "Execute /feature ou /setup-projeto primeiro" |
|
|
20
|
+
| 4 | Status é `not_started` ou `extract_done` | Se posterior → "Extração já aprovada" |
|
|
157
21
|
|
|
158
|
-
## Passos
|
|
22
|
+
## Passos
|
|
159
23
|
|
|
160
24
|
### 1. Ler contexto
|
|
161
|
-
-
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
-
|
|
190
|
-
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
25
|
+
- `.context.md` → tipo (feature/setup) e documento (PRD/TRD)
|
|
26
|
+
- `discovery.md` (se existir) → análise profunda prévia dos insumos
|
|
27
|
+
- `docs/` se existir
|
|
28
|
+
- Template: tipo=feature → `PRD.template.md` | tipo=setup → `TRD.template.md`
|
|
29
|
+
|
|
30
|
+
> Se `discovery.md` existir: usar mapa do sistema e perguntas já respondidas como contexto
|
|
31
|
+
> enriquecido. Resultado: menos ambiguidades, melhor estruturação.
|
|
32
|
+
|
|
33
|
+
### 2. Inventariar insumos
|
|
34
|
+
Para cada arquivo em `workspace/Input/$ARGUMENTS/` (ignorar .gitkeep):
|
|
35
|
+
- Calcular hash SHA-256 (primeiros 8 chars)
|
|
36
|
+
- Se `.extract-log.md` existe → classificar: NOVO / MODIFICADO / INALTERADO
|
|
37
|
+
- Se não existe → todos são NOVOS
|
|
38
|
+
|
|
39
|
+
### 3. Processar (simulando Reader por arquivo)
|
|
40
|
+
Para cada arquivo NOVO ou MODIFICADO:
|
|
41
|
+
|
|
42
|
+
| Formato | O que extrair |
|
|
43
|
+
|---------|---------------|
|
|
44
|
+
| .md, .txt | Requisitos, regras, contexto, restrições |
|
|
45
|
+
| .sql | Entidades, campos, tipos, constraints, índices |
|
|
46
|
+
| .html | Telas, campos, ações, validações, rotas, permissões |
|
|
47
|
+
| .xml, .json | Fluxos, decisões, configurações |
|
|
48
|
+
| .csv | Dados tabulares, mapeamentos |
|
|
49
|
+
| .png, .jpg, .pdf | Análise visual (wireframes, mockups) |
|
|
50
|
+
| Não identificado | Registrar como NÃO IDENTIFICADO, gerar ambiguidade |
|
|
51
|
+
|
|
52
|
+
### 4. Gerar documento (simulando Analyzer)
|
|
53
|
+
- Consolidar todas informações por seção do template
|
|
54
|
+
- Detectar contradições entre fontes → ambiguidade
|
|
55
|
+
- Detectar gaps (seções sem info) → ambiguidade
|
|
56
|
+
- **Validar Checklist de Temas Críticos** (ver abaixo) — temas ausentes viram ambiguidades obrigatórias
|
|
57
|
+
- Nunca inferir regra de negócio — se não explícito, é ambiguidade
|
|
58
|
+
- IDs estáveis: RN-001 nunca renumera, novos continuam sequência
|
|
59
|
+
- Rastreabilidade: cada info aponta pro arquivo fonte
|
|
60
|
+
|
|
61
|
+
#### Checklist de Temas Críticos
|
|
62
|
+
|
|
63
|
+
Após consolidar os Readers, verificar se os insumos cobrem os temas abaixo.
|
|
64
|
+
Se um tema **não foi mencionado em nenhum insumo**, gera **ambiguidade obrigatória**.
|
|
65
|
+
|
|
66
|
+
**Para TRD (setup):**
|
|
67
|
+
|
|
68
|
+
| # | Tema | Se ausente |
|
|
69
|
+
|---|------|------------|
|
|
70
|
+
| 1 | **Autenticação** (JWT, OAuth, API Key, Session?) | Ambiguidade: "Nenhum mecanismo de autenticação definido" |
|
|
71
|
+
| 2 | **Autorização / Roles** (perfis, RBAC, ABAC, quem acessa o quê) | Ambiguidade: "Perfis de acesso e regras de autorização não definidos" |
|
|
72
|
+
| 3 | **Separação de serviços** (monolito, microserviços, API vs Worker) | Ambiguidade: "Arquitetura de serviços não definida" |
|
|
73
|
+
| 4 | **Ambientes** (dev, staging, prod, Docker, CI/CD) | Ambiguidade: "Estratégia de ambientes e deploy não definida" |
|
|
74
|
+
| 5 | **Dados sensíveis** (PII, LGPD, criptografia, masking) | Ambiguidade: "Tratamento de dados sensíveis / LGPD não mencionado" |
|
|
75
|
+
|
|
76
|
+
**Para PRD (feature):**
|
|
77
|
+
|
|
78
|
+
| # | Tema | Se ausente |
|
|
79
|
+
|---|------|------------|
|
|
80
|
+
| 1 | **Autenticação requerida** (quais endpoints públicos vs autenticados?) | Ambiguidade: "Não definido quais operações exigem autenticação" |
|
|
81
|
+
| 2 | **Permissões / Roles** (quais perfis podem executar cada ação?) | Ambiguidade: "Não definido quais perfis têm acesso a cada operação" |
|
|
82
|
+
| 3 | **Validações de entrada** (regras, limites, formatos) | Ambiguidade: "Validações de entrada não detalhadas" |
|
|
83
|
+
| 4 | **Tratamento de erros** (cenários de falha, mensagens) | Ambiguidade: "Cenários de erro e mensagens ao usuário não definidos" |
|
|
84
|
+
| 5 | **Impacto em dados existentes** (migração necessária?) | Ambiguidade: "Impacto em dados existentes não avaliado" |
|
|
85
|
+
|
|
86
|
+
> O Analyzer NÃO inventa respostas — se não está nos insumos, PERGUNTA.
|
|
87
|
+
|
|
88
|
+
### 5. Gerar roadmap de produto faseado (APENAS no setup)
|
|
206
89
|
Quando tipo=setup, o Analyzer encontra informações que não são infraestrutura
|
|
207
90
|
(regras de negócio, jornadas, telas, fluxos). Em vez de descartar, organizar em
|
|
208
|
-
`backlog_extraido.md` como **roadmap faseado** com entregáveis incrementais
|
|
91
|
+
`backlog_extraido.md` como **roadmap faseado** com entregáveis incrementais.
|
|
209
92
|
|
|
210
93
|
O Analyzer deve:
|
|
211
94
|
1. Identificar funcionalidades, entidades, regras de negócio, jornadas, telas
|
|
@@ -223,62 +106,41 @@ Este arquivo:
|
|
|
223
106
|
- Serve como roadmap quando o usuário for criar `/feature`
|
|
224
107
|
- O /sf-extract da feature usa as fases como referência para o PRD
|
|
225
108
|
|
|
226
|
-
###
|
|
227
|
-
|
|
109
|
+
### 6. Gerar `.extract-log.md`
|
|
228
110
|
```markdown
|
|
229
|
-
# Extract Log —
|
|
230
|
-
|
|
231
|
-
## Extração 1 — {{ISO_DATETIME}}
|
|
232
|
-
| Arquivo | Hash | Classificação | Seções alimentadas |
|
|
233
|
-
|---------|------|---------------|-------------------|
|
|
234
|
-
| requisitos.txt | a1b2c3d4 | NOVO | §1, §5, §9 |
|
|
235
|
-
| modelagem.sql | e5f6g7h8 | NOVO | §3, §6 |
|
|
111
|
+
# Extract Log — $ARGUMENTS
|
|
236
112
|
|
|
237
|
-
## Extração
|
|
238
|
-
| Arquivo | Hash | Classificação | Seções alimentadas |
|
|
239
|
-
|
|
240
|
-
| novas_regras.md | m3n4o5p6 | NOVO | §5, §9 |
|
|
241
|
-
| modelagem.sql | q7r8s9t0 | MODIFICADO | §3 |
|
|
242
|
-
| requisitos.txt | a1b2c3d4 | INALTERADO | — |
|
|
113
|
+
## Extração N — {{ISO_DATETIME}}
|
|
114
|
+
| Arquivo | Hash | Classificação | Status | Seções alimentadas |
|
|
115
|
+
|---------|------|---------------|--------|--------------------|
|
|
243
116
|
```
|
|
244
117
|
|
|
245
|
-
###
|
|
118
|
+
### 6. Atualizar `.context.md`
|
|
246
119
|
```yaml
|
|
247
120
|
status: "extract_done"
|
|
248
121
|
ultima_skill: "/sf-extract"
|
|
249
122
|
atualizado_em: "{{ISO_DATETIME}}"
|
|
250
123
|
```
|
|
251
124
|
|
|
252
|
-
|
|
125
|
+
### 7. Publicar artefato no(s) backend(s)
|
|
253
126
|
|
|
254
|
-
|
|
127
|
+
Se existe `sfw.config.yml` com `output.targets[]` ativo:
|
|
128
|
+
- Executar `/sf-publish $ARGUMENTS TRD` (setup) ou `/sf-publish $ARGUMENTS PRD` (feature)
|
|
129
|
+
- O `/sf-publish` respeita o `mode` (auto/manual/off) de cada target
|
|
130
|
+
- Se não existe `sfw.config.yml` → pular silenciosamente (projeto 100% local)
|
|
255
131
|
|
|
256
|
-
|
|
257
|
-
|---------|-----------|
|
|
258
|
-
| `PRD.md` ou `TRD.md` | Documento de extração com todas as seções preenchidas |
|
|
259
|
-
| `.extract-log.md` | Registro de arquivos processados com hashes e classificação |
|
|
260
|
-
| `.context.md` | Atualizado com status `extract_done` |
|
|
132
|
+
Ver `.github/skills/sf-publish.md`.
|
|
261
133
|
|
|
262
|
-
##
|
|
263
|
-
-
|
|
264
|
-
-
|
|
265
|
-
-
|
|
134
|
+
## Re-extração
|
|
135
|
+
- Merge ADITIVO com documento existente (nunca remove info de inalterados)
|
|
136
|
+
- Seções afetadas marcadas com `<!-- ATUALIZADO: re-extração -->`
|
|
137
|
+
- Novos IDs continuam sequência
|
|
266
138
|
|
|
267
139
|
## Erros
|
|
268
|
-
|
|
269
140
|
| Erro | Ação |
|
|
270
141
|
|------|------|
|
|
271
|
-
|
|
|
272
|
-
| .context.md não existe | Parar, sugerir /
|
|
273
|
-
| Nenhum arquivo novo/modificado | Informar "Nenhuma alteração detectada
|
|
274
|
-
|
|
|
275
|
-
|
|
|
276
|
-
| Extração parcial | Registrar como PARCIAL no extract-log, extrair o que for possível, avisar quais seções ficaram incompletas |
|
|
277
|
-
| Contradição entre arquivos | Analyzer gera ambiguidade citando os dois arquivos e a contradição |
|
|
278
|
-
|
|
279
|
-
## Notas
|
|
280
|
-
- O `/extract` é a ÚNICA skill que lê `workspace/Input/` — nenhuma outra skill acessa insumos brutos
|
|
281
|
-
- Na re-extração, o merge é ADITIVO — nunca remove informação de arquivos inalterados
|
|
282
|
-
- Para recomeçar do zero: apagar PRD/TRD e .extract-log.md manualmente
|
|
283
|
-
- Readers são stateless — não conhecem outros arquivos, apenas o seu
|
|
284
|
-
- Analyzer é quem tem visão global e detecta contradições cross-arquivo
|
|
142
|
+
| Pasta vazia | Parar, listar formatos aceitos |
|
|
143
|
+
| .context.md não existe | Parar, sugerir /feature ou /setup-projeto |
|
|
144
|
+
| Nenhum arquivo novo/modificado | Informar "Nenhuma alteração detectada" |
|
|
145
|
+
| Arquivo não identificado | Registrar no log, gerar ambiguidade |
|
|
146
|
+
| Contradição entre arquivos | Gerar ambiguidade citando os dois |
|
|
@@ -71,9 +71,29 @@ function loadScope(pageId, targetDir):
|
|
|
71
71
|
collectAllPages(pageId, allPages)
|
|
72
72
|
|
|
73
73
|
para cada page em allPages:
|
|
74
|
-
|
|
74
|
+
// IMPORTANTE: SEMPRE pedir markdown, NUNCA storage format (HTML)
|
|
75
|
+
result = mcp__atlassian__confluence_get_page(page_id=page.id, convert_to_markdown=true)
|
|
76
|
+
content = result.content (ou result.body — depende da resposta do MCP)
|
|
77
|
+
|
|
78
|
+
// LIMPEZA OBRIGATÓRIA — Confluence pode vazar HTML mesmo com convert_to_markdown
|
|
79
|
+
// Se o conteúdo contém tags HTML (<p>, <div>, <span>, <table>, etc.):
|
|
80
|
+
// 1. Remover tags de metadata: <p local-id="...">, <ri:...>, <ac:...>
|
|
81
|
+
// 2. Converter tags semânticas pra markdown:
|
|
82
|
+
// <h1> → #, <h2> → ##, <h3> → ###
|
|
83
|
+
// <strong>/<b> → **texto**
|
|
84
|
+
// <em>/<i> → *texto*
|
|
85
|
+
// <a href="url"> → [texto](url)
|
|
86
|
+
// <ul>/<li> → - item
|
|
87
|
+
// <ol>/<li> → 1. item
|
|
88
|
+
// <code> → `código`
|
|
89
|
+
// <pre> → ```bloco```
|
|
90
|
+
// <table>/<tr>/<td> → tabela markdown
|
|
91
|
+
// 3. Remover tags restantes sem equivalente markdown (strip tags, manter texto)
|
|
92
|
+
// 4. Limpar linhas vazias excessivas
|
|
93
|
+
// O arquivo salvo DEVE ser markdown limpo, sem nenhuma tag HTML.
|
|
94
|
+
|
|
75
95
|
filename = sanitize(page.title) + ".md"
|
|
76
|
-
salvar content em {targetDir}/{filename}
|
|
96
|
+
salvar content LIMPO em {targetDir}/{filename}
|
|
77
97
|
registrar no load-log
|
|
78
98
|
|
|
79
99
|
// Attachments de CADA page
|
|
@@ -1,180 +1,104 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
|
39
|
-
|
|
40
|
-
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
|
|
53
|
-
-
|
|
54
|
-
|
|
55
|
-
###
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
**Regras de decomposição:**
|
|
106
|
-
1. Cada task é **atômica** — implementável sem consultar nada além de `specs/{nome}/` + `rules.md`
|
|
107
|
-
2. **Repo obrigatório** — consultar `projetos.yaml` para mapear área → repo. Caminhos de arquivo são relativos à raiz do repo
|
|
108
|
-
3. **Área** é uma coluna, não mais um arquivo. Valores: BANCO, BACK, FRONT, INFRA, DOC, MOBILE, etc.
|
|
109
|
-
4. Tamanhos realistas: **S** (<30min), **M** (30min-2h), **L** (2h+)
|
|
110
|
-
5. Se uma task é L, avaliar se pode ser quebrada em M+S
|
|
111
|
-
6. IDs sequenciais **por área**: BANCO-001, BANCO-002, BACK-001, BACK-002
|
|
112
|
-
7. IDs nunca reutilizados — se uma task for removida, o ID é aposentado
|
|
113
|
-
8. Dependências explícitas — inclusive cross-area (FRONT-001 depende BACK-001)
|
|
114
|
-
9. `Ref spec`: referência a seção do SDD (fonte humana) — ex: `SDD §3.1`
|
|
115
|
-
10. `Ref CA`: ID do critério de aceite em `specs/{nome}/scenarios.md` (CA-001, CA-002...) — pode ser `—`
|
|
116
|
-
|
|
117
|
-
**Organização lógica dentro da tabela:**
|
|
118
|
-
- Ordenar por Fase → Área → ID
|
|
119
|
-
- Dependências garantem ordem de execução; a ordenação na tabela é só visual
|
|
120
|
-
|
|
121
|
-
### 5. Gerar `workspace/Output/{nome}/Progresso.md` (tracking)
|
|
122
|
-
|
|
123
|
-
`Progresso.md` fica em **workspace/Output** (é user tracking, não spec).
|
|
124
|
-
Usando template `.github/templates/feature/Progresso.template.md`:
|
|
125
|
-
|
|
126
|
-
- Resumo por Área × Fase com contagem de tasks (derivado de `specs/{nome}/tasks.md`)
|
|
127
|
-
- Status por fase: ⬜ pendente | 🔄 em andamento | ✅ concluída
|
|
128
|
-
- **Ordem de execução** com paralelismos:
|
|
129
|
-
```
|
|
130
|
-
1. BANCO Fase 1 — primeiro sempre
|
|
131
|
-
2. BANCO Fase 2 + BACK Fase 1 — podem paralelizar
|
|
132
|
-
3. FRONT após BACK Fase 2
|
|
133
|
-
...
|
|
134
|
-
```
|
|
135
|
-
- Totais por área e geral
|
|
136
|
-
- Checklist pós-conclusão (merge delta, atualizar progresso global, napkin)
|
|
137
|
-
|
|
138
|
-
**Regra**: status vive SÓ em Progresso.md. `specs/{nome}/tasks.md` é o plano imutável (até re-planejar).
|
|
139
|
-
|
|
140
|
-
### 6. Atualizar progresso global
|
|
141
|
-
Adicionar entrada em `workspace/Output/progresso.md`:
|
|
142
|
-
|
|
143
|
-
```markdown
|
|
144
|
-
| {nome} | plan_done | BANCO: 0/N | BACK: 0/N | FRONT: 0/N |
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### 7. Atualizar `.context.md`
|
|
148
|
-
```yaml
|
|
149
|
-
status: "plan_done"
|
|
150
|
-
ultima_skill: "/sf-plan"
|
|
151
|
-
atualizado_em: "{{ISO_DATETIME}}"
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
## Saídas
|
|
157
|
-
|
|
158
|
-
| Arquivo | Descrição |
|
|
159
|
-
|---------|-----------|
|
|
160
|
-
| `specs/{nome}/tasks.md` | Tabela única de tasks com coluna Área |
|
|
161
|
-
| `workspace/Output/{nome}/Progresso.md` | Dashboard da feature com ordem de execução (tracking) |
|
|
162
|
-
| `workspace/Output/progresso.md` (global) | Atualizado com nova feature |
|
|
163
|
-
| `.context.md` | Atualizado com status `plan_done` |
|
|
164
|
-
|
|
165
|
-
## Pós-condições
|
|
166
|
-
- `specs/{nome}/tasks.md` é único arquivo de plano — coder lê daqui
|
|
167
|
-
- Cada task é auto-contida com referência a `specs/{nome}/` (não ao SDD direto)
|
|
168
|
-
- Dependências resolvíveis (não há ciclos)
|
|
169
|
-
- Ordem de execução definida em `Progresso.md`
|
|
170
|
-
- Feature pronta para `/sf-dev`
|
|
171
|
-
|
|
172
|
-
## Erros
|
|
173
|
-
|
|
174
|
-
| Erro | Ação |
|
|
175
|
-
|------|------|
|
|
176
|
-
| Nome não informado | Parar, mostrar exemplo |
|
|
177
|
-
| Status não é design_done | Parar, sugerir skill correspondente |
|
|
178
|
-
| SDD não encontrado | Parar, sugerir /sf-design |
|
|
179
|
-
| SDD com seções vazias obrigatórias | Parar, listar o que falta — sugerir voltar ao /sf-design |
|
|
180
|
-
| Dependência circular detectada | Parar, reportar o ciclo e sugerir reorganização |
|
|
1
|
+
# /sf-plan $ARGUMENTS
|
|
2
|
+
|
|
3
|
+
Skill atômica de planejamento. Lê SDD + specs/{nome}/ e gera `specs/{nome}/tasks.md` (arquivo único) + `workspace/Output/{nome}/Progresso.md`.
|
|
4
|
+
$ARGUMENTS = nome (ex: setup_projeto, feat_cadastro_cliente)
|
|
5
|
+
|
|
6
|
+
## Agente: Planner (Opus)
|
|
7
|
+
Metódico e exaustivo. Cada task auto-contida. Prioriza ordem correta.
|
|
8
|
+
|
|
9
|
+
## Pré-condições
|
|
10
|
+
|
|
11
|
+
| # | Validação | Se falhar |
|
|
12
|
+
|---|-----------|-----------|
|
|
13
|
+
| 1 | $ARGUMENTS informado | Parar |
|
|
14
|
+
| 2 | `.context.md` com status `design_done` | Se anterior → "/sf-design primeiro". Se posterior → "Tasks já geradas" |
|
|
15
|
+
| 3 | `workspace/Output/{nome}/sdd.md` existe | Parar → "/sf-design primeiro" |
|
|
16
|
+
| 4 | `specs/{nome}/contracts.md` e `scenarios.md` existem (projeções) | Parar → "/sf-design não gerou projeções — re-rode" |
|
|
17
|
+
|
|
18
|
+
## Passos
|
|
19
|
+
|
|
20
|
+
### 1. Ler contexto
|
|
21
|
+
- `workspace/Output/{nome}/sdd.md` completo (fonte humana)
|
|
22
|
+
- `specs/{nome}/contracts.md` e `scenarios.md` (projeções já geradas pelo /sf-design)
|
|
23
|
+
- `projetos.yaml` + `docs/` (architecture, domain, conventions) + `.claude/rules.md`
|
|
24
|
+
- Template `.claude/templates/specs/tasks.template.md`
|
|
25
|
+
|
|
26
|
+
### 2. Identificar fases de entrega
|
|
27
|
+
Ler PRD §11 (Fases de Entrega) — cada fase vira um agrupamento de tasks:
|
|
28
|
+
- Fases são sequenciais: Fase 2 depende de Fase 1 concluída
|
|
29
|
+
- Cada fase tem entregável e critério de done
|
|
30
|
+
- O `/sf-dev` pode rodar por fase: `/sf-dev feat_nome --fase 1`
|
|
31
|
+
|
|
32
|
+
### 3. Identificar áreas (por fase)
|
|
33
|
+
|
|
34
|
+
| Seção SDD | Área |
|
|
35
|
+
|-----------|------|
|
|
36
|
+
| §3 Modelo de dados | BANCO |
|
|
37
|
+
| §5 Endpoints API | BACK |
|
|
38
|
+
| §6 Componentes/Telas | FRONT |
|
|
39
|
+
| §8 Integrações | INFRA |
|
|
40
|
+
| Outras | MOBILE, DEVOPS, etc. conforme SDD |
|
|
41
|
+
|
|
42
|
+
> **Nota**: Área DOC NÃO existe mais no setup. `docs/` é gerado pelo /sf-design (passo 3).
|
|
43
|
+
> DOC só aparece em features se houver necessidade explícita de documentação adicional.
|
|
44
|
+
|
|
45
|
+
Áreas são DINÂMICAS — só criar as que o SDD exige.
|
|
46
|
+
|
|
47
|
+
**Área INFRA obrigatória no setup:**
|
|
48
|
+
```
|
|
49
|
+
- [ ] INFRA-001: Validar e configurar ambiente local [M]
|
|
50
|
+
- [ ] INFRA-002: Criar docker-compose.yml + Dockerfiles [M]
|
|
51
|
+
- [ ] INFRA-003: Hello world — subir stack completa e validar [M]
|
|
52
|
+
```
|
|
53
|
+
INFRA-001 é a PRIMEIRA task do setup. INFRA-003 é a ÚLTIMA (validação final).
|
|
54
|
+
|
|
55
|
+
### 4. Gerar `specs/{nome}/tasks.md` (arquivo único)
|
|
56
|
+
|
|
57
|
+
Gerar UM arquivo só em `specs/{nome}/tasks.md` com tabela única de todas as tasks, coluna `Área` diferencia.
|
|
58
|
+
|
|
59
|
+
```markdown
|
|
60
|
+
| ID | Área | Fase | Tam | Título | Repo | Arquivos | Depende de | Ref spec | Ref CA |
|
|
61
|
+
|----|------|------|-----|--------|------|----------|-----------|----------|--------|
|
|
62
|
+
| BANCO-001 | BANCO | 1 | S | Migration clientes | api | src/Migrations/... | — | SDD §3.1 | — |
|
|
63
|
+
| BACK-001 | BACK | 1 | M | Endpoint POST /clientes | api | src/Api/... | BANCO-001 | SDD §5.1 | CA-001 |
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Regras:
|
|
67
|
+
- Cada task é atômica — coder lê `specs/{nome}/` + task, nada mais
|
|
68
|
+
- **Repo obrigatório** — consultar `projetos.yaml`. Caminhos relativos ao repo
|
|
69
|
+
- Área é COLUNA, não arquivo (BANCO, BACK, FRONT, INFRA, DOC, MOBILE...)
|
|
70
|
+
- Tamanhos: S (<30min), M (30min-2h), L (2h+). L → avaliar se quebra em M+S
|
|
71
|
+
- IDs sequenciais por área, nunca reutilizar
|
|
72
|
+
- Dependências cross-area permitidas
|
|
73
|
+
- `Ref spec`: seção do SDD (ex: `SDD §3.1`)
|
|
74
|
+
- `Ref CA`: ID do critério em `specs/{nome}/scenarios.md` ou `—`
|
|
75
|
+
- Ordenar tabela por Fase → Área → ID (visual)
|
|
76
|
+
|
|
77
|
+
### 5. Gerar `workspace/Output/{nome}/Progresso.md` (tracking)
|
|
78
|
+
Progresso.md fica em **workspace/Output** (user tracking, não spec).
|
|
79
|
+
- Resumo Área × Fase com contagem (derivado de `tasks.md`)
|
|
80
|
+
- Ordem de execução com paralelismos
|
|
81
|
+
- Checklist pós-conclusão
|
|
82
|
+
|
|
83
|
+
**Regra**: status vive SÓ em Progresso.md. `tasks.md` é o plano imutável.
|
|
84
|
+
|
|
85
|
+
### 6. Atualizar progresso global + `.context.md`
|
|
86
|
+
```yaml
|
|
87
|
+
status: "plan_done"
|
|
88
|
+
ultima_skill: "/sf-plan"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 7. Publicar Progresso no(s) backend(s)
|
|
92
|
+
|
|
93
|
+
Se existe `sfw.config.yml` com `output.targets[]` ativo:
|
|
94
|
+
- Executar `/sf-publish $ARGUMENTS Progresso`
|
|
95
|
+
- O `/sf-publish` respeita o `mode` (auto/manual/off) de cada target
|
|
96
|
+
- Se não existe `sfw.config.yml` → pular silenciosamente
|
|
97
|
+
- **Nota**: `tasks.md`, `specs/`, `docs/`, `projetos.yaml` são LOCAL ONLY — nunca publicados
|
|
98
|
+
|
|
99
|
+
Ver `.github/skills/sf-publish.md`.
|
|
100
|
+
|
|
101
|
+
## Saídas
|
|
102
|
+
- `specs/{nome}/tasks.md` — tabela única
|
|
103
|
+
- `workspace/Output/{nome}/Progresso.md` — tracking
|
|
104
|
+
- `workspace/Output/progresso.md` (global) — atualizado
|
|
@@ -0,0 +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` | `TRD` | `SDD` | `Progresso`
|
|
9
|
+
|
|
10
|
+
## Quando é chamado
|
|
11
|
+
|
|
12
|
+
Automaticamente pelos commands:
|
|
13
|
+
- `/sf-extract` → publica `TRD` ou `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
|
+
- `TRD` → `TRD.md`
|
|
49
|
+
- `PRD` → `PRD.md`
|
|
50
|
+
- `SDD` → `sdd.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 - TRD"`
|
|
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/sf-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/sf-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 - TRD (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, só 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/sf-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`
|