@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.
- package/README.md +6 -1
- 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/findings-command.ts +11 -1
- package/src/cli/commands/golden-command.ts +92 -0
- package/src/cli/commands/hunt-command.ts +105 -4
- package/src/cli/commands/review-command.ts +38 -0
- package/src/cli/commands/status-command.ts +3 -2
- package/src/cli/help.ts +6 -1
- package/src/cli/index.ts +5 -1
- package/src/cli/progress.ts +7 -2
- package/src/core/ai/ai-client.ts +38 -2
- 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 +8 -0
- 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/usage-recorder.ts +53 -1
- package/src/core/brief.ts +278 -16
- package/src/core/builtins.ts +108 -0
- package/src/core/business-summary.ts +583 -0
- package/src/core/commands/compare.ts +266 -0
- package/src/core/commands/context.ts +6 -2
- package/src/core/commands/findings.ts +38 -30
- package/src/core/commands/golden.ts +176 -0
- package/src/core/commands/review.ts +6 -0
- package/src/core/commands/scaffold.ts +29 -0
- package/src/core/commands/status.ts +9 -4
- package/src/core/compare.ts +310 -0
- package/src/core/concurrency.ts +30 -0
- package/src/core/config.ts +41 -3
- package/src/core/defaults.ts +50 -4
- 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 +371 -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 +14 -1
- package/src/core/engine/review-session.ts +11 -13
- package/src/core/engine/run-artifacts.ts +196 -0
- package/src/core/engine/run-format.ts +4 -0
- package/src/core/findings-state.ts +22 -2
- package/src/core/github-review.ts +5 -2
- package/src/core/golden.ts +346 -0
- package/src/core/hunt/hunt-runner.ts +621 -34
- package/src/core/hunt/index.ts +40 -1
- package/src/core/hunt/maki-intent-prompt.ts +50 -0
- package/src/core/hunt/maki-prompt.ts +298 -5
- package/src/core/hunt/maki-runner.ts +93 -16
- package/src/core/hunt/pool.ts +4 -26
- package/src/core/hunt/review-checks.ts +460 -0
- package/src/core/logging/index.ts +6 -1
- package/src/core/logging/progress.ts +85 -1
- package/src/core/orchestrator.ts +33 -1289
- 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 +18 -1
- package/src/core/propagation.ts +127 -0
- package/src/core/registry-check.ts +90 -27
- package/src/core/renderers/manifest-writer.ts +13 -0
- package/src/core/renderers/resume-renderer.ts +151 -11
- package/src/core/report-builder.ts +116 -278
- package/src/core/severity.ts +245 -0
- 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 +51 -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 +55 -10
- package/src/skill/README.md +19 -14
- package/src/skill/SETUP.md +1 -0
- package/src/skill/SKILL.md +13 -4
- package/src/skill/example-resume.md +43 -0
- package/src/skill/hunt.md +205 -58
- package/src/skill/train.md +3 -0
- package/src/tests/__snapshots__/baseline.test.ts.snap +208 -184
- package/src/tests/ai-core.test.ts +46 -0
- 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/compare.test.ts +256 -0
- package/src/tests/findings-state.test.ts +82 -0
- package/src/tests/fixtures/fake-model-provider.ts +2 -1
- package/src/tests/golden.test.ts +195 -0
- package/src/tests/hunt-maki.test.ts +710 -2
- package/src/tests/markdown.test.ts +3 -3
- package/src/tests/progress.test.ts +29 -1
- package/src/tests/propagation.test.ts +119 -0
- package/src/tests/review-resume.test.ts +60 -1
- package/src/tests/review-scope.test.ts +38 -29
- package/src/tests/review-scripts.test.ts +125 -218
- package/src/tests/server.test.ts +7 -4
- package/src/tests/severity.test.ts +235 -0
- 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
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
|
|
51
|
-
| 1. Preparar | `houndsman` | skill | `classification.json` + `candidates.json` + `briefs/` + `manifest.json` |
|
|
52
|
-
|
|
|
53
|
-
|
|
|
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
|
|
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
|
-
|
|
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
|
-
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
|
185
|
-
|
|
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
|
|
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
|
-
`
|
|
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.
|
|
217
|
-
|
|
218
|
-
4.
|
|
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
|
|
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
|
|
390
|
+
## Estrutura do Resumo Final
|
|
234
391
|
|
|
235
392
|
```markdown
|
|
236
|
-
#
|
|
393
|
+
# Resumo da revisão — [branch]
|
|
394
|
+
|
|
395
|
+
**Data:** YYYY-MM-DD · **Status:** ✅ Aprovado / ⚠️ Aprovado com Ressalvas / ❌ Mudanças Necessárias
|
|
237
396
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
**Achados:** N bloqueantes · N atenção · N sugestões · N nits
|
|
397
|
+
## Resumo de negócio
|
|
398
|
+
...
|
|
241
399
|
|
|
242
|
-
##
|
|
243
|
-
**
|
|
244
|
-
**Branch:** `feature/x` → `main`
|
|
245
|
-
**Objetivo:** ...
|
|
246
|
-
**Resumo das alterações:**
|
|
247
|
-
- ...
|
|
400
|
+
## Pontos técnicos
|
|
401
|
+
- **Contratos** — ...
|
|
248
402
|
|
|
249
|
-
##
|
|
250
|
-
|
|
|
403
|
+
## Cobertura por domínio
|
|
404
|
+
| Domínio | Achados | Revisados | Faltam |
|
|
251
405
|
|---|---|---|---|
|
|
252
406
|
|
|
253
|
-
##
|
|
254
|
-
|
|
255
|
-
|---|---|---|
|
|
407
|
+
## Candidatos não verificados (N) ← se houver
|
|
408
|
+
- `arquivo` · severity · regra
|
|
256
409
|
|
|
257
410
|
## Conclusão
|
|
258
|
-
**
|
|
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
|
-
>
|
|
270
|
-
>
|
|
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
|
|
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
|
|
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
|
↓
|
package/src/skill/train.md
CHANGED
|
@@ -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)
|