@payconductor/houndsman 0.13.0 → 0.16.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 (116) hide show
  1. package/README.md +6 -1
  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/findings-command.ts +11 -1
  6. package/src/cli/commands/golden-command.ts +92 -0
  7. package/src/cli/commands/hunt-command.ts +105 -4
  8. package/src/cli/commands/review-command.ts +38 -0
  9. package/src/cli/commands/status-command.ts +3 -2
  10. package/src/cli/help.ts +6 -1
  11. package/src/cli/index.ts +5 -1
  12. package/src/cli/progress.ts +7 -2
  13. package/src/core/ai/ai-client.ts +38 -2
  14. package/src/core/ai/features/brief-enricher.ts +1 -1
  15. package/src/core/ai/features/business-analyzer.ts +61 -0
  16. package/src/core/ai/features/business-summarizer.ts +44 -0
  17. package/src/core/ai/index.ts +8 -0
  18. package/src/core/ai/prompts/brief.ts +33 -7
  19. package/src/core/ai/prompts/business.ts +76 -0
  20. package/src/core/ai/provider-capabilities.ts +12 -0
  21. package/src/core/ai/schemas.ts +70 -2
  22. package/src/core/ai/usage-recorder.ts +53 -1
  23. package/src/core/brief.ts +278 -16
  24. package/src/core/builtins.ts +108 -0
  25. package/src/core/business-summary.ts +583 -0
  26. package/src/core/commands/compare.ts +266 -0
  27. package/src/core/commands/context.ts +6 -2
  28. package/src/core/commands/findings.ts +38 -30
  29. package/src/core/commands/golden.ts +176 -0
  30. package/src/core/commands/review.ts +6 -0
  31. package/src/core/commands/scaffold.ts +29 -0
  32. package/src/core/commands/status.ts +9 -4
  33. package/src/core/compare.ts +310 -0
  34. package/src/core/concurrency.ts +30 -0
  35. package/src/core/config.ts +41 -3
  36. package/src/core/defaults.ts +50 -4
  37. package/src/core/domain/budget.ts +62 -4
  38. package/src/core/domain/classification.ts +12 -2
  39. package/src/core/engine/carryover.ts +4 -0
  40. package/src/core/engine/finalize-pipeline.ts +371 -0
  41. package/src/core/engine/prepare-pipeline.ts +1294 -0
  42. package/src/core/engine/review-context.ts +51 -0
  43. package/src/core/engine/review-options.ts +47 -0
  44. package/src/core/engine/review-scope.ts +14 -1
  45. package/src/core/engine/review-session.ts +11 -13
  46. package/src/core/engine/run-artifacts.ts +196 -0
  47. package/src/core/engine/run-format.ts +4 -0
  48. package/src/core/findings-state.ts +22 -2
  49. package/src/core/github-review.ts +5 -2
  50. package/src/core/golden.ts +346 -0
  51. package/src/core/hunt/hunt-runner.ts +621 -34
  52. package/src/core/hunt/index.ts +40 -1
  53. package/src/core/hunt/maki-intent-prompt.ts +50 -0
  54. package/src/core/hunt/maki-prompt.ts +298 -5
  55. package/src/core/hunt/maki-runner.ts +93 -16
  56. package/src/core/hunt/pool.ts +4 -26
  57. package/src/core/hunt/review-checks.ts +460 -0
  58. package/src/core/logging/index.ts +6 -1
  59. package/src/core/logging/progress.ts +85 -1
  60. package/src/core/orchestrator.ts +33 -1289
  61. package/src/core/paths.ts +6 -3
  62. package/src/core/pr-context.ts +2 -4
  63. package/src/core/prepare-report.ts +61 -0
  64. package/src/core/project-config.ts +18 -1
  65. package/src/core/propagation.ts +127 -0
  66. package/src/core/registry-check.ts +90 -27
  67. package/src/core/renderers/manifest-writer.ts +13 -0
  68. package/src/core/renderers/resume-renderer.ts +151 -11
  69. package/src/core/report-builder.ts +116 -278
  70. package/src/core/severity.ts +245 -0
  71. package/src/core/storage/file/file-storage.ts +7 -3
  72. package/src/core/storage/sqlite/mappers.ts +10 -0
  73. package/src/core/storage/sqlite/schema.ts +104 -23
  74. package/src/core/storage/sqlite/sqlite-storage.ts +22 -9
  75. package/src/core/storage/types.ts +17 -4
  76. package/src/core/storage/work-area.ts +59 -1
  77. package/src/core/types.ts +31 -0
  78. package/src/core/watchdog-registry.ts +21 -3
  79. package/src/index.ts +51 -4
  80. package/src/server/client/ArtifactsPanel.tsx +4 -2
  81. package/src/server/client/FindingCard.tsx +21 -1
  82. package/src/server/client/RunsSection.tsx +5 -0
  83. package/src/server/client/utils/constants.ts +21 -11
  84. package/src/server/client/utils/markdown.ts +1 -1
  85. package/src/server/client/utils/types.ts +14 -2
  86. package/src/server/run-repository.ts +35 -14
  87. package/src/server/styles.css +2 -0
  88. package/src/skill/OUTPUT-FORMAT.md +55 -10
  89. package/src/skill/README.md +19 -14
  90. package/src/skill/SETUP.md +1 -0
  91. package/src/skill/SKILL.md +13 -4
  92. package/src/skill/example-resume.md +43 -0
  93. package/src/skill/hunt.md +205 -58
  94. package/src/skill/train.md +3 -0
  95. package/src/tests/__snapshots__/baseline.test.ts.snap +208 -184
  96. package/src/tests/ai-core.test.ts +46 -0
  97. package/src/tests/ai-features.test.ts +95 -4
  98. package/src/tests/baseline.test.ts +29 -121
  99. package/src/tests/brief-scope.test.ts +250 -0
  100. package/src/tests/business-summary.test.ts +258 -0
  101. package/src/tests/compare.test.ts +256 -0
  102. package/src/tests/findings-state.test.ts +82 -0
  103. package/src/tests/fixtures/fake-model-provider.ts +2 -1
  104. package/src/tests/golden.test.ts +195 -0
  105. package/src/tests/hunt-maki.test.ts +710 -2
  106. package/src/tests/markdown.test.ts +3 -3
  107. package/src/tests/progress.test.ts +29 -1
  108. package/src/tests/propagation.test.ts +119 -0
  109. package/src/tests/review-resume.test.ts +60 -1
  110. package/src/tests/review-scope.test.ts +38 -29
  111. package/src/tests/review-scripts.test.ts +125 -218
  112. package/src/tests/server.test.ts +7 -4
  113. package/src/tests/severity.test.ts +235 -0
  114. package/src/tests/storage.test.ts +194 -9
  115. package/src/core/renderers/report-renderer.ts +0 -66
  116. package/src/skill/example-review.md +0 -66
package/src/skill/hunt.md CHANGED
@@ -22,6 +22,66 @@ Os dois modos produzem os mesmos artefatos, usam o mesmo staging e o mesmo ciclo
22
22
  > maki e despacha outro harness. Siga os passos 0–3 normalmente; o comando CLI é para quem
23
23
  > quer rodar tudo no terminal.
24
24
 
25
+ ### Harness local (CLI) — profundidade por checklist
26
+
27
+ `houndsman hunt` usa o mesmo `prepare`/`finalize`, mas cada watchdog roda headless. Para não
28
+ trocar profundidade por velocidade:
29
+
30
+ - o **`general` roda em três papéis separados** (sessões distintas): (1) **fluxo** — caça
31
+ achados sem devolver `checks`/`rules`; (2) **bookkeeping** — tarefa estreita, só vereditos
32
+ com `at` comprovado; (3) **adversarial** — sessão nova, com os achados já cobertos como
33
+ contexto, atacando as cinco classes (credencial/estado, capacidade, identificador,
34
+ idempotência, contrato). Antes, um único JSON de 60 KB misturava tudo e o revisor entregava
35
+ poucos achados com checklist “ok” sem lastro;
36
+ - nos demais watchdogs, o prompt exige **uma verificação por fluxo/invariante** (`checks`:
37
+ `ok`/`gap`/`n/a` + `arquivo:linha`) e **uma por regra numerada** (`rules`);
38
+ - **`n/a` não é cobertura**: só conta como verificado o `ok`/`gap` cujo `at` resolve para um
39
+ arquivo existente e uma linha dentro dele (e, quando o arquivo não está na raiz, não conta);
40
+ - se a primeira resposta não cobrir o checklist, o harness **retoma a sessão** (`--resume`) e
41
+ pede só os vereditos pendentes; os achados das passadas são **unidos** (dedupe por
42
+ arquivo+linha+regra, maior severidade vence);
43
+ - o prompt do `general` só pede o `businessSummary` quando o prepare **não** trouxe um modelo
44
+ da IA (gerar um resumo que seria rejeitado custava atenção do revisor);
45
+ - o orçamento de exploração cresce com o tamanho do domínio (piso 6/10, teto 14/24 leituras);
46
+ - a saída do maki concatena **todas** as mensagens do agente; o parser procura o último JSON
47
+ válido (bloco cercado ou objeto balanceado), não o primeiro `{`;
48
+ - retry de saída inválida **retoma a mesma sessão** enviando só o schema — não refaz a
49
+ exploração inteira; e o system prompt do harness prioriza profundidade sobre economia de
50
+ tool calls;
51
+ - `hunt-report.json` traz `rules`/`checks { expected, verified, missing, notApplicable, gaps }`,
52
+ `coverage` (`reviewed`/`skipped`/`undeclared`), o custo de cada passada extra (`checklist`,
53
+ `secondOpinion`) e a decisão sobre o modelo de intenção por watchdog. Desligue com
54
+ `--no-checklist`/`--no-second-opinion` (ou `hunt.checklist`/`hunt.secondOpinion: false`).
55
+
56
+ ### Golden set — medir em vez de contar
57
+
58
+ Contagem de findings não mede profundidade: variantes diferentes amostram pontos diferentes do
59
+ mesmo diff. O golden set **não gera** achados nem julga intenção — é uma lista de defeitos que
60
+ você já confirmou no código (âncora), usada para dar nota a uma execução:
61
+
62
+ - **recall** = quantos defeitos congelados a run encontrou;
63
+ - **precisão** = quanto do que a run reportou cai num defeito congelado (o resto pode ser achado
64
+ legítimo ainda não triado — o relatório avisa);
65
+ - **faltaram / fora do golden** = onde melhorar o brief/harness e o que ainda falta triar.
66
+
67
+ ```bash
68
+ houndsman golden .houndsman/golden/<pr>.json # todas as variantes da branch
69
+ houndsman golden .houndsman/golden/<pr>.json --variant x # uma variante
70
+ ```
71
+
72
+ - formato: `{ "version": 1, "commit": "abc1234", "expected": [{ "id", "file", "line",
73
+ "tolerance", "match", "severity", "note" }] }`;
74
+ - cada expectativa é uma **âncora** (arquivo + faixa de linha + trecho), nunca um fingerprint;
75
+ um finding comprova no máximo um defeito;
76
+ - o `commit` é a referência do congelamento. Run que revisou **outro commit** é avaliada
77
+ normalmente, mas o relatório abre com **aviso** de commit divergente (não é erro): as linhas
78
+ podem ter se deslocado e a “falta” pode ser drift, não perda de profundidade — revalide o
79
+ golden antes de concluir;
80
+ - `.houndsman/golden/` é massa local de avaliação (fica no `.gitignore` da camada), não
81
+ configuração do projeto;
82
+ - saída gravada como `golden-<slug>.md|json` na run avaliada. Use para comparar
83
+ prompts/harness na **mesma** PR.
84
+
25
85
  ## Alvo da revisão
26
86
 
27
87
  Traduza o pedido do usuário para flags **antes** de começar:
@@ -47,10 +107,11 @@ mudanças antes de push.
47
107
 
48
108
  | Passo | Comando | Quem roda | Resultado |
49
109
  |---|---|---|---|
50
- | 0. Contexto | `houndsman context` | subagente | `context.json` + `context-brief.md` → `context-summary.json` |
51
- | 1. Preparar | `houndsman` | skill | `classification.json` + `candidates.json` + `briefs/` + `manifest.json` |
52
- | 2. Revisar | *(subagentes)* | skill (via `runSubagent`) | `findings/<watchdog>.json` (um por watchdog) |
53
- | 3. Finalizar | `houndsman --finalize` | skill | `review.md` + triagem/status no storage |
110
+ | 0. Contexto | `houndsman --pr` (via `gh`) | prepare | `context.json` + `context-brief.md` → `context-summary.json` (IA; sem IA, subagente) |
111
+ | 1. Preparar | `houndsman` | skill | `classification.json` + `candidates.json` + `business-summary.json` + `briefs/` + `manifest.json` |
112
+ | 1.5. Intenção | *(subagente)* | skill, só sem IA | `business-summary.json` enriquecido (`source: "reviewer"`) |
113
+ | 2. Revisar | *(subagentes)* | skill (via `runSubagent`) | `findings/<watchdog>.json` (um por watchdog, incluindo `general`) |
114
+ | 3. Finalizar | `houndsman --finalize` | skill | `review-resume.md` + triagem/status no storage |
54
115
 
55
116
  > Por que comandos separados? Entre o passo 1 e o 3 acontece trabalho de LLM (os subagentes).
56
117
  > Depois do passo 3, a correção dos achados é a capability **`fix`** — ver `fix.md`.
@@ -76,10 +137,14 @@ mudanças antes de push.
76
137
 
77
138
  ---
78
139
 
79
- ## Passo 0 — Contexto da PR (subagente)
140
+ ## Passo 0 — Contexto da PR
80
141
 
81
142
  O contexto vem da **descrição da PR** via GitHub CLI (`gh`), quando disponível e logado.
82
- Um subagente executa o CLI e resume:
143
+
144
+ **Com IA ligada** (`HOUNDSMAN_DEEP_SEEK_API_KEY`), o próprio `houndsman --pr 456` coleta o
145
+ contexto e o resume (`AiContextSummarizer`) — **não despache subagente** para este passo.
146
+
147
+ Sem IA, um subagente executa o CLI e resume:
83
148
 
84
149
  ```
85
150
  Você é o subagente de contexto do houndsman. Execute `houndsman context --pr 456`
@@ -118,6 +183,8 @@ staging dos subagentes em `<HOUNDSMAN_HOME>/work/<reviewId>/`:
118
183
  | `ast-summary.json` | Fatos estruturais + delta por arquivo (AST TS/JS) (storage) |
119
184
  | `ast-impact.json` | Importadores reversos e exports públicos alterados (storage) |
120
185
  | `candidates.json` | Indícios da pré-análise Jev (regra + arquivo + confiança) (storage) |
186
+ | `business-summary.json` | Modelo de intenção (fluxos, invariantes, contratos, estados) (staging + storage) |
187
+ | `business-brief.md` | Brief do passo de intenção (staging + storage) |
121
188
  | `briefs/<watchdog>.md` | Instruções prontas para cada subagente (staging + storage, para auditoria) |
122
189
  | `manifest.json` | Resumo: watchdogs, arquivos, deletados, status, contexto, Jev, orçamento (storage) |
123
190
 
@@ -129,6 +196,11 @@ staging dos subagentes em `<HOUNDSMAN_HOME>/work/<reviewId>/`:
129
196
  > símbolos adicionados/removidos/alterados, assinaturas e imports; o impacto reverso
130
197
  > (quem importa os arquivos alterados) aparece como mapa de leitura. É fail-open:
131
198
  > sem grammar/ABI, a revisão segue só com regex. Desative com `--no-ast`.
199
+ >
200
+ > **Trechos do diff:** cada brief recebe o patch `-U0` do seu domínio, com o teto
201
+ > distribuído entre **todos** os arquivos (rateio igual + excedente por churn) — não há
202
+ > arquivo "sem diff" só porque outro era maior. Trecho cortado vem com o marcador
203
+ > `… [trecho truncado — abra o arquivo para o restante]`.
132
204
 
133
205
  **Excluídos automaticamente:** lock files, `dist/`, `build/`, `.env*`, imagens, source
134
206
  maps (padrões do projeto em `.houndsman/exclusions.ts`).
@@ -142,13 +214,22 @@ com **churn** (linhas adicionadas/removidas) por arquivo — o custo não cresce
142
214
  arquivos da PR. Cada brief recebe no máximo `budgets.maxFilesPerBrief` arquivos (default 40),
143
215
  **priorizados pelo maior churn**:
144
216
 
145
- - O excedente vai para a seção **Fora do orçamento (NÃO revisar)** do brief e o watchdog deve
146
- registrá-lo em `skipped` — a tabela de **Cobertura** mostra o que ficou de fora (nunca some
147
- silenciosamente).
217
+ - No **`general`**, acima de **40 arquivos** ou **2.000 linhas alteradas** o prepare aplica o
218
+ **recorte por fluxo**: até 15 arquivos (os citados pelos fluxos do modelo de intenção + os de
219
+ maior churn), com diff de até 2k por arquivo. O restante vai para **Fora do recorte** e deve
220
+ ser registrado em `skipped` (`fora do fluxo`). A tabela de cobertura do resumo mostra
221
+ `Revisados`, `Fora do recorte` e `Faltam` (sem declaração).
222
+ - O excedente do orçamento vai para a seção **Fora do recorte (NÃO revisar)** do brief e o
223
+ watchdog deve registrá-lo em `skipped` — a tabela de **Cobertura** mostra o que ficou de fora
224
+ (nunca some silenciosamente).
148
225
  - Isso mantém o contexto do subagente limitado mesmo num PR de 10k linhas com centenas de
149
226
  arquivos num único domínio.
150
227
  - Ajuste em `houndsman.config.ts`: `budgets: { maxFilesPerBrief: 60 }` e
151
228
  `concurrency: { jev: 8 }`. Valores não-positivos caem no default (o `doctor` avisa).
229
+ - **Prioridade por caminho (opcional):** `priorities: [{ pattern, bonus?, maxRiskFromChurn? }]`.
230
+ O risco é `min(churn, maxRiskFromChurn) + bonus`: `bonus` promove caminho crítico (`db` +300,
231
+ `services` +200) e o teto satura o superchurn de caminho de baixa criticidade (`client` com
232
+ 2.000 linhas reformatadas não passa de 120). A primeira regra que casar vence.
152
233
 
153
234
  ### Pré-análise Jev (Passo 1.5, opcional)
154
235
 
@@ -166,10 +247,10 @@ Cada `--finalize` grava o **commit revisado** (`reviewedSha` da review no storag
166
247
  seguinte, se o `HEAD` descende desse commit (sem rebase), o motor revisa **só o delta** — os
167
248
  arquivos alterados desde a última revisão — e **carrega** os findings dos arquivos inalterados
168
249
  (carry-over), sem re-revisá-los. O `manifest.json` traz o bloco `incremental` (`from`,
169
- `changedFiles`, `carried`) e o `review.md` abre com um aviso.
250
+ `changedFiles`, `carried`) e o `review-resume.md` abre com um aviso.
170
251
 
171
252
  - Sem mudanças desde a última revisão → **no-op**: o prepare não gera briefs nem reescreve
172
- artefatos (classification, manifest, review.md), e o `--finalize` também vira no-op — pare o
253
+ artefatos (classification, manifest, review-resume.md), e o `--finalize` também vira no-op — pare o
173
254
  fluxo aí (nenhum subagente é despachado).
174
255
  - Rebase/force-push (histórico reescrito) → cai automaticamente no **review completo**.
175
256
  - Forçar completo: `houndsman --full` (ou `--clean`, que também descarta a triagem anterior).
@@ -179,27 +260,101 @@ arquivos alterados desde a última revisão — e **carrega** os findings dos ar
179
260
 
180
261
  ---
181
262
 
263
+ ## Passo 1.5 — Intenção da PR (subagente, condicional)
264
+
265
+ O motor **sempre** grava `business-summary.json` (determinístico) e `business-brief.md`.
266
+ Quando a IA está configurada (`HOUNDSMAN_DEEP_SEEK_API_KEY`), o prepare já gravou o modelo
267
+ com `source: "ai"` e este passo é **pulado**.
268
+
269
+ > **Quando pular (operacional):** se o prepare imprimir "Intenção da PR reconstruída pela IA"
270
+ > ou `business-summary.json` tiver `source: "ai"`, não despache este subagente. Se a mensagem
271
+ > for "Intenção da PR determinística", despache.
272
+
273
+ Sem IA, despache **um** subagente antes dos watchdogs:
274
+
275
+ ```
276
+ Leia e execute o brief de intenção: <staging>/business-brief.md
277
+ Você é o passo de intenção do houndsman no {{projectName}}.
278
+ Use como raiz de leitura o **Worktree:** indicado. Grave o JSON em
279
+ `<staging>/business-summary.json` com `source: "reviewer"`.
280
+ Não produza achados.
281
+ ```
282
+
283
+ - O modelo descreve **o que a PR deve entregar** (fluxos, invariantes, contratos,
284
+ estados) — não a estrutura do código.
285
+ - Ele é lido por todos os briefs; o revisor `general` o reconstrói no primeiro passo da
286
+ revisão e pode refiná-lo.
287
+ - Falha do subagente mantém a versão determinística (fail-open).
288
+
289
+ > **Obrigatório:** a revisão de lógica (`general`) nunca é opcional. Se o Passo 1.5 não
290
+ > rodar, o `general` ainda reconstrói o modelo no próprio brief — a revisão degrada, mas
291
+ > não perde o eixo de lógica/domínio.
292
+
293
+ ---
294
+
182
295
  ## Passo 2 — Revisar (skill despacha os subagentes)
183
296
 
184
- Um subagente por brief. Despache em **ondas** (ex.: até 8 subagentes por bloco de tool
185
- calls) — evita estourar limites de taxa quando há muitos watchdogs. O prompt é o próprio brief:
297
+ Um subagente por brief. Despache **todos os briefs da onda no MESMO bloco de tool calls**
298
+ (paralelo real) — não espere um terminar para despachar o próximo. Só divida em ondas
299
+ menores se a plataforma recusar a concorrência.
300
+
301
+ > **Custo:** cada subagente é um agente completo. Despacho serial transforma 8 briefs em
302
+ > 8 × o tempo de um watchdog; o paralelo custa o do mais lento.
303
+
304
+ > **`general` é obrigatório.** O motor injeta esse watchdog reservado em todos os ciclos
305
+ > (com todos os arquivos alterados). Ele audita o fluxo inteiro e emite `Lógica:`/`Domínio:`.
306
+ > Nunca remova o brief dele da onda. Despache-o primeiro (é o mais longo).
307
+
186
308
 
187
309
  > **Heartbeat:** antes de despachar cada onda, rode `houndsman status ping`. A UI usa esse
188
310
  > sinal (e não `updatedAt`) para saber que a execução está viva; sem ping por 10 min ela
189
311
  > mostra "Timeout na revisão".
190
312
 
313
+ ### Teste A/B (variantes)
314
+
315
+ Para comparar duas formas de rodar a mesma PR (prompt, modelo, configuração, versão do
316
+ houndsman), dê um **rótulo** a cada tentativa — cada variante é uma run própria
317
+ (`(repo, branch, variante)`) e nada é apagado:
318
+
319
+ ```bash
320
+ houndsman --pr 456 --variant baseline # prepare da variante A
321
+ # despache os briefs e grave findings/baseline
322
+ houndsman --pr 456 --variant baseline --finalize
323
+
324
+ houndsman --pr 456 --variant otimizado # prepare da variante B
325
+ # ...
326
+ houndsman --pr 456 --variant otimizado --finalize
327
+
328
+ houndsman compare --branch <head> --a baseline --b otimizado
329
+ houndsman compare --list --branch <head> # ver as runs e contagens
330
+ ```
331
+
332
+ - `--variant <label>` vale para o comando default, `hunt`, `context`, `status`,
333
+ `findings` e `verify`; use o mesmo rótulo em todas as etapas.
334
+ - Repetir a **mesma** variante: `--full` re-revisa o commit; para um teste realmente
335
+ limpo, use um rótulo novo.
336
+ - `compare` grava `compare-<a>--<b>.md|.json` na run B (aparece nos artefatos da UI) e
337
+ mostra achados novos/sumidos, mudança de severidade, cobertura, tempo e tokens.
338
+ - Sem rótulo, a run principal continua sendo a da branch (o `compare` assume A = principal
339
+ quando só `--b` é informado).
340
+
191
341
  ```
192
342
  Leia e execute o brief: <caminho absoluto impresso pelo prepare>/briefs/<watchdog-id>.md
193
343
  Você é o watchdog <watchdog-id> do {{projectName}}.
194
344
  Use como raiz de leitura o **Worktree:** indicado no brief (nunca o clone principal).
345
+ O brief já traz os trechos alterados (`## Trechos alterados (diff)`): comece por eles.
346
+ Respeite o **Orçamento de exploração** do brief (6 leituras/6 buscas; `general`: 10/10):
347
+ se a prova não estiver no brief nem nesse orçamento, **não é achado**.
348
+ Em `reviewedFiles`, liste apenas arquivos do seu domínio (subconjunto do brief).
195
349
  ```
196
350
 
197
351
  Cada subagente grava o `outputPath` indicado no brief (schema `.houndsman/core/skill/OUTPUT-FORMAT.md`).
198
- Sem achados → `"findings": []` (arquivo obrigatório). Arquivos na seção **Fora do orçamento**
199
- não são lidos: registre-os em `skipped`.
352
+ Sem achados → `"findings": []` (arquivo obrigatório). Arquivos na seção **Fora do recorte**
353
+ não são lidos: registre-os em `skipped` com o motivo (`budget` ou `fora do fluxo`).
200
354
 
201
355
  **NUNCA enviar:** `git diff` completo · histórico de commits · arquivos de outros domínios ·
202
- `AGENTS.md` completo (já está no contexto global).
356
+ o `business-summary.json` inteiro (o brief já traz o recorte do domínio) · `AGENTS.md` completo
357
+ (já está no contexto global).
203
358
 
204
359
  ---
205
360
 
@@ -213,76 +368,68 @@ houndsman --finalize # alvo = branch atual
213
368
  Falha com mensagem clara se faltar algum `findings/<watchdog>.json` no staging. Quando todos existem:
214
369
  1. Valida o schema de cada JSON
215
370
  2. Deduplica achados por `(file, line, rule)` mesclando watchdogs sobrepostos
216
- 3. Grava um `review.<watchdog>.md` por watchdog com achados e indexa no `review.md`
217
- (**Relatórios por domínio**) — mantém o relatório consolidado enxuto
218
- 4. Grava o `review.md` abrindo pelo **sumário**: contexto, relatórios por domínio, cobertura e
219
- conclusão — antes dos achados
220
- 5. Agrupa os achados por severidade (❌ blocking > ⚠️ attention > 💡 suggestion > 🔎 nit) e
221
- **por arquivo** dentro de cada severidade (navegabilidade em PRs grandes)
222
- 6. Anexa os candidatos Jev não confirmados em `🔎 Candidatos não verificados` ao final
223
- (não bloqueiam)
224
- 7. Persiste a **triagem** no storage — um `id` curto e um `fingerprint` de conteúdo por
225
- finding, preservados entre execuções9. Marca como **`done`** os findings que sumiram do relatório (corrigidos manualmente entre
371
+ 3. Persiste a **triagem** no storage — um `id` curto e um `fingerprint` de conteúdo por
372
+ finding, preservados entre execuções
373
+ 4. Marca como **`done`** os findings que sumiram do relatório (corrigidos manualmente entre
226
374
  revisões) e **resolve as conversas correspondentes no GitHub** — só as ainda abertas, e
227
- falha-aberto (sem `gh`/PR o relatório segue igual)
375
+ falha-aberto (sem `gh`/PR o resumo segue igual)
376
+ 5. Grava o **resumo final** (`review-resume.md`): negócio, pontos técnicos, **tabela de
377
+ cobertura por domínio** (achados · revisados/esperados · faltam), candidatos não
378
+ confirmados e **conclusão**. É o único relatório em markdown — os achados ficam na triagem
379
+ (`findings`, UI), sem serem duplicados em arquivo
380
+
381
+ > **Resultado da revisão:** leia o `review-resume.md` (a saída do `--finalize` imprime o
382
+ > caminho no storage). Ele é o contexto final para responder ao usuário sobre o resultado;
383
+ > os achados individuais vêm de `findings list --json`.
384
+
228
385
  Após finalizar, corrija os achados com a capability **`fix`** (`fix.md`): a UI ou os
229
386
  comandos `findings` levam do achado à correção.
230
387
 
231
388
  ---
232
389
 
233
- ## Estrutura do Relatório
390
+ ## Estrutura do Resumo Final
234
391
 
235
392
  ```markdown
236
- # Review — [branch]
393
+ # Resumo da revisão — [branch]
394
+
395
+ **Data:** YYYY-MM-DD · **Status:** ✅ Aprovado / ⚠️ Aprovado com Ressalvas / ❌ Mudanças Necessárias
237
396
 
238
- **Data:** YYYY-MM-DD
239
- **Watchdogs ativos:** [lista]
240
- **Achados:** N bloqueantes · N atenção · N sugestões · N nits
397
+ ## Resumo de negócio
398
+ ...
241
399
 
242
- ## Contexto da PR
243
- **PR:** #123 Título — url
244
- **Branch:** `feature/x` → `main`
245
- **Objetivo:** ...
246
- **Resumo das alterações:**
247
- - ...
400
+ ## Pontos técnicos
401
+ - **Contratos** — ...
248
402
 
249
- ## Relatórios por domínio
250
- | Watchdog | Achados | Revisados | Relatório |
403
+ ## Cobertura por domínio
404
+ | Domínio | Achados | Revisados | Faltam |
251
405
  |---|---|---|---|
252
406
 
253
- ## Cobertura
254
- | Watchdog | Arquivos revisados | Findings |
255
- |---|---|---|
407
+ ## Candidatos não verificados (N) ← se houver
408
+ - `arquivo` · severity · regra
256
409
 
257
410
  ## Conclusão
258
- **Status:** ✅ Aprovado / ⚠️ Aprovado com Ressalvas / ❌ Mudanças Necessárias
259
-
260
- ## ❌ blocking
261
- ### `src/routes/order-route.ts`
262
- - **<regra>** — `src/routes/order-route.ts:5` · _<watchdogs>_
263
- <mensagem>
264
- **Ação:** <ação>
265
-
266
- ## 🔎 Candidatos não verificados (Jev) ← se houver, sempre ao final
411
+ **Resumo:** N bloqueantes · N atenção · N sugestões · N nits.
267
412
  ```
268
413
 
269
- > O **sumário** (relatórios por domínio, cobertura e conclusão) vem **antes** dos achados;
270
- > os pontos específicos ficam no fim.
414
+ > Tabelas e conclusão têm orçamento reservado: crescer o texto de negócio nunca as corta.
415
+ > Achados individuais (com `id` de triagem) vivem na UI (`Findings`) e em `findings list --json`.
271
416
 
272
417
  ---
273
418
 
274
419
  ## Fluxo Completo
275
420
 
276
421
  ```
277
- houndsman context (gh) ──► context.json ──► subagente ──► context-summary.json
422
+ houndsman --pr (gh) ──► context.json ──► prepare resume (IA) ──► context-summary.json
278
423
  ↓
279
424
  git diff --name-status (base...head)
280
425
  ↓
281
- [1] houndsman ──► storage (classification/candidates/manifest) + briefs/ no staging
426
+ [1] houndsman ──► storage (classification/candidates/business/manifest) + briefs/ no staging
427
+ ↓
428
+ [1.5] subagente de intenção ──► business-summary.json (só quando não veio da IA)
282
429
  ↓
283
- [2] N subagentes em paralelo ──► findings/<watchdog>.json no staging
430
+ [2] N+1 subagentes em paralelo ──► findings/<watchdog>.json (+ findings/general.json)
284
431
  ↓
285
- [3] houndsman --finalize ──► review.md + triagem no storage (review_done)
432
+ [3] houndsman --finalize ──► review-resume.md + triagem no storage (review_done)
286
433
  ↓
287
434
  [4] server (UI) ──► validar a revisão + marcar decision: execute
288
435
  ↓
@@ -147,6 +147,9 @@ Cada informação tem o seu campo — não espelhe a regra em vários lugares:
147
147
 
148
148
  > Severidade não é aspiração: se o projeto só aplica o padrão em 15/72 lugares, é `suggestion`.
149
149
 
150
+ > A severidade é **derivada**, não escolhida na revisão: finding de regra usa a severidade
151
+ > declarada aqui; emergente usa `impactClass`. O motor corrige divergências no `--finalize`.
152
+
150
153
  ---
151
154
 
152
155
  ## Pré-análise Jev (opcional)