@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
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Formato de Saída dos Watchdogs
|
|
2
2
|
|
|
3
3
|
Todo watchdog DEVE gravar **um arquivo JSON** com seus achados. O `report-builder.ts`
|
|
4
|
-
|
|
4
|
+
valida e deduplica os JSONs; o `--finalize` grava a triagem no storage e o
|
|
5
|
+
`review-resume.md` com a cobertura por domínio.
|
|
5
6
|
|
|
6
7
|
> **Não** escrever markdown livre no chat. O único output consumido pelo pipeline é o JSON.
|
|
7
8
|
|
|
@@ -33,7 +34,12 @@ staging global da review:
|
|
|
33
34
|
"line": 5,
|
|
34
35
|
"message": "Arquivo de rota importa `db` e executa query inline.",
|
|
35
36
|
"action": "Mover a query para o service correspondente.",
|
|
36
|
-
"evidence": "import { db } from '../db'"
|
|
37
|
+
"evidence": "import { db } from '../db'",
|
|
38
|
+
"scenario": "request autenticada em /orders executa a query na rota",
|
|
39
|
+
"impact": "acoplamento e bypass das regras do service",
|
|
40
|
+
"impactClass": "flow-break",
|
|
41
|
+
"confidence": 0.9,
|
|
42
|
+
"basis": "logic"
|
|
37
43
|
}
|
|
38
44
|
]
|
|
39
45
|
}
|
|
@@ -44,7 +50,7 @@ staging global da review:
|
|
|
44
50
|
| Campo | Tipo | Obrigatório | Descrição |
|
|
45
51
|
|---|---|---|---|
|
|
46
52
|
| `watchdogId` | string | ✅ | Id do watchdog (deve casar com uma chave de `.houndsman/watchdogs/index.ts`) |
|
|
47
|
-
| `reviewedFiles` | string[] | ✅ | Arquivos efetivamente
|
|
53
|
+
| `reviewedFiles` | string[] | ✅ | Arquivos **do seu domínio** efetivamente revisados (subconjunto de `## Arquivos do seu domínio`; não inclua chamadores/importadores nem arquivos de outros domínios) |
|
|
48
54
|
| `skipped` | string[] | ✅ | Arquivos do domínio que NÃO foram lidos + motivo |
|
|
49
55
|
| `findings` | object[] | ✅ | Achados (vazio se nada encontrado) |
|
|
50
56
|
| `findings[].rule` | string | ✅ | Regra violada (conforme o brief do watchdog) |
|
|
@@ -54,9 +60,28 @@ staging global da review:
|
|
|
54
60
|
| `findings[].message` | string | ✅ | O que está errado (curto, específico) |
|
|
55
61
|
| `findings[].action` | string | ✅ | O que fazer |
|
|
56
62
|
| `findings[].evidence` | string | — | Trecho que comprova o achado |
|
|
63
|
+
| `findings[].scenario` | string | — | Gatilho concreto que expõe o gap (ex.: "renovação de assinatura Pix sem split") |
|
|
64
|
+
| `findings[].impact` | string | — | Consequência observável (ex.: "cobrança recriada sem o split configurado") |
|
|
65
|
+
| `findings[].impactClass` | `"flow-break" \| "contract-drift" \| "degradation" \| "cosmetic"` | emergente | Classe de impacto que define a severidade fora de regra |
|
|
66
|
+
| `findings[].confidence` | number | — | Confiança do revisor (0–1) |
|
|
67
|
+
| `findings[].basis` | `"rule" \| "logic" \| "domain"` | — | Origem do achado; inferida pelo prefixo `Lógica:`/`Domínio:` |
|
|
57
68
|
|
|
58
69
|
## Severidade
|
|
59
70
|
|
|
71
|
+
A severidade é **derivada**, não escolhida pelo watchdog:
|
|
72
|
+
|
|
73
|
+
| Origem do finding | Fonte da severidade |
|
|
74
|
+
|---|---|
|
|
75
|
+
| Regra do brief (`rule` copiada) | `severity` **declarada na regra** — outro valor é ignorado e corrigido pelo motor |
|
|
76
|
+
| Emergente (`Lógica:`/`Domínio:`) | `impactClass`, pela tabela abaixo |
|
|
77
|
+
|
|
78
|
+
| `impactClass` | Quando usar | Severidade |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| `flow-break` | o caminho não completa (criação/renovação/cancelamento) ou a capacidade declarada não é honrada | `blocking` (exige `scenario` + `evidence`) |
|
|
81
|
+
| `contract-drift` | contrato, identificador ou estado divergente — mas o fluxo completa | `attention` |
|
|
82
|
+
| `degradation` | funciona, mas com borda, erro, retry ou idempotência frágil | `suggestion` |
|
|
83
|
+
| `cosmetic` | clareza, nome, detalhe cosmético | `nit` |
|
|
84
|
+
|
|
60
85
|
| Severidade | Emoji | Bloqueia merge? |
|
|
61
86
|
|---|---|---|
|
|
62
87
|
| `blocking` | ❌ | Sim |
|
|
@@ -64,11 +89,21 @@ staging global da review:
|
|
|
64
89
|
| `suggestion` | 💡 | Não |
|
|
65
90
|
| `nit` | 🔎 | Não (detalhe/observação) |
|
|
66
91
|
|
|
92
|
+
> Sem `impactClass` (relatório antigo), o motor mantém o valor emitido em `severity`.
|
|
93
|
+
> Conflito de severidade numa mesma regra entre reviews deixa de existir: a regra é a fonte.
|
|
94
|
+
|
|
67
95
|
## Regras
|
|
68
96
|
|
|
69
97
|
- Sem achados → `"findings": []` (arquivo **obrigatório**).
|
|
70
98
|
- Um achado por regra violada; não agrupar regras diferentes.
|
|
99
|
+
- **Teto de 20 achados por watchdog.** Se houver mais, mantenha os de maior severidade e
|
|
100
|
+
agrupe ocorrências idênticas (mesmo trecho + mesma regra) em um único item. O JSON precisa
|
|
101
|
+
caber inteiro — relatório cortado perde achados.
|
|
102
|
+
- `reviewedFiles ∪ skipped` deve cobrir **todo** o escopo do brief. O que não foi revisado
|
|
103
|
+
entra em `skipped` com o motivo (`budget`, `truncated`, `fora do fluxo`).
|
|
71
104
|
- `file:line` sempre que possível; `evidence` quando o achado não é óbvio.
|
|
105
|
+
- **Trecho truncado** (`… [trecho truncado]`): sem abrir o arquivo para ver o restante, não
|
|
106
|
+
afirme violação sobre ele — reduza a `confidence` ou não reporte.
|
|
72
107
|
- **Escopo do diff:** a `line` deve cair dentro das faixas listadas em
|
|
73
108
|
*Escopo do diff (símbolos alterados)* no brief. Código fora delas é contexto — não é
|
|
74
109
|
achado desta revisão. Se a alteração quebra código não alterado, ancore o finding na
|
|
@@ -76,14 +111,24 @@ staging global da review:
|
|
|
76
111
|
- Achado **sem linha** só quando for inerente à alteração (vira comentário de arquivo).
|
|
77
112
|
- Não inventar achados — se não houver violação, o array fica vazio.
|
|
78
113
|
|
|
79
|
-
## Findings emergentes (
|
|
114
|
+
## Findings emergentes (obrigatórios no `general`)
|
|
80
115
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
reservados:
|
|
116
|
+
O watchdog `general` (id reservado, sempre ativo) **deve** reportar gaps de lógica e domínio
|
|
117
|
+
que não correspondem a uma regra explícita, usando os prefixos reservados:
|
|
84
118
|
|
|
85
119
|
- `Lógica: <descrição>` — nome/contrato vs comportamento, fluxos, estados, bordas.
|
|
86
|
-
- `Domínio: <descrição>` — transições, idempotência, invariantes, arredondamento, timezone
|
|
120
|
+
- `Domínio: <descrição>` — transições, idempotência, invariantes, arredondamento, timezone,
|
|
121
|
+
paridade de capacidade, propagação de credencial.
|
|
122
|
+
|
|
123
|
+
Demonstre o gap em três partes:
|
|
124
|
+
|
|
125
|
+
1. `scenario` — o gatilho concreto (ex.: "`AsaasSplit` recebe `RenewAutomaticPix`").
|
|
126
|
+
2. `message` — o comportamento observado e o invariante/regra violado.
|
|
127
|
+
3. `evidence` — o trecho que comprova.
|
|
128
|
+
|
|
129
|
+
**Severidade:** fora de regra, `blocking` só é aceito com `scenario` **e** `evidence`. Sem os
|
|
130
|
+
dois, o motor rebaixa para `attention` (e registra um aviso). Regras explícitas mantêm a
|
|
131
|
+
severidade declarada **na regra**.
|
|
87
132
|
|
|
88
|
-
|
|
89
|
-
|
|
133
|
+
Os demais watchdogs podem usar os mesmos prefixos apenas quando declararem
|
|
134
|
+
`allowEmergentFindings: true`.
|
package/src/skill/README.md
CHANGED
|
@@ -45,25 +45,29 @@ O CLI só substitui o despacho manual dos subagentes por processos maki headless
|
|
|
45
45
|
|
|
46
46
|
| Passo | Comando | Quem roda | Resultado |
|
|
47
47
|
|---|---|---|---|
|
|
48
|
-
| 0. Contexto | `
|
|
49
|
-
| 1. Preparar | `bun run houndsman` | skill | `classification.json` + `candidates.json` + `briefs/` + `manifest.json` |
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
>
|
|
55
|
-
>
|
|
56
|
-
>
|
|
48
|
+
| 0. Contexto | `houndsman --pr` (via `gh`) | prepare | `context.json` + `context-brief.md` → `context-summary.json` (IA; sem IA, subagente) |
|
|
49
|
+
| 1. Preparar | `bun run houndsman` | skill | `classification.json` + `candidates.json` + `business-summary.json` + `briefs/` + `manifest.json` |
|
|
50
|
+
| 1.5. Intenção | *(subagente)* | skill, só sem IA | `business-summary.json` enriquecido (só quando não veio da IA) |
|
|
51
|
+
| 2. Revisar | *(subagentes)* | skill | `findings/<watchdog>.json` (inclui o `general`, sempre ativo) |
|
|
52
|
+
| 3. Finalizar | `bun run houndsman --finalize` | skill | `review-resume.md` + triagem no storage |
|
|
53
|
+
|
|
54
|
+
> **Alvo = PR** (ex.: “revise a PR 456”): use `houndsman --pr 456` e
|
|
55
|
+
> `houndsman --pr 456 --finalize`. O prepare coleta o contexto via `gh`, cria um **worktree**
|
|
56
|
+
> detached em `<repo>/.houndsman/worktrees/<repo>/<branch>` e resume o contexto com IA;
|
|
57
|
+
> os briefs trazem `**Worktree:**` e os subagentes devem ler essa árvore (nunca o clone
|
|
58
|
+
> principal). Despache os briefs em paralelo (mesmo bloco de tool calls).
|
|
57
59
|
|
|
58
60
|
## Comandos
|
|
59
61
|
|
|
60
62
|
| Comando | Função |
|
|
61
63
|
|---|---|
|
|
62
|
-
| `houndsman context` |
|
|
64
|
+
| `houndsman context` | Contexto da PR via `gh` (`--pr <n>`/`--worktree <path>`) — o prepare já coleta com `--pr` |
|
|
63
65
|
| `houndsman` | Passo 1 — preparar (gera os briefs) |
|
|
64
66
|
| `houndsman --pr <n>` | Passo 1 em worktree dedicado (revisões paralelas) |
|
|
65
|
-
| `houndsman --finalize` | Passo 3 —
|
|
67
|
+
| `houndsman --finalize` | Passo 3 — gravar a triagem e o resumo final (`--pr <n>` reusa o worktree) |
|
|
66
68
|
| `houndsman hunt [--pr <n>]` | Harness local opcional (maki): prepare → watchdogs → finalize |
|
|
69
|
+
| `houndsman compare` | Compara duas runs/variantes (`--list`, `--a`, `--b` ou dois slugs) |
|
|
70
|
+
| `houndsman golden` | Avalia runs contra um golden set de defeitos (`recall`/`precisão`) |
|
|
67
71
|
| `houndsman hunt install` | Baixa o maki fixado para `<HOUNDSMAN_HOME>/tools/maki` |
|
|
68
72
|
| `houndsman worktree <ação>` | `list`/`add`/`remove`/`prune`/`path` dos worktrees |
|
|
69
73
|
| `houndsman watchdog <id>` | Contexto de um watchdog (`--json`, `--rules`) |
|
|
@@ -90,9 +94,10 @@ Runs, findings e artefatos vivem no **storage global** (SQLite em `<HOUNDSMAN_HO
|
|
|
90
94
|
| findings | Decisão/execução + fingerprint + âncora + histórico + vínculo com o GitHub |
|
|
91
95
|
| `classification.json` | Watchdogs ativados + status (A/M/D/R) + churn |
|
|
92
96
|
| `candidates.json` | Candidatos da pré-análise Jev |
|
|
93
|
-
| `
|
|
97
|
+
| `business-summary.json` / `business-brief.md` | Modelo de intenção da PR e o brief do passo |
|
|
98
|
+
| `manifest.json` | Resumo (watchdogs, arquivos, deletados, contexto, intenção, orçamento, churn) |
|
|
94
99
|
| `briefs/<watchdog>.md` | Brief enviado a cada sub-agente (auditoria) |
|
|
95
|
-
| `review.md`
|
|
100
|
+
| `review-resume.md` | Resumo final: negócio, pontos técnicos, cobertura por domínio e conclusão |
|
|
96
101
|
| `verify.md` | Relatório do `findings verify` |
|
|
97
102
|
| `context.json` / `context-brief.md` / `context-summary.json` | Contexto da PR |
|
|
98
103
|
|
|
@@ -121,7 +126,7 @@ src/
|
|
|
121
126
|
│ ├── paths.ts # layout fixo da camada (.houndsman/) + relFromRoot
|
|
122
127
|
│ ├── types.ts # Severity, Rule, WatchdogDefinition, defineWatchdog
|
|
123
128
|
│ ├── watchdog-registry.ts # getWatchdog/findWatchdog/getWatchdogContext(config)
|
|
124
|
-
│ ├── orchestrator.ts # preparar/finalizar
|
|
129
|
+
│ ├── orchestrator.ts # fachada: preparar/finalizar (pipelines em engine/)
|
|
125
130
|
│ ├── brief.ts # defaultRenderBrief + PROCEDURE
|
|
126
131
|
│ ├── pr-context.ts # contexto da PR via gh
|
|
127
132
|
│ ├── file-classifier.ts # classificação (via `classify` dos watchdogs) + churn
|
package/src/skill/SETUP.md
CHANGED
|
@@ -106,6 +106,7 @@ Definido em `src/core/config.ts` (pacote) e espelhado em `.houndsman/core/types.
|
|
|
106
106
|
| `watchdogs` | Definições dos watchdogs (incluem `classify`); os **ids são derivados** das chaves. |
|
|
107
107
|
| `exclusions` | Arquivos que nunca entram na revisão. |
|
|
108
108
|
| `docMappings` | Path → documentação de contexto. |
|
|
109
|
+
| `priorities` | **Opcional** — prioridade por caminho `[{ pattern: RegExp, bonus?: number, maxRiskFromChurn?: number }]`. Risco = `min(churn, maxRiskFromChurn) + bonus`: `bonus` promove caminho crítico e o teto impede que superchurn de caminho de baixa criticidade escale. A primeira regra que casar vence. Ordena o orçamento, o rateio do diff e o recorte do `general`. Sem config: churn puro. |
|
|
109
110
|
| `alwaysIncludeDocs` | Docs sempre presentes nos briefs (default `["AGENTS.md"]`). |
|
|
110
111
|
| `budgets` | **Opcional** — teto de arquivos por brief (`maxFilesPerBrief`, default `40`); o excedente vira "fora do orçamento" (registrar em `skipped`). |
|
|
111
112
|
| `concurrency` | **Opcional** — chamadas Jev simultâneas (`jev`, default `5`). |
|
package/src/skill/SKILL.md
CHANGED
|
@@ -14,6 +14,11 @@ consolida tudo num relatório. O motor é o CLI **`houndsman`**; as regras do pr
|
|
|
14
14
|
**Terminologia:** **houndsman** = orquestrador/treinador (CLI + motor) · **watchdog** = agente
|
|
15
15
|
especialista por domínio · **finding** = um achado da revisão · **Jev** = pré-análise opcional.
|
|
16
16
|
|
|
17
|
+
> **Duas etapas são obrigatórias em toda revisão:** o **modelo de intenção**
|
|
18
|
+
> (`business-summary.json`) e o revisor de fluxo **`general`** (id reservado, sempre ativo).
|
|
19
|
+
> O modelo vem da IA no prepare quando há chave; sem chave, um subagente (Passo 1.5) ou o
|
|
20
|
+
> pré-passe maki o produz. Nenhum dos dois é configurável pelo usuário.
|
|
21
|
+
|
|
17
22
|
## Capabilities
|
|
18
23
|
|
|
19
24
|
| Capability | Objetivo | Documento |
|
|
@@ -60,12 +65,16 @@ Interprete o alvo em linguagem natural **antes** de rodar o CLI:
|
|
|
60
65
|
Sequência para uma PR (ex.: 456):
|
|
61
66
|
|
|
62
67
|
```bash
|
|
63
|
-
houndsman
|
|
64
|
-
|
|
65
|
-
# despache os briefs (cada um traz **Worktree:** <path>)
|
|
68
|
+
houndsman --pr 456 # cria/reusa o worktree, coleta o contexto e prepara
|
|
69
|
+
# despache os briefs em paralelo (cada um traz **Worktree:** <path>)
|
|
66
70
|
houndsman --pr 456 --finalize
|
|
67
71
|
```
|
|
68
72
|
|
|
73
|
+
- O contexto da PR é coletado pelo próprio prepare (via `gh`); com IA ligada ele também é
|
|
74
|
+
resumido ali — não gaste um subagente nisso. Desative com `--no-context`.
|
|
75
|
+
- Para comparar duas execuções, use `--variant <label>` em cada uma e depois
|
|
76
|
+
`houndsman compare --branch <head> --a <a> --b <b>` (ou `compare --list`).
|
|
77
|
+
|
|
69
78
|
- O worktree vive em `<repo>/.houndsman/worktrees/<repo>/<branch>` (detached no commit da PR)
|
|
70
79
|
e é reutilizado nas próximas execuções da mesma branch. Ele fica **dentro do workspace**
|
|
71
80
|
(e o staging também) para o agente ler/executar sem prompts de permissão.
|
|
@@ -83,4 +92,4 @@ houndsman --pr 456 --finalize
|
|
|
83
92
|
- `.houndsman/core/skill/OUTPUT-FORMAT.md` — schema do JSON de saída dos watchdogs.
|
|
84
93
|
- `.houndsman/core/skill/AUDIT-PROTOCOL.md` — taxonomia da auditoria de regras (Modo B do `train`).
|
|
85
94
|
- `.houndsman/core/skill/SETUP.md` · `.houndsman/core/skill/README.md` — configuração e visão geral.
|
|
86
|
-
- `.houndsman/core/skill/example-
|
|
95
|
+
- `.houndsman/core/skill/example-resume.md` — exemplo do resumo final.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Resumo da revisão — feature/add-webhook-retry
|
|
2
|
+
|
|
3
|
+
**Data:** 2026-04-20 · **Status:** ❌ Mudanças Necessárias
|
|
4
|
+
|
|
5
|
+
## Resumo de negócio
|
|
6
|
+
|
|
7
|
+
Tornar o envio de webhooks resiliente a falhas temporárias do destinatário, sem perda de
|
|
8
|
+
eventos e sem reenvio manual.
|
|
9
|
+
|
|
10
|
+
**Invariantes:**
|
|
11
|
+
- Todo evento entregue tem no máximo uma tentativa `in_flight` por destinatário.
|
|
12
|
+
- O retry nunca duplica o `eventId` já aceito pelo integrador.
|
|
13
|
+
|
|
14
|
+
**Fluxos (2):**
|
|
15
|
+
- **Retry de webhook** — disparo: resposta não-2xx/timeout — esperado: reagendamento com
|
|
16
|
+
backoff exponencial e registro da tentativa.
|
|
17
|
+
|
|
18
|
+
## Pontos técnicos
|
|
19
|
+
|
|
20
|
+
- **Contratos** — `WebhookRetryPolicy`, `RetryAttempt` (`src/webhooks/types.ts`).
|
|
21
|
+
- **Implementações** — `WebhookDispatcher` (`src/webhooks/dispatcher.ts`).
|
|
22
|
+
- **Novas dependências** — `p-retry`.
|
|
23
|
+
|
|
24
|
+
## Cobertura por domínio
|
|
25
|
+
|
|
26
|
+
| Domínio | Achados | Revisados | Faltam |
|
|
27
|
+
|---|---|---|---|
|
|
28
|
+
| Arquitetura Backend | 2 | 3/3 | — |
|
|
29
|
+
| Pagamentos & Integrações | 1 | 4/4 | — |
|
|
30
|
+
| Acquirer Integrations | 2 | 3/4 | 1 |
|
|
31
|
+
|
|
32
|
+
## Candidatos não verificados (1)
|
|
33
|
+
|
|
34
|
+
> Indícios da pré-análise que nenhum watchdog confirmou. Não bloqueiam.
|
|
35
|
+
|
|
36
|
+
- `src/webhooks/queue.ts` · attention · Fila sem limite de tentativas.
|
|
37
|
+
|
|
38
|
+
## Conclusão
|
|
39
|
+
|
|
40
|
+
**Resumo:** 2 bloqueantes · 1 atenção · 1 sugestões · 1 nits.
|
|
41
|
+
|
|
42
|
+
> Achados individuais (com `id` de triagem) vivem na UI (`Findings`) e em
|
|
43
|
+
> `houndsman findings list --json` — o resumo não os duplica.
|