@payconductor/houndsman 0.1.1 → 0.1.4

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 (44) hide show
  1. package/README.md +32 -14
  2. package/package.json +1 -1
  3. package/src/cli/index.ts +22 -11
  4. package/src/core/assets.ts +3 -0
  5. package/src/core/brief.ts +2 -3
  6. package/src/core/commands/findings.ts +232 -4
  7. package/src/core/commands/review.ts +2 -0
  8. package/src/core/commands/scaffold.ts +13 -44
  9. package/src/core/diff-source.ts +4 -4
  10. package/src/core/findings-state.ts +20 -2
  11. package/src/core/fix-batch.ts +236 -0
  12. package/src/core/git-revision.ts +105 -0
  13. package/src/core/jev/index.ts +1 -0
  14. package/src/core/jev/jev-detector.ts +2 -2
  15. package/src/core/jev/jev-verify.ts +178 -0
  16. package/src/core/orchestrator.ts +202 -15
  17. package/src/core/paths.ts +6 -0
  18. package/src/core/registry-check.ts +53 -0
  19. package/src/core/report-builder.ts +5 -0
  20. package/src/core/run-status.ts +123 -0
  21. package/src/core/verify.ts +175 -0
  22. package/src/core/watchdog-registry.ts +1 -2
  23. package/src/index.ts +1 -1
  24. package/src/server/artifacts.ts +1 -0
  25. package/src/server/client/RunList.tsx +22 -13
  26. package/src/server/client/constants.ts +32 -1
  27. package/src/server/client/types.ts +4 -0
  28. package/src/server/index.ts +12 -1
  29. package/src/skill/AUDIT-PROTOCOL.md +7 -2
  30. package/src/skill/README.md +32 -6
  31. package/src/skill/SETUP.md +11 -2
  32. package/src/skill/SKILL.md +48 -0
  33. package/src/skill/fix.md +206 -0
  34. package/src/skill/{houndsman.md → hunt.md} +42 -68
  35. package/src/skill/{houndsman-update.md → train.md} +38 -17
  36. package/src/skill/verify.md +70 -0
  37. package/src/tests/findings-commands.test.ts +252 -2
  38. package/src/tests/findings-state.test.ts +52 -1
  39. package/src/tests/fix-batch.test.ts +257 -0
  40. package/src/tests/review-scripts.test.ts +36 -0
  41. package/src/tests/run-status.test.ts +147 -0
  42. package/src/tests/scaffold.test.ts +59 -0
  43. package/src/tests/server.test.ts +30 -0
  44. package/src/tests/verify.test.ts +170 -0
@@ -0,0 +1,206 @@
1
+ # houndsman — {{projectName}} · `fix` (correção dos findings)
2
+
3
+ > **Documento canônico da capability `fix`.** O entry point do skill é o `SKILL.md`
4
+ > (`.agents/skills/houndsman/SKILL.md` e `.claude/skills/houndsman/SKILL.md`).
5
+
6
+ Corrige os achados de uma revisão **já finalizada** (`hunt`): lê a triagem, aplica as
7
+ correções marcadas e mantém o estado de triagem em dia — **sem editar o `state.json` à mão**.
8
+
9
+ Invocação: `/houndsman fix`. Não revisa nem altera regras; consome o que o `hunt` produziu.
10
+
11
+ **Quando usar:**
12
+
13
+ - Depois de `/houndsman` (ou `houndsman --finalize`), para corrigir os achados.
14
+ - O usuário marcou achados como `execute` na UI (`bun run houndsman server --open`) ou via
15
+ `findings set <id> --decision execute`.
16
+ - "Corrija os findings", "aplica as correções", "resolve os bloqueantes".
17
+
18
+ > **Pré-requisito:** existe `.houndsman/.runs/<branch-slug>/state.json` da run atual
19
+ > (gerado no `--finalize`). Se não existir, a revisão não foi finalizada — rode o `hunt` antes.
20
+ > A triagem (`execute`) é feita na UI (`bun run houndsman server --open`) ou via `findings set`,
21
+ > e é o que alimenta a fila de correção.
22
+
23
+ ---
24
+
25
+ ## Modelo de triagem
26
+
27
+ Cada finding tem duas dimensões independentes (ver `findings-state.ts`):
28
+
29
+ - **decision:** `pending` · `execute` · `ignore` (+ `comment` opcional).
30
+ - **execState:** `pending` · `in_progress` · `done` · `stale`.
31
+
32
+ `fix` atua **somente** sobre `decision: execute`. Achados `pending` (ainda não triados) e
33
+ `ignore` (descartados) ficam intocados — não "conserte" o que o usuário não pediu.
34
+
35
+ > **A linha de um finding não é a identidade.** A identidade é o **fingerprint** de conteúdo
36
+ > (arquivo + regra + âncora). As correções deslocam linhas; o motor reancora pelo conteúdo.
37
+ > Ocorrências byte-idênticas (mesmo trecho E mesmo contexto) compartilham o id — tratadas
38
+ > como um grupo (`×N`); corrigir uma resolve o grupo.
39
+
40
+ ---
41
+
42
+ ## Procedimento (incremental — nunca de uma vez)
43
+
44
+ Em PRs grandes há muitos achados. **Nunca** carregue a fila inteira: o `batch` entrega um
45
+ **grupo coeso, já paginado**, e a fila avança sozinha conforme você conclui os itens.
46
+
47
+ ```
48
+ repita:
49
+ 1. findings summary --json # contagem barata da fila
50
+ 2. fila vazia? → fim
51
+ 3. findings batch --json # grupo atual + outros grupos (sem parâmetros)
52
+ 4. corrigir APENAS o grupo atual
53
+ 5. findings sync # reancora por conteúdo (uma vez)
54
+ 6. findings done <ids> | set --decision pending --comment <motivo>
55
+ até a fila esvaziar
56
+ ```
57
+
58
+ ### 1. Medir a fila
59
+
60
+ ```bash
61
+ bun run houndsman findings summary --json
62
+ ```
63
+
64
+ `byDecision.execute` (menos os `done`) é o tamanho da fila. Se for `0`, acabou.
65
+
66
+ ### 2. Pegar o lote (contexto para correção)
67
+
68
+ ```bash
69
+ bun run houndsman findings batch --json
70
+ ```
71
+
72
+ O `batch` decide sozinho o **melhor agrupamento** para a run atual (por arquivo, por regra ou
73
+ por watchdog) e devolve:
74
+
75
+ - o **grupo atual** (paginado) — a unidade de trabalho;
76
+ - a lista dos **outros grupos disponíveis**;
77
+ - os totais (`fila`, `retornados`, `grupos`).
78
+
79
+ Sem parâmetros, ele devolve **o primeiro grupo**. Como a fila exclui o que já está `done`,
80
+ cada chamada após progresso traz **o próximo grupo naturalmente** — não há contador para
81
+ gerenciar.
82
+
83
+ Flags (use só quando precisar — o mínimo de decisão):
84
+
85
+ | Flag | Quando usar |
86
+ |---|---|
87
+ | `--severity blocking` | Só os bloqueantes (ex.: "quero corrigir apenas os bloqueantes"). |
88
+ | `--group <key>` | Focar um grupo específico (a key aparece em "outros grupos"). |
89
+ | `--offset <n>` | Paginar dentro de um grupo grande. Raramente necessário. |
90
+ | `--include-done` | Auditar/rever itens já concluídos. |
91
+
92
+ ### 3. Corrigir apenas o grupo atual
93
+
94
+ Para cada finding do grupo: abra o arquivo, leia o trecho ancorado (`line` é cache; confirme
95
+ pelo conteúdo) e aplique a **correção mínima** que satisfaz a `rule`, seguindo a **`action`** e
96
+ a `evidence`. Respeite o padrão que o watchdog cobra — não introduza um novo anti-padrão para
97
+ "calar" o finding. Marque antes: `findings set <id> --exec in_progress`.
98
+
99
+ **Contexto grande? Use um subagente** (ver abaixo) para o grupo — um grupo por vez.
100
+
101
+ ### 4. Reancorar o estado
102
+
103
+ ```bash
104
+ bun run houndsman findings sync
105
+ ```
106
+
107
+ O `sync` reancora cada finding por **conteúdo** (trecho + contexto) e reporta `ok` / `moved` /
108
+ `stale`: âncora corrigida → vira `done` (quando a decisão era `execute`); âncora sumida de
109
+ outro modo → `stale` (revisar).
110
+
111
+ ### 5. Confirmar ou devolver
112
+
113
+ Antes de fechar, confirme com o `verify` (barato): ele diz o que **resolveu** (`resolved`), o que
114
+ **persiste** e o que ficou **incerto** — sem re-revisar a PR. Com `--apply`, os `resolved` viram
115
+ `done` automaticamente.
116
+
117
+ ```bash
118
+ bun run houndsman findings verify # relatório (não altera o estado)
119
+ bun run houndsman findings verify --apply # marca os resolvidos como done
120
+ bun run houndsman findings done <id...> # corrigidos (manual)
121
+ bun run houndsman findings set <id> --decision pending --comment "<motivo / falta>" # não corrigidos
122
+ ```
123
+
124
+ Não deixe achado `execute` no limbo. `--decision ignore` só quando o achado for aceito como
125
+ não-aplicável.
126
+
127
+ ### 6. Repetir
128
+
129
+ Volte ao passo 1. A fila encolhe a cada volta; o `batch` traz o próximo grupo sem `--offset`.
130
+
131
+ ---
132
+
133
+ ## Perguntas de decisão ao usuário
134
+
135
+ Pergunte (ferramenta de perguntas do harness) **antes** de corrigir quando o achado for:
136
+
137
+ - ambíguo ou com **múltiplas correções válidas**;
138
+ - uma mudança de **produto/arquitetura** (não é "só código");
139
+ - conflitante com outro achado/grupo.
140
+
141
+ Apresente o achado (`rule`, `message`, `action`, `evidence`) e as opções. Com a resposta,
142
+ registre-a: `findings set <id> --comment "<decisão>"`. Sem resposta, devolva à fila com
143
+ `--decision pending --comment "Aguardando decisão: …"` — **nunca "chute"**.
144
+
145
+ ---
146
+
147
+ ## Subagentes — contexto, não velocidade
148
+
149
+ Subagente serve para **isolar contexto**, não para paralelizar. Regras:
150
+
151
+ - **Um grupo por vez, em sequência.** Não dispare uma onda paralela: grupos podem editar o
152
+ mesmo arquivo, arquivos relacionados, imports ou código gerado — correções concorrentes
153
+ colidem.
154
+ - O subagente recebe **só** o grupo atual (findings + arquivo) e devolve um resumo compacto
155
+ (ids corrigidos / não corrigidos + motivo). Assim o agente principal não carrega o arquivo.
156
+ - A escrita do `state.json` fica **centralizada no agente principal**: o subagente apenas
157
+ lê/edita; `sync` / `done` / `set` são do orquestrador. Nada de `findings` dentro do subagente.
158
+ - Grupos pequenos (1–2 findings) o próprio agente corrige inline.
159
+
160
+ Prompt do subagente (modelo):
161
+
162
+ ```
163
+ Corrija APENAS os findings abaixo, sem tocar em mais nada. Aplique a correção mínima que
164
+ satisfaz cada `rule`, seguindo `action`/`evidence`. Não rode comandos `findings`.
165
+ Retorne: id → corrigido/não corrigido + 1 linha de motivo.
166
+
167
+ Arquivo: <file>
168
+ - <id> [<severity>] <rule> (linha <line>) — <message>
169
+ Ação: <action>
170
+ Evidência: `<evidence>`
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Verificação
176
+
177
+ - `bun run houndsman findings summary` → os corrigidos saíram de `execute`/`in_progress`.
178
+ - `bun run houndsman findings sync` → sem `stale` inesperado.
179
+ - `bun run houndsman findings verify` → o que **resolveu** / **persiste** / ficou **incerto**
180
+ (sem re-revisar). Use `--apply` para marcar os `resolved` como `done`.
181
+ - Rode o build/testes do **projeto consumidor** (não o houndsman) depois das correções.
182
+ - Se a mudança for grande, reexecute o `hunt` para uma segunda passada:
183
+
184
+ ```bash
185
+ bun run houndsman --base main
186
+ # ... subagentes ...
187
+ bun run houndsman --finalize
188
+ ```
189
+
190
+ > O `--finalize` preserva os ids/fingerprints entre execuções (reancoragem por conteúdo);
191
+ > use `--clean` só quando quiser descartar a triagem anterior.
192
+
193
+ ---
194
+
195
+ ## Anti-padrões
196
+
197
+ - ❌ Carregar a fila inteira de uma vez (`findings list` sem filtro) — use `findings batch`.
198
+ - ❌ Corrigir vários grupos em paralelo (subagentes simultâneos sobre arquivos que se relacionam).
199
+ - ❌ Editar `.houndsman/.runs/<slug>/state.json` à mão — use os comandos `findings`.
200
+ - ❌ Corrigir findings `pending` ou `ignore` sem o usuário marcar `execute`.
201
+ - ❌ Chavear por `(file, line)` — a confiança é o **fingerprint** de conteúdo.
202
+ - ❌ Correção cosmética para "sumir" com o finding sem atender a `rule`.
203
+ - ❌ Reescrever o arquivo inteiro — correção mínima e localizada.
204
+ - ❌ Inventar mudança de produto/arquitetura para fechar um achado ambíguo — pergunte.
205
+ - ❌ Marcar `done` sem ter aplicado a correção (o `sync` reancora; o achado volta).
206
+ - ❌ Reexecutar o `hunt` inteiro só para conferir o fix — use `findings verify`.
@@ -1,18 +1,18 @@
1
- # houndsman — {{projectName}} (v1)
1
+ # houndsman — {{projectName}} · `hunt` (revisão de PR)
2
2
 
3
- > **Documento canônico do skill `/houndsman`.** Os `SKILL.md` de cada harness
4
- > (`.agents/skills/houndsman/` e `.claude/skills/houndsman/`) são apenas ponteiros para cá.
3
+ > **Documento canônico da capability `hunt`.** O entry point do skill é o `SKILL.md`
4
+ > (`.agents/skills/houndsman/SKILL.md` e `.claude/skills/houndsman/SKILL.md`).
5
5
 
6
6
  Revisão de PR: classificação de arquivos → revisão paralela por domínio → consolidação.
7
- O motor é o CLI **`houndsman`**; as regras do projeto ficam em `houndsman.config.ts` + `houndsman/`.
7
+ Invocação: `/houndsman` (default) ou `/houndsman hunt`. O motor é o CLI **`houndsman`**;
8
+ as regras do projeto ficam em `houndsman.config.ts` + `.houndsman/`.
8
9
 
9
- **Terminologia:** **houndsman** = orquestrador/treinador (CLI + motor); **watchdog** = cada agente
10
- especialista por domínio que audita o diff (antigo "revisor"); **review/revisão** = o processo;
11
- **Jev** = pré-análise opcional (Passo 1.5).
10
+ **Quando usar:** revisar PR antes de merge · code review de feature branch · validar
11
+ mudanças antes de push.
12
12
 
13
13
  ## Quem executa o quê
14
14
 
15
- - **Você** só invoca o skill: `/houndsman`. Não precisa rodar nenhum script à mão.
15
+ - **Você** só invoca o skill: `/houndsman [hunt]`. Não precisa rodar nenhum script à mão.
16
16
  - **O skill** orquestra: executa o CLI `houndsman` e despacha os subagentes.
17
17
  - **O CLI** tem passos distintos, um comando cada:
18
18
 
@@ -21,9 +21,10 @@ especialista por domínio que audita o diff (antigo "revisor"); **review/revisã
21
21
  | 0. Contexto | `houndsman context` | subagente | `context.json` + `context-brief.md` → `context-summary.json` |
22
22
  | 1. Preparar | `houndsman` | skill | `classification.json` + `candidates.json` + `briefs/` + `manifest.json` |
23
23
  | 2. Revisar | *(subagentes)* | skill (via `runSubagent`) | `findings/<watchdog>.json` (um por watchdog) |
24
- | 3. Finalizar | `houndsman --finalize` | skill | `review.md` |
24
+ | 3. Finalizar | `houndsman --finalize` | skill | `review.md` + `state.json` + `run.json` |
25
25
 
26
26
  > Por que comandos separados? Entre o passo 1 e o 3 acontece trabalho de LLM (os subagentes).
27
+ > Depois do passo 3, a correção dos achados é a capability **`fix`** — ver `fix.md`.
27
28
 
28
29
  **Arquitetura:**
29
30
 
@@ -42,12 +43,6 @@ especialista por domínio que audita o diff (antigo "revisor"); **review/revisã
42
43
  - Cada watchdog recebe apenas seus arquivos relevantes (brief pronto) — nunca o diff completo.
43
44
  - Saída estruturada (JSON) por watchdog → consolidada e deduplicada automaticamente.
44
45
 
45
- ## Quando Usar
46
-
47
- - Revisar PR antes de merge
48
- - Code review de feature branch
49
- - Validar mudanças antes de push
50
-
51
46
  ---
52
47
 
53
48
  ## Passo 0 — Contexto da PR (subagente)
@@ -114,6 +109,20 @@ as regras atômicas dos watchdogs. Respostas acima do limiar viram **candidatos*
114
109
  - **Opcional**: sem chave / erro / timeout → `available:false`; a revisão segue idêntica.
115
110
  - Desativar: `houndsman --no-jev`.
116
111
 
112
+ ### Review incremental (da 2ª revisão em diante)
113
+
114
+ Cada `--finalize` grava o **commit revisado** (`reviewed.headSha` no `state.json`). No prepare
115
+ seguinte, se o `HEAD` descende desse commit (sem rebase), o motor revisa **só o delta** — os
116
+ arquivos alterados desde a última revisão — e **carrega** os findings dos arquivos inalterados
117
+ (carry-over), sem re-revisá-los. O `manifest.json` traz o bloco `incremental` (`from`,
118
+ `changedFiles`, `carried`) e o `review.md` abre com um aviso.
119
+
120
+ - Sem mudanças desde a última revisão → **no-op** (nada a revisar; o estado é preservado).
121
+ - Rebase/force-push (histórico reescrito) → cai automaticamente no **review completo**.
122
+ - Forçar completo: `houndsman --full` (ou `--clean`, que também descarta a triagem anterior).
123
+
124
+ > Custo: o LLM só é gasto nos arquivos que mudaram desde a última revisão — não na PR inteira.
125
+
117
126
  ---
118
127
 
119
128
  ## Passo 2 — Revisar (skill despacha os subagentes)
@@ -151,46 +160,10 @@ Falha com mensagem clara se faltar algum `findings/<watchdog>.json`. Quando todo
151
160
  7. Grava um `review.<watchdog>.md` por watchdog com achados e indexa no `review.md`
152
161
  (**Relatórios por domínio**) — mantém o relatório consolidado enxuto
153
162
  8. Grava `.houndsman/.runs/<branch-slug>/state.json` — a **triagem**: um `id` curto e um
154
- `fingerprint` de conteúdo por finding (Passo 4), preservados entre execuções
163
+ `fingerprint` de conteúdo por finding, preservados entre execuções
155
164
 
156
- > Compatível com `classification.json` antigo: se faltar o churn, o orçamento não é aplicado.
157
-
158
- ---
159
-
160
- ## Passo 4 — Triagem (opcional)
161
-
162
- Cada finding recebe um `id` curto e um `fingerprint` de **conteúdo** no `--finalize`,
163
- gravados em `.houndsman/.runs/<branch-slug>/state.json`. A triagem é feita pela UI ou
164
- pelo agente — sem editar o JSON à mão. Duas dimensões independentes:
165
-
166
- - **decision:** `pending` · `execute` · `ignore` (+ `comment` opcional).
167
- - **execState:** `pending` · `in_progress` · `done` · `stale`.
168
-
169
- ### UI local
170
-
171
- ```bash
172
- houndsman server --open
173
- ```
174
-
175
- Abre a UI (Bun.serve + Preact): lista as runs, triar os findings por severidade, comentar,
176
- marcar como feito e ler os artefatos (`manifest.json`, `classification.json`, `review.md`).
177
- Bind em `127.0.0.1` (ferramenta local, sem auth).
178
-
179
- ### Auto-fix pelo agente
180
-
181
- ```bash
182
- houndsman findings list --decision execute --json # pendentes marcados p/ corrigir
183
- # ... o agente aplica as correções ...
184
- houndsman findings sync # reancora por conteúdo
185
- houndsman findings done <id> # confirma os concluídos
186
- ```
187
-
188
- > **A linha não é a identidade.** O auto-fix desloca linhas; o motor reancora cada finding
189
- > pelo **conteúdo** (trecho + contexto) e não perde itens que se movem. Se a âncora some
190
- > (o trecho foi corrigido), o finding vira `done` automaticamente quando a decisão era
191
- > `execute`, ou `stale` caso contrário.
192
- > Ocorrências byte-idênticas (mesmo trecho E mesmo contexto) compartilham o id — são
193
- > tratadas como um grupo (`×N`); limitação conhecida.
165
+ Após finalizar, corrija os achados com a capability **`fix`** (`fix.md`): a UI ou os
166
+ comandos `findings` levam do achado à correção.
194
167
 
195
168
  ---
196
169
 
@@ -243,9 +216,11 @@ git diff --name-status (base...head)
243
216
  ↓
244
217
  [2] N subagentes em paralelo ──► findings/<watchdog>.json
245
218
  ↓
246
- [3] houndsman --finalize ──► review.md + state.json
219
+ [3] houndsman --finalize ──► review.md + state.json + run.json (review_done)
247
220
  ↓
248
- [4] triagem (UI ou agente) ──► state.json (decision/execState)
221
+ [4] server (UI) ──► validar a revisão + marcar decision: execute
222
+ ↓
223
+ [5] fix ──► correções + state.json/run.json (fix_done)
249
224
  ```
250
225
 
251
226
  ---
@@ -254,25 +229,23 @@ git diff --name-status (base...head)
254
229
 
255
230
  ```
256
231
  /houndsman
257
- /houndsman feature/add-webhook-retry
232
+ /houndsman hunt
233
+ /houndsman hunt feature/add-webhook-retry
258
234
  ```
259
235
 
260
236
  Se a branch não for informada, detecta com `git branch --show-current`. Base do diff: `main`.
261
237
 
262
- **Comandos do CLI:**
238
+ **Comandos do CLI usados no `hunt`:**
263
239
 
264
240
  | Comando | Função |
265
241
  |---|---|
266
242
  | `houndsman context` | Passo 0 — contexto da PR via `gh` |
267
- | `houndsman` | Passo 1 — preparar (briefs + manifesto) |
243
+ | `houndsman` | Passo 1 — preparar (briefs + manifesto; incremental quando possível) |
268
244
  | `houndsman --finalize` | Passo 3 — gerar o relatório |
269
245
  | `houndsman watchdog <id>` | Contexto de um watchdog (`--json`, `--rules`) |
270
- | `houndsman findings <sub>` | Triagem dos findings (list/show/set/done/reset/sync/summary/path) |
271
- | `houndsman server` | UI local de triagem + leitura de artefatos (`--port`, `--host`, `--open`) |
272
- | `houndsman setup` | Cria a configuração inicial do projeto |
273
- | `houndsman update` | Sincroniza os arquivos auto-gerados (`.houndsman/core`) |
274
- | `houndsman doctor` | Valida a configuração, o ambiente e a credencial Jev |
275
- | `houndsman test` | Suíte de testes da lib |
246
+
247
+ Flags do review: `--base` · `--head` · `--branch` · `--dir` · `--clean` · `--full` (força
248
+ completo) · `--no-jev` · `--fail-on-blocking` (com `--finalize`).
276
249
 
277
250
  ---
278
251
 
@@ -294,11 +267,12 @@ Se a branch não for informada, detecta com `git branch --show-current`. Base do
294
267
 
295
268
  ## Manutenção das Regras
296
269
 
297
- > Alterar qualquer regra (adicionar, ajustar severidade, remover, corrigir escopo) → usar o
298
- > skill **`houndsman-update`** (`src/skill/houndsman-update.md`).
270
+ > Alterar qualquer regra (adicionar, ajustar severidade, remover, corrigir escopo) → capability
271
+ > **`train`** (`/houndsman train`, doc `train.md`).
299
272
  > Regra de ouro: só é regra o que o projeto **aplica hoje** — prove com evidência no código
300
273
  > (regra negativa com 0 ocorrências = seguida → **manter**).
301
- > Após qualquer alteração, rodar `houndsman doctor` + `houndsman test` + `ci:fix` + `ci:check`.
274
+ > Após qualquer alteração, rodar `houndsman doctor`. (`houndsman test` e `ci:fix`/`ci` são
275
+ > comandos da **lib**, não do projeto consumidor.)
302
276
 
303
277
  ---
304
278
 
@@ -1,14 +1,14 @@
1
- # Atualização de Lógicas do houndsman
1
+ # houndsman — {{projectName}} · `train` (atualização de regras)
2
2
 
3
- > **Documento canônico do skill `/houndsman-update`.** Os `SKILL.md` de cada harness
4
- > (`.agents/skills/houndsman-update/` e `.claude/skills/houndsman-update/`) são apenas ponteiros para cá.
3
+ > **Documento canônico da capability `train`.** O entry point do skill é o `SKILL.md`
4
+ > (`.agents/skills/houndsman/SKILL.md` e `.claude/skills/houndsman/SKILL.md`).
5
5
 
6
6
  > **Propósito:** manter os watchdogs do skill `houndsman` alinhados ao que o
7
7
  > projeto **realmente aplica** — seja para adicionar/ajustar uma regra a pedido do
8
8
  > usuário, seja para uma auditoria geral após mudanças de padrão no código.
9
9
 
10
- Este skill é o **mantenedor** do `houndsman`. Ele não revisa PRs; ele atualiza as regras
11
- que o `houndsman` usa.
10
+ Invocação: `/houndsman train`. Esta capability é a **mantenedora** do `houndsman`.
11
+ Ela não revisa PRs (isso é `hunt`); ela atualiza as regras que o `houndsman` usa.
12
12
 
13
13
  ---
14
14
 
@@ -72,10 +72,29 @@ Toda regra (nova ou alterada) deve passar por **todos** os itens:
72
72
  direta da afirmação). Aí o prefixo lidera o sentido dominante e o outro entra como oração
73
73
  subordinada — nunca como segundo juízo coordenado.
74
74
  9. **Escopo coerente** — a regra pertence ao domínio do watchdog.
75
- 10. **Sem duplicata** — nenhuma regra repetida literalmente no mesmo watchdog.
75
+ 10. **Sem duplicata** — nenhuma regra repetida (texto normalizado) no mesmo watchdog.
76
+ 11. **Lugar único** — a regra vive **apenas** em `rules`. Nunca repita o texto (nem o anti-padrão)
77
+ em `reviewFocus`, `contextFiles`, `scope`, `description` ou `exclude`.
76
78
 
77
79
  > O `houndsman doctor` emite um **aviso** (não bloqueante) para regra sem polaridade explícita
78
- > (`Promover:`, `Evitar:`, `Não` ou `Nunca`).
80
+ > (`Promover:`, `Evitar:`, `Não` ou `Nunca`), para regra duplicada e para texto de regra que
81
+ > vazou para `reviewFocus`/`contextFiles`/`exclude`.
82
+
83
+ ### Onde cada coisa vive (não duplique a regra)
84
+
85
+ Cada informação tem o seu campo — não espelhe a regra em vários lugares:
86
+
87
+ | O que você quer expressar | Campo | Observação |
88
+ |---|---|---|
89
+ | A **regra** (o que DEVE/NÃO DEVE acontecer) | `rules[]` | Único lugar da regra: `{ severity, text, jev? }`. |
90
+ | **Quais arquivos** o watchdog cobre | `classify` | Regex de path (ou de conteúdo). |
91
+ | **Que arquivos** olhar primeiro | `reviewFocus` | **Paths/áreas** do código — não texto de regra. |
92
+ | **Que docs** consultar | `contextFiles` | Caminhos de **documentação** — não regra nem código. |
93
+ | O que **nunca** carregar | `exclude` | Paths a ignorar. |
94
+ | O **território** em prosa | `scope` / `description` | Contexto do domínio, não regra. |
95
+
96
+ > A regra aparece **uma única vez** no arquivo — em `rules`. Repeti-la em
97
+ > `reviewFocus`/`contextFiles`/`scope`/`description`/`exclude` só cria ruído no brief do subagente.
79
98
 
80
99
  ---
81
100
 
@@ -86,7 +105,7 @@ Toda regra (nova ou alterada) deve passar por **todos** os itens:
86
105
  - O projeto mudou de padrão (ex.: passou a usar uma lib, mudou autenticação, etc.).
87
106
  - **Auditoria completa** dos watchdogs após revisão geral do código.
88
107
  - **Regra confusa/ambígua** (humano ou IA não entende) — ver Modo C.
89
- - O usuário invoca `/houndsman-update`.
108
+ - O usuário invoca `/houndsman train`.
90
109
 
91
110
  ---
92
111
 
@@ -108,7 +127,7 @@ Toda regra (nova ou alterada) deve passar por **todos** os itens:
108
127
  | `src/core/config-loader.ts` | Descoberta/carregamento de `houndsman.config.ts` |
109
128
  | `src/core/brief.ts` | Render do brief: `defaultRenderBrief` + `PROCEDURE` |
110
129
  | `src/core/registry-check.ts` | Validação anti-drift (config-driven) |
111
- | `src/skill/houndsman.md` | Orquestração + tabela de watchdogs |
130
+ | `src/skill/hunt.md` | Orquestração da revisão (capability `hunt`) |
112
131
  | `src/tests/**` | Suíte da lib (project-agnóstica; usa `fixtures/fake-project.ts`) |
113
132
  | `src/cli/index.ts` | **CLI único** — `houndsman [context, setup, doctor, test, watchdog, --finalize]` |
114
133
 
@@ -166,10 +185,12 @@ verificáveis por leitura local. Candidatos não confirmados pelo watchdog **nã
166
185
  `Evitar:`/`Não`/`Nunca` (NÃO DEVE), conforme as Convenções de escrita.
167
186
  - Regra que mistura afirmação e negação (dois sentidos) → dividir em **duas entradas** (*Unipolar*, item 8).
168
187
  - `jev` (opcional): `{ kind: "noul" }`, com `instructions` e/ou `criteria` — ver seção acima.
169
- - Ajustar `scope` / `description` / `reviewFocus` / `exclude` / `contextFiles` se necessário.
188
+ - **A regra vai só em `rules`** — não a repita em `reviewFocus`/`contextFiles`/`scope`/
189
+ `description`/`exclude`. Só toque nesses campos se o **domínio/paths** mudou (ver
190
+ *Onde cada coisa vive*), nunca para reafirmar a regra.
170
191
  - Se a regra muda para outro domínio (paths), ajustar o `classify` do watchdog.
171
192
  5. **Watchdog novo?** criar `.houndsman/watchdogs/<id>.ts` e registrar em `.houndsman/watchdogs/index.ts` (o id é derivado das chaves).
172
- 6. **Atualizar `src/skill/houndsman.md`/`README.md`** se escopo/regra visível mudou (no motor).
193
+ 6. **Atualizar `src/skill/hunt.md`/`README.md`** se escopo/regra visível mudou (no motor).
173
194
  7. **Atualizar a suíte da lib** se o comportamento do MOTOR mudou (a suíte é project-agnóstica).
174
195
  8. **Verificar** (seção abaixo).
175
196
 
@@ -226,24 +247,24 @@ todos os itens — em especial: **geral/reutilizável** (não regra de negócio
226
247
 
227
248
  ```bash
228
249
  bun run houndsman doctor # config sem drift + ambiente + credencial Jev
229
- bun run houndsman test # suíte da lib (project-agnóstica)
230
- bun run ci:fix # formatação/imports/lint (no repo da lib)
231
- bun run ci:check # tipagem (no repo da lib)
232
250
  ```
233
251
 
252
+ > `bun run houndsman test`, `bun run ci:fix` e `bun run ci` são comandos para **manter a lib** do
253
+ > houndsman (repo do pacote) — não para quem só usa o houndsman no projeto.
254
+
234
255
  Checklist final:
235
256
 
236
257
  - [ ] `bun run houndsman doctor` → sem problemas reportados.
237
- - [ ] `bun run houndsman test` → **0 fail**.
238
- - [ ] `ci:fix` + `ci:check` → exit 0 (warnings pré-existentes não contam).
239
258
  - [ ] `WATCHDOG_DEFINITIONS[<id>].id` bate com a chave e `description` não vazio.
240
- - [ ] `src/skill/houndsman.md` continua consistente com os watchdogs do projeto.
259
+ - [ ] `src/skill/hunt.md` continua consistente com os watchdogs do projeto.
241
260
  - [ ] Toda regra nova/alterada tem **evidência** registrada no PR/relatório
242
261
  (`file:line` se afirmativa; `0 ocorrências do anti-padrão` se negativa).
243
262
  - [ ] Nenhuma regra **negativa** foi removida por "0 ocorrências" (Regra de Ouro).
244
263
  - [ ] Brief de amostra não contém regra removida (dry-run abaixo).
245
264
  - [ ] Toda regra passa nas convenções de escrita (geral/reutilizável, sem jargão abreviado,
246
265
  sem qualificador vago, com polaridade explícita e **unipolar**) — conferir via grep.
266
+ - [ ] O texto de cada regra aparece **exatamente uma vez** no arquivo (só em `rules`) — nada em
267
+ `reviewFocus`/`contextFiles`/`scope`/`description`/`exclude`.
247
268
 
248
269
  ```bash
249
270
  # Dry-run: gerar briefs e conferir ausência de regras removidas
@@ -0,0 +1,70 @@
1
+ # houndsman — {{projectName}} · `verify` (violações resolvidas?)
2
+
3
+ > **Documento canônico da capability `verify`.** O entry point do skill é o `SKILL.md`
4
+ > (`.agents/skills/houndsman/SKILL.md` e `.claude/skills/houndsman/SKILL.md`).
5
+
6
+ Confere se os findings de uma revisão **já finalizada** foram resolvidos — **sem re-revisar a
7
+ PR**. Invocação: `/houndsman verify`. Consome o `state.json` do `hunt`; não revisa nem altera
8
+ regras.
9
+
10
+ **Quando usar:**
11
+
12
+ - Depois de corrigir achados (`fix`), para confirmar que as violações sumiram.
13
+ - As violações foram resolvidas? · confere se ainda está lá · valida o fix.
14
+
15
+ > **Pré-requisito:** existe `.houndsman/.runs/<branch-slug>/state.json` (gerado no `--finalize`).
16
+
17
+ ---
18
+
19
+ ## Como funciona (2 tiers)
20
+
21
+ 1. **Tier local (grátis, determinístico).** Para cada finding presente, reancora a âncora de
22
+ conteúdo contra o working tree (`core/finding-anchor.ts`):
23
+ - **âncora presente** (`ok`/`moved`) → **persiste** (a violação ainda está lá);
24
+ - **âncora sumida** (`stale`) → provável **resolvido** — mas o trecho pode ter sido reescrito;
25
+ - **arquivo ausente** → fora da verificação (deletado/movido).
26
+
27
+ 2. **Tier Jev (opcional, só nos ambíguos).** Com `TYPESAFE_API_KEY`, os casos `stale` / sem
28
+ âncora são confirmados pelo LLM sobre um **diff focado** do arquivo (`foundAtSha..HEAD`), uma
29
+ pergunta `noul` por finding. Falha-aberto: sem chave/erro → vale o resultado local.
30
+
31
+ **Custo:** ~0 LLM quando o tier local decide; 1 chamada por arquivo ambíguo — nunca uma revisão
32
+ completa.
33
+
34
+ ---
35
+
36
+ ## Procedimento
37
+
38
+ ```bash
39
+ bun run houndsman findings verify # relatório (não altera o estado)
40
+ bun run houndsman findings verify --json # saída estruturada
41
+ bun run houndsman findings verify --apply # marca os resolvidos como done (ping no run.json)
42
+ ```
43
+
44
+ - Sem `--apply`: **só relatório** (grava `verify.md` na pasta da run). Nada muda no `state.json`.
45
+ - Com `--apply`: os findings com status **`resolved`** viram `execState: done` (histórico
46
+ `by: "verify"`). `persisting` e `uncertain` **não** são tocados.
47
+
48
+ Filtros (como no `findings list`): `--severity`, `--watchdog`, `--file`, `--decision`. `--all`
49
+ inclui ausentes. `--no-jev` desliga o tier LLM. `--fail-on-persisting` sai com código 1 se algum
50
+ `blocking` persistir (útil em CI).
51
+
52
+ ---
53
+
54
+ ## Status possíveis
55
+
56
+ | Status | Significado | `--apply`? |
57
+ |---|---|---|
58
+ | `resolved` | Violação não encontrada (âncora sumida; confirmada pelo Jev quando há chave). | ✅ vira `done` |
59
+ | `persisting` | Âncora ainda presente — a violação continua. | ❌ |
60
+ | `uncertain` | Sem âncora e sem confirmação do Jev (ou Jev indisponível). | ❌ |
61
+ | `file-missing` | Arquivo não está no working tree (deletado/movido). | ❌ |
62
+
63
+ ---
64
+
65
+ ## Anti-padrões
66
+
67
+ - ❌ Reexecutar o `hunt` inteiro só para conferir se um fix funcionou — use o `verify`.
68
+ - ❌ Esperar que o `verify` marque `done` sem `--apply` (sem a flag, nada muda no estado).
69
+ - ❌ Tratar `persisting` como resolvido — a âncora ainda está no arquivo.
70
+ - ❌ Esperar verificação 100% pelo LLM — o tier local resolve a maioria de graça.