@luanpdd/kit-mcp 1.9.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +86 -0
- package/README.md +58 -0
- package/gates/ai-prompt-stability.md +120 -0
- package/gates/golden-signals-coverage.md +133 -0
- package/gates/legacy-refactor-safety.md +178 -0
- package/gates/observability-coverage.md +151 -0
- package/gates/postmortem-template-required.md +127 -0
- package/gates/prr-checklist-coverage.md +128 -0
- package/gates/release-pipeline-policy.md +132 -0
- package/kit/COMANDOS.md +15 -0
- package/kit/agents/ai-mutation-tester.md +298 -0
- package/kit/agents/cascading-failures-auditor.md +306 -0
- package/kit/agents/executor.md +13 -0
- package/kit/agents/golden-signals-instrumenter.md +241 -0
- package/kit/agents/legacy-characterizer.md +378 -0
- package/kit/agents/load-shedding-instrumenter.md +297 -0
- package/kit/agents/observability-coverage-auditor.md +325 -0
- package/kit/agents/omm-auditor.md +99 -0
- package/kit/agents/payload-capture-instrumenter.md +283 -0
- package/kit/agents/planner.md +29 -0
- package/kit/agents/postmortem-writer.md +282 -0
- package/kit/agents/prr-conductor.md +296 -0
- package/kit/agents/refactor-safety-auditor.md +414 -0
- package/kit/agents/release-pipeline-auditor.md +360 -0
- package/kit/agents/seam-finder.md +367 -0
- package/kit/agents/shotgun-surgery-detector.md +359 -0
- package/kit/agents/storytelling-analyst.md +309 -0
- package/kit/agents/supabase-architect.md +49 -0
- package/kit/agents/supabase-edge-fn-writer.md +114 -0
- package/kit/agents/supabase-migration-writer.md +80 -0
- package/kit/agents/supabase-storage-implementer.md +156 -0
- package/kit/agents/toil-auditor.md +277 -0
- package/kit/agents/verifier.md +30 -0
- package/kit/commands/auditar-cascading.md +111 -0
- package/kit/commands/auditar-marco.md +124 -1
- package/kit/commands/auditar-observabilidade-cobertura.md +183 -0
- package/kit/commands/auditar-refactor.md +219 -0
- package/kit/commands/auditar-release.md +109 -0
- package/kit/commands/auditar-toil.md +129 -0
- package/kit/commands/capturar-payloads.md +193 -0
- package/kit/commands/caracterizar-prompt.md +195 -0
- package/kit/commands/caracterizar.md +212 -0
- package/kit/commands/concluir-marco.md +95 -1
- package/kit/commands/detectar-duplicacao.md +197 -0
- package/kit/commands/discutir-fase.md +41 -0
- package/kit/commands/encontrar-seams.md +136 -0
- package/kit/commands/forense.md +103 -1
- package/kit/commands/golden-signals.md +142 -0
- package/kit/commands/legacy.md +263 -0
- package/kit/commands/load-shedding.md +117 -0
- package/kit/commands/observabilidade.md +2 -0
- package/kit/commands/postmortem.md +179 -0
- package/kit/commands/prr.md +205 -0
- package/kit/commands/refactor-seguro.md +321 -0
- package/kit/commands/risk-budget.md +220 -0
- package/kit/commands/sre.md +230 -0
- package/kit/commands/storytelling.md +179 -0
- package/kit/skills/_shared-legacy/glossary.md +389 -0
- package/kit/skills/_shared-sre/glossary.md +712 -0
- package/kit/skills/ai-prompt-characterization/SKILL.md +335 -0
- package/kit/skills/blameless-postmortems/SKILL.md +340 -0
- package/kit/skills/cascading-failures/SKILL.md +307 -0
- package/kit/skills/eliminating-toil/SKILL.md +243 -0
- package/kit/skills/event-based-slos/SKILL.md +22 -0
- package/kit/skills/four-golden-signals/SKILL.md +314 -0
- package/kit/skills/hermetic-builds/SKILL.md +323 -0
- package/kit/skills/legacy-api-only-applications/SKILL.md +358 -0
- package/kit/skills/legacy-characterization-tests/SKILL.md +330 -0
- package/kit/skills/legacy-effect-analysis/SKILL.md +331 -0
- package/kit/skills/legacy-extract-class/SKILL.md +203 -0
- package/kit/skills/legacy-monster-methods/SKILL.md +444 -0
- package/kit/skills/legacy-programming-by-difference/SKILL.md +252 -0
- package/kit/skills/legacy-seams-and-test-harness/SKILL.md +460 -0
- package/kit/skills/legacy-shotgun-surgery/SKILL.md +286 -0
- package/kit/skills/legacy-sprout-wrap-techniques/SKILL.md +434 -0
- package/kit/skills/legacy-storytelling-naked-crc/SKILL.md +270 -0
- package/kit/skills/llm-as-dependency/SKILL.md +436 -0
- package/kit/skills/load-shedding-graceful-degradation/SKILL.md +396 -0
- package/kit/skills/pre-refactor-characterization/SKILL.md +421 -0
- package/kit/skills/production-readiness-review/SKILL.md +305 -0
- package/kit/skills/release-engineering/SKILL.md +367 -0
- package/kit/skills/retry-strategies/SKILL.md +372 -0
- package/kit/skills/sre-risk-management/SKILL.md +221 -0
- package/package.json +2 -2
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: legacy-shotgun-surgery
|
|
3
|
+
description: Use ao detectar mesma mudança espalhada em N lugares (cap 21 Feathers) — extract before modify para reduzir change point. Modernização 2026 — semantic search via embeddings detecta duplicação semântica que regex não pega.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Legacy — Shotgun Surgery
|
|
7
|
+
|
|
8
|
+
## Quando usar
|
|
9
|
+
|
|
10
|
+
LLM carrega esta skill quando user descobre que uma mudança requer edição em múltiplos pontos do codebase. Trigger phrases:
|
|
11
|
+
|
|
12
|
+
- "tenho que mudar isso em 5 lugares"
|
|
13
|
+
- "shotgun surgery", "cirurgia espalhada"
|
|
14
|
+
- "duplicação de código", "code duplication"
|
|
15
|
+
- "extrair função", "extract method para reduzir duplicação"
|
|
16
|
+
- "esses 3 lugares fazem a mesma coisa"
|
|
17
|
+
- "cap 21 Feathers"
|
|
18
|
+
- "semantic duplication", "duplicação semântica"
|
|
19
|
+
|
|
20
|
+
## Regras absolutas
|
|
21
|
+
|
|
22
|
+
- **Extract first, modify second.** Antes de mudar, EXTRAIR para 1 lugar. Depois mudar 1 lugar. Reduz N change points para 1.
|
|
23
|
+
- **Detectar duplicação tem 2 níveis:**
|
|
24
|
+
- **Sintática (regex):** mesmo identifier, mesma estrutura. Detect via grep/AST.
|
|
25
|
+
- **Semântica (embeddings — modernização 2026):** intenção igual, implementação diferente. Detect via embedding similarity.
|
|
26
|
+
- **Threshold canônico:** 3+ ocorrências da MESMA lógica = candidato. 2 ocorrências = "regra do dois" (DRY); 3 = sinal forte; 4+ = veto-extract-imediato.
|
|
27
|
+
- **Effect-narrowing precede modify.** Mudar em 5 lugares ÉE shotgun surgery. Mudar em 1 lugar não é. Pré-trabalho: extract.
|
|
28
|
+
- **Modernização semantic search:** modelos de embedding pequenos (`text-embedding-3-small` da OpenAI, `bge-small-en` open) custam < $0.01 para projeto inteiro. Threshold típico 0.85 cosine similarity = duplicação semântica forte.
|
|
29
|
+
- **Não extract se única ocorrência é "candidata".** Extract sob demanda. Sem 3 ocorrências reais, abstração é especulativa (YAGNI).
|
|
30
|
+
- **Extract preserves comportamento.** Cada chamada deve ter resultado IDÊNTICO ao código inline original. Bug preservation aplicável (veja skill characterization).
|
|
31
|
+
|
|
32
|
+
## Patterns canônicos
|
|
33
|
+
|
|
34
|
+
### Pattern 1: Detecção sintática (Feathers original cap 21)
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# PT-BR: padrões sintáticos canônicos
|
|
38
|
+
|
|
39
|
+
# Functions/methods com nome similar
|
|
40
|
+
grep -rE "function (compute|calc)Total" --include="*.ts" .
|
|
41
|
+
grep -rE "(compute|calc)Total" --include="*.ts" -A 5 .
|
|
42
|
+
|
|
43
|
+
# Bloco de código repetido (heurística)
|
|
44
|
+
# Usar `jscpd` (Copy/Paste Detector) ou `simian` para JS/TS/Python
|
|
45
|
+
npx jscpd --min-lines 5 --threshold 0 --reporters json src/
|
|
46
|
+
|
|
47
|
+
# AST-level (mais preciso) — usar `tree-sitter` queries
|
|
48
|
+
# Rust/JS — encontrar all calls com mesmo padrão
|
|
49
|
+
ast-grep --pattern 'orderTotal($O) + shippingCost($O) + tax($O)' src/
|
|
50
|
+
|
|
51
|
+
# git log — quando mesma mudança aparece em múltiplos commits
|
|
52
|
+
git log --since=6.months --pretty=format: --name-only | sort | uniq -c | sort -rn | head -20
|
|
53
|
+
# arquivos co-modificados juntos = candidatos a shotgun
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Pattern 2: Detecção semântica (modernização 2026 via embeddings)
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
// PT-BR: workflow de detecção semântica de duplicação
|
|
60
|
+
// (sem precedente em 2004 — embedding APIs maduras só em 2023+)
|
|
61
|
+
|
|
62
|
+
import { OpenAI } from 'openai'
|
|
63
|
+
|
|
64
|
+
const client = new OpenAI({ apiKey: Deno.env.get('OPENAI_API_KEY') })
|
|
65
|
+
|
|
66
|
+
async function detectSemanticDuplicates(codeBlocks: CodeBlock[]) {
|
|
67
|
+
// Step 1: gerar embedding por bloco
|
|
68
|
+
const embeddings = await Promise.all(
|
|
69
|
+
codeBlocks.map(async (block) => ({
|
|
70
|
+
block,
|
|
71
|
+
embedding: (await client.embeddings.create({
|
|
72
|
+
model: 'text-embedding-3-small',
|
|
73
|
+
input: extractIntent(block), // function signature + comments + body summary
|
|
74
|
+
})).data[0].embedding,
|
|
75
|
+
}))
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
// Step 2: clusterizar por similaridade
|
|
79
|
+
const clusters: CodeBlock[][] = []
|
|
80
|
+
for (const item of embeddings) {
|
|
81
|
+
let assigned = false
|
|
82
|
+
for (const cluster of clusters) {
|
|
83
|
+
const sim = cosineSim(item.embedding, cluster[0].embedding)
|
|
84
|
+
if (sim >= 0.85) { // threshold canônico
|
|
85
|
+
cluster.push(item.block)
|
|
86
|
+
assigned = true
|
|
87
|
+
break
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (!assigned) clusters.push([item.block])
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Step 3: filtrar clusters com 3+ membros (regra do três)
|
|
94
|
+
return clusters.filter(c => c.length >= 3)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function extractIntent(block: CodeBlock): string {
|
|
98
|
+
// intent = function signature + leading comment + first 3 lines of body
|
|
99
|
+
return [
|
|
100
|
+
block.signature,
|
|
101
|
+
block.leadingComment ?? '',
|
|
102
|
+
block.body.slice(0, 3).join('\n'),
|
|
103
|
+
].join('\n')
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function cosineSim(a: number[], b: number[]): number {
|
|
107
|
+
let dot = 0, na = 0, nb = 0
|
|
108
|
+
for (let i = 0; i < a.length; i++) {
|
|
109
|
+
dot += a[i] * b[i]
|
|
110
|
+
na += a[i] ** 2
|
|
111
|
+
nb += b[i] ** 2
|
|
112
|
+
}
|
|
113
|
+
return dot / (Math.sqrt(na) * Math.sqrt(nb))
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Insight:** semantic search detecta:
|
|
118
|
+
- `computeTotalCents` em arquivo A
|
|
119
|
+
- `calc_total_in_cents` em arquivo B
|
|
120
|
+
- `getOrderTotalInPennies` em arquivo C
|
|
121
|
+
- 3 implementações diferentes mas mesma intenção. Regex puro não pega.
|
|
122
|
+
|
|
123
|
+
**Custo:** 1000 blocos × text-embedding-3-small ≈ $0.02. Praticamente grátis.
|
|
124
|
+
|
|
125
|
+
**Cross-suite:** `pgvector` self-hosted (skill `supabase-pgvector-rag` v1.8) pode hospedar embeddings sem dep externa.
|
|
126
|
+
|
|
127
|
+
### Pattern 3: Workflow extract-before-modify
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
1. Detectar shotgun surgery (sintática OR semântica)
|
|
131
|
+
2. CONFIRMAR comportamento idêntico via characterization tests
|
|
132
|
+
- Capturar output de CADA ocorrência com mesmo input
|
|
133
|
+
- Outputs devem ser idênticos (ou docs explicar diferenças intencionais)
|
|
134
|
+
3. EXTRACT — criar função/classe única
|
|
135
|
+
- Nome canônico (busca consenso: pelo menos 1 dos N nomes existentes está OK)
|
|
136
|
+
- Localização canônica (módulo de utils, ou domain layer adequada)
|
|
137
|
+
4. SUBSTITUIR cada ocorrência por chamada
|
|
138
|
+
- 1 commit por substituição
|
|
139
|
+
- Tests verdes a cada commit
|
|
140
|
+
5. AGORA mudança é em 1 lugar
|
|
141
|
+
6. Modify
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Pattern 4: Heurística de "vale extract?"
|
|
145
|
+
|
|
146
|
+
Trade-off entre custo de extract e benefício futuro:
|
|
147
|
+
|
|
148
|
+
| Ocorrências | Tamanho cada | Vale extract? |
|
|
149
|
+
|---|---|---|
|
|
150
|
+
| 2 | 5 linhas | NÃO — Rule of 2 (DRY pode ser violado uma vez) |
|
|
151
|
+
| 2 | 30+ linhas | TALVEZ — depende de churn esperado |
|
|
152
|
+
| 3 | 5+ linhas | SIM — Rule of 3 |
|
|
153
|
+
| 3+ | 10+ linhas | SIM forte |
|
|
154
|
+
| N | 1-2 linhas | TALVEZ — ganho marginal vs noise de função tiny |
|
|
155
|
+
| N | 50+ linhas | SIM máximo (extract para classe própria) |
|
|
156
|
+
|
|
157
|
+
### Pattern 5: Naming canônico
|
|
158
|
+
|
|
159
|
+
Função extraída precisa de nome que "ressoa" com TODAS as ocorrências originais. Estratégia:
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
1. Listar os N nomes (ou comments) das ocorrências:
|
|
163
|
+
- "computeTotalCents"
|
|
164
|
+
- "calcOrderTotal"
|
|
165
|
+
- "getCartTotalInCents"
|
|
166
|
+
|
|
167
|
+
2. Encontrar o COMUM SEMÂNTICO:
|
|
168
|
+
- "Total" presente em todos
|
|
169
|
+
- "Cents" / "Cents" / "InCents" — variantes
|
|
170
|
+
- Order/Cart — contexto chamador, não nome interno
|
|
171
|
+
|
|
172
|
+
3. Nome canônico: `computeOrderTotalCents` (verb + entity + unit explicit)
|
|
173
|
+
|
|
174
|
+
4. Documentar deprecation comments nas N localizações que usavam nomes diferentes.
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Pattern 6: Cross-module shotgun (mais difícil)
|
|
178
|
+
|
|
179
|
+
Quando duplicação está em camadas diferentes (e.g., 1 backend + 2 frontends):
|
|
180
|
+
|
|
181
|
+
```text
|
|
182
|
+
- Não extract para "shared module" sem pensar em deploy/release coupling
|
|
183
|
+
- Considerar: API contract centralizada (OpenAPI) + geração de types
|
|
184
|
+
- Considerar: SDK comum (TypeScript types compartilhados via package)
|
|
185
|
+
- Última resort: aceitar duplicação cross-stack (custo de unificação > benefício)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Anti-patterns
|
|
189
|
+
|
|
190
|
+
### ANTI: extract sem characterization
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
ANTI: detectou duplicação, extract direto, push.
|
|
194
|
+
|
|
195
|
+
PROBLEMA: as 3 ocorrências podem ter VARIAÇÕES sutis (1 retorna em
|
|
196
|
+
rounding diferente, outra trata null diferentemente). Sem
|
|
197
|
+
characterization, extract uniformiza E quebra a variante.
|
|
198
|
+
|
|
199
|
+
CERTO: characterize cada ocorrência ANTES de extract. Outputs
|
|
200
|
+
idênticos? extract OK. Outputs diferentes? document, decide se
|
|
201
|
+
quer uniformizar (com aceite de mudança comportamental) OR
|
|
202
|
+
deixe múltiplas (porque diferenças são intencionais).
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### ANTI: nome que só funciona em 1 das N localizações
|
|
206
|
+
|
|
207
|
+
```text
|
|
208
|
+
ANTI: extracted como "calcCartTotal" — mas era usado em 3 contextos:
|
|
209
|
+
Cart, Order, Quote.
|
|
210
|
+
|
|
211
|
+
PROBLEMA: callers de Order chamando calcCartTotal lê estranho. Reviewer
|
|
212
|
+
confundido. Refactor seguinte (rename) gera mais churn.
|
|
213
|
+
|
|
214
|
+
CERTO: nome neutro / contextualizado por parâmetro. `calcTotal(items)`
|
|
215
|
+
em vez de `calcCartTotal()`. Caller informa contexto via input,
|
|
216
|
+
extracted function é generic.
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### ANTI: detectar via line-level diff sem AST
|
|
220
|
+
|
|
221
|
+
```text
|
|
222
|
+
ANTI: jscpd com min-tokens 5. Reporta 200 "duplicações" — maioria
|
|
223
|
+
false positives (assertions de testes, imports, boilerplate).
|
|
224
|
+
|
|
225
|
+
PROBLEMA: signal/noise ruim. Equipe ignora reports.
|
|
226
|
+
|
|
227
|
+
CERTO: min-lines ≥ 10 + min-tokens ≥ 50 + ignore tests/. AST-based
|
|
228
|
+
(ast-grep, semgrep) é melhor — pega "função com mesma estrutura"
|
|
229
|
+
não "linhas idênticas".
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### ANTI: semantic search sem revisão humana
|
|
233
|
+
|
|
234
|
+
```text
|
|
235
|
+
ANTI: embedding similarity > 0.85 → automatically suggest extract.
|
|
236
|
+
|
|
237
|
+
PROBLEMA: false positives. 2 funções com nomes/comentários similares
|
|
238
|
+
mas implementações diferentes (`fetchUser` em backend vs
|
|
239
|
+
`fetchUser` em frontend service worker — completamente
|
|
240
|
+
diferentes mas embeddings 0.88).
|
|
241
|
+
|
|
242
|
+
CERTO: semantic search é PRIMEIRA passada. Cluster proposto vai para
|
|
243
|
+
review humano. Aceita/rejeita por cluster. Extract somente
|
|
244
|
+
após aprovação.
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### ANTI: extract para "future-proofing" speculative
|
|
248
|
+
|
|
249
|
+
```text
|
|
250
|
+
ANTI: "essa função vai ser usada em mais lugares no futuro, vou
|
|
251
|
+
extract agora".
|
|
252
|
+
|
|
253
|
+
PROBLEMA: YAGNI. Abstração premature gera função vazia /
|
|
254
|
+
parametrizada demais. Quando o "futuro" chega, abstração
|
|
255
|
+
não cabe.
|
|
256
|
+
|
|
257
|
+
CERTO: 3 usos REAIS = extract. Antes disso, código inline com TODO
|
|
258
|
+
é melhor (aceita duplicação temporária; extract quando 3º uso
|
|
259
|
+
aparece).
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Verificação
|
|
263
|
+
|
|
264
|
+
1. Detecção rodada (sintática + semântica se IA disponível)
|
|
265
|
+
2. Clusters com 3+ ocorrências reportados
|
|
266
|
+
3. Cada cluster validado por humano (não auto-extract)
|
|
267
|
+
4. Characterization de cada ocorrência ANTES de extract
|
|
268
|
+
5. Outputs idênticos confirmados (OR diferenças documentadas)
|
|
269
|
+
6. Nome canônico escolhido (resonates com todas N localizações)
|
|
270
|
+
7. 1 commit por substituição (revertível individual)
|
|
271
|
+
8. Tests verdes a cada commit
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Ver também
|
|
276
|
+
|
|
277
|
+
- [`_shared-legacy/glossary.md`](../_shared-legacy/glossary.md) — vocabulário (shotgun surgery, effect-narrowing)
|
|
278
|
+
- [`legacy-effect-analysis`](../legacy-effect-analysis/SKILL.md) — sketch detecta shotgun (mesma mudança em N lugares)
|
|
279
|
+
- [`legacy-extract-class`](../legacy-extract-class/SKILL.md) — quando shotgun é cluster grande, extract class em vez de extract method
|
|
280
|
+
- [`legacy-monster-methods`](../legacy-monster-methods/SKILL.md) — extract method canônico (precursor de extract class)
|
|
281
|
+
- [`legacy-characterization-tests`](../legacy-characterization-tests/SKILL.md) — characterize ANTES de extract para confirmar comportamento idêntico
|
|
282
|
+
- [`supabase-pgvector-rag`](../supabase-pgvector-rag/SKILL.md) (v1.8) — pgvector self-hosted para embeddings sem dep externa
|
|
283
|
+
- [`shotgun-surgery-detector`](../../agents/shotgun-surgery-detector.md) — agent que automatiza detecção semântica
|
|
284
|
+
|
|
285
|
+
*Material-fonte: Working Effectively with Legacy Code — Feathers, 2004 — Cap 21: "I'm Changing the Same Code All Over the Place".*
|
|
286
|
+
*Modernização (2026):* Detecção semântica via embeddings (text-embedding-3-small ou pgvector) — sem precedente em 2004; ML maduro só após 2018.
|