@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.
Files changed (119) hide show
  1. package/README.md +23 -2
  2. package/package.json +1 -1
  3. package/src/cli/commands/compare-command.ts +112 -0
  4. package/src/cli/commands/context-command.ts +1 -0
  5. package/src/cli/commands/doctor-command.ts +22 -0
  6. package/src/cli/commands/findings-command.ts +11 -1
  7. package/src/cli/commands/hunt-command.ts +479 -0
  8. package/src/cli/commands/review-command.ts +58 -2
  9. package/src/cli/commands/status-command.ts +3 -2
  10. package/src/cli/help.ts +20 -3
  11. package/src/cli/index.ts +20 -3
  12. package/src/cli/progress.ts +50 -0
  13. package/src/core/ai/ai-client.ts +38 -2
  14. package/src/core/ai/ai-sdk-model-provider.ts +39 -0
  15. package/src/core/ai/features/brief-enricher.ts +1 -1
  16. package/src/core/ai/features/business-analyzer.ts +61 -0
  17. package/src/core/ai/features/business-summarizer.ts +44 -0
  18. package/src/core/ai/index.ts +14 -1
  19. package/src/core/ai/prompts/brief.ts +33 -7
  20. package/src/core/ai/prompts/business.ts +76 -0
  21. package/src/core/ai/provider-capabilities.ts +12 -0
  22. package/src/core/ai/schemas.ts +70 -2
  23. package/src/core/ai/types.ts +2 -0
  24. package/src/core/ai/usage-recorder.ts +53 -1
  25. package/src/core/brief.ts +246 -12
  26. package/src/core/builtins.ts +108 -0
  27. package/src/core/business-summary.ts +583 -0
  28. package/src/core/commands/compare.ts +233 -0
  29. package/src/core/commands/context.ts +6 -2
  30. package/src/core/commands/findings.ts +38 -30
  31. package/src/core/commands/review.ts +6 -0
  32. package/src/core/commands/scaffold.ts +38 -0
  33. package/src/core/commands/status.ts +9 -4
  34. package/src/core/compare.ts +243 -0
  35. package/src/core/concurrency.ts +30 -0
  36. package/src/core/config.ts +57 -1
  37. package/src/core/defaults.ts +63 -2
  38. package/src/core/domain/budget.ts +62 -4
  39. package/src/core/domain/classification.ts +12 -2
  40. package/src/core/engine/carryover.ts +4 -0
  41. package/src/core/engine/finalize-pipeline.ts +347 -0
  42. package/src/core/engine/prepare-pipeline.ts +1294 -0
  43. package/src/core/engine/review-context.ts +51 -0
  44. package/src/core/engine/review-options.ts +47 -0
  45. package/src/core/engine/review-scope.ts +106 -26
  46. package/src/core/engine/review-session.ts +18 -16
  47. package/src/core/engine/review-workspace.ts +14 -0
  48. package/src/core/engine/run-artifacts.ts +196 -0
  49. package/src/core/engine/run-format.ts +4 -0
  50. package/src/core/env.ts +14 -0
  51. package/src/core/findings-state.ts +13 -1
  52. package/src/core/github-review.ts +5 -2
  53. package/src/core/hunt/hunt-runner.ts +418 -0
  54. package/src/core/hunt/index.ts +61 -0
  55. package/src/core/hunt/maki-install.ts +331 -0
  56. package/src/core/hunt/maki-intent-prompt.ts +50 -0
  57. package/src/core/hunt/maki-model.ts +101 -0
  58. package/src/core/hunt/maki-prompt.ts +83 -0
  59. package/src/core/hunt/maki-release.ts +104 -0
  60. package/src/core/hunt/maki-runner.ts +276 -0
  61. package/src/core/hunt/pool.ts +8 -0
  62. package/src/core/logging/index.ts +7 -0
  63. package/src/core/logging/logger.ts +19 -0
  64. package/src/core/logging/progress.ts +366 -0
  65. package/src/core/orchestrator.ts +33 -1180
  66. package/src/core/paths.ts +6 -3
  67. package/src/core/pr-context.ts +2 -4
  68. package/src/core/prepare-report.ts +61 -0
  69. package/src/core/project-config.ts +46 -1
  70. package/src/core/propagation.ts +127 -0
  71. package/src/core/registry-check.ts +60 -21
  72. package/src/core/renderers/manifest-writer.ts +13 -0
  73. package/src/core/renderers/resume-renderer.ts +151 -11
  74. package/src/core/report-builder.ts +108 -278
  75. package/src/core/storage/file/file-storage.ts +7 -3
  76. package/src/core/storage/sqlite/mappers.ts +10 -0
  77. package/src/core/storage/sqlite/schema.ts +104 -23
  78. package/src/core/storage/sqlite/sqlite-storage.ts +22 -9
  79. package/src/core/storage/types.ts +17 -4
  80. package/src/core/storage/work-area.ts +59 -1
  81. package/src/core/types.ts +31 -0
  82. package/src/core/watchdog-registry.ts +21 -3
  83. package/src/index.ts +78 -4
  84. package/src/server/client/ArtifactsPanel.tsx +4 -2
  85. package/src/server/client/FindingCard.tsx +21 -1
  86. package/src/server/client/RunsSection.tsx +5 -0
  87. package/src/server/client/utils/constants.ts +21 -11
  88. package/src/server/client/utils/markdown.ts +1 -1
  89. package/src/server/client/utils/types.ts +14 -2
  90. package/src/server/run-repository.ts +35 -14
  91. package/src/server/styles.css +2 -0
  92. package/src/skill/OUTPUT-FORMAT.md +36 -10
  93. package/src/skill/README.md +30 -14
  94. package/src/skill/SETUP.md +22 -1
  95. package/src/skill/SKILL.md +17 -4
  96. package/src/skill/example-resume.md +43 -0
  97. package/src/skill/hunt.md +181 -58
  98. package/src/tests/__snapshots__/baseline.test.ts.snap +206 -178
  99. package/src/tests/ai-core.test.ts +84 -1
  100. package/src/tests/ai-features.test.ts +95 -4
  101. package/src/tests/baseline.test.ts +29 -121
  102. package/src/tests/brief-scope.test.ts +250 -0
  103. package/src/tests/business-summary.test.ts +258 -0
  104. package/src/tests/cli.test.ts +1 -0
  105. package/src/tests/compare.test.ts +233 -0
  106. package/src/tests/fixtures/fake-model-provider.ts +2 -1
  107. package/src/tests/hunt-cli.test.ts +185 -0
  108. package/src/tests/hunt-install.test.ts +153 -0
  109. package/src/tests/hunt-maki.test.ts +525 -0
  110. package/src/tests/markdown.test.ts +3 -3
  111. package/src/tests/progress.test.ts +145 -0
  112. package/src/tests/propagation.test.ts +119 -0
  113. package/src/tests/review-resume.test.ts +60 -1
  114. package/src/tests/review-scope.test.ts +90 -19
  115. package/src/tests/review-scripts.test.ts +106 -218
  116. package/src/tests/server.test.ts +7 -4
  117. package/src/tests/storage.test.ts +194 -9
  118. package/src/core/renderers/report-renderer.ts +0 -66
  119. package/src/skill/example-review.md +0 -66
package/src/skill/hunt.md CHANGED
@@ -8,6 +8,20 @@ Invocação: `/houndsman` (default), `/houndsman hunt` ou `/houndsman hunt pr 45
8
8
  O motor é o CLI **`houndsman`**; as regras do projeto ficam em `houndsman.config.ts` +
9
9
  `.houndsman/`.
10
10
 
11
+ ## Dois modos de execução
12
+
13
+ | Modo | Quem usa | Requisitos | Quem despacha os briefs |
14
+ |---|---|---|---|
15
+ | **Skill `/houndsman hunt`** (padrão) | agente externo (Copilot/Claude/etc.) | nenhum | o próprio agente, via subagentes |
16
+ | **CLI `houndsman hunt`** | operador/CI, sem agente | `houndsman hunt install` uma vez | o houndsman, via maki headless |
17
+
18
+ Os dois modos produzem os mesmos artefatos, usam o mesmo staging e o mesmo ciclo
19
+ `prepare → findings → finalize`. Nada muda no fluxo abaixo para quem usa a skill.
20
+
21
+ > **Se você é o agente executando esta skill, NÃO rode `houndsman hunt`.** Ele instala/usa o
22
+ > maki e despacha outro harness. Siga os passos 0–3 normalmente; o comando CLI é para quem
23
+ > quer rodar tudo no terminal.
24
+
11
25
  ## Alvo da revisão
12
26
 
13
27
  Traduza o pedido do usuário para flags **antes** de começar:
@@ -33,10 +47,11 @@ mudanças antes de push.
33
47
 
34
48
  | Passo | Comando | Quem roda | Resultado |
35
49
  |---|---|---|---|
36
- | 0. Contexto | `houndsman context` | subagente | `context.json` + `context-brief.md` → `context-summary.json` |
37
- | 1. Preparar | `houndsman` | skill | `classification.json` + `candidates.json` + `briefs/` + `manifest.json` |
38
- | 2. Revisar | *(subagentes)* | skill (via `runSubagent`) | `findings/<watchdog>.json` (um por watchdog) |
39
- | 3. Finalizar | `houndsman --finalize` | skill | `review.md` + triagem/status no storage |
50
+ | 0. Contexto | `houndsman --pr` (via `gh`) | prepare | `context.json` + `context-brief.md` → `context-summary.json` (IA; sem IA, subagente) |
51
+ | 1. Preparar | `houndsman` | skill | `classification.json` + `candidates.json` + `business-summary.json` + `briefs/` + `manifest.json` |
52
+ | 1.5. Intenção | *(subagente)* | skill, só sem IA | `business-summary.json` enriquecido (`source: "reviewer"`) |
53
+ | 2. Revisar | *(subagentes)* | skill (via `runSubagent`) | `findings/<watchdog>.json` (um por watchdog, incluindo `general`) |
54
+ | 3. Finalizar | `houndsman --finalize` | skill | `review-resume.md` + triagem/status no storage |
40
55
 
41
56
  > Por que comandos separados? Entre o passo 1 e o 3 acontece trabalho de LLM (os subagentes).
42
57
  > Depois do passo 3, a correção dos achados é a capability **`fix`** — ver `fix.md`.
@@ -62,10 +77,14 @@ mudanças antes de push.
62
77
 
63
78
  ---
64
79
 
65
- ## Passo 0 — Contexto da PR (subagente)
80
+ ## Passo 0 — Contexto da PR
66
81
 
67
82
  O contexto vem da **descrição da PR** via GitHub CLI (`gh`), quando disponível e logado.
68
- Um subagente executa o CLI e resume:
83
+
84
+ **Com IA ligada** (`HOUNDSMAN_DEEP_SEEK_API_KEY`), o próprio `houndsman --pr 456` coleta o
85
+ contexto e o resume (`AiContextSummarizer`) — **não despache subagente** para este passo.
86
+
87
+ Sem IA, um subagente executa o CLI e resume:
69
88
 
70
89
  ```
71
90
  Você é o subagente de contexto do houndsman. Execute `houndsman context --pr 456`
@@ -104,6 +123,8 @@ staging dos subagentes em `<HOUNDSMAN_HOME>/work/<reviewId>/`:
104
123
  | `ast-summary.json` | Fatos estruturais + delta por arquivo (AST TS/JS) (storage) |
105
124
  | `ast-impact.json` | Importadores reversos e exports públicos alterados (storage) |
106
125
  | `candidates.json` | Indícios da pré-análise Jev (regra + arquivo + confiança) (storage) |
126
+ | `business-summary.json` | Modelo de intenção (fluxos, invariantes, contratos, estados) (staging + storage) |
127
+ | `business-brief.md` | Brief do passo de intenção (staging + storage) |
107
128
  | `briefs/<watchdog>.md` | Instruções prontas para cada subagente (staging + storage, para auditoria) |
108
129
  | `manifest.json` | Resumo: watchdogs, arquivos, deletados, status, contexto, Jev, orçamento (storage) |
109
130
 
@@ -115,6 +136,11 @@ staging dos subagentes em `<HOUNDSMAN_HOME>/work/<reviewId>/`:
115
136
  > símbolos adicionados/removidos/alterados, assinaturas e imports; o impacto reverso
116
137
  > (quem importa os arquivos alterados) aparece como mapa de leitura. É fail-open:
117
138
  > sem grammar/ABI, a revisão segue só com regex. Desative com `--no-ast`.
139
+ >
140
+ > **Trechos do diff:** cada brief recebe o patch `-U0` do seu domínio, com o teto
141
+ > distribuído entre **todos** os arquivos (rateio igual + excedente por churn) — não há
142
+ > arquivo "sem diff" só porque outro era maior. Trecho cortado vem com o marcador
143
+ > `… [trecho truncado — abra o arquivo para o restante]`.
118
144
 
119
145
  **Excluídos automaticamente:** lock files, `dist/`, `build/`, `.env*`, imagens, source
120
146
  maps (padrões do projeto em `.houndsman/exclusions.ts`).
@@ -128,13 +154,22 @@ com **churn** (linhas adicionadas/removidas) por arquivo — o custo não cresce
128
154
  arquivos da PR. Cada brief recebe no máximo `budgets.maxFilesPerBrief` arquivos (default 40),
129
155
  **priorizados pelo maior churn**:
130
156
 
131
- - O excedente vai para a seção **Fora do orçamento (NÃO revisar)** do brief e o watchdog deve
132
- registrá-lo em `skipped` — a tabela de **Cobertura** mostra o que ficou de fora (nunca some
133
- silenciosamente).
157
+ - No **`general`**, acima de **40 arquivos** ou **2.000 linhas alteradas** o prepare aplica o
158
+ **recorte por fluxo**: até 15 arquivos (os citados pelos fluxos do modelo de intenção + os de
159
+ maior churn), com diff de até 2k por arquivo. O restante vai para **Fora do recorte** e deve
160
+ ser registrado em `skipped` (`fora do fluxo`). A tabela de cobertura do resumo mostra
161
+ `Revisados`, `Fora do recorte` e `Faltam` (sem declaração).
162
+ - O excedente do orçamento vai para a seção **Fora do recorte (NÃO revisar)** do brief e o
163
+ watchdog deve registrá-lo em `skipped` — a tabela de **Cobertura** mostra o que ficou de fora
164
+ (nunca some silenciosamente).
134
165
  - Isso mantém o contexto do subagente limitado mesmo num PR de 10k linhas com centenas de
135
166
  arquivos num único domínio.
136
167
  - Ajuste em `houndsman.config.ts`: `budgets: { maxFilesPerBrief: 60 }` e
137
168
  `concurrency: { jev: 8 }`. Valores não-positivos caem no default (o `doctor` avisa).
169
+ - **Prioridade por caminho (opcional):** `priorities: [{ pattern, bonus?, maxRiskFromChurn? }]`.
170
+ O risco é `min(churn, maxRiskFromChurn) + bonus`: `bonus` promove caminho crítico (`db` +300,
171
+ `services` +200) e o teto satura o superchurn de caminho de baixa criticidade (`client` com
172
+ 2.000 linhas reformatadas não passa de 120). A primeira regra que casar vence.
138
173
 
139
174
  ### Pré-análise Jev (Passo 1.5, opcional)
140
175
 
@@ -152,10 +187,10 @@ Cada `--finalize` grava o **commit revisado** (`reviewedSha` da review no storag
152
187
  seguinte, se o `HEAD` descende desse commit (sem rebase), o motor revisa **só o delta** — os
153
188
  arquivos alterados desde a última revisão — e **carrega** os findings dos arquivos inalterados
154
189
  (carry-over), sem re-revisá-los. O `manifest.json` traz o bloco `incremental` (`from`,
155
- `changedFiles`, `carried`) e o `review.md` abre com um aviso.
190
+ `changedFiles`, `carried`) e o `review-resume.md` abre com um aviso.
156
191
 
157
192
  - Sem mudanças desde a última revisão → **no-op**: o prepare não gera briefs nem reescreve
158
- artefatos (classification, manifest, review.md), e o `--finalize` também vira no-op — pare o
193
+ artefatos (classification, manifest, review-resume.md), e o `--finalize` também vira no-op — pare o
159
194
  fluxo aí (nenhum subagente é despachado).
160
195
  - Rebase/force-push (histórico reescrito) → cai automaticamente no **review completo**.
161
196
  - Forçar completo: `houndsman --full` (ou `--clean`, que também descarta a triagem anterior).
@@ -165,27 +200,101 @@ arquivos alterados desde a última revisão — e **carrega** os findings dos ar
165
200
 
166
201
  ---
167
202
 
203
+ ## Passo 1.5 — Intenção da PR (subagente, condicional)
204
+
205
+ O motor **sempre** grava `business-summary.json` (determinístico) e `business-brief.md`.
206
+ Quando a IA está configurada (`HOUNDSMAN_DEEP_SEEK_API_KEY`), o prepare já gravou o modelo
207
+ com `source: "ai"` e este passo é **pulado**.
208
+
209
+ > **Quando pular (operacional):** se o prepare imprimir "Intenção da PR reconstruída pela IA"
210
+ > ou `business-summary.json` tiver `source: "ai"`, não despache este subagente. Se a mensagem
211
+ > for "Intenção da PR determinística", despache.
212
+
213
+ Sem IA, despache **um** subagente antes dos watchdogs:
214
+
215
+ ```
216
+ Leia e execute o brief de intenção: <staging>/business-brief.md
217
+ Você é o passo de intenção do houndsman no {{projectName}}.
218
+ Use como raiz de leitura o **Worktree:** indicado. Grave o JSON em
219
+ `<staging>/business-summary.json` com `source: "reviewer"`.
220
+ Não produza achados.
221
+ ```
222
+
223
+ - O modelo descreve **o que a PR deve entregar** (fluxos, invariantes, contratos,
224
+ estados) — não a estrutura do código.
225
+ - Ele é lido por todos os briefs; o revisor `general` o reconstrói no primeiro passo da
226
+ revisão e pode refiná-lo.
227
+ - Falha do subagente mantém a versão determinística (fail-open).
228
+
229
+ > **Obrigatório:** a revisão de lógica (`general`) nunca é opcional. Se o Passo 1.5 não
230
+ > rodar, o `general` ainda reconstrói o modelo no próprio brief — a revisão degrada, mas
231
+ > não perde o eixo de lógica/domínio.
232
+
233
+ ---
234
+
168
235
  ## Passo 2 — Revisar (skill despacha os subagentes)
169
236
 
170
- Um subagente por brief. Despache em **ondas** (ex.: até 8 subagentes por bloco de tool
171
- calls) — evita estourar limites de taxa quando há muitos watchdogs. O prompt é o próprio brief:
237
+ Um subagente por brief. Despache **todos os briefs da onda no MESMO bloco de tool calls**
238
+ (paralelo real) — não espere um terminar para despachar o próximo. Só divida em ondas
239
+ menores se a plataforma recusar a concorrência.
240
+
241
+ > **Custo:** cada subagente é um agente completo. Despacho serial transforma 8 briefs em
242
+ > 8 × o tempo de um watchdog; o paralelo custa o do mais lento.
243
+
244
+ > **`general` é obrigatório.** O motor injeta esse watchdog reservado em todos os ciclos
245
+ > (com todos os arquivos alterados). Ele audita o fluxo inteiro e emite `Lógica:`/`Domínio:`.
246
+ > Nunca remova o brief dele da onda. Despache-o primeiro (é o mais longo).
247
+
172
248
 
173
249
  > **Heartbeat:** antes de despachar cada onda, rode `houndsman status ping`. A UI usa esse
174
250
  > sinal (e não `updatedAt`) para saber que a execução está viva; sem ping por 10 min ela
175
251
  > mostra "Timeout na revisão".
176
252
 
253
+ ### Teste A/B (variantes)
254
+
255
+ Para comparar duas formas de rodar a mesma PR (prompt, modelo, configuração, versão do
256
+ houndsman), dê um **rótulo** a cada tentativa — cada variante é uma run própria
257
+ (`(repo, branch, variante)`) e nada é apagado:
258
+
259
+ ```bash
260
+ houndsman --pr 456 --variant baseline # prepare da variante A
261
+ # despache os briefs e grave findings/baseline
262
+ houndsman --pr 456 --variant baseline --finalize
263
+
264
+ houndsman --pr 456 --variant otimizado # prepare da variante B
265
+ # ...
266
+ houndsman --pr 456 --variant otimizado --finalize
267
+
268
+ houndsman compare --branch <head> --a baseline --b otimizado
269
+ houndsman compare --list --branch <head> # ver as runs e contagens
270
+ ```
271
+
272
+ - `--variant <label>` vale para o comando default, `hunt`, `context`, `status`,
273
+ `findings` e `verify`; use o mesmo rótulo em todas as etapas.
274
+ - Repetir a **mesma** variante: `--full` re-revisa o commit; para um teste realmente
275
+ limpo, use um rótulo novo.
276
+ - `compare` grava `compare-<a>--<b>.md|.json` na run B (aparece nos artefatos da UI) e
277
+ mostra achados novos/sumidos, mudança de severidade, cobertura, tempo e tokens.
278
+ - Sem rótulo, a run principal continua sendo a da branch (o `compare` assume A = principal
279
+ quando só `--b` é informado).
280
+
177
281
  ```
178
282
  Leia e execute o brief: <caminho absoluto impresso pelo prepare>/briefs/<watchdog-id>.md
179
283
  Você é o watchdog <watchdog-id> do {{projectName}}.
180
284
  Use como raiz de leitura o **Worktree:** indicado no brief (nunca o clone principal).
285
+ O brief já traz os trechos alterados (`## Trechos alterados (diff)`): comece por eles.
286
+ Respeite o **Orçamento de exploração** do brief (6 leituras/6 buscas; `general`: 10/10):
287
+ se a prova não estiver no brief nem nesse orçamento, **não é achado**.
288
+ Em `reviewedFiles`, liste apenas arquivos do seu domínio (subconjunto do brief).
181
289
  ```
182
290
 
183
291
  Cada subagente grava o `outputPath` indicado no brief (schema `.houndsman/core/skill/OUTPUT-FORMAT.md`).
184
- Sem achados → `"findings": []` (arquivo obrigatório). Arquivos na seção **Fora do orçamento**
185
- não são lidos: registre-os em `skipped`.
292
+ Sem achados → `"findings": []` (arquivo obrigatório). Arquivos na seção **Fora do recorte**
293
+ não são lidos: registre-os em `skipped` com o motivo (`budget` ou `fora do fluxo`).
186
294
 
187
295
  **NUNCA enviar:** `git diff` completo · histórico de commits · arquivos de outros domínios ·
188
- `AGENTS.md` completo (já está no contexto global).
296
+ o `business-summary.json` inteiro (o brief já traz o recorte do domínio) · `AGENTS.md` completo
297
+ (já está no contexto global).
189
298
 
190
299
  ---
191
300
 
@@ -199,76 +308,68 @@ houndsman --finalize # alvo = branch atual
199
308
  Falha com mensagem clara se faltar algum `findings/<watchdog>.json` no staging. Quando todos existem:
200
309
  1. Valida o schema de cada JSON
201
310
  2. Deduplica achados por `(file, line, rule)` mesclando watchdogs sobrepostos
202
- 3. Grava um `review.<watchdog>.md` por watchdog com achados e indexa no `review.md`
203
- (**Relatórios por domínio**) — mantém o relatório consolidado enxuto
204
- 4. Grava o `review.md` abrindo pelo **sumário**: contexto, relatórios por domínio, cobertura e
205
- conclusão — antes dos achados
206
- 5. Agrupa os achados por severidade (❌ blocking > ⚠️ attention > 💡 suggestion > 🔎 nit) e
207
- **por arquivo** dentro de cada severidade (navegabilidade em PRs grandes)
208
- 6. Anexa os candidatos Jev não confirmados em `🔎 Candidatos não verificados` ao final
209
- (não bloqueiam)
210
- 7. Persiste a **triagem** no storage — um `id` curto e um `fingerprint` de conteúdo por
211
- finding, preservados entre execuções9. Marca como **`done`** os findings que sumiram do relatório (corrigidos manualmente entre
311
+ 3. Persiste a **triagem** no storage — um `id` curto e um `fingerprint` de conteúdo por
312
+ finding, preservados entre execuções
313
+ 4. Marca como **`done`** os findings que sumiram do relatório (corrigidos manualmente entre
212
314
  revisões) e **resolve as conversas correspondentes no GitHub** — só as ainda abertas, e
213
- falha-aberto (sem `gh`/PR o relatório segue igual)
315
+ falha-aberto (sem `gh`/PR o resumo segue igual)
316
+ 5. Grava o **resumo final** (`review-resume.md`): negócio, pontos técnicos, **tabela de
317
+ cobertura por domínio** (achados · revisados/esperados · faltam), candidatos não
318
+ confirmados e **conclusão**. É o único relatório em markdown — os achados ficam na triagem
319
+ (`findings`, UI), sem serem duplicados em arquivo
320
+
321
+ > **Resultado da revisão:** leia o `review-resume.md` (a saída do `--finalize` imprime o
322
+ > caminho no storage). Ele é o contexto final para responder ao usuário sobre o resultado;
323
+ > os achados individuais vêm de `findings list --json`.
324
+
214
325
  Após finalizar, corrija os achados com a capability **`fix`** (`fix.md`): a UI ou os
215
326
  comandos `findings` levam do achado à correção.
216
327
 
217
328
  ---
218
329
 
219
- ## Estrutura do Relatório
330
+ ## Estrutura do Resumo Final
220
331
 
221
332
  ```markdown
222
- # Review — [branch]
333
+ # Resumo da revisão — [branch]
223
334
 
224
- **Data:** YYYY-MM-DD
225
- **Watchdogs ativos:** [lista]
226
- **Achados:** N bloqueantes · N atenção · N sugestões · N nits
335
+ **Data:** YYYY-MM-DD · **Status:** ✅ Aprovado / ⚠️ Aprovado com Ressalvas / ❌ Mudanças Necessárias
227
336
 
228
- ## Contexto da PR
229
- **PR:** #123 Título — url
230
- **Branch:** `feature/x` → `main`
231
- **Objetivo:** ...
232
- **Resumo das alterações:**
233
- - ...
337
+ ## Resumo de negócio
338
+ ...
234
339
 
235
- ## Relatórios por domínio
236
- | Watchdog | Achados | Revisados | Relatório |
340
+ ## Pontos técnicos
341
+ - **Contratos** — ...
342
+
343
+ ## Cobertura por domínio
344
+ | Domínio | Achados | Revisados | Faltam |
237
345
  |---|---|---|---|
238
346
 
239
- ## Cobertura
240
- | Watchdog | Arquivos revisados | Findings |
241
- |---|---|---|
347
+ ## Candidatos não verificados (N) ← se houver
348
+ - `arquivo` · severity · regra
242
349
 
243
350
  ## Conclusão
244
- **Status:** ✅ Aprovado / ⚠️ Aprovado com Ressalvas / ❌ Mudanças Necessárias
245
-
246
- ## ❌ blocking
247
- ### `src/routes/order-route.ts`
248
- - **<regra>** — `src/routes/order-route.ts:5` · _<watchdogs>_
249
- <mensagem>
250
- **Ação:** <ação>
251
-
252
- ## 🔎 Candidatos não verificados (Jev) ← se houver, sempre ao final
351
+ **Resumo:** N bloqueantes · N atenção · N sugestões · N nits.
253
352
  ```
254
353
 
255
- > O **sumário** (relatórios por domínio, cobertura e conclusão) vem **antes** dos achados;
256
- > os pontos específicos ficam no fim.
354
+ > Tabelas e conclusão têm orçamento reservado: crescer o texto de negócio nunca as corta.
355
+ > Achados individuais (com `id` de triagem) vivem na UI (`Findings`) e em `findings list --json`.
257
356
 
258
357
  ---
259
358
 
260
359
  ## Fluxo Completo
261
360
 
262
361
  ```
263
- houndsman context (gh) ──► context.json ──► subagente ──► context-summary.json
362
+ houndsman --pr (gh) ──► context.json ──► prepare resume (IA) ──► context-summary.json
264
363
  ↓
265
364
  git diff --name-status (base...head)
266
365
  ↓
267
- [1] houndsman ──► storage (classification/candidates/manifest) + briefs/ no staging
366
+ [1] houndsman ──► storage (classification/candidates/business/manifest) + briefs/ no staging
367
+ ↓
368
+ [1.5] subagente de intenção ──► business-summary.json (só quando não veio da IA)
268
369
  ↓
269
- [2] N subagentes em paralelo ──► findings/<watchdog>.json no staging
370
+ [2] N+1 subagentes em paralelo ──► findings/<watchdog>.json (+ findings/general.json)
270
371
  ↓
271
- [3] houndsman --finalize ──► review.md + triagem no storage (review_done)
372
+ [3] houndsman --finalize ──► review-resume.md + triagem no storage (review_done)
272
373
  ↓
273
374
  [4] server (UI) ──► validar a revisão + marcar decision: execute
274
375
  ↓
@@ -306,6 +407,28 @@ completo) · `--no-jev` · `--no-ast` · `--fail-on-blocking` (com `--finalize`)
306
407
 
307
408
  ---
308
409
 
410
+ ## Harness local (opcional, fora da skill)
411
+
412
+ Para rodar a revisão inteira pelo terminal, sem agente externo, o mesmo `hunt` existe como
413
+ comando. A instalação é única e fica fora do projeto:
414
+
415
+ ```bash
416
+ houndsman hunt install # baixa o maki fixado em <HOUNDSMAN_HOME>/tools/maki
417
+ houndsman hunt doctor # diagnóstico (não falha se o maki não existir)
418
+ houndsman hunt --pr 456 # prepare → um processo maki por brief → finalize
419
+ houndsman hunt --pr 456 --allow-partial # finaliza mesmo se algum watchdog falhar
420
+ ```
421
+
422
+ - Reaproveita a credencial já configurada (`HOUNDSMAN_DEEP_SEEK_API_KEY` → `DEEPSEEK_API_KEY`)
423
+ e o modelo de `ai.model` (default `deepseek/deepseek-v4-pro`).
424
+ - O watchdog **não recebe escrita**: o maki devolve o JSON na resposta final e o houndsman
425
+ valida e grava `findings/<watchdog>.json`. `bash`, rede e edição ficam negados.
426
+ - Sem maki instalado, nada muda para a skill: `setup`, `doctor` e `/houndsman hunt` seguem
427
+ funcionando.
428
+ - O relatório do harness fica em `hunt-report.json` (sessões, custo e tokens por watchdog).
429
+
430
+ ---
431
+
309
432
  ## Anti-padrões
310
433
 
311
434
  - ❌ Enviar git diff completo para qualquer watchdog