@brunosps00/dev-workflow 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -9
- package/lib/constants.js +10 -6
- package/lib/init.js +28 -0
- package/package.json +1 -1
- package/scaffold/en/agent-instructions.md +28 -3
- package/scaffold/en/commands/dw-analyze-project.md +64 -0
- package/scaffold/en/commands/dw-autopilot.md +64 -5
- package/scaffold/en/commands/dw-brainstorm.md +166 -23
- package/scaffold/en/commands/dw-bugfix.md +124 -26
- package/scaffold/en/commands/dw-intel.md +30 -3
- package/scaffold/en/commands/dw-pause.md +92 -0
- package/scaffold/en/commands/dw-qa.md +87 -11
- package/scaffold/en/commands/dw-resume.md +90 -0
- package/scaffold/en/commands/dw-review.md +22 -12
- package/scaffold/en/templates/bugfix-summary-template.md +66 -0
- package/scaffold/en/templates/concerns-template.md +59 -0
- package/scaffold/en/templates/state-template.md +59 -0
- package/scaffold/pt-br/agent-instructions.md +28 -3
- package/scaffold/pt-br/commands/dw-analyze-project.md +64 -0
- package/scaffold/pt-br/commands/dw-autopilot.md +64 -5
- package/scaffold/pt-br/commands/dw-brainstorm.md +166 -23
- package/scaffold/pt-br/commands/dw-bugfix.md +134 -18
- package/scaffold/pt-br/commands/dw-intel.md +30 -3
- package/scaffold/pt-br/commands/dw-pause.md +92 -0
- package/scaffold/pt-br/commands/dw-qa.md +87 -11
- package/scaffold/pt-br/commands/dw-resume.md +90 -0
- package/scaffold/pt-br/commands/dw-review.md +22 -12
- package/scaffold/pt-br/templates/bugfix-summary-template.md +66 -0
- package/scaffold/pt-br/templates/concerns-template.md +59 -0
- package/scaffold/pt-br/templates/state-template.md +59 -0
- package/scaffold/skills/dw-codebase-intel/SKILL.md +9 -5
- package/scaffold/skills/dw-codebase-intel/references/query-patterns.md +52 -0
- package/scaffold/skills/dw-memory/SKILL.md +26 -1
- package/scaffold/skills/dw-memory/references/context-budget.md +63 -0
- package/scaffold/skills/dw-simplification/SKILL.md +10 -5
- package/scaffold/skills/dw-simplification/references/deep-modules.md +105 -0
|
@@ -15,16 +15,28 @@ Você é o orquestrador de review. Roda Level 2 (PRD compliance / cobertura) e L
|
|
|
15
15
|
|
|
16
16
|
| Invocação | O que roda |
|
|
17
17
|
|-----------|------------|
|
|
18
|
-
| `/dw-review` | **Padrão.** Level 2 (cobertura PRD) + Level 3 (qualidade de código) em sequência. Relatório consolidado em
|
|
19
|
-
| `/dw-review --coverage-only` | Apenas Level 2 — mapeia cada requisito do PRD para o código que entrega. Pula qualidade. |
|
|
20
|
-
| `/dw-review --code-only` | Apenas Level 3 — qualidade / convenção / security checks. Pula mapeamento PRD. |
|
|
18
|
+
| `/dw-review` | **Padrão.** Level 2 (cobertura PRD) + Level 3 (qualidade de código) em sequência. Relatório consolidado em `<target>/QA/review-consolidated.md` (target resolve pra dir do PRD ou do bugfix; ver Resolução de Target). |
|
|
19
|
+
| `/dw-review --coverage-only` | Apenas Level 2 — mapeia cada requisito do PRD (ou escopo do bugfix) para o código que entrega. Pula qualidade. |
|
|
20
|
+
| `/dw-review --code-only` | Apenas Level 3 — qualidade / convenção / security checks. Pula mapeamento de PRD/escopo. |
|
|
21
|
+
| `/dw-review --bugfix <NNN-slug>` | Aponta para um bugfix em `.dw/bugfixes/NNN-slug/` em vez de um PRD. Level 2 mapeia o escopo do bugfix (TASK.md + fix-report.md + SUMMARY.md) para o código que entrega o fix; Level 3 checa o diff. Output: `.dw/bugfixes/NNN-slug/review/`. |
|
|
21
22
|
|
|
22
23
|
## Entradas
|
|
23
24
|
|
|
24
25
|
| Variável | Descrição | Exemplo |
|
|
25
26
|
|----------|-----------|---------|
|
|
26
|
-
| `{{PRD_PATH}}` | Caminho do dir PRD (auto-detect da branch ativa se omitido) | `.dw/spec/prd-invoice-export` |
|
|
27
|
-
| `{{
|
|
27
|
+
| `{{PRD_PATH}}` | Caminho do dir PRD (auto-detect da branch ativa se omitido; ignorado quando `--bugfix` é usado) | `.dw/spec/prd-invoice-export` |
|
|
28
|
+
| `{{BUGFIX_SLUG}}` | Slug do bugfix quando a flag `--bugfix` é usada | `001-login-nao-funciona` |
|
|
29
|
+
| `{{MODE}}` | `--coverage-only` / `--code-only` / `--bugfix <slug>` (opcional; default = ambos, target = PRD) | — |
|
|
30
|
+
|
|
31
|
+
## Resolução de Target
|
|
32
|
+
|
|
33
|
+
O review roda contra um de dois tipos de target. Compute `<target>` UMA VEZ no início; substitua onde aparecer `<target>` abaixo.
|
|
34
|
+
|
|
35
|
+
1. **Target PRD (padrão):** `<target>` = `{{PRD_PATH}}` (auto-detectado da branch ativa quando omitido). Artefatos lidos: `prd.md`, `techspec.md`, `tasks.md`, `tasks/<N>_task.md`, `tasks-validation.md`. Output em `<target>/QA/`. Nomes de arquivo: `review-coverage.md`, `dw-code-review.md`, `review-consolidated.md`.
|
|
36
|
+
|
|
37
|
+
2. **Target Bugfix (`--bugfix <slug>`):** `<target>` = `.dw/bugfixes/<slug>/`. Artefatos lidos: `TASK.md` (o plano de fix com tasks numeradas 1..≤5), `fix-report.md` (evidência de verify), `SUMMARY.md` (registro de uma página). Não há FRs no sentido de PRD — em vez disso, cada task numerada em `TASK.md` é a unidade de cobertura. Output em `<target>/review/`. Nomes: `review-coverage.md`, `dw-code-review.md`, `review-consolidated.md`.
|
|
38
|
+
|
|
39
|
+
Quando o target Bugfix é usado, o mapeamento de cobertura (Level 2) opera sobre as tasks numeradas do `TASK.md` (não FR-N.M); uma task é ENTREGUE quando (a) os arquivos que ela alegou tocar estão no diff e (b) o teste de regressão referenciado em `fix-report.md` existe e roda. Código órfão em modo bugfix é qualquer coisa no diff que não corresponde a uma task numerada — sinal forte de que o safety valve deveria ter escalado para `/dw-plan`.
|
|
28
40
|
|
|
29
41
|
## Skills Complementares
|
|
30
42
|
|
|
@@ -59,10 +71,8 @@ Quando disponíveis em `./.agents/skills/`, são invocadas como apoio analítico
|
|
|
59
71
|
### Comportamento
|
|
60
72
|
|
|
61
73
|
1. **Carregar artefatos:**
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
- `.dw/spec/<prd>/tasks.md` + per-task files → extrair trabalho commitado.
|
|
65
|
-
- `tasks-validation.md` → trazer status das dimensões.
|
|
74
|
+
- **Target PRD:** `<target>/prd.md` → extrair requisitos funcionais. `<target>/techspec.md` → extrair decisões arquiteturais. `<target>/tasks.md` + per-task files → extrair trabalho commitado. `<target>/tasks-validation.md` → trazer status das dimensões.
|
|
75
|
+
- **Target Bugfix:** `<target>/TASK.md` → extrair as tasks numeradas (1..≤5) e seus arquivos-alvo. `<target>/fix-report.md` → extrair evidência de verify e referência do teste de regressão. `<target>/SUMMARY.md` → extrair Sintoma, Causa Raiz, Arquivos Tocados, Verificação.
|
|
66
76
|
|
|
67
77
|
2. **Mapear cada FR para código:**
|
|
68
78
|
- Para cada `FR-N.M`, encontrar código que entrega (file path + line range + commit SHA).
|
|
@@ -78,7 +88,7 @@ Quando disponíveis em `./.agents/skills/`, são invocadas como apoio analítico
|
|
|
78
88
|
|
|
79
89
|
### Output
|
|
80
90
|
|
|
81
|
-
Salvo em
|
|
91
|
+
Salvo em `<target>/QA/review-coverage.md` (target PRD) ou `<target>/review/review-coverage.md` (target Bugfix):
|
|
82
92
|
|
|
83
93
|
```markdown
|
|
84
94
|
# Coverage Review
|
|
@@ -145,14 +155,14 @@ Se FALTANDO > 0, o veredicto sugere revisitar `/dw-plan tasks` pra escopar ou `/
|
|
|
145
155
|
|
|
146
156
|
### Output
|
|
147
157
|
|
|
148
|
-
Salvo em
|
|
158
|
+
Salvo em `<target>/QA/dw-code-review.md` (target PRD) ou `<target>/review/dw-code-review.md` (target Bugfix). Linha de verdict é uma de:
|
|
149
159
|
- **APROVADO** — todos os gates verdes; pronto pra commit + PR.
|
|
150
160
|
- **APROVADO COM RESSALVAS** — verde mas findings valem corrigir em follow-up (filed com severities).
|
|
151
161
|
- **REPROVADO** — ao menos um hard gate falhou. Especifique qual.
|
|
152
162
|
|
|
153
163
|
## Output consolidado (modo padrão)
|
|
154
164
|
|
|
155
|
-
Quando ambos níveis rodam, relatório consolidado em
|
|
165
|
+
Quando ambos níveis rodam, relatório consolidado em `<target>/QA/review-consolidated.md` (target PRD) ou `<target>/review/review-consolidated.md` (target Bugfix):
|
|
156
166
|
|
|
157
167
|
```markdown
|
|
158
168
|
# Review Consolidado
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: "1.0"
|
|
3
|
+
slug: ""
|
|
4
|
+
created: ""
|
|
5
|
+
status: "Fixed | In Review | QA Pending | Reverted"
|
|
6
|
+
severity: "Low | Medium | High"
|
|
7
|
+
related_concerns: []
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Bugfix Summary — {{NNN}}-{{slug}}
|
|
11
|
+
|
|
12
|
+
Registro de uma pagina de um bugfix. Arquivos irmaos neste diretorio:
|
|
13
|
+
|
|
14
|
+
- `TASK.md` — a triagem original, respostas das perguntas de clarificacao e o plano de fix que rodou
|
|
15
|
+
- `fix-report.md` — evidencia de verificacao (saida do `dw-verify` PASS, prova de reproducao, execucao do teste de regressao)
|
|
16
|
+
- `review/` — populado por `/dw-review --bugfix {{NNN}}-{{slug}}`
|
|
17
|
+
- `QA/` — populado por `/dw-qa --bugfix {{NNN}}-{{slug}}` (quando aplicavel)
|
|
18
|
+
|
|
19
|
+
## Sintoma
|
|
20
|
+
|
|
21
|
+
O que o usuario observou. Cite a descricao original do bug verbatim; nao parafraseie.
|
|
22
|
+
|
|
23
|
+
> _"…"_
|
|
24
|
+
|
|
25
|
+
## Causa Raiz
|
|
26
|
+
|
|
27
|
+
O que estava de fato quebrado, em uma frase. Nao o sintoma — a causa.
|
|
28
|
+
|
|
29
|
+
_…_
|
|
30
|
+
|
|
31
|
+
## Resolucao
|
|
32
|
+
|
|
33
|
+
O que mudou, em 2-4 bullets. Paths de arquivos, nao snippets.
|
|
34
|
+
|
|
35
|
+
- _mudanca 1_
|
|
36
|
+
- _mudanca 2_
|
|
37
|
+
|
|
38
|
+
## Arquivos Tocados
|
|
39
|
+
|
|
40
|
+
Lista completa, incluindo testes. <=5 — se mais, o safety valve deveria ter escalado para `/dw-plan`.
|
|
41
|
+
|
|
42
|
+
| Path | Mudanca |
|
|
43
|
+
|------|---------|
|
|
44
|
+
| `src/foo/bar.ts` | _fix cirurgico em X_ |
|
|
45
|
+
| `src/foo/bar.test.ts` | _teste de regressao adicionado_ |
|
|
46
|
+
|
|
47
|
+
## Verificacao
|
|
48
|
+
|
|
49
|
+
Como o fix foi provado, alem de "os testes passam".
|
|
50
|
+
|
|
51
|
+
- **Reproducao antes do fix:** _passo que disparava o bug, capturado_
|
|
52
|
+
- **Reproducao depois do fix:** _mesmo passo, agora passa_
|
|
53
|
+
- **Teste de regressao:** _nome + path_
|
|
54
|
+
- **Relatorio de verify:** `fix-report.md`
|
|
55
|
+
|
|
56
|
+
## Relacionado
|
|
57
|
+
|
|
58
|
+
- **Concerns tocados:** _refs de `.dw/rules/concerns.md` se o fix caiu em area flagada_
|
|
59
|
+
- **Bugfixes adjacentes:** _slugs de fixes anteriores no mesmo modulo, se houver_
|
|
60
|
+
- **Contexto de PRD:** _se o bug apareceu dentro de uma feature em andamento, link para o path do PRD_
|
|
61
|
+
|
|
62
|
+
## Followups
|
|
63
|
+
|
|
64
|
+
Pontas soltas que este fix descobriu mas nao resolveu. Adicione ao `.dw/STATE.md` Open-Loops ao fechar.
|
|
65
|
+
|
|
66
|
+
- _nenhum_
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: "1.0"
|
|
3
|
+
generated_by: dw-analyze-project (Step 9)
|
|
4
|
+
last_refreshed: ""
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Concerns — Mapa de Riscos
|
|
8
|
+
|
|
9
|
+
Mapa de riscos deste codebase. Nao sao convencoes ("como fazemos as coisas" — isso e `.dw/rules/`), nao e arquitetura ("como esta construido" — isso e `.dw/intel/arch.md`). Este arquivo responde uma unica pergunta: **onde e perigoso mexer?**
|
|
10
|
+
|
|
11
|
+
Carregado on-demand por `/dw-plan`, `/dw-run` e `/dw-bugfix` quando o alvo deles toca uma entrada abaixo. Auto-instalado pelo `/dw-analyze-project` Step 9; nunca bloqueia (ausencia = nenhuma area flagada ainda).
|
|
12
|
+
|
|
13
|
+
## Hot Spots
|
|
14
|
+
|
|
15
|
+
Arquivos ou modulos com churn alto, reports frequentes de bug ou historico repetido de "mexi aqui e quebrou algo". Mencione em PRDs que toquem a mesma area; adicione revisor extra ou passada extra de teste.
|
|
16
|
+
|
|
17
|
+
| Path | Por que e quente | Primeiro flag | Ultimo incidente |
|
|
18
|
+
|------|------------------|---------------|------------------|
|
|
19
|
+
| _ex. `src/auth/session.ts`_ | _3 fixes de token em 60d_ | _YYYY-MM-DD_ | _YYYY-MM-DD_ |
|
|
20
|
+
|
|
21
|
+
## Integracoes Fragis
|
|
22
|
+
|
|
23
|
+
Sistemas externos (APIs, filas, vendors, bancos legados) com historico de falhas silenciosas, drift de schema, surpresas de rate-limit ou comportamento nao-documentado. Codigo novo que toque eles precisa de tratamento explicito de retry/timeout/idempotencia.
|
|
24
|
+
|
|
25
|
+
| Integracao | Modo de falha | Mitigacao esperada |
|
|
26
|
+
|------------|---------------|--------------------|
|
|
27
|
+
| _ex. export SAP legado_ | _200 OK silencioso com body vazio quando source esta lockado_ | _checar tamanho do body; logar e alertar_ |
|
|
28
|
+
|
|
29
|
+
## Codigo Hostil
|
|
30
|
+
|
|
31
|
+
Funcoes especificas, regexes, parsers ou algoritmos dificeis de raciocinar — quem toca precisa entender 100% primeiro (ou reescrever, nao remendar). Suspeitos comuns: regex artesanal, parsers de string ad-hoc, serializadores custom, async com race condition, codigo de transacao manual.
|
|
32
|
+
|
|
33
|
+
| Path / funcao | Por que e hostil | Owner / contexto |
|
|
34
|
+
|---------------|------------------|------------------|
|
|
35
|
+
| _ex. `src/billing/parseInvoice.ts:parseLine`_ | _regex de 900 chars com 12 alternativas, sem comentarios_ | _Bruno escreveu em 2024; reescrever se quebrar_ |
|
|
36
|
+
|
|
37
|
+
## Historico de Bugs Conhecidos
|
|
38
|
+
|
|
39
|
+
Agregado de `.dw/bugfixes/*/SUMMARY.md` pelo `/dw-intel --build`. Lista modulos com >=2 fixes historicos. Leia junto com Hot Spots ao planejar trabalho relacionado.
|
|
40
|
+
|
|
41
|
+
| Modulo | Contagem de bugs | Slugs recentes |
|
|
42
|
+
|--------|------------------|----------------|
|
|
43
|
+
| _ex. `src/payments/`_ | _4_ | _002-stripe-webhook-retry, 007-refund-rounding_ |
|
|
44
|
+
|
|
45
|
+
## Tech Debt — Reconhecida
|
|
46
|
+
|
|
47
|
+
Pedacos de debt que o time concorda que existem. Nao sao para limpar oportunisticamente sem coordenacao — podem ser load-bearing de formas nao obvias.
|
|
48
|
+
|
|
49
|
+
| Area | Descricao do debt | Por que fica | Trigger de cleanup |
|
|
50
|
+
|------|-------------------|--------------|--------------------|
|
|
51
|
+
| _ex. `src/legacy/userMapper.ts`_ | _Dois codepaths paralelos de field-mapping_ | _Esperando migracao v3 da API_ | _Q3 2026 apos cutover do vendor_ |
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
**Como manter este arquivo:**
|
|
56
|
+
|
|
57
|
+
- `/dw-analyze-project` reescreve a cada execucao. Entradas escritas a mao entre `<!-- preserved:start -->` e `<!-- preserved:end -->` sao mantidas.
|
|
58
|
+
- Quando um bugfix descobrir uma nova area perigosa, adicione manualmente em Hot Spots e deixe a proxima analise confirmar.
|
|
59
|
+
- Promova entradas para `.dw/constitution.md` quando virarem regras nao-negociaveis ("nunca toque X sem ADR").
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: "1.0"
|
|
3
|
+
last_paused: ""
|
|
4
|
+
last_resumed: ""
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Estado da Sessao
|
|
8
|
+
|
|
9
|
+
Memoria de trabalho entre sessoes. Indice leve do que esta em andamento, do que foi decidido, do que ficou parado. Atualizado por `/dw-pause` (consolida) e lido por `/dw-resume` (orienta).
|
|
10
|
+
|
|
11
|
+
Diferente do `MEMORY.md` por-PRD (memoria de workflow para uma feature) ou dos ADRs (decisoes arquiteturais duraveis), este arquivo vive no nivel do projeto e sobrevive entre PRDs, branches e sessoes. Edite livremente entre pausas.
|
|
12
|
+
|
|
13
|
+
## Open Loops (Pontas Soltas)
|
|
14
|
+
|
|
15
|
+
O que esta em andamento — trabalho comecado mas nao terminado. Cada entrada: label curto + path/alvo + proxima acao concreta.
|
|
16
|
+
|
|
17
|
+
- _nenhum_
|
|
18
|
+
|
|
19
|
+
## Decisoes
|
|
20
|
+
|
|
21
|
+
Decisoes transversais que ainda nao viraram ADR (porque nao justificam um, ou porque a formalizacao foi adiada). Formato: `YYYY-MM-DD — decisao — contexto (1 linha)`.
|
|
22
|
+
|
|
23
|
+
- _nenhuma_
|
|
24
|
+
|
|
25
|
+
## Bloqueios
|
|
26
|
+
|
|
27
|
+
O que esta impedindo o avanco. Externo (esperando alguem), interno (lacuna de conhecimento) ou tecnico (tooling quebrado). Cada entrada: label curto + o que esta bloqueado + dono / condicao de desbloqueio.
|
|
28
|
+
|
|
29
|
+
- _nenhum_
|
|
30
|
+
|
|
31
|
+
## Todos
|
|
32
|
+
|
|
33
|
+
Pequenos follow-ups que nao justificam um PRD ou task. Uma linha cada. Limpe conforme forem feitos ou migrados para um PRD.
|
|
34
|
+
|
|
35
|
+
- _nenhum_
|
|
36
|
+
|
|
37
|
+
## Ideias Adiadas
|
|
38
|
+
|
|
39
|
+
Ideias consideradas mas parqueadas. Capture para nao perder; revisite quando o escopo mudar. Cada entrada: ideia + motivo do park + trigger de revisita (se conhecido).
|
|
40
|
+
|
|
41
|
+
- _nenhuma_
|
|
42
|
+
|
|
43
|
+
## Licoes
|
|
44
|
+
|
|
45
|
+
Pequenas licoes aprendidas no trabalho recente — padroes que funcionaram, pegadinhas, "da proxima vez eu...". Nao sao arquiteturais (essas vao para ADRs); sao operacionais.
|
|
46
|
+
|
|
47
|
+
- _nenhuma_
|
|
48
|
+
|
|
49
|
+
## Preferencias
|
|
50
|
+
|
|
51
|
+
Convencoes acordadas durante o trabalho que afetam como o agent deve se comportar dali em diante. Exemplos: "sempre rodar `pnpm typecheck` antes do commit", "preferir named exports a default exports em utils".
|
|
52
|
+
|
|
53
|
+
- _nenhuma_
|
|
54
|
+
|
|
55
|
+
## Notas
|
|
56
|
+
|
|
57
|
+
Bloco livre. Opcional.
|
|
58
|
+
|
|
59
|
+
- _nenhuma_
|
|
@@ -44,8 +44,9 @@ The intel directory is the contract. Every file is machine-parseable and referen
|
|
|
44
44
|
| `files.json` | File graph: per-file imports/exports/type | JSON |
|
|
45
45
|
| `apis.json` | API surface: routes, methods, params, source file | JSON |
|
|
46
46
|
| `deps.json` | Dependencies: version, type, used_by, invocation | JSON |
|
|
47
|
+
| `bugfixes.json` | Historical bugfix index aggregated from `.dw/bugfixes/*/SUMMARY.md` (slug, date, modules touched, related concerns, by_module map). Optional — present only if `.dw/bugfixes/` is non-empty. | JSON |
|
|
47
48
|
| `arch.md` | Human-readable architecture overview + key components + data flow | Markdown |
|
|
48
|
-
| `.last-refresh.json` | Timestamps + content hashes for incremental detection | JSON |
|
|
49
|
+
| `.last-refresh.json` | Timestamps + content hashes for incremental detection (now includes `bugfixes_indexed` count) | JSON |
|
|
49
50
|
|
|
50
51
|
Schemas are documented in `references/intel-format.md`.
|
|
51
52
|
|
|
@@ -61,9 +62,10 @@ This skill ships ONE agent — `intel-updater` — which produces machine-readab
|
|
|
61
62
|
|
|
62
63
|
1. **`/dw-intel --build`** is invoked.
|
|
63
64
|
2. The command spawns `intel-updater` with `focus: full` (first run) or `focus: partial --files <paths>` (incremental).
|
|
64
|
-
3. The agent reads source files (using Glob/Read/Grep; no Bash file listing for cross-platform safety) and writes the
|
|
65
|
-
4.
|
|
66
|
-
5.
|
|
65
|
+
3. The agent reads source files (using Glob/Read/Grep; no Bash file listing for cross-platform safety) and writes the intel files (`stack.json`, `files.json`, `apis.json`, `deps.json`, `arch.md`).
|
|
66
|
+
4. If `.dw/bugfixes/` exists and contains at least one `SUMMARY.md`, the agent additionally scans every SUMMARY frontmatter + Files Touched section and writes `bugfixes.json`. SUMMARY files with invalid frontmatter are logged and skipped.
|
|
67
|
+
5. The agent writes `.last-refresh.json` with timestamps + hashes for incremental change detection on the next run, including a `bugfixes_indexed` count.
|
|
68
|
+
6. `/dw-intel --build` reports completion and invites the user to query via `/dw-intel "<question>"`.
|
|
67
69
|
|
|
68
70
|
For human-readable analysis (architecture overview, module conventions, anti-patterns), run `/dw-analyze-project` after `/dw-intel --build` — it reads `.dw/intel/` as input and produces `.dw/rules/`.
|
|
69
71
|
|
|
@@ -88,7 +90,7 @@ If no `.dw/intel/` exists at all, `/dw-intel` falls back to `.dw/rules/` (seeded
|
|
|
88
90
|
- **Cross-platform**: use Glob/Read/Grep; never Bash `ls`/`find`/`cat` (those break on Windows).
|
|
89
91
|
- **Forbidden files**: never read `.env*` (except `.env.example`/`.env.template`), `*.key`, `*.pem`, `*.pfx`, `*.p12`, `*.keystore`, `*.jks`, `id_rsa`, `id_ed25519`, or files matching `*credential*`/`*secret*` in name. Skip silently if encountered.
|
|
90
92
|
- **Excluded directories**: `node_modules/`, `.git/`, `dist/`, `build/`, `.dw/` (planning docs, not project code).
|
|
91
|
-
- **Output budget**: `files.json` ≤2K tokens, `apis.json` ≤1.5K, `deps.json` ≤1K, `stack.json` ≤500, `arch.md` ≤1.5K. For large repos, prioritize coverage of key files over exhaustive listing.
|
|
93
|
+
- **Output budget**: `files.json` ≤2K tokens, `apis.json` ≤1.5K, `deps.json` ≤1K, `stack.json` ≤500, `arch.md` ≤1.5K, `bugfixes.json` ≤1K. For large repos, prioritize coverage of key files over exhaustive listing. For `bugfixes.json`, keep one-line symptom/root-cause summaries; do not embed full SUMMARY.md content.
|
|
92
94
|
|
|
93
95
|
## References
|
|
94
96
|
|
|
@@ -100,3 +102,5 @@ If no `.dw/intel/` exists at all, `/dw-intel` falls back to `.dw/rules/` (seeded
|
|
|
100
102
|
## Inspired by
|
|
101
103
|
|
|
102
104
|
Adapted from [`get-shit-done-cc`](https://github.com/gsd-build/get-shit-done) (`gsd-intel-updater`) by gsd-build (MIT license). Core schemas (`files.json`, `apis.json`, `deps.json`, `stack.json`, `arch.md`) and incremental update protocol preserved. Path conventions changed from `.planning/intel/` to `.dw/intel/`. CLI tooling (`gsd-sdk query intel.*`) replaced by agent-driven inline operations (no separate runtime). The companion `gsd-codebase-mapper` agent (human-readable analysis docs) was NOT ported — its scope overlaps with the existing `/dw-analyze-project` command which writes to `.dw/rules/`.
|
|
105
|
+
|
|
106
|
+
The `bugfixes.json` index and the `bugfix-history` / `risk-area` query shapes (see `references/query-patterns.md`) were added in v1.0.2 to enable cross-skill awareness of `.dw/bugfixes/` — adapted from the operational-memory pattern in [`tech-leads-club/agent-skills/tlc-spec-driven`](https://github.com/tech-leads-club/agent-skills/tree/main/packages/skills-catalog/skills/(development)/tlc-spec-driven) (CC-BY-4.0, Felipe Rodrigues). The original skill maintains a single `STATE.md`; dev-workflow splits this into project-level `.dw/STATE.md` (session continuity) and a queryable `bugfixes.json` (historical fixes), which compose with the existing per-PRD `MEMORY.md`.
|
|
@@ -16,6 +16,8 @@ The command classifies the query into one of these shapes before searching:
|
|
|
16
16
|
| **api-list** | "list endpoints", "what routes exist?" | `apis.json` | — |
|
|
17
17
|
| **find-export** | "where is `createServer` exported from?", "find the `userSchema` symbol" | `files.json` (search `exports` arrays) | grep fallback |
|
|
18
18
|
| **convention** | "what's the file naming convention?", "are tests co-located?" | `arch.md` | `.dw/rules/` if available |
|
|
19
|
+
| **bugfix-history** | "bugs in `src/auth/`?", "recent fixes touching login?", "what broke in payments?", "fix history for the export feature" | `bugfixes.json` | `.dw/rules/concerns.md`, `.dw/bugfixes/<NNN-slug>/SUMMARY.md` for top hits |
|
|
20
|
+
| **risk-area** | "is `src/auth/session.ts` risky?", "what's fragile here?", "where are the hot spots?", "tech debt in payments?" | `.dw/rules/concerns.md` | `bugfixes.json` (cross-ref bug history for the same module) |
|
|
19
21
|
|
|
20
22
|
## Match algorithm
|
|
21
23
|
|
|
@@ -122,6 +124,56 @@ Users (5)
|
|
|
122
124
|
Orders (5) ...
|
|
123
125
|
```
|
|
124
126
|
|
|
127
|
+
### Query: "bugs in src/auth/?"
|
|
128
|
+
|
|
129
|
+
**Shape:** bugfix-history
|
|
130
|
+
|
|
131
|
+
**Process:**
|
|
132
|
+
1. Read `bugfixes.json`, look up `by_module["src/auth/"]`.
|
|
133
|
+
2. For each slug returned, fetch the matching `fixes[]` entry (one-line symptom + root cause + date).
|
|
134
|
+
3. Cross-reference `.dw/rules/concerns.md` — if `src/auth/` appears under Hot Spots or Known Bug History, surface that callout.
|
|
135
|
+
4. Return chronological list with paths to the full SUMMARY.md for the top 3.
|
|
136
|
+
|
|
137
|
+
**Output:**
|
|
138
|
+
```
|
|
139
|
+
3 historical fixes touched src/auth/ (concerns.md flags it as a Hot Spot — 4 fixes in 60d):
|
|
140
|
+
|
|
141
|
+
- 007-refresh-token-leak (2026-03-12, Fixed, High)
|
|
142
|
+
Symptom: refresh token survived sign-out
|
|
143
|
+
Root cause: session map keyed by user id, not session id
|
|
144
|
+
→ .dw/bugfixes/007-refresh-token-leak/SUMMARY.md
|
|
145
|
+
|
|
146
|
+
- 003-mfa-skip-on-redirect (2026-02-04, Fixed, Medium)
|
|
147
|
+
Symptom: redirect chain bypassed MFA check
|
|
148
|
+
→ .dw/bugfixes/003-mfa-skip-on-redirect/SUMMARY.md
|
|
149
|
+
|
|
150
|
+
- 001-login-not-working (2026-01-20, Fixed, Medium)
|
|
151
|
+
Symptom: 500 on POST /login when email casing varied
|
|
152
|
+
→ .dw/bugfixes/001-login-not-working/SUMMARY.md
|
|
153
|
+
|
|
154
|
+
Consider adding a regression-test guard before further changes here.
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Query: "what's fragile in payments?"
|
|
158
|
+
|
|
159
|
+
**Shape:** risk-area
|
|
160
|
+
|
|
161
|
+
**Process:**
|
|
162
|
+
1. Read `.dw/rules/concerns.md`. Search each section (Hot Spots, Fragile Integrations, Hostile Code, Known Bug History, Tech Debt) for `payments`.
|
|
163
|
+
2. For Known Bug History matches, cross-reference `bugfixes.json` `by_module["src/payments/"]` to enumerate recent slugs.
|
|
164
|
+
3. Return one paragraph per concerns.md section that matched, with cross-ref to the bugfix slugs.
|
|
165
|
+
|
|
166
|
+
**Output:**
|
|
167
|
+
```
|
|
168
|
+
Three risk signals for src/payments/:
|
|
169
|
+
|
|
170
|
+
Hot Spot: 5 commits in last 30 days; 2 historical bugfixes (refund-rounding, stripe-webhook-retry).
|
|
171
|
+
Fragile Integration: Stripe webhook delivery — concerns.md notes "silent 200 OK when signature header is absent".
|
|
172
|
+
Hostile Code: src/payments/parseInvoice.ts:parseLine — 900-char regex, no comments; original author flagged "rewrite if it breaks".
|
|
173
|
+
|
|
174
|
+
See: .dw/rules/concerns.md, .dw/bugfixes/{002-stripe-webhook-retry,007-refund-rounding}/SUMMARY.md
|
|
175
|
+
```
|
|
176
|
+
|
|
125
177
|
## Stale-index handling
|
|
126
178
|
|
|
127
179
|
Before answering, check `.dw/intel/.last-refresh.json`:
|
|
@@ -145,6 +145,29 @@ When flagged for compaction, apply inline:
|
|
|
145
145
|
4. **Rewrite** retained items as short factual bullets. No narrative logs, no chronological play-by-play.
|
|
146
146
|
5. Keep the default section headings intact. Remove empty sections only if truly unused.
|
|
147
147
|
|
|
148
|
+
## Context Budget
|
|
149
|
+
|
|
150
|
+
Memory is part of a broader **context budget** the agent must respect during execution. A blown budget degrades reasoning before any output is produced — the model starts missing requirements, drops constraints, and reverts to averaged-over-training answers. Full guidance: [`references/context-budget.md`](references/context-budget.md).
|
|
151
|
+
|
|
152
|
+
**Targets:**
|
|
153
|
+
|
|
154
|
+
- **Total active context:** under **40k tokens** (rough working budget across PRD + TechSpec + tasks + MEMORY.md + per-task memory + open files).
|
|
155
|
+
- **Reserve:** at least **120k tokens** of headroom for actual reasoning, tool output, and the model's response stream.
|
|
156
|
+
- **Hard ceiling per memory file:** `MEMORY.md` ≤ 6KB; `<N>_memory.md` ≤ 3KB. Past those, compact instead of growing.
|
|
157
|
+
|
|
158
|
+
**Anti-co-load rules** (apply on every load):
|
|
159
|
+
|
|
160
|
+
1. Never load two PRD specs in the same context. If switching PRDs, drop the previous PRD's spec/techspec/tasks references from the active set.
|
|
161
|
+
2. Never load multiple archived `.dw/bugfixes/` SUMMARY.md files together — load only what's needed for the active fix or query.
|
|
162
|
+
3. Never load `.dw/intel/files.json` and `.dw/intel/deps.json` simultaneously when answering a single question — pick the primary per query shape (see `dw-codebase-intel/references/query-patterns.md`).
|
|
163
|
+
4. Never load a design proposal AND the prior design's full text — if comparing, summarize the prior into 5-10 lines.
|
|
164
|
+
|
|
165
|
+
**Monitoring signal:**
|
|
166
|
+
|
|
167
|
+
If the agent finds itself reading large files repeatedly or summarizing the same fact across multiple turns, that's a budget signal. Compact memory and explicitly drop unrelated loaded context before proceeding. Note this in `MEMORY.md` under Handoff Notes so the next task starts lean.
|
|
168
|
+
|
|
169
|
+
This budget is doctrine, not a hard gate. No command currently rejects work for exceeding 40k. The discipline lives here because future sessions read this skill first.
|
|
170
|
+
|
|
148
171
|
## Error Handling
|
|
149
172
|
|
|
150
173
|
- If any caller-provided memory path is missing, stop and report the mismatch instead of guessing another path.
|
|
@@ -165,6 +188,8 @@ Ported from Compozy's `cy-workflow-memory` skill (`/tmp/compozy/.agents/skills/c
|
|
|
165
188
|
|
|
166
189
|
- Paths are `.dw/spec/<prd-slug>/` instead of `.compozy/tasks/<name>/`.
|
|
167
190
|
- Task-local file is `<N>_memory.md` next to `<N>_task.md` (mirrors the existing dev-workflow task layout).
|
|
168
|
-
- Inline Compaction Rules (Compozy keeps them in `references/memory-guidelines.md`);
|
|
191
|
+
- Inline Compaction Rules (Compozy keeps them in `references/memory-guidelines.md`); the budget discipline was extracted to `references/context-budget.md` because it's about model behavior, not file management.
|
|
169
192
|
|
|
170
193
|
Credit: Compozy project (https://github.com/compozy/compozy).
|
|
194
|
+
|
|
195
|
+
The Context Budget section adapts the context-loading discipline from [`tech-leads-club/agent-skills/tlc-spec-driven`](https://github.com/tech-leads-club/agent-skills/tree/main/packages/skills-catalog/skills/(development)/tlc-spec-driven) (CC-BY-4.0, Felipe Rodrigues). The target, the anti-co-load rules, and the "monitoring signal" framing come from there; the integration with two-tier memory and the specific file ceilings are dev-workflow-specific.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Context Budget — Discipline
|
|
2
|
+
|
|
3
|
+
A working context window is finite. Past about 40k tokens of active content, model output quality degrades — the model starts to miss requirements, lose constraints, blur details across sources, and revert to training-set averages. This file codifies the discipline that keeps active context lean across a long dev-workflow session.
|
|
4
|
+
|
|
5
|
+
## The numbers
|
|
6
|
+
|
|
7
|
+
- **Target active load:** under **40k tokens** total — PRD, TechSpec, tasks, MEMORY.md, per-task memory, all open files together.
|
|
8
|
+
- **Reasoning reserve:** **120k+ tokens** of headroom for tool output, model thinking, and response generation.
|
|
9
|
+
- **Soft alert:** when active load crosses **30k tokens**, plan to compact before the next major task.
|
|
10
|
+
- **Compaction threshold for `MEMORY.md`:** ≤ 6KB on disk.
|
|
11
|
+
- **Compaction threshold for `<N>_memory.md`:** ≤ 3KB on disk.
|
|
12
|
+
|
|
13
|
+
These are doctrine, not enforced by any hard gate. The cost of breaking them is degraded output, not a command failure. Catch it yourself; the framework can't.
|
|
14
|
+
|
|
15
|
+
## The anti-co-load rules
|
|
16
|
+
|
|
17
|
+
Each is a "do not load both simultaneously" pairing. Pick one; if you must consult the other, summarize it to 5–10 lines first and drop the full version.
|
|
18
|
+
|
|
19
|
+
1. **Two PRDs at once.** Working on `prd-foo`, then user asks about `prd-bar`? Finish `prd-foo`'s active turn first, drop its spec/techspec/tasks from active context, then load `prd-bar`. Never carry both spec sets.
|
|
20
|
+
|
|
21
|
+
2. **Multiple archived bugfix SUMMARY.md files.** Bugfix history queries should go through `.dw/intel/bugfixes.json` (compact, indexed), not by reading 20 SUMMARY.md files. Read individual SUMMARY.md only when the user is acting on that specific fix.
|
|
22
|
+
|
|
23
|
+
3. **Files.json + deps.json simultaneously.** They overlap. Each query has a primary file per `dw-codebase-intel/references/query-patterns.md`. Pick the primary; consult the secondary only if the primary returns nothing.
|
|
24
|
+
|
|
25
|
+
4. **A design proposal AND its predecessor's full text.** When comparing two designs, summarize the older one to 5–10 lines (the deltas the new one addresses) and reference it that way. Don't carry both in full.
|
|
26
|
+
|
|
27
|
+
5. **Per-task memories from non-adjacent tasks.** Only the current task's `<N>_memory.md` and the immediately-previous one (for handoff) belong in active context. Older `<N>_memory.md` files are durable storage — read them when explicitly handing back to an old task, not as part of routine loading.
|
|
28
|
+
|
|
29
|
+
## The monitoring signal
|
|
30
|
+
|
|
31
|
+
You will not see a token counter. You can't measure your own budget directly. But these are observable proxies that mean **you are over budget**:
|
|
32
|
+
|
|
33
|
+
- You are reading the same file twice in the same session without it having changed.
|
|
34
|
+
- You are summarizing the same fact across multiple turns to keep it in scope.
|
|
35
|
+
- You are answering questions by re-deriving from the repo what a memory file would tell you in one line.
|
|
36
|
+
- You are confusing details between two PRDs, tasks, or designs.
|
|
37
|
+
- Your turn outputs are getting longer to compensate for context that is silently slipping out of the model's attention.
|
|
38
|
+
|
|
39
|
+
When you notice any of these, stop:
|
|
40
|
+
|
|
41
|
+
1. Compact `MEMORY.md` and the active `<N>_memory.md` per the Compaction Rules in `SKILL.md`.
|
|
42
|
+
2. Explicitly state in chat what you are dropping from active context.
|
|
43
|
+
3. Note the budget event in `MEMORY.md` under Handoff Notes ("compacted at task N — see this section for what was dropped").
|
|
44
|
+
4. Resume the turn.
|
|
45
|
+
|
|
46
|
+
## What is NOT a budget problem
|
|
47
|
+
|
|
48
|
+
These look like budget problems but aren't — don't compact for them:
|
|
49
|
+
|
|
50
|
+
- **A genuinely complex task.** Some features legitimately need many files. Read what you need; the alternative (working from partial context) is worse.
|
|
51
|
+
- **A long verification report.** Verify output can be long. Don't summarize it before logging it to disk; truncate the chat surface, not the artifact.
|
|
52
|
+
- **A long user message.** The user wrote what they wrote. Don't compact to shave their words.
|
|
53
|
+
- **The first PRD load of a new feature.** First-load is fine; second-load of the same PRD in the same turn is the signal.
|
|
54
|
+
|
|
55
|
+
## Integration with other skills
|
|
56
|
+
|
|
57
|
+
- **`dw-memory` (this skill)**: compaction is the lever for memory files; this file describes when and why.
|
|
58
|
+
- **`dw-codebase-intel`**: `query-patterns.md` defines the primary-vs-secondary rule that anti-co-load rule #3 references.
|
|
59
|
+
- **`dw-verify`**: a budget-related degradation may show up as a verify regression. If verify keeps failing on facts the PRD already states, suspect budget before suspecting code.
|
|
60
|
+
|
|
61
|
+
## Source
|
|
62
|
+
|
|
63
|
+
Adapted from [`tech-leads-club/agent-skills/tlc-spec-driven`](https://github.com/tech-leads-club/agent-skills/tree/main/packages/skills-catalog/skills/(development)/tlc-spec-driven) (CC-BY-4.0, Felipe Rodrigues). The 40k target, the anti-co-load principle, and the monitoring-signal framing come from there. The specific anti-co-load pairings, file-size ceilings, and the integration with `dw-memory`/`dw-codebase-intel` are dev-workflow-specific.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dw-simplification
|
|
3
|
-
description: Use when simplifying code. Chesterton's Fence (
|
|
3
|
+
description: Use when simplifying code. Chesterton's Fence (WHY first), behavior-preserving refactor, complexity metrics, deep-modules analysis. Triggers from /dw-review and /dw-brainstorm refactor-audit.
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Read
|
|
6
6
|
- Edit
|
|
@@ -18,7 +18,7 @@ Behavioral discipline for simplifying code without breaking it. The trap of refa
|
|
|
18
18
|
Read this skill when:
|
|
19
19
|
|
|
20
20
|
- `/dw-review --code-only` flagged a complexity issue (deep nesting, long function, duplication).
|
|
21
|
-
- `/dw-brainstorm
|
|
21
|
+
- `/dw-brainstorm` dispatched its **refactor-audit** mode and proposed a simplification target.
|
|
22
22
|
- The user explicitly asks to "clean this up" / "simplify X".
|
|
23
23
|
- During `/dw-run` if the implementation accidentally produced complex code that wants pre-commit cleanup.
|
|
24
24
|
|
|
@@ -117,11 +117,13 @@ For changes that altered cyclomatic complexity, optionally run a complexity anal
|
|
|
117
117
|
|
|
118
118
|
In the formal Level 3 review (post-Level 2 chain from `dw-review-implementation`), code-review flags complexity issues using the patterns above. Each flagged issue references this skill: "consider simplifying via guard clauses; apply Chesterton's Fence — verify why the nested check exists before flattening."
|
|
119
119
|
|
|
120
|
-
## How
|
|
120
|
+
## How `/dw-brainstorm` refactor-audit mode uses this
|
|
121
|
+
|
|
122
|
+
The refactor-audit mode dispatched by `/dw-brainstorm` catalogs code smells (Fowler vocabulary) AND runs the deep-modules analysis (`references/deep-modules.md`) against the target area. For each smell or shallow-module flag, the proposed refactor cites:
|
|
121
123
|
|
|
122
|
-
The analysis catalogs code smells (Fowler vocabulary). For each smell, the proposed refactor cites:
|
|
123
124
|
1. Which simplification rule applies (early return / extract method / lookup table / etc.).
|
|
124
125
|
2. Whether Chesterton's Fence concerns block the refactor (existing tests inadequate? no recent commits explaining the structure? → flag as YELLOW, don't act).
|
|
126
|
+
3. Whether the deep-modules test points the other way (some "code smells" are actually deep-module wrappers that absorb complexity; the fix is to make the wrapper deeper, not to flatten it).
|
|
125
127
|
|
|
126
128
|
## Anti-patterns
|
|
127
129
|
|
|
@@ -136,7 +138,10 @@ The analysis catalogs code smells (Fowler vocabulary). For each smell, the propo
|
|
|
136
138
|
- `references/chestertons-fence.md` — the protocol in detail; case studies of "obvious-but-wrong" removals.
|
|
137
139
|
- `references/complexity-metrics.md` — when each metric (cyclomatic, cognitive, depth, fanout) actually matters; how to measure cheaply.
|
|
138
140
|
- `references/behavior-preserving.md` — characterization tests, refactor with test gate, rollback patterns, codemod tooling per language.
|
|
141
|
+
- `references/deep-modules.md` — high-leverage modules behind small interfaces; deletion test, locality, leverage, seam, adapter diagnostic; anti-patterns (shallow wrapper, god-module). Invoked by `/dw-brainstorm` refactor-audit mode.
|
|
139
142
|
|
|
140
143
|
## Inspired by
|
|
141
144
|
|
|
142
|
-
Adapted from [`addyosmani/agent-skills/code-simplification`](https://github.com/addyosmani/agent-skills) by Addy Osmani (MIT license). Core principles (Chesterton's Fence, behavior preservation, scope discipline, Rule of 500) preserved. dev-workflow integration: invoked by `dw-code-review` and
|
|
145
|
+
Adapted from [`addyosmani/agent-skills/code-simplification`](https://github.com/addyosmani/agent-skills) by Addy Osmani (MIT license). Core principles (Chesterton's Fence, behavior preservation, scope discipline, Rule of 500) preserved. dev-workflow integration: invoked by `dw-code-review` and `/dw-brainstorm` refactor-audit mode via Complementary Skills.
|
|
146
|
+
|
|
147
|
+
The deep-modules reference is adapted from [`mattpocock/skills/improve-codebase-architecture`](https://github.com/mattpocock/skills/tree/main/improve-codebase-architecture) by Matt Pocock (MIT license). Core framing (deep modules = high leverage at small interface, deletion test, shallow-wrapper anti-pattern) preserved; paths and integration points rebased on dev-workflow conventions.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Deep modules — high leverage at small interface
|
|
2
|
+
|
|
3
|
+
A **deep module** absorbs complexity behind a narrow public surface. Its callers see a small, stable API and get a lot of work done per call. A **shallow module** is the opposite — small interface AND small implementation, so it adds an indirection without absorbing any complexity. Or worse: a god-module, deep implementation BUT huge interface, where the surface itself is the complexity.
|
|
4
|
+
|
|
5
|
+
The refactor-audit mode of `/dw-brainstorm` checks every candidate module against this framing alongside the Fowler smell taxonomy. A "code smell" can mislead if the construct is actually a deep wrapper doing its job correctly.
|
|
6
|
+
|
|
7
|
+
## The premise
|
|
8
|
+
|
|
9
|
+
Good abstractions hide complexity. The metric isn't "how short is the code?" — it's "how much complexity does the interface eliminate per unit of public surface area?"
|
|
10
|
+
|
|
11
|
+
- **Deep module**: 1000 lines of implementation, 3 public functions. Caller does NOT need to know the 1000 lines.
|
|
12
|
+
- **Shallow module**: 50 lines of implementation, 8 public functions. Caller has to learn all 8 to use the 50 productively.
|
|
13
|
+
- **God-module**: 5000 lines of implementation, 60 public functions. Surface area is itself unmanageable.
|
|
14
|
+
|
|
15
|
+
The deep version wins not because it's shorter overall (it's longer), but because the cost of using it is concentrated in the implementation, not spread to every caller.
|
|
16
|
+
|
|
17
|
+
## Diagnostic checklist
|
|
18
|
+
|
|
19
|
+
When the refactor-audit mode evaluates a module, ask these in order:
|
|
20
|
+
|
|
21
|
+
### 1. Deletion test
|
|
22
|
+
|
|
23
|
+
> If this module were deleted, how many call sites would break?
|
|
24
|
+
|
|
25
|
+
- **0–1 callers**: the module isn't pulling its weight. Inline it; the abstraction is shallower than the call sites' real shape. Mark this as `low` priority candidate for removal.
|
|
26
|
+
- **2–3 callers**: borderline. Look at what each caller does with the result — if they immediately wrap/unwrap, the module is shallow. If they consume the result directly, leave it alone.
|
|
27
|
+
- **4+ callers**: the module is at least somewhat load-bearing. Move to next checks.
|
|
28
|
+
|
|
29
|
+
### 2. Locality test
|
|
30
|
+
|
|
31
|
+
> Does the caller pass everything the module needs, OR does the module reach into globals / shared state to fill gaps?
|
|
32
|
+
|
|
33
|
+
A deep module is **self-contained**: callers pass in arguments, get back results. A module that reads from `process.env`, a shared singleton, or implicit thread-local state has a deeper coupling than its interface admits — the caller has to know about the hidden inputs too.
|
|
34
|
+
|
|
35
|
+
If the module reaches into shared state, its **effective interface** is bigger than what the function signature shows. That's a hidden shallowness — the public surface lies about its real cost.
|
|
36
|
+
|
|
37
|
+
### 3. Leverage test
|
|
38
|
+
|
|
39
|
+
> LOC saved per caller × number of callers — what's the multiplicative payoff?
|
|
40
|
+
|
|
41
|
+
Crude formula: if each caller would otherwise write ~N lines of inline code to replace this module's call, and there are M callers, the module's leverage is N × M. A module whose leverage is < 2× its own LOC is shallow — it's not absorbing enough complexity to justify itself.
|
|
42
|
+
|
|
43
|
+
### 4. Seam test
|
|
44
|
+
|
|
45
|
+
> How often does the public interface change relative to the implementation?
|
|
46
|
+
|
|
47
|
+
A stable public interface with frequently-changing implementation is the **ideal seam** — callers stay put while internals evolve. An interface that changes every few months means callers track it; the abstraction is leaking.
|
|
48
|
+
|
|
49
|
+
Check `git log --oneline -- <module>` against `git log --oneline -- <module-public-surface-file>`. If they move together, the seam is weak.
|
|
50
|
+
|
|
51
|
+
### 5. Adapter test
|
|
52
|
+
|
|
53
|
+
> Does this module mediate between two foreign vocabularies?
|
|
54
|
+
|
|
55
|
+
The best deep modules are **adapters** — they translate between two domains that have different naming conventions, error semantics, or state models. A module that doesn't mediate between domains is harder to justify as deep; it's probably either a passthrough (shallow) or just a piece of the same domain stretched across files (cohesion issue).
|
|
56
|
+
|
|
57
|
+
## Anti-patterns
|
|
58
|
+
|
|
59
|
+
### Shallow wrapper
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
// shallow — passthrough with one line of "work"
|
|
63
|
+
export function getUserName(id: string) {
|
|
64
|
+
return db.users.findById(id).name;
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The wrapper saves the caller 8 characters (`.name`) and forces them to learn a new function name. The leverage is < 1. Inline it.
|
|
69
|
+
|
|
70
|
+
When to keep a one-liner: it's an **adapter** that locks down ONE meaning of a query. If `getUserName` exists specifically because there are 4 candidate fields (`name`, `displayName`, `username`, `fullName`) and the team's canonical answer is "use `name`", the function IS pulling its weight by serving as the project's vocabulary anchor. Document the WHY in the function body.
|
|
71
|
+
|
|
72
|
+
### God-module
|
|
73
|
+
|
|
74
|
+
A class with 60 public methods is shallow even if each method is 100 lines, because the caller has to learn 60 concepts. Split by **role**: what is the smallest subset of methods a caller typically uses together? Each subset becomes a deep module of its own.
|
|
75
|
+
|
|
76
|
+
### Implementation-leak abstraction
|
|
77
|
+
|
|
78
|
+
A module that returns its internal representation directly (`return this.cache;`) makes callers depend on the internals. The first time the cache shape changes, every caller breaks. Wrap or copy on egress.
|
|
79
|
+
|
|
80
|
+
## When refactor-audit raises a smell, also check deep-modules
|
|
81
|
+
|
|
82
|
+
The combined verdict:
|
|
83
|
+
|
|
84
|
+
| Fowler smell | Deep-modules check | Action |
|
|
85
|
+
|--------------|--------------------|--------|
|
|
86
|
+
| Long Method | Is the method INSIDE a deep module that callers don't see? | If yes, leave it — internal complexity is OK in deep modules. If no, extract. |
|
|
87
|
+
| Large Class | Is the public surface narrow despite the line count? | If yes, leave it — that's deep. If no, split by role. |
|
|
88
|
+
| Long Parameter List | Does each parameter represent a real choice the caller makes? | If yes, the deep module is forcing necessary configuration; introduce a config object. If parameters are derivable from each other, reduce. |
|
|
89
|
+
| Feature Envy | Is the module a deep adapter between domains? | If yes, the "envy" is the mediation — keep it. If no, move the logic closer to its data. |
|
|
90
|
+
| Middle Man | Does the middle man absorb any complexity? | If no, delete the middle man. If yes, document the why (it's a deep wrapper). |
|
|
91
|
+
|
|
92
|
+
A flat "this is too long, extract method" recommendation is shallow analysis. Combining Fowler + deep-modules surfaces when the smell is actually a feature.
|
|
93
|
+
|
|
94
|
+
## Output for refactor-audit findings
|
|
95
|
+
|
|
96
|
+
When the audit flags a module as a shallow-wrapper or god-module candidate, the finding entry adds a `Deep-modules: <verdict>` line:
|
|
97
|
+
|
|
98
|
+
```markdown
|
|
99
|
+
### P1 — Shallow Wrapper
|
|
100
|
+
**Files:** src/lib/getUserName.ts
|
|
101
|
+
**Symptom:** 1-line passthrough wrapper around `db.users.findById(id).name`; 2 callers.
|
|
102
|
+
**Deep-modules:** SHALLOW — fails deletion test (only 2 callers) AND leverage test (0 LOC saved per call).
|
|
103
|
+
**Refactor:** Inline at both call sites. If the wrapper exists for vocabulary reasons, document and keep — otherwise remove.
|
|
104
|
+
**Risk:** Low.
|
|
105
|
+
```
|