@payconductor/houndsman 0.0.0-stage → 0.1.1

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 (65) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +156 -3
  3. package/assets/houndsman.png +0 -0
  4. package/assets/logo-legacy.png +0 -0
  5. package/assets/logo.png +0 -0
  6. package/package.json +64 -5
  7. package/src/cli/index.ts +290 -0
  8. package/src/core/assets.ts +28 -0
  9. package/src/core/brief.ts +185 -0
  10. package/src/core/commands/context.ts +39 -0
  11. package/src/core/commands/findings.ts +390 -0
  12. package/src/core/commands/review.ts +50 -0
  13. package/src/core/commands/scaffold.ts +393 -0
  14. package/src/core/commands/setup.ts +75 -0
  15. package/src/core/commands/test.ts +20 -0
  16. package/src/core/commands/update.ts +30 -0
  17. package/src/core/commands/watchdog.ts +105 -0
  18. package/src/core/config-loader.ts +87 -0
  19. package/src/core/config.ts +101 -0
  20. package/src/core/diff-source.ts +140 -0
  21. package/src/core/doc-discoverer.ts +33 -0
  22. package/src/core/file-classifier.ts +295 -0
  23. package/src/core/finding-anchor.ts +147 -0
  24. package/src/core/findings-state.ts +538 -0
  25. package/src/core/jev/index.ts +12 -0
  26. package/src/core/jev/jev-candidates.ts +105 -0
  27. package/src/core/jev/jev-client.ts +160 -0
  28. package/src/core/jev/jev-detector.ts +205 -0
  29. package/src/core/jev/jev-questions.ts +92 -0
  30. package/src/core/jev/jev-types.ts +91 -0
  31. package/src/core/orchestrator.ts +596 -0
  32. package/src/core/paths.ts +33 -0
  33. package/src/core/pr-context.ts +271 -0
  34. package/src/core/registry-check.ts +160 -0
  35. package/src/core/report-builder.ts +461 -0
  36. package/src/core/types.ts +147 -0
  37. package/src/core/watchdog-registry.ts +43 -0
  38. package/src/index.ts +132 -0
  39. package/src/server/artifacts.ts +66 -0
  40. package/src/server/client/App.tsx +158 -0
  41. package/src/server/client/ArtifactsPanel.tsx +48 -0
  42. package/src/server/client/Filters.tsx +83 -0
  43. package/src/server/client/FindingCard.tsx +122 -0
  44. package/src/server/client/FindingsList.tsx +54 -0
  45. package/src/server/client/RunList.tsx +43 -0
  46. package/src/server/client/SummaryBar.tsx +21 -0
  47. package/src/server/client/api.ts +37 -0
  48. package/src/server/client/constants.ts +63 -0
  49. package/src/server/client/index.tsx +12 -0
  50. package/src/server/client/types.ts +48 -0
  51. package/src/server/client-build.ts +47 -0
  52. package/src/server/index.ts +365 -0
  53. package/src/skill/AUDIT-PROTOCOL.md +96 -0
  54. package/src/skill/OUTPUT-FORMAT.md +70 -0
  55. package/src/skill/README.md +124 -0
  56. package/src/skill/SETUP.md +101 -0
  57. package/src/skill/example-review.md +58 -0
  58. package/src/skill/houndsman-update.md +251 -0
  59. package/src/skill/houndsman.md +316 -0
  60. package/src/tests/findings-anchor.test.ts +120 -0
  61. package/src/tests/findings-commands.test.ts +226 -0
  62. package/src/tests/findings-state.test.ts +274 -0
  63. package/src/tests/fixtures/fake-project.ts +64 -0
  64. package/src/tests/review-scripts.test.ts +1150 -0
  65. package/src/tests/server.test.ts +212 -0
@@ -0,0 +1,96 @@
1
+ # Protocolo de Auditoria dos Watchdogs — houndsman
2
+
3
+ Referência do Modo B do skill `houndsman-update`. Objetivo: garantir que as regras dos
4
+ watchdogs validam **apenas padrões que o projeto aplica hoje**. Regras "utópicas" (não
5
+ aplicadas em nenhuma parte do código) devem ser **removidas**, não apenas rebaixadas.
6
+
7
+ ---
8
+
9
+ ## Entradas
10
+
11
+ 1. `.houndsman/watchdogs/<id>.ts` — `WATCHDOG_DEFINITIONS[<id>]` é a fonte única de verdade:
12
+ `description`, `scope`, `rules` (severidade + texto), `classify`, `contextFiles`,
13
+ `reviewFocus`, `exclude`.
14
+ 2. `src/core/brief.ts` (no motor) — `PROCEDURE` (passos de revisão compartilhados).
15
+ 3. Ground truth (padrões reais do projeto):
16
+ - Documentos de convenção do projeto (ex.: `AGENTS.md`, `CLAUDE.md`, `.github/copilot-instructions.md`).
17
+ - Documentação de arquitetura/domínio do projeto.
18
+ - Código-fonte real do domínio (fonte final da verdade).
19
+
20
+ ## Regra de ouro
21
+
22
+ > Só é regra o que o projeto **aplica hoje** — mas como provar depende da **polaridade**:
23
+ >
24
+ > - Regra **afirmativa** (`Promover:`): a **ausência** do padrão no código prova que ele **não é
25
+ > aplicado** → `UTOPIAN` (remover/rebaixar). Não inferir intenção aspiracional.
26
+ > - Regra **negativa** (`Evitar:`, `Não`, `Nunca`): a **ausência** do anti-padrão prova que a regra
27
+ > **é seguida** → `ALIGNED` (**manter**). Nunca remover uma regra negativa por "0 ocorrências".
28
+
29
+ Use regra **geral e reutilizável** (padrão do domínio), nunca regra de negócio pontual amarrada a
30
+ uma classe/use-case — isso é papel de teste automatizado.
31
+
32
+ Use `grep_search`/`file_search`/`read_file` para **provar** cada veredito. Nunca
33
+ classifique sem evidência (caminho de arquivo, linha, ou "0 ocorrências via grep X").
34
+
35
+ ## Taxonomia de veredito
36
+
37
+ | Veredito | Significado | Ação proposta |
38
+ |---|---|---|
39
+ | `ALIGNED` | Padrão documentado E aplicado no código (regra negativa: anti-padrão **ausente**) | Manter |
40
+ | `UTOPIAN` | Regra **afirmativa** cujo padrão não existe em lugar nenhum hoje | **Remover** |
41
+ | `OUTDATED` | Já foi aplicado, mas o código mudou | Remover ou reescrever |
42
+ | `MISCALIBRATED` | Regra válida, mas severidade errada | Ajustar severidade |
43
+ | `DEAD-PATH` | `scope`/`contextFiles`/`classify` apontam para caminho/arquivo inexistente | Corrigir ou remover |
44
+
45
+ ## Formato do relatório
46
+
47
+ Gravar `.houndsman-audit/<watchdog-id>.md`:
48
+
49
+ ```markdown
50
+ # Auditoria — <Nome do watchdog> (`<watchdog-id>`)
51
+
52
+ ## Ground truth do domínio
53
+ - Padrões reais observados (com caminhos de arquivo).
54
+ - Caminhos reais do domínio (confirmar existência).
55
+
56
+ ## Veredito por regra
57
+
58
+ | # | Severidade atual | Polaridade | Regra | Veredito | Evidência | Ação proposta |
59
+ |---|---|---|---|---|---|---|
60
+ | 1 | blocking | afirmativa | <texto da regra> | UTOPIAN | 0 matches em `src/...` | Remover |
61
+ | 2 | attention | negativa | <texto da regra> | ALIGNED | 0 ocorrências do anti-padrão | Manter |
62
+ | ... |
63
+
64
+ ## Correções de metadados
65
+ - `scope`: ...
66
+ - `contextFiles`: ...
67
+
68
+ ## Protocolo (procedimento)
69
+ - Ajustes no `PROCEDURE` compartilhado (`src/core/brief.ts`) ou no `reviewFocus`/`exclude` do watchdog.
70
+
71
+ ## Resumo
72
+ - Total de regras: N · ALIGNED: N · UTOPIAN: N · OUTDATED: N · MISCALIBRATED: N · DEAD-PATH: N
73
+ - Regras a remover: ...
74
+ - Regras a corrigir: ...
75
+ ```
76
+
77
+ ## Consolidação
78
+
79
+ - Um relatório consolidado em `.houndsman-audit/audit-summary.md`.
80
+ - Agrupar **temas transversais** (ex.: a mesma regra aparecia em 2 watchdogs).
81
+ - Resolver conflitos: uma regra duplicada entre watchdogs deve viver no watchdog dono do domínio.
82
+
83
+ ## Disparo dos subagentes
84
+
85
+ - 1 subagente por watchdog; despachar em ondas paralelas (ex.: 8 + 7).
86
+ - Prompt mínimo:
87
+
88
+ > Você é um auditor do skill `houndsman` do {{projectName}}. Leia e siga
89
+ > `.houndsman/core/skill/AUDIT-PROTOCOL.md`. Watchdog alvo: `<watchdog-id>`. Audite CADA regra de
90
+ > `WATCHDOG_DEFINITIONS["<watchdog-id>"]` contra o código/docs reais, provando cada veredito.
91
+ > Grave `.houndsman-audit/<watchdog-id>.md`. Retorne: contagem por veredito,
92
+ > regras a REMOVER e a CORRIGIR. Não altere outros arquivos.
93
+
94
+ ## Idioma
95
+
96
+ Relatórios em português. Código e identificadores em inglês. Seja sucinto.
@@ -0,0 +1,70 @@
1
+ # Formato de Saída dos Watchdogs
2
+
3
+ Todo watchdog DEVE gravar **um arquivo JSON** com seus achados. O `report-builder.ts`
4
+ consolida os JSONs em `.houndsman/.runs/<branch-slug>/review.md`.
5
+
6
+ > **Não** escrever markdown livre no chat. O único output consumido pelo pipeline é o JSON.
7
+
8
+ ## Caminho do arquivo
9
+
10
+ O caminho exato é informado no brief do watchdog (gerado por `houndsman`):
11
+
12
+ ```
13
+ .houndsman/.runs/<branch-slug>/findings/<watchdogId>.json
14
+ ```
15
+
16
+ - `<branch-slug>`: branch com `/` substituído por `-` (ex.: `feature/x` → `feature-x`).
17
+ - `<watchdogId>`: id do watchdog (ex.: `backend-architecture`).
18
+
19
+ ## Schema
20
+
21
+ ```json
22
+ {
23
+ "watchdogId": "backend-architecture",
24
+ "reviewedFiles": ["src/services/order/order-service.ts"],
25
+ "skipped": [],
26
+ "findings": [
27
+ {
28
+ "rule": "Route acessando db",
29
+ "severity": "blocking",
30
+ "file": "src/routes/order-route.ts",
31
+ "line": 5,
32
+ "message": "Arquivo de rota importa `db` e executa query inline.",
33
+ "action": "Mover a query para o service correspondente.",
34
+ "evidence": "import { db } from '../db'"
35
+ }
36
+ ]
37
+ }
38
+ ```
39
+
40
+ ### Campos
41
+
42
+ | Campo | Tipo | Obrigatório | Descrição |
43
+ |---|---|---|---|
44
+ | `watchdogId` | string | ✅ | Id do watchdog (deve casar com uma chave de `.houndsman/watchdogs/index.ts`) |
45
+ | `reviewedFiles` | string[] | ✅ | Arquivos efetivamente inspecionados |
46
+ | `skipped` | string[] | ✅ | Arquivos do domínio que NÃO foram lidos + motivo |
47
+ | `findings` | object[] | ✅ | Achados (vazio se nada encontrado) |
48
+ | `findings[].rule` | string | ✅ | Regra violada (conforme o brief do watchdog) |
49
+ | `findings[].severity` | `"blocking" \| "attention" \| "suggestion" \| "nit"` | ✅ | Severidade |
50
+ | `findings[].file` | string | ✅ | Caminho relativo à raiz |
51
+ | `findings[].line` | number | — | Linha do achado |
52
+ | `findings[].message` | string | ✅ | O que está errado (curto, específico) |
53
+ | `findings[].action` | string | ✅ | O que fazer |
54
+ | `findings[].evidence` | string | — | Trecho que comprova o achado |
55
+
56
+ ## Severidade
57
+
58
+ | Severidade | Emoji | Bloqueia merge? |
59
+ |---|---|---|
60
+ | `blocking` | ❌ | Sim |
61
+ | `attention` | ⚠️ | Não (requer atenção) |
62
+ | `suggestion` | 💡 | Não |
63
+ | `nit` | 🔎 | Não (detalhe/observação) |
64
+
65
+ ## Regras
66
+
67
+ - Sem achados → `"findings": []` (arquivo **obrigatório**).
68
+ - Um achado por regra violada; não agrupar regras diferentes.
69
+ - `file:line` sempre que possível; `evidence` quando o achado não é óbvio.
70
+ - Não inventar achados — se não houver violação, o array fica vazio.
@@ -0,0 +1,124 @@
1
+ # houndsman — skill
2
+
3
+ Revisão automatizada de Pull Requests — CLI independente + camada de configuração do projeto.
4
+
5
+ ## Terminologia
6
+
7
+ - **houndsman** — o orquestrador/treinador (CLI + motor).
8
+ - **watchdog** — cada agente especialista por domínio que audita o diff.
9
+ - **brief** — instruções prontas para um watchdog (o prompt do subagente).
10
+ - **findings** — os achados que o subagente grava em JSON (único output consumido).
11
+ - **candidato (Jev)** — indício automático; **não** é achado (o watchdog confirma ou refuta).
12
+ - **churn** — linhas adicionadas/removidas por arquivo; usado para priorizar a leitura.
13
+ - **budget / orçamento** — teto de arquivos por brief; o excedente ("fora do orçamento")
14
+ não é revisado, mas fica registrado em `skipped`.
15
+ - **review/revisão** — o processo de revisão.
16
+
17
+ ## Quem executa o quê
18
+
19
+ - **Você** só invoca o skill: `/houndsman`. Não roda script à mão.
20
+ - **O skill** orquestra: executa o CLI `bun run houndsman` e despacha os subagentes.
21
+ - **O CLI** tem passos distintos — um comando cada:
22
+
23
+ | Passo | Comando | Quem roda | Resultado |
24
+ |---|---|---|---|
25
+ | 0. Contexto | `bun run houndsman context` | subagente | `context.json` + `context-brief.md` → `context-summary.json` |
26
+ | 1. Preparar | `bun run houndsman` | skill | `classification.json` + `candidates.json` + `briefs/` + `manifest.json` |
27
+ | 2. Revisar | *(subagentes)* | skill | `findings/<watchdog>.json` (um por watchdog) |
28
+ | 3. Finalizar | `bun run houndsman --finalize` | skill | `review.md` |
29
+
30
+ ## Comandos
31
+
32
+ | Comando | Função |
33
+ |---|---|
34
+ | `houndsman context` | Passo 0 — contexto da PR via `gh` |
35
+ | `houndsman` | Passo 1 — preparar (gera os briefs) |
36
+ | `houndsman --finalize` | Passo 3 — gerar o relatório |
37
+ | `houndsman watchdog <id>` | Contexto de um watchdog (`--json`, `--rules`) |
38
+ | `houndsman setup` | Cria a configuração inicial do projeto |
39
+ | `houndsman update` | Sincroniza os arquivos auto-gerados (`.houndsman/core`) |
40
+ | `houndsman doctor` | Valida a configuração, o ambiente e a credencial Jev (anti-drift) |
41
+ | `houndsman test` | Roda a suíte de testes da lib |
42
+
43
+ ### Flags
44
+
45
+ `--config <path>` · `--base <branch>` (default `main`) · `--head <ref>` (default `HEAD`) ·
46
+ `--branch <nome>` · `--dir <dir>` · `--clean` · `--no-jev` · `--fail-on-blocking` (no `--finalize`).
47
+
48
+ ## Artefatos
49
+
50
+ Tudo em `.houndsman/.runs/<branch-slug>/` (default do `artifactDir`, `.houndsman/.runs`):
51
+
52
+ | Arquivo | Conteúdo |
53
+ |---|---|
54
+ | `classification.json` | Watchdogs ativados + status (A/M/D/R) + churn |
55
+ | `candidates.json` | Candidatos da pré-análise Jev |
56
+ | `context.json` | Payload bruto da PR via `gh` (ou marcador de indisponível) |
57
+ | `context-summary.json` | Resumo do subagente (objetivo/motivação/alterações) |
58
+ | `briefs/<watchdog>.md` | Instruções prontas para cada sub-agente (arquivos por risco) |
59
+ | `manifest.json` | Resumo (watchdogs, arquivos, deletados, status, contexto, orçamento, churn) |
60
+ | `findings/<watchdog>.json` | Saída dos sub-agentes (schema `OUTPUT-FORMAT.md`) |
61
+ | `review.md` | Relatório final (achados agrupados por arquivo) |
62
+ | `review.<watchdog>.md` | Relatório por domínio (só quando há achados) |
63
+
64
+ ## Estrutura
65
+
66
+ ### Pacote (motor)
67
+
68
+ ```
69
+ src/
70
+ ├── index.ts # API pública (defineWatchdog, defineHoundsmanConfig, tipos)
71
+ ├── cli/index.ts # CLI ÚNICO (bin `houndsman`)
72
+ ├── core/ # bibliotecas genéricas
73
+ │ ├── config.ts # contrato HoundsmanConfig + defineHoundsmanConfig
74
+ │ ├── config-loader.ts # descoberta/carregamento de houndsman.config.ts
75
+ │ ├── assets.ts # assets embarcados (src/skill/) — usados para gerar a camada
76
+ │ ├── paths.ts # layout fixo da camada (.houndsman/) + relFromRoot
77
+ │ ├── types.ts # Severity, Rule, WatchdogDefinition, defineWatchdog
78
+ │ ├── watchdog-registry.ts # getWatchdog/findWatchdog/getWatchdogContext(config)
79
+ │ ├── orchestrator.ts # preparar/finalizar
80
+ │ ├── brief.ts # defaultRenderBrief + PROCEDURE
81
+ │ ├── pr-context.ts # contexto da PR via gh
82
+ │ ├── file-classifier.ts # classificação (via `classify` dos watchdogs) + churn
83
+ │ ├── diff-source.ts # diff único (patch + --numstat) p/ churn/orçamento
84
+ │ ├── doc-discoverer.ts # descoberta de docs
85
+ │ ├── report-builder.ts # dedupe/render do relatório
86
+ │ ├── registry-check.ts # validações anti-drift (config-driven)
87
+ │ ├── commands/ # context · review · watchdog · setup · update · test
88
+ │ └── jev/ # subsistema Jev (Passo 1.5)
89
+ ├── skill/*.md # assets markdown (embarcados no pacote)
90
+ └── tests/ # suíte da lib (project-agnóstica, "project fake")
91
+ ```
92
+
93
+ ### Projeto (consumidor — gerado por `houndsman setup`)
94
+
95
+ ```
96
+ houndsman.config.ts # HoundsmanConfig (dados; descoberto em runtime)
97
+ .houndsman/
98
+ ├── .gitignore # AUTO — ignora core/ e .runs/
99
+ ├── core/ # AUTO — sincronizado por `houndsman update`
100
+ │ ├── types.ts # snapshot dos tipos + helpers (autocontido)
101
+ │ └── skill/*.md # documentação do skill
102
+ ├── watchdogs/ # USUÁRIO — 1 módulo .ts por watchdog
103
+ │ └── index.ts # WATCHDOG_DEFINITIONS + type WatchdogId
104
+ ├── exclusions.ts # USUÁRIO
105
+ └── doc-mappings.ts # USUÁRIO
106
+ ```
107
+
108
+ > Os `SKILL.md` em `.agents/skills/houndsman/` e `.claude/skills/houndsman/` são
109
+ > ponteiros para `.houndsman/core/skill/houndsman.md`.
110
+
111
+ ## Manutenção
112
+
113
+ > As regras devem refletir os padrões **aplicados hoje**. Antes de adicionar uma regra,
114
+ > prove que o padrão existe no código (regra negativa: prove que o anti-padrão **não** existe).
115
+ > Regras devem ser **gerais/reutilizáveis** no domínio e declarar a **polaridade** no texto
116
+ > (`Promover:` = deve acontecer; `Evitar:`/`Não`/`Nunca` = não deve acontecer).
117
+
118
+ 1. Novas regras/watchdogs → editar `.houndsman/watchdogs/<id>.ts` (regras + escopo +
119
+ `classify`) ou `doc-mappings.ts`/`exclusions.ts`. Um watchdog novo exige só o módulo em
120
+ `.houndsman/watchdogs/<id>.ts` + entrada em `.houndsman/watchdogs/index.ts`.
121
+ 2. Rodar `bun run houndsman doctor` — valida a config (definições, classificação, specs Jev).
122
+
123
+ > Para qualquer alteração de regra (pontual ou auditoria completa), use o skill
124
+ > **`houndsman-update`**: `.houndsman/core/skill/houndsman-update.md`.
@@ -0,0 +1,101 @@
1
+ # Setup — usar o houndsman no seu projeto
2
+
3
+ O **houndsman** é um CLI instalado **globalmente**. A camada de configuração que ele gera
4
+ no seu projeto é **autocontida** — não exige nenhuma dependência local do pacote.
5
+
6
+ ## Pré-requisitos
7
+
8
+ - **Bun** — o CLI e o motor usam a runtime Bun (execução de TS, `Bun.spawnSync`).
9
+ - **git** — o diff usa `git diff <base>...<head> --name-status`.
10
+ - Opcional: **`gh`** (contexto da PR) e **`TYPESAFE_API_KEY`** (pré-análise Jev). O pipeline
11
+ segue normalmente sem eles.
12
+
13
+ ## Instalação (global)
14
+
15
+ ```bash
16
+ bun add -g @payconductor/houndsman
17
+ ```
18
+
19
+ O comando `houndsman` fica disponível em qualquer diretório.
20
+
21
+ ## Configuração
22
+
23
+ Na raiz do seu projeto:
24
+
25
+ ```bash
26
+ bun run houndsman setup
27
+ ```
28
+
29
+ Isso cria:
30
+
31
+ A camada separa o que é **auto-gerado** do que é **do usuário**:
32
+
33
+ | Caminho | Dono | O que é |
34
+ |---|---|---|
35
+ | `houndsman.config.ts` | usuário | Configuração — um objeto de dados (sem imports do pacote) |
36
+ | `.houndsman/watchdogs/example.ts` + `index.ts` | usuário | Comece com **1 watchdog de exemplo** |
37
+ | `.houndsman/exclusions.ts` | usuário | Arquivos que nunca entram na revisão |
38
+ | `.houndsman/doc-mappings.ts` | usuário | path → documentação de contexto |
39
+ | `.houndsman/core/types.ts` | **auto** | Snapshot dos tipos + helpers (tipagem sem install) |
40
+ | `.houndsman/core/skill/*.md` | **auto** | Documentação do skill |
41
+ | `.houndsman/.gitignore` | **auto** | Ignora `core/` e `.runs/` (gerados/temporários) |
42
+ | `.agents/skills/houndsman/SKILL.md` etc. | **auto** | Ponteiros de skill dos harnesses |
43
+
44
+ Além disso, adiciona o script `"houndsman": "houndsman"` ao `package.json` — assim
45
+ `bun run houndsman [...]` funciona na raiz do projeto. Os artefatos ficam em
46
+ `.houndsman/.runs/<branch-slug>/` (auto-ignorados).
47
+
48
+ Flags: `--name <projeto>` · `--harness agents,claude|both|none` · `--force` (sobrescreve só os
49
+ arquivos do usuário). É **idempotente** — arquivos do usuário existentes são mantidos.
50
+
51
+ ## Atualizar (auto-gerados)
52
+
53
+ Depois de atualizar a lib, sincronize os arquivos auto-gerados **sem tocar** nas suas regras:
54
+
55
+ ```bash
56
+ bun run houndsman update # reescreve .houndsman/core/** e .houndsman/.gitignore
57
+ ```
58
+
59
+ ## Verificar
60
+
61
+ ```bash
62
+ bun run houndsman doctor # valida config + ambiente + credencial Jev
63
+ bun run houndsman test # suíte da lib (project-agnóstica)
64
+ bun run houndsman --base main # prepara briefs do diff atual
65
+ ```
66
+
67
+ ## Contrato do motor (`HoundsmanConfig`)
68
+
69
+ Definido em `src/core/config.ts` (pacote) e espelhado em `.houndsman/core/types.ts` (gerado):
70
+
71
+ | Campo | Descrição |
72
+ |---|---|
73
+ | `projectName` | Nome legível (prompts/docs). |
74
+ | `artifactDir` | **Opcional** — onde gravar os artefatos (default `.houndsman/.runs`). |
75
+ | `watchdogs` | Definições dos watchdogs (incluem `classify`); os **ids são derivados** das chaves. |
76
+ | `exclusions` | Arquivos que nunca entram na revisão. |
77
+ | `docMappings` | Path → documentação de contexto. |
78
+ | `alwaysIncludeDocs` | Docs sempre presentes nos briefs (default `["AGENTS.md"]`). |
79
+ | `budgets` | **Opcional** — teto de arquivos por brief (`maxFilesPerBrief`, default `40`); o excedente vira "fora do orçamento" (registrar em `skipped`). |
80
+ | `concurrency` | **Opcional** — chamadas Jev simultâneas (`jev`, default `5`). |
81
+
82
+ > O motor **não contém** ids, paths ou regras do projeto — tudo chega por `HoundsmanConfig`,
83
+ > carregado em runtime a partir de `houndsman.config.ts` (ou `--config <path>`).
84
+
85
+ ## Estrutura do pacote (motor)
86
+
87
+ ```
88
+ houndsman/
89
+ ├── package.json
90
+ └── src/
91
+ ├── index.ts # API pública (defineWatchdog, defineHoundsmanConfig, tipos)
92
+ ├── cli/index.ts # CLI único — bin `houndsman`
93
+ ├── core/ # bibliotecas genéricas (config, orchestrator, brief, jev/, …)
94
+ ├── skill/*.md # assets markdown (embarcados no pacote)
95
+ └── tests/ # suíte da lib (project-agnóstica, "project fake")
96
+ ```
97
+
98
+ ## Desenvolvimento da lib
99
+
100
+ - Scripts: `bun run test`, `bun run typecheck`, `bun run ci`.
101
+ - O motor é 100% agnóstico ao consumidor: nenhuma regra, path ou nome de projeto vive aqui.
@@ -0,0 +1,58 @@
1
+ # PR Review — feature/add-webhook-retry
2
+
3
+ **Data:** 2026-04-20
4
+ **Watchdogs ativos:** api-contracts, backend-architecture, payments-integrations, acquirer-integrations
5
+ **Achados:** 2 bloqueantes · 1 atenção · 1 sugestões · 1 nit
6
+
7
+ ## Contexto da PR
8
+ **PR:** #482 Adicionar retry de webhooks — https://github.com/org/repo/pull/482
9
+ **Branch:** `feature/add-webhook-retry` → `main`
10
+ **Objetivo:** Tornar o envio de webhooks resiliente a falhas temporárias do destinatário.
11
+ **Motivação:** Webhooks com falha exigiam reenvio manual e causavam perda de eventos em integradores.
12
+ **Resumo das alterações:**
13
+ - Nova fila de retry para webhooks que falharam.
14
+ - Novo endpoint interno para reprocessar eventos manualmente.
15
+ - Registro de tentativas no handler de envio.
16
+
17
+ ## ❌ blocking
18
+
19
+ - **Webhook handler sem verifySignature** — `server/src/services/integrations/acquirer/webhook/handle-charge-event.ts:15` · _Acquirer Integrations, Pagamentos & Integrações_
20
+ Payload processado antes de validar a assinatura do provider.
21
+ **Ação:** Validar `verifyWebhookSignature(payload, signature, secret)` antes de qualquer efeito.
22
+ **Evidência:** `const event = JSON.parse(body)`
23
+
24
+ - **Promise não aguardada** — `server/src/services/webhook/webhook-retry-service.ts:92` · _Pagamentos & Integrações_
25
+ `updateWebhookStatus(id, 'failed')` sem `await` — status pode não persistir antes do retorno.
26
+ **Ação:** Adicionar `await`.
27
+
28
+ ## ⚠️ attention
29
+
30
+ - **Retry sem backoff** — `server/src/services/webhook/webhook-retry-service.ts:55` · _Acquirer Integrations_
31
+ Retry com intervalo fixo de 1s.
32
+ **Ação:** Usar exponential backoff com jitter.
33
+
34
+ ## 💡 suggestion
35
+
36
+ - **Complexidade** — `server/src/services/webhook/webhook-retry-service.ts:45-78` · _Arquitetura Backend_
37
+ `retryWithBackoff` com 6 níveis de indentação.
38
+ **Ação:** Extrair `calculateBackoffDelay(attempt, config)` e usar early returns.
39
+
40
+ ## 🔎 nit
41
+
42
+ - **Ordem de membros** — `server/src/services/webhook/webhook-retry-service.ts:12` · _Arquitetura Backend_
43
+ Campo privado declarado antes do construtor público.
44
+ **Ação:** Reordenar membros (públicos primeiro).
45
+
46
+ ## Cobertura
47
+
48
+ | Watchdog | Arquivos revisados | Findings |
49
+ |---|---|---|
50
+ | API & Contratos | 2 | 0 |
51
+ | Arquitetura Backend | 3 | 1 |
52
+ | Pagamentos & Integrações | 4 | 2 |
53
+ | Acquirer Integrations | 3/4 (faltam 1) | 2 |
54
+
55
+ ## Conclusão
56
+
57
+ **Status:** ❌ Mudanças Necessárias
58
+ **Resumo:** 2 violações bloqueantes, 1 ponto de atenção, 1 sugestão.