@payconductor/houndsman 0.12.0 → 0.14.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/README.md +23 -2
- package/package.json +1 -1
- package/src/cli/commands/compare-command.ts +112 -0
- package/src/cli/commands/context-command.ts +1 -0
- package/src/cli/commands/doctor-command.ts +22 -0
- package/src/cli/commands/findings-command.ts +11 -1
- package/src/cli/commands/hunt-command.ts +479 -0
- package/src/cli/commands/review-command.ts +58 -2
- package/src/cli/commands/status-command.ts +3 -2
- package/src/cli/help.ts +20 -3
- package/src/cli/index.ts +20 -3
- package/src/cli/progress.ts +50 -0
- package/src/core/ai/ai-client.ts +38 -2
- package/src/core/ai/ai-sdk-model-provider.ts +39 -0
- package/src/core/ai/features/brief-enricher.ts +1 -1
- package/src/core/ai/features/business-analyzer.ts +61 -0
- package/src/core/ai/features/business-summarizer.ts +44 -0
- package/src/core/ai/index.ts +14 -1
- package/src/core/ai/prompts/brief.ts +33 -7
- package/src/core/ai/prompts/business.ts +76 -0
- package/src/core/ai/provider-capabilities.ts +12 -0
- package/src/core/ai/schemas.ts +70 -2
- package/src/core/ai/types.ts +2 -0
- package/src/core/ai/usage-recorder.ts +53 -1
- package/src/core/brief.ts +246 -12
- package/src/core/builtins.ts +108 -0
- package/src/core/business-summary.ts +583 -0
- package/src/core/commands/compare.ts +233 -0
- package/src/core/commands/context.ts +6 -2
- package/src/core/commands/findings.ts +38 -30
- package/src/core/commands/review.ts +6 -0
- package/src/core/commands/scaffold.ts +38 -0
- package/src/core/commands/status.ts +9 -4
- package/src/core/compare.ts +243 -0
- package/src/core/concurrency.ts +30 -0
- package/src/core/config.ts +57 -1
- package/src/core/defaults.ts +63 -2
- package/src/core/domain/budget.ts +62 -4
- package/src/core/domain/classification.ts +12 -2
- package/src/core/engine/carryover.ts +4 -0
- package/src/core/engine/finalize-pipeline.ts +347 -0
- package/src/core/engine/prepare-pipeline.ts +1294 -0
- package/src/core/engine/review-context.ts +51 -0
- package/src/core/engine/review-options.ts +47 -0
- package/src/core/engine/review-scope.ts +106 -26
- package/src/core/engine/review-session.ts +18 -16
- package/src/core/engine/review-workspace.ts +14 -0
- package/src/core/engine/run-artifacts.ts +196 -0
- package/src/core/engine/run-format.ts +4 -0
- package/src/core/env.ts +14 -0
- package/src/core/findings-state.ts +13 -1
- package/src/core/github-review.ts +5 -2
- package/src/core/hunt/hunt-runner.ts +418 -0
- package/src/core/hunt/index.ts +61 -0
- package/src/core/hunt/maki-install.ts +331 -0
- package/src/core/hunt/maki-intent-prompt.ts +50 -0
- package/src/core/hunt/maki-model.ts +101 -0
- package/src/core/hunt/maki-prompt.ts +83 -0
- package/src/core/hunt/maki-release.ts +104 -0
- package/src/core/hunt/maki-runner.ts +276 -0
- package/src/core/hunt/pool.ts +8 -0
- package/src/core/logging/index.ts +7 -0
- package/src/core/logging/logger.ts +19 -0
- package/src/core/logging/progress.ts +366 -0
- package/src/core/orchestrator.ts +33 -1180
- package/src/core/paths.ts +6 -3
- package/src/core/pr-context.ts +2 -4
- package/src/core/prepare-report.ts +61 -0
- package/src/core/project-config.ts +46 -1
- package/src/core/propagation.ts +127 -0
- package/src/core/registry-check.ts +60 -21
- package/src/core/renderers/manifest-writer.ts +13 -0
- package/src/core/renderers/resume-renderer.ts +151 -11
- package/src/core/report-builder.ts +108 -278
- package/src/core/storage/file/file-storage.ts +7 -3
- package/src/core/storage/sqlite/mappers.ts +10 -0
- package/src/core/storage/sqlite/schema.ts +104 -23
- package/src/core/storage/sqlite/sqlite-storage.ts +22 -9
- package/src/core/storage/types.ts +17 -4
- package/src/core/storage/work-area.ts +59 -1
- package/src/core/types.ts +31 -0
- package/src/core/watchdog-registry.ts +21 -3
- package/src/index.ts +78 -4
- package/src/server/client/ArtifactsPanel.tsx +4 -2
- package/src/server/client/FindingCard.tsx +21 -1
- package/src/server/client/RunsSection.tsx +5 -0
- package/src/server/client/utils/constants.ts +21 -11
- package/src/server/client/utils/markdown.ts +1 -1
- package/src/server/client/utils/types.ts +14 -2
- package/src/server/run-repository.ts +35 -14
- package/src/server/styles.css +2 -0
- package/src/skill/OUTPUT-FORMAT.md +36 -10
- package/src/skill/README.md +30 -14
- package/src/skill/SETUP.md +22 -1
- package/src/skill/SKILL.md +17 -4
- package/src/skill/example-resume.md +43 -0
- package/src/skill/hunt.md +181 -58
- package/src/tests/__snapshots__/baseline.test.ts.snap +206 -178
- package/src/tests/ai-core.test.ts +84 -1
- package/src/tests/ai-features.test.ts +95 -4
- package/src/tests/baseline.test.ts +29 -121
- package/src/tests/brief-scope.test.ts +250 -0
- package/src/tests/business-summary.test.ts +258 -0
- package/src/tests/cli.test.ts +1 -0
- package/src/tests/compare.test.ts +233 -0
- package/src/tests/fixtures/fake-model-provider.ts +2 -1
- package/src/tests/hunt-cli.test.ts +185 -0
- package/src/tests/hunt-install.test.ts +153 -0
- package/src/tests/hunt-maki.test.ts +525 -0
- package/src/tests/markdown.test.ts +3 -3
- package/src/tests/progress.test.ts +145 -0
- package/src/tests/propagation.test.ts +119 -0
- package/src/tests/review-resume.test.ts +60 -1
- package/src/tests/review-scope.test.ts +90 -19
- package/src/tests/review-scripts.test.ts +106 -218
- package/src/tests/server.test.ts +7 -4
- package/src/tests/storage.test.ts +194 -9
- package/src/core/renderers/report-renderer.ts +0 -66
- package/src/skill/example-review.md +0 -66
|
@@ -40,11 +40,11 @@ src/alpha/**
|
|
|
40
40
|
- \`src/alpha/a.ts\` (modified, +3/−1)
|
|
41
41
|
- \`src/alpha/b.ts\` (added, +2/−0)
|
|
42
42
|
|
|
43
|
-
## Fora do
|
|
43
|
+
## Fora do recorte (NÃO revisar)
|
|
44
44
|
|
|
45
|
-
> 1 arquivo(s) do
|
|
46
|
-
> (
|
|
47
|
-
>
|
|
45
|
+
> 1 arquivo(s) do escopo ficaram fora do recorte
|
|
46
|
+
> (orçamento ou prioridade de fluxo). Não os leia: registre-os em \`skipped\`
|
|
47
|
+
> com o motivo (\`budget\` ou \`fora do fluxo\`) para que a cobertura fique honesta.
|
|
48
48
|
|
|
49
49
|
- \`src/alpha/c.ts\`
|
|
50
50
|
|
|
@@ -60,111 +60,22 @@ src/alpha/**
|
|
|
60
60
|
|
|
61
61
|
- \`src/alpha/old.ts\`
|
|
62
62
|
|
|
63
|
-
##
|
|
64
|
-
|
|
65
|
-
1. **FILTER** — descarte o que não for do seu domínio (ver *Prioridade de leitura* e *Não carregar*).
|
|
66
|
-
2. **READ SCOPE** — carregue apenas as faixas alteradas em *Escopo do diff*; o restante do arquivo é só contexto.
|
|
67
|
-
3. **GREP** — use as regras críticas/anti-padrões como heurística para localizar violações nas faixas alteradas.
|
|
68
|
-
4. **DEEP-READ** — aprofunde apenas as faixas com suspeita de violação dentro do escopo.
|
|
69
|
-
5. **CONCLUDE** — grave o JSON no caminho de output, com \`reviewedFiles\` preenchido e \`line\` dentro das faixas alteradas. Sem achados → \`"findings": []\` (arquivo obrigatório). Não escreva markdown livre."
|
|
70
|
-
`;
|
|
71
|
-
|
|
72
|
-
exports[`baseline — relatório renderReport consolidado 1`] = `
|
|
73
|
-
"# PR Review — feature/x
|
|
74
|
-
|
|
75
|
-
**Data:** <date>
|
|
76
|
-
**Watchdogs ativos:** alpha, beta
|
|
77
|
-
**Achados:** 1 bloqueantes · 1 atenção · 0 sugestões · 0 nits
|
|
78
|
-
|
|
79
|
-
## Contexto da PR
|
|
80
|
-
|
|
81
|
-
**PR:** #42 Entrega X — https://example.test/pull/42
|
|
82
|
-
**Branch:** \`feature/x\` → \`main\`
|
|
83
|
-
**Objetivo:** Entregar X
|
|
84
|
-
**Motivação:** Reduzir Y
|
|
85
|
-
|
|
86
|
-
**Resumo das alterações:**
|
|
87
|
-
|
|
88
|
-
- Faz A
|
|
89
|
-
- Remove B
|
|
63
|
+
## Orçamento de exploração
|
|
90
64
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
## Cobertura
|
|
98
|
-
|
|
99
|
-
| Watchdog | Arquivos revisados | Findings |
|
|
100
|
-
|---|---|---|
|
|
101
|
-
| Alpha | 2 | 2 |
|
|
102
|
-
| Beta | 1 | 0 |
|
|
103
|
-
|
|
104
|
-
## Conclusão
|
|
105
|
-
|
|
106
|
-
**Status:** ❌ Mudanças Necessárias
|
|
107
|
-
**Resumo:** 1 violações bloqueantes, 1 pontos de atenção, 0 sugestões e 0 nits.
|
|
108
|
-
|
|
109
|
-
## ❌ blocking
|
|
110
|
-
|
|
111
|
-
### \`src/alpha/a.ts\`
|
|
112
|
-
|
|
113
|
-
- **Nunca usar \`any\`.** — \`src/alpha/a.ts:1\` · _Alpha_ · \`id-alpha\`
|
|
114
|
-
any detectado
|
|
115
|
-
**Ação:** tipar
|
|
116
|
-
**Evidência:** \`export const a: any = 1;\`
|
|
117
|
-
|
|
118
|
-
## ⚠️ attention
|
|
119
|
-
|
|
120
|
-
### \`src/alpha/b.ts\`
|
|
65
|
+
> O diff já está no brief. Limite **neste brief**: 6 leitura(s) de arquivo
|
|
66
|
+
> e 6 busca(s) (grep).
|
|
67
|
+
> Abra arquivo só para chamador/contexto de um símbolo citado nos trechos.
|
|
68
|
+
> Se a prova não estiver no brief nem nesse orçamento, **não é achado** —
|
|
69
|
+
> registre a dúvida no campo \`action\` do finding mais próximo ou descarte.
|
|
121
70
|
|
|
122
|
-
|
|
123
|
-
sem validação
|
|
124
|
-
**Ação:** adicionar schema
|
|
125
|
-
"
|
|
126
|
-
`;
|
|
127
|
-
|
|
128
|
-
exports[`baseline — relatório renderDomainReport isolado 1`] = `
|
|
129
|
-
"# Review — Alpha (\`alpha\`) — feature/x
|
|
130
|
-
|
|
131
|
-
**Data:** <date>
|
|
132
|
-
**Arquivos revisados:** 2/2
|
|
133
|
-
**Achados:** 2
|
|
134
|
-
|
|
135
|
-
## Contexto da PR
|
|
136
|
-
|
|
137
|
-
**PR:** #42 Entrega X — https://example.test/pull/42
|
|
138
|
-
**Branch:** \`feature/x\` → \`main\`
|
|
139
|
-
**Objetivo:** Entregar X
|
|
140
|
-
**Motivação:** Reduzir Y
|
|
141
|
-
|
|
142
|
-
**Resumo das alterações:**
|
|
143
|
-
|
|
144
|
-
- Faz A
|
|
145
|
-
- Remove B
|
|
146
|
-
|
|
147
|
-
## ❌ blocking
|
|
148
|
-
|
|
149
|
-
### \`src/alpha/a.ts\`
|
|
150
|
-
|
|
151
|
-
- **Nunca usar \`any\`.** — \`src/alpha/a.ts:1\` · _Alpha_ · \`id-alpha\`
|
|
152
|
-
any detectado
|
|
153
|
-
**Ação:** tipar
|
|
154
|
-
**Evidência:** \`export const a: any = 1;\`
|
|
155
|
-
|
|
156
|
-
## ⚠️ attention
|
|
157
|
-
|
|
158
|
-
### \`src/alpha/b.ts\`
|
|
159
|
-
|
|
160
|
-
- **Promover: validar a entrada.** — \`src/alpha/b.ts:2\` · _Alpha, Beta_ · \`id-beta\`
|
|
161
|
-
sem validação
|
|
162
|
-
**Ação:** adicionar schema
|
|
163
|
-
|
|
164
|
-
## Não revisados
|
|
71
|
+
## Procedimento
|
|
165
72
|
|
|
166
|
-
|
|
167
|
-
|
|
73
|
+
1. **RECONSTRUCT** — leia o recorte do *Modelo de intenção (negócio)* e diga para si mesmo o que a mudança DEVE entregar (fluxos, invariantes, contratos). Sem modelo, derive do contexto da PR.
|
|
74
|
+
2. **SCOPE** — os *Trechos alterados (diff)* já estão no brief: **não releia o arquivo inteiro** para vê-los. Trecho com o marcador \`… [trecho truncado]\` pode ser aberto, uma vez, para o restante.
|
|
75
|
+
3. **TRACE** — siga cada símbolo alterado até seus chamadores, adapters e tipos compartilhados **dentro do seu domínio** (use os importadores do AST), **dentro do orçamento de exploração** (seção acima). Priorize os arquivos de maior churn.
|
|
76
|
+
4. **GREP** — use as regras críticas/anti-padrões como heurística para localizar violações nas faixas alteradas, **dentro do orçamento**. Pare quando tiver a prova: repetir busca não aumenta certeza.
|
|
77
|
+
5. **PROVE** — para cada suspeita, descreva gatilho → comportamento observado → invariante/regra violada. Sem prova, não é achado. Trecho com o marcador de truncamento só sustenta achado depois de abrir o arquivo para ver o restante.
|
|
78
|
+
6. **CONCLUDE** — grave o JSON no caminho de output. \`reviewedFiles\` é um subconjunto de \`## Arquivos do seu domínio\` (só o que você revisou; **não** liste chamadores/importadores nem arquivos de outros domínios) e o que ficou de fora entra em \`skipped\` ("budget", "truncated" ou "fora do fluxo"). Máximo de 20 achados: priorize severidade e agrupe ocorrências idênticas. \`line\` dentro das faixas alteradas. Sem achados → \`"findings": []\` (arquivo obrigatório). Não escreva markdown livre."
|
|
168
79
|
`;
|
|
169
80
|
|
|
170
81
|
exports[`baseline — camada gerada setup gera os mesmos arquivos e conteúdos 1`] = `
|
|
@@ -180,7 +91,7 @@ exports[`baseline — camada gerada setup gera os mesmos arquivos e conteúdos 1
|
|
|
180
91
|
".houndsman/core/skill/OUTPUT-FORMAT.md",
|
|
181
92
|
".houndsman/core/skill/README.md",
|
|
182
93
|
".houndsman/core/skill/SETUP.md",
|
|
183
|
-
".houndsman/core/skill/example-
|
|
94
|
+
".houndsman/core/skill/example-resume.md",
|
|
184
95
|
".houndsman/core/skill/fix.md",
|
|
185
96
|
".houndsman/core/skill/hunt.md",
|
|
186
97
|
".houndsman/core/skill/train.md",
|
|
@@ -214,6 +125,11 @@ consolida tudo num relatório. O motor é o CLI **\`houndsman\`**; as regras do
|
|
|
214
125
|
**Terminologia:** **houndsman** = orquestrador/treinador (CLI + motor) · **watchdog** = agente
|
|
215
126
|
especialista por domínio · **finding** = um achado da revisão · **Jev** = pré-análise opcional.
|
|
216
127
|
|
|
128
|
+
> **Duas etapas são obrigatórias em toda revisão:** o **modelo de intenção**
|
|
129
|
+
> (\`business-summary.json\`) e o revisor de fluxo **\`general\`** (id reservado, sempre ativo).
|
|
130
|
+
> O modelo vem da IA no prepare quando há chave; sem chave, um subagente (Passo 1.5) ou o
|
|
131
|
+
> pré-passe maki o produz. Nenhum dos dois é configurável pelo usuário.
|
|
132
|
+
|
|
217
133
|
## Capabilities
|
|
218
134
|
|
|
219
135
|
| Capability | Objetivo | Documento |
|
|
@@ -238,6 +154,10 @@ especialista por domínio · **finding** = um achado da revisão · **Jev** = pr
|
|
|
238
154
|
Um argumento extra é o alvo da capability. Escolha a capability pelo que o usuário quer,
|
|
239
155
|
leia o documento correspondente em \`.houndsman/core/skill/<capability>.md\` e siga-o.
|
|
240
156
|
|
|
157
|
+
> **Harness local (opcional):** para rodar sem agente externo, o operador pode instalar o
|
|
158
|
+
> maki (\`houndsman hunt install\`) e usar \`houndsman hunt --pr 456\`. Isso não muda esta
|
|
159
|
+
> skill: se você é o agente, siga o fluxo normal e não rode \`houndsman hunt\`.
|
|
160
|
+
|
|
241
161
|
### Alvo da revisão (PR × branch)
|
|
242
162
|
|
|
243
163
|
Interprete o alvo em linguagem natural **antes** de rodar o CLI:
|
|
@@ -256,12 +176,16 @@ Interprete o alvo em linguagem natural **antes** de rodar o CLI:
|
|
|
256
176
|
Sequência para uma PR (ex.: 456):
|
|
257
177
|
|
|
258
178
|
\`\`\`bash
|
|
259
|
-
houndsman
|
|
260
|
-
|
|
261
|
-
# despache os briefs (cada um traz **Worktree:** <path>)
|
|
179
|
+
houndsman --pr 456 # cria/reusa o worktree, coleta o contexto e prepara
|
|
180
|
+
# despache os briefs em paralelo (cada um traz **Worktree:** <path>)
|
|
262
181
|
houndsman --pr 456 --finalize
|
|
263
182
|
\`\`\`
|
|
264
183
|
|
|
184
|
+
- O contexto da PR é coletado pelo próprio prepare (via \`gh\`); com IA ligada ele também é
|
|
185
|
+
resumido ali — não gaste um subagente nisso. Desative com \`--no-context\`.
|
|
186
|
+
- Para comparar duas execuções, use \`--variant <label>\` em cada uma e depois
|
|
187
|
+
\`houndsman compare --branch <head> --a <a> --b <b>\` (ou \`compare --list\`).
|
|
188
|
+
|
|
265
189
|
- O worktree vive em \`<repo>/.houndsman/worktrees/<repo>/<branch>\` (detached no commit da PR)
|
|
266
190
|
e é reutilizado nas próximas execuções da mesma branch. Ele fica **dentro do workspace**
|
|
267
191
|
(e o staging também) para o agente ler/executar sem prompts de permissão.
|
|
@@ -279,7 +203,7 @@ houndsman --pr 456 --finalize
|
|
|
279
203
|
- \`.houndsman/core/skill/OUTPUT-FORMAT.md\` — schema do JSON de saída dos watchdogs.
|
|
280
204
|
- \`.houndsman/core/skill/AUDIT-PROTOCOL.md\` — taxonomia da auditoria de regras (Modo B do \`train\`).
|
|
281
205
|
- \`.houndsman/core/skill/SETUP.md\` · \`.houndsman/core/skill/README.md\` — configuração e visão geral.
|
|
282
|
-
- \`.houndsman/core/skill/example-
|
|
206
|
+
- \`.houndsman/core/skill/example-resume.md\` — exemplo do resumo final.
|
|
283
207
|
"
|
|
284
208
|
,
|
|
285
209
|
".claude/skills/houndsman/SKILL.md":
|
|
@@ -299,6 +223,11 @@ consolida tudo num relatório. O motor é o CLI **\`houndsman\`**; as regras do
|
|
|
299
223
|
**Terminologia:** **houndsman** = orquestrador/treinador (CLI + motor) · **watchdog** = agente
|
|
300
224
|
especialista por domínio · **finding** = um achado da revisão · **Jev** = pré-análise opcional.
|
|
301
225
|
|
|
226
|
+
> **Duas etapas são obrigatórias em toda revisão:** o **modelo de intenção**
|
|
227
|
+
> (\`business-summary.json\`) e o revisor de fluxo **\`general\`** (id reservado, sempre ativo).
|
|
228
|
+
> O modelo vem da IA no prepare quando há chave; sem chave, um subagente (Passo 1.5) ou o
|
|
229
|
+
> pré-passe maki o produz. Nenhum dos dois é configurável pelo usuário.
|
|
230
|
+
|
|
302
231
|
## Capabilities
|
|
303
232
|
|
|
304
233
|
| Capability | Objetivo | Documento |
|
|
@@ -323,6 +252,10 @@ especialista por domínio · **finding** = um achado da revisão · **Jev** = pr
|
|
|
323
252
|
Um argumento extra é o alvo da capability. Escolha a capability pelo que o usuário quer,
|
|
324
253
|
leia o documento correspondente em \`.houndsman/core/skill/<capability>.md\` e siga-o.
|
|
325
254
|
|
|
255
|
+
> **Harness local (opcional):** para rodar sem agente externo, o operador pode instalar o
|
|
256
|
+
> maki (\`houndsman hunt install\`) e usar \`houndsman hunt --pr 456\`. Isso não muda esta
|
|
257
|
+
> skill: se você é o agente, siga o fluxo normal e não rode \`houndsman hunt\`.
|
|
258
|
+
|
|
326
259
|
### Alvo da revisão (PR × branch)
|
|
327
260
|
|
|
328
261
|
Interprete o alvo em linguagem natural **antes** de rodar o CLI:
|
|
@@ -341,12 +274,16 @@ Interprete o alvo em linguagem natural **antes** de rodar o CLI:
|
|
|
341
274
|
Sequência para uma PR (ex.: 456):
|
|
342
275
|
|
|
343
276
|
\`\`\`bash
|
|
344
|
-
houndsman
|
|
345
|
-
|
|
346
|
-
# despache os briefs (cada um traz **Worktree:** <path>)
|
|
277
|
+
houndsman --pr 456 # cria/reusa o worktree, coleta o contexto e prepara
|
|
278
|
+
# despache os briefs em paralelo (cada um traz **Worktree:** <path>)
|
|
347
279
|
houndsman --pr 456 --finalize
|
|
348
280
|
\`\`\`
|
|
349
281
|
|
|
282
|
+
- O contexto da PR é coletado pelo próprio prepare (via \`gh\`); com IA ligada ele também é
|
|
283
|
+
resumido ali — não gaste um subagente nisso. Desative com \`--no-context\`.
|
|
284
|
+
- Para comparar duas execuções, use \`--variant <label>\` em cada uma e depois
|
|
285
|
+
\`houndsman compare --branch <head> --a <a> --b <b>\` (ou \`compare --list\`).
|
|
286
|
+
|
|
350
287
|
- O worktree vive em \`<repo>/.houndsman/worktrees/<repo>/<branch>\` (detached no commit da PR)
|
|
351
288
|
e é reutilizado nas próximas execuções da mesma branch. Ele fica **dentro do workspace**
|
|
352
289
|
(e o staging também) para o agente ler/executar sem prompts de permissão.
|
|
@@ -364,7 +301,7 @@ houndsman --pr 456 --finalize
|
|
|
364
301
|
- \`.houndsman/core/skill/OUTPUT-FORMAT.md\` — schema do JSON de saída dos watchdogs.
|
|
365
302
|
- \`.houndsman/core/skill/AUDIT-PROTOCOL.md\` — taxonomia da auditoria de regras (Modo B do \`train\`).
|
|
366
303
|
- \`.houndsman/core/skill/SETUP.md\` · \`.houndsman/core/skill/README.md\` — configuração e visão geral.
|
|
367
|
-
- \`.houndsman/core/skill/example-
|
|
304
|
+
- \`.houndsman/core/skill/example-resume.md\` — exemplo do resumo final.
|
|
368
305
|
"
|
|
369
306
|
,
|
|
370
307
|
".houndsman/.gitignore":
|
|
@@ -489,6 +426,7 @@ export type AiProviderOptions = Record<string, Record<string, unknown>>;
|
|
|
489
426
|
/** Features de IA do fluxo normal (todas fail-open). */
|
|
490
427
|
export type HoundsmanAiFeatures = {
|
|
491
428
|
context?: boolean;
|
|
429
|
+
business?: boolean;
|
|
492
430
|
brief?: boolean;
|
|
493
431
|
technical?: boolean;
|
|
494
432
|
classification?: boolean;
|
|
@@ -516,6 +454,28 @@ export type HoundsmanAi = {
|
|
|
516
454
|
watchdogs?: Record<string, HoundsmanAiWatchdog>;
|
|
517
455
|
};
|
|
518
456
|
|
|
457
|
+
/** Harness local da capability \`hunt\` (\`houndsman hunt\`) — opcional. */
|
|
458
|
+
export type HoundsmanHunt = {
|
|
459
|
+
enabled?: boolean;
|
|
460
|
+
model?: string;
|
|
461
|
+
concurrency?: number;
|
|
462
|
+
timeoutMs?: number;
|
|
463
|
+
retries?: number;
|
|
464
|
+
binaryPath?: string;
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Prioridade por caminho.
|
|
469
|
+
*
|
|
470
|
+
* \`bonus\` promove (linhas de churn equivalentes) e \`maxRiskFromChurn\` satura o
|
|
471
|
+
* superchurn de caminhos de baixa criticidade.
|
|
472
|
+
*/
|
|
473
|
+
export type HoundsmanPriority = {
|
|
474
|
+
pattern: RegExp;
|
|
475
|
+
bonus?: number;
|
|
476
|
+
maxRiskFromChurn?: number;
|
|
477
|
+
};
|
|
478
|
+
|
|
519
479
|
/** Contrato de configuração do motor. */
|
|
520
480
|
export type HoundsmanConfig<TId extends string = string> = {
|
|
521
481
|
projectName: string;
|
|
@@ -524,11 +484,14 @@ export type HoundsmanConfig<TId extends string = string> = {
|
|
|
524
484
|
watchdogs: Record<TId, WatchdogDefinition>;
|
|
525
485
|
exclusions: readonly RegExp[];
|
|
526
486
|
docMappings: readonly (readonly [RegExp, readonly string[]])[];
|
|
487
|
+
/** Prioridade por caminho (opcional; a primeira regra que casar vence). */
|
|
488
|
+
priorities?: readonly HoundsmanPriority[];
|
|
527
489
|
alwaysIncludeDocs?: readonly string[];
|
|
528
490
|
budgets?: HoundsmanBudgets;
|
|
529
491
|
concurrency?: HoundsmanConcurrency;
|
|
530
492
|
ast?: HoundsmanAst;
|
|
531
493
|
ai?: HoundsmanAi;
|
|
494
|
+
hunt?: HoundsmanHunt;
|
|
532
495
|
};
|
|
533
496
|
|
|
534
497
|
/** Helper de autoria (identidade) — apenas tipagem. */
|
|
@@ -607,6 +570,9 @@ import { exampleWatchdog } from "./example";
|
|
|
607
570
|
/**
|
|
608
571
|
* Definições dos watchdogs — as chaves definem o union \`WatchdogId\`.
|
|
609
572
|
* Adicionar um watchdog = criar \`<id>.ts\` e registrá-lo aqui.
|
|
573
|
+
*
|
|
574
|
+
* NÃO declare um watchdog com id \`general\`: ele é reservado pelo motor
|
|
575
|
+
* (revisor de fluxo obrigatório) e é injetado em todo ciclo.
|
|
610
576
|
*/
|
|
611
577
|
export const WATCHDOG_DEFINITIONS = {
|
|
612
578
|
default: defaultWatchdog,
|
|
@@ -634,6 +600,15 @@ export const houndsmanConfig = {
|
|
|
634
600
|
watchdogs: WATCHDOG_DEFINITIONS,
|
|
635
601
|
exclusions: EXCLUSION_PATTERNS,
|
|
636
602
|
docMappings: DOC_MAPPINGS,
|
|
603
|
+
// Prioridade por caminho (opcional): "linhas de churn equivalentes".
|
|
604
|
+
// \`bonus\` promove caminho crítico; \`maxRiskFromChurn\` satura o superchurn de
|
|
605
|
+
// caminho de baixa criticidade (risco = min(churn, teto) + bonus).
|
|
606
|
+
// A primeira regra que casar vence; sem regra, o risco é o churn puro.
|
|
607
|
+
// priorities: [
|
|
608
|
+
// { pattern: /^src\\/(db|repositories)\\//, bonus: 300 },
|
|
609
|
+
// { pattern: /^src\\/(services|domain)\\//, bonus: 200 },
|
|
610
|
+
// { pattern: /^src\\/(components|styles)\\//, maxRiskFromChurn: 120 },
|
|
611
|
+
// ],
|
|
637
612
|
} satisfies HoundsmanConfig;
|
|
638
613
|
|
|
639
614
|
export default houndsmanConfig;
|
|
@@ -650,19 +625,19 @@ exports[`baseline — camada gerada setup gera os mesmos arquivos e conteúdos 3
|
|
|
650
625
|
},
|
|
651
626
|
{
|
|
652
627
|
"file": ".houndsman/core/skill/OUTPUT-FORMAT.md",
|
|
653
|
-
"sha256": "
|
|
628
|
+
"sha256": "49d36854d10f795c",
|
|
654
629
|
},
|
|
655
630
|
{
|
|
656
631
|
"file": ".houndsman/core/skill/README.md",
|
|
657
|
-
"sha256": "
|
|
632
|
+
"sha256": "4d200cf9e5c1d748",
|
|
658
633
|
},
|
|
659
634
|
{
|
|
660
635
|
"file": ".houndsman/core/skill/SETUP.md",
|
|
661
|
-
"sha256": "
|
|
636
|
+
"sha256": "e7f587d1c8e459d1",
|
|
662
637
|
},
|
|
663
638
|
{
|
|
664
|
-
"file": ".houndsman/core/skill/example-
|
|
665
|
-
"sha256": "
|
|
639
|
+
"file": ".houndsman/core/skill/example-resume.md",
|
|
640
|
+
"sha256": "4993f56afdf2ffd1",
|
|
666
641
|
},
|
|
667
642
|
{
|
|
668
643
|
"file": ".houndsman/core/skill/fix.md",
|
|
@@ -670,7 +645,7 @@ exports[`baseline — camada gerada setup gera os mesmos arquivos e conteúdos 3
|
|
|
670
645
|
},
|
|
671
646
|
{
|
|
672
647
|
"file": ".houndsman/core/skill/hunt.md",
|
|
673
|
-
"sha256": "
|
|
648
|
+
"sha256": "0a81003a5b39b84a",
|
|
674
649
|
},
|
|
675
650
|
{
|
|
676
651
|
"file": ".houndsman/core/skill/train.md",
|
|
@@ -683,25 +658,31 @@ exports[`baseline — camada gerada setup gera os mesmos arquivos e conteúdos 3
|
|
|
683
658
|
]
|
|
684
659
|
`;
|
|
685
660
|
|
|
686
|
-
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest,
|
|
687
|
-
"Discovery: 1 watchdog(s)
|
|
661
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, resumo e state 1`] = `
|
|
662
|
+
"Discovery: 1 watchdog(s) de domínio + revisor general, 3 arquivo(s), 1 deletado(s).
|
|
688
663
|
Briefs: <cwd>/.home/work/<uuid>/briefs/
|
|
689
664
|
Deletado (breaking change): src/alpha/old.ts
|
|
690
665
|
Escopo: 2 arquivo(s), 0 símbolo(s) em 2 faixa(s) alterada(s).
|
|
666
|
+
Escopo: 2 arquivo(s) em mais de um domínio (máx. 2) — cada domínio revisa o arquivo com o seu recorte.
|
|
691
667
|
Jev: pulado (desativado (--no-jev)).
|
|
692
668
|
AST: desabilitado ou sem grammar compatível.
|
|
693
669
|
Sem contexto da PR (rode \`bun run houndsman context\` antes, se houver PR).
|
|
670
|
+
Intenção da PR determinística (1 fluxo(s)) — enriquecida no passo de intenção (<cwd>/.home/work/<uuid>/business-brief.md).
|
|
694
671
|
|
|
695
672
|
Próximo passo: despachar os sub-agentes (um por brief em <cwd>/.home/work/<uuid>/briefs/).
|
|
696
673
|
Quando os findings estiverem gravados: bun run houndsman --finalize"
|
|
697
674
|
`;
|
|
698
675
|
|
|
699
|
-
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest,
|
|
676
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, resumo e state: classification.json 1`] = `
|
|
700
677
|
"{
|
|
701
678
|
"watchdogs": {
|
|
702
679
|
"alpha": [
|
|
703
680
|
"src/alpha/a.ts",
|
|
704
681
|
"src/alpha/b.ts"
|
|
682
|
+
],
|
|
683
|
+
"general": [
|
|
684
|
+
"src/alpha/a.ts",
|
|
685
|
+
"src/alpha/b.ts"
|
|
705
686
|
]
|
|
706
687
|
},
|
|
707
688
|
"files": {
|
|
@@ -735,7 +716,8 @@ exports[`baseline — artefatos de prepare/finalize gera classification, brief,
|
|
|
735
716
|
"src/alpha/old.ts"
|
|
736
717
|
],
|
|
737
718
|
"stats": {
|
|
738
|
-
"alpha": 2
|
|
719
|
+
"alpha": 2,
|
|
720
|
+
"general": 2
|
|
739
721
|
},
|
|
740
722
|
"excludedCount": 0,
|
|
741
723
|
"headSha": "<sha>",
|
|
@@ -766,7 +748,7 @@ exports[`baseline — artefatos de prepare/finalize gera classification, brief,
|
|
|
766
748
|
"
|
|
767
749
|
`;
|
|
768
750
|
|
|
769
|
-
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest,
|
|
751
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, resumo e state: manifest.json 1`] = `
|
|
770
752
|
"{
|
|
771
753
|
"branch": "main",
|
|
772
754
|
"slug": "main",
|
|
@@ -795,12 +777,31 @@ exports[`baseline — artefatos de prepare/finalize gera classification, brief,
|
|
|
795
777
|
"brief": "<cwd>\\\\.home\\\\work\\\\<uuid>\\\\briefs\\\\alpha.md",
|
|
796
778
|
"findings": "<cwd>\\\\.home\\\\work\\\\<uuid>\\\\findings\\\\alpha.json",
|
|
797
779
|
"status": "pending"
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
"id": "general",
|
|
783
|
+
"name": "Lógica e domínio (fluxo)",
|
|
784
|
+
"files": [
|
|
785
|
+
"src/alpha/a.ts",
|
|
786
|
+
"src/alpha/b.ts"
|
|
787
|
+
],
|
|
788
|
+
"overflow": 0,
|
|
789
|
+
"brief": "<cwd>\\\\.home\\\\work\\\\<uuid>\\\\briefs\\\\general.md",
|
|
790
|
+
"findings": "<cwd>\\\\.home\\\\work\\\\<uuid>\\\\findings\\\\general.json",
|
|
791
|
+
"status": "pending"
|
|
798
792
|
}
|
|
799
793
|
],
|
|
800
794
|
"context": {
|
|
801
795
|
"summarized": false,
|
|
802
796
|
"source": null
|
|
803
797
|
},
|
|
798
|
+
"business": {
|
|
799
|
+
"source": "deterministic",
|
|
800
|
+
"flows": 1,
|
|
801
|
+
"invariants": 0,
|
|
802
|
+
"contracts": 0,
|
|
803
|
+
"states": 0
|
|
804
|
+
},
|
|
804
805
|
"jev": {
|
|
805
806
|
"available": false,
|
|
806
807
|
"reason": "desativado (--no-jev)"
|
|
@@ -824,7 +825,7 @@ exports[`baseline — artefatos de prepare/finalize gera classification, brief,
|
|
|
824
825
|
"
|
|
825
826
|
`;
|
|
826
827
|
|
|
827
|
-
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest,
|
|
828
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, resumo e state: briefs/alpha.md 1`] = `
|
|
828
829
|
"# Brief — Alpha (\`alpha\`)
|
|
829
830
|
|
|
830
831
|
**Branch:** main
|
|
@@ -849,6 +850,47 @@ src/alpha/**
|
|
|
849
850
|
- \`src/alpha/a.ts\` — linhas 1-2 _(faixas do diff)_
|
|
850
851
|
- \`src/alpha/b.ts\` — linhas 1 _(faixas do diff)_
|
|
851
852
|
|
|
853
|
+
## Modelo de intenção (negócio)
|
|
854
|
+
|
|
855
|
+
> Fonte: determinístico. Use para saber o que a mudança **deve** entregar; não é achado.
|
|
856
|
+
|
|
857
|
+
> Recorte do seu domínio: fluxos/arquivos de outros domínios pertencem a outros watchdogs — não os investigue.
|
|
858
|
+
|
|
859
|
+
**Fluxos (1):**
|
|
860
|
+
- **Alpha**
|
|
861
|
+
arquivos: src/alpha/a.ts, src/alpha/b.ts
|
|
862
|
+
|
|
863
|
+
## Trechos alterados (diff)
|
|
864
|
+
|
|
865
|
+
> Trechos já extraídos do diff (\`-U0\`, só linhas alteradas). Eles bastam
|
|
866
|
+
> para achar violações: **não abra os arquivos apenas para reler o que já
|
|
867
|
+
> está aqui**. Use o arquivo só para contexto adjacente ou chamadores.
|
|
868
|
+
|
|
869
|
+
### \`src/alpha/a.ts\`
|
|
870
|
+
|
|
871
|
+
\`\`\`diff
|
|
872
|
+
diff --git a/src/alpha/a.ts b/src/alpha/a.ts
|
|
873
|
+
index cc798ff..bc84e2e 100644
|
|
874
|
+
--- a/src/alpha/a.ts
|
|
875
|
+
+++ b/src/alpha/a.ts
|
|
876
|
+
@@ -1 +1,2 @@
|
|
877
|
+
-export const a = 1;
|
|
878
|
+
+export const a: any = 1;
|
|
879
|
+
+export const b = 2;
|
|
880
|
+
\`\`\`
|
|
881
|
+
|
|
882
|
+
### \`src/alpha/b.ts\`
|
|
883
|
+
|
|
884
|
+
\`\`\`diff
|
|
885
|
+
diff --git a/src/alpha/b.ts b/src/alpha/b.ts
|
|
886
|
+
new file mode 100644
|
|
887
|
+
index 0000000..f4082f0
|
|
888
|
+
--- /dev/null
|
|
889
|
+
+++ b/src/alpha/b.ts
|
|
890
|
+
@@ -0,0 +1 @@
|
|
891
|
+
+export const b = 3;
|
|
892
|
+
\`\`\`
|
|
893
|
+
|
|
852
894
|
## Regras (por severidade)
|
|
853
895
|
|
|
854
896
|
- ❌ **blocking** — Nunca usar \`any\`.
|
|
@@ -867,77 +909,62 @@ src/alpha/**
|
|
|
867
909
|
|
|
868
910
|
- \`src/alpha/old.ts\`
|
|
869
911
|
|
|
912
|
+
## Orçamento de exploração
|
|
913
|
+
|
|
914
|
+
> O diff já está no brief. Limite **neste brief**: 6 leitura(s) de arquivo
|
|
915
|
+
> e 6 busca(s) (grep).
|
|
916
|
+
> Abra arquivo só para chamador/contexto de um símbolo citado nos trechos.
|
|
917
|
+
> Se a prova não estiver no brief nem nesse orçamento, **não é achado** —
|
|
918
|
+
> registre a dúvida no campo \`action\` do finding mais próximo ou descarte.
|
|
919
|
+
|
|
870
920
|
## Procedimento
|
|
871
921
|
|
|
872
|
-
1. **
|
|
873
|
-
2. **
|
|
874
|
-
3. **
|
|
875
|
-
4. **
|
|
876
|
-
5. **
|
|
922
|
+
1. **RECONSTRUCT** — leia o recorte do *Modelo de intenção (negócio)* e diga para si mesmo o que a mudança DEVE entregar (fluxos, invariantes, contratos). Sem modelo, derive do contexto da PR.
|
|
923
|
+
2. **SCOPE** — os *Trechos alterados (diff)* já estão no brief: **não releia o arquivo inteiro** para vê-los. Trecho com o marcador \`… [trecho truncado]\` pode ser aberto, uma vez, para o restante.
|
|
924
|
+
3. **TRACE** — siga cada símbolo alterado até seus chamadores, adapters e tipos compartilhados **dentro do seu domínio** (use os importadores do AST), **dentro do orçamento de exploração** (seção acima). Priorize os arquivos de maior churn.
|
|
925
|
+
4. **GREP** — use as regras críticas/anti-padrões como heurística para localizar violações nas faixas alteradas, **dentro do orçamento**. Pare quando tiver a prova: repetir busca não aumenta certeza.
|
|
926
|
+
5. **PROVE** — para cada suspeita, descreva gatilho → comportamento observado → invariante/regra violada. Sem prova, não é achado. Trecho com o marcador de truncamento só sustenta achado depois de abrir o arquivo para ver o restante.
|
|
927
|
+
6. **CONCLUDE** — grave o JSON no caminho de output. \`reviewedFiles\` é um subconjunto de \`## Arquivos do seu domínio\` (só o que você revisou; **não** liste chamadores/importadores nem arquivos de outros domínios) e o que ficou de fora entra em \`skipped\` ("budget", "truncated" ou "fora do fluxo"). Máximo de 20 achados: priorize severidade e agrupe ocorrências idênticas. \`line\` dentro das faixas alteradas. Sem achados → \`"findings": []\` (arquivo obrigatório). Não escreva markdown livre.
|
|
877
928
|
"
|
|
878
929
|
`;
|
|
879
930
|
|
|
880
|
-
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest,
|
|
931
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, resumo e state 2`] = `
|
|
881
932
|
"Triagem: sqlite:<cwd>\\houndsman.db#<uuid> — 1 finding(s).
|
|
882
|
-
|
|
933
|
+
Resumo: sqlite:<cwd>\\houndsman.db#<uuid> (review-resume.md) — 1 bloqueante(s), 0 atenção."
|
|
883
934
|
`;
|
|
884
935
|
|
|
885
|
-
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest,
|
|
886
|
-
"#
|
|
936
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, resumo e state: review-resume.md 1`] = `
|
|
937
|
+
"# Resumo da revisão — main
|
|
887
938
|
|
|
888
|
-
**Data:** <date>
|
|
889
|
-
**Watchdogs ativos:** alpha
|
|
890
|
-
**Achados:** 1 bloqueantes · 0 atenção · 0 sugestões · 0 nits
|
|
939
|
+
**Data:** <date> · **Status:** ❌ Mudanças necessárias
|
|
891
940
|
|
|
892
|
-
##
|
|
941
|
+
## Resumo de negócio
|
|
893
942
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
943
|
+
**Fluxos (1):**
|
|
944
|
+
- **Alpha**
|
|
945
|
+
arquivos: src/alpha/a.ts, src/alpha/b.ts
|
|
897
946
|
|
|
898
|
-
##
|
|
947
|
+
## Pontos técnicos
|
|
899
948
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
| Alpha | 2 | 1 |
|
|
903
|
-
|
|
904
|
-
## Conclusão
|
|
905
|
-
|
|
906
|
-
**Status:** ❌ Mudanças Necessárias
|
|
907
|
-
**Resumo:** 1 violações bloqueantes, 0 pontos de atenção, 0 sugestões e 0 nits.
|
|
908
|
-
|
|
909
|
-
## ❌ blocking
|
|
910
|
-
|
|
911
|
-
### \`src/alpha/a.ts\`
|
|
949
|
+
- **Estrutura** — Novo diretório \`src/alpha\` com 1 arquivo(s).
|
|
950
|
+
- **Remoções** — \`src/alpha/old.ts\`
|
|
912
951
|
|
|
913
|
-
|
|
914
|
-
any detectado
|
|
915
|
-
**Ação:** tipar
|
|
916
|
-
**Evidência:** \`export const a: any = 1;\`
|
|
952
|
+
## Cobertura por domínio
|
|
917
953
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
"# Review — Alpha (\`alpha\`) — main
|
|
923
|
-
|
|
924
|
-
**Data:** <date>
|
|
925
|
-
**Arquivos revisados:** 2/2
|
|
926
|
-
**Achados:** 1
|
|
954
|
+
| Domínio | Achados | Revisados | Fora do recorte | Faltam |
|
|
955
|
+
|---|---|---|---|---|
|
|
956
|
+
| Alpha | 1 | 2/2 | — | — |
|
|
957
|
+
| Lógica e domínio (fluxo) | 0 | 2/2 | — | — |
|
|
927
958
|
|
|
928
|
-
|
|
959
|
+
> \`Faltam\` = arquivos do escopo sem revisão e sem declaração em \`skipped\`.
|
|
929
960
|
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
- **Nunca usar \`any\`.** — \`src/alpha/a.ts:1\` · _Alpha_
|
|
933
|
-
any detectado
|
|
934
|
-
**Ação:** tipar
|
|
935
|
-
**Evidência:** \`export const a: any = 1;\`
|
|
961
|
+
## Conclusão
|
|
936
962
|
|
|
963
|
+
**Resumo:** 1 bloqueantes · 0 atenção · 0 sugestões · 0 nits.
|
|
937
964
|
"
|
|
938
965
|
`;
|
|
939
966
|
|
|
940
|
-
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest,
|
|
967
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, resumo e state: state.json 1`] = `
|
|
941
968
|
"{
|
|
942
969
|
"version": 2,
|
|
943
970
|
"branch": "main",
|
|
@@ -960,6 +987,7 @@ exports[`baseline — artefatos de prepare/finalize gera classification, brief,
|
|
|
960
987
|
"message": "any detectado",
|
|
961
988
|
"action": "tipar",
|
|
962
989
|
"evidence": "export const a: any = 1;",
|
|
990
|
+
"basis": "rule",
|
|
963
991
|
"anchor": {
|
|
964
992
|
"snippet": "export const a: any = 1;",
|
|
965
993
|
"line": 1,
|
|
@@ -982,7 +1010,7 @@ exports[`baseline — artefatos de prepare/finalize gera classification, brief,
|
|
|
982
1010
|
}"
|
|
983
1011
|
`;
|
|
984
1012
|
|
|
985
|
-
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest,
|
|
1013
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, resumo e state: run.json 1`] = `
|
|
986
1014
|
"{
|
|
987
1015
|
"id": "<uuid>",
|
|
988
1016
|
"repoKey": "path:<cwd>",
|