@payconductor/houndsman 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +25 -39
  2. package/package.json +1 -1
  3. package/src/cli/commands/context-command.ts +11 -9
  4. package/src/cli/commands/doctor-command.ts +5 -0
  5. package/src/cli/commands/findings-command.ts +13 -3
  6. package/src/cli/commands/review-command.ts +1 -2
  7. package/src/cli/commands/status-command.ts +46 -0
  8. package/src/cli/help.ts +8 -3
  9. package/src/cli/index.ts +5 -2
  10. package/src/core/commands/context.ts +29 -13
  11. package/src/core/commands/findings.ts +216 -125
  12. package/src/core/commands/review.ts +7 -8
  13. package/src/core/commands/scaffold.ts +15 -16
  14. package/src/core/commands/status.ts +63 -0
  15. package/src/core/config.ts +16 -7
  16. package/src/core/engine/houndsman-engine.ts +15 -1
  17. package/src/core/engine/review-scope.ts +26 -8
  18. package/src/core/engine/review-session.ts +37 -9
  19. package/src/core/findings-state.ts +53 -75
  20. package/src/core/github-review.ts +620 -57
  21. package/src/core/jev/jev-candidates.ts +49 -35
  22. package/src/core/orchestrator.ts +271 -134
  23. package/src/core/paths.ts +26 -17
  24. package/src/core/pr-context.ts +19 -5
  25. package/src/core/project-config.ts +4 -5
  26. package/src/core/renderers/manifest-writer.ts +29 -18
  27. package/src/core/renderers/resume-renderer.ts +151 -0
  28. package/src/core/report-builder.ts +7 -4
  29. package/src/core/run-layout.ts +4 -104
  30. package/src/core/run-status.ts +59 -50
  31. package/src/core/services/git-repository.ts +16 -0
  32. package/src/core/services/project-files.ts +13 -1
  33. package/src/core/storage/factory.ts +24 -0
  34. package/src/core/storage/file/file-storage.ts +271 -0
  35. package/src/core/storage/paths.ts +64 -0
  36. package/src/core/storage/repo-identity.ts +70 -0
  37. package/src/core/storage/sqlite/mappers.ts +162 -0
  38. package/src/core/storage/sqlite/schema.ts +116 -0
  39. package/src/core/storage/sqlite/sqlite-storage.ts +431 -0
  40. package/src/core/storage/types.ts +152 -0
  41. package/src/core/storage/work-area.ts +191 -0
  42. package/src/index.ts +27 -6
  43. package/src/server/artifacts.ts +8 -61
  44. package/src/server/client/App.tsx +26 -9
  45. package/src/server/client/ArtifactsPanel.tsx +144 -23
  46. package/src/server/client/AutoRefresh.tsx +1 -1
  47. package/src/server/client/Filters.tsx +7 -2
  48. package/src/server/client/FindingCard.tsx +50 -15
  49. package/src/server/client/FindingsList.tsx +2 -2
  50. package/src/server/client/MarkdownText.tsx +181 -0
  51. package/src/server/client/ResumePanel.tsx +368 -0
  52. package/src/server/client/RunList.tsx +3 -3
  53. package/src/server/client/SubmitModal.tsx +58 -10
  54. package/src/server/client/SummaryBar.tsx +1 -1
  55. package/src/server/client/icons.tsx +17 -0
  56. package/src/server/client/utils/code-highlight.ts +422 -0
  57. package/src/server/client/utils/constants.ts +226 -0
  58. package/src/server/client/utils/json-highlight.ts +55 -0
  59. package/src/server/client/utils/markdown.ts +319 -0
  60. package/src/server/client/{types.ts → utils/types.ts} +81 -0
  61. package/src/server/index.ts +154 -16
  62. package/src/server/run-repository.ts +153 -136
  63. package/src/skill/OUTPUT-FORMAT.md +6 -4
  64. package/src/skill/README.md +22 -14
  65. package/src/skill/SETUP.md +4 -4
  66. package/src/skill/example-review.md +22 -14
  67. package/src/skill/fix.md +5 -5
  68. package/src/skill/hunt.md +55 -32
  69. package/src/skill/train.md +1 -1
  70. package/src/skill/verify.md +7 -6
  71. package/src/tests/__snapshots__/baseline.test.ts.snap +74 -61
  72. package/src/tests/baseline.test.ts +79 -34
  73. package/src/tests/cli.test.ts +40 -19
  74. package/src/tests/code-highlight.test.ts +123 -0
  75. package/src/tests/domain.test.ts +1 -1
  76. package/src/tests/findings-commands.test.ts +153 -131
  77. package/src/tests/findings-state.test.ts +56 -5
  78. package/src/tests/fixtures/fake-project.ts +0 -1
  79. package/src/tests/github-review.test.ts +409 -60
  80. package/src/tests/infrastructure.test.ts +33 -38
  81. package/src/tests/markdown.test.ts +149 -0
  82. package/src/tests/review-resume.test.ts +101 -0
  83. package/src/tests/review-scope.test.ts +302 -0
  84. package/src/tests/review-scripts.test.ts +81 -5
  85. package/src/tests/run-status-view.test.ts +94 -0
  86. package/src/tests/run-status.test.ts +86 -23
  87. package/src/tests/server.test.ts +184 -96
  88. package/src/tests/storage.test.ts +449 -0
  89. package/src/server/client/constants.ts +0 -91
  90. /package/src/server/client/{api.ts → utils/api.ts} +0 -0
  91. /package/src/server/client/{format.ts → utils/format.ts} +0 -0
package/src/skill/hunt.md CHANGED
@@ -21,7 +21,7 @@ mudanças antes de push.
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` + `state.json` + `run.json` |
24
+ | 3. Finalizar | `houndsman --finalize` | skill | `review.md` + triagem/status no storage |
25
25
 
26
26
  > Por que comandos separados? Entre o passo 1 e o 3 acontece trabalho de LLM (os subagentes).
27
27
  > Depois do passo 3, a correção dos achados é a capability **`fix`** — ver `fix.md`.
@@ -70,14 +70,19 @@ leia o `context-brief.md` indicado na saída; siga as instruções e grave
70
70
  houndsman --base main
71
71
  ```
72
72
 
73
- Gera em `.houndsman/.runs/<branch-slug>/`:
73
+ Grava os artefatos no **storage global** (SQLite em `<HOUNDSMAN_HOME>/houndsman.db`) e o
74
+ staging dos subagentes em `<HOUNDSMAN_HOME>/work/<reviewId>/`:
74
75
 
75
76
  | Artefato | Conteúdo |
76
77
  |---|---|
77
- | `classification.json` | Watchdogs ativados por arquivo + status (A/M/D/R) + churn |
78
- | `candidates.json` | Indícios da pré-análise Jev (regra + arquivo + confiança) |
79
- | `briefs/<watchdog>.md` | Instruções prontas para cada subagente (arquivos por risco) |
80
- | `manifest.json` | Resumo: watchdogs, arquivos, deletados, status, contexto, Jev, orçamento |
78
+ | `classification.json` | Watchdogs ativados por arquivo + status (A/M/D/R) + churn (storage) |
79
+ | `candidates.json` | Indícios da pré-análise Jev (regra + arquivo + confiança) (storage) |
80
+ | `briefs/<watchdog>.md` | Instruções prontas para cada subagente (staging + storage, para auditoria) |
81
+ | `manifest.json` | Resumo: watchdogs, arquivos, deletados, status, contexto, Jev, orçamento (storage) |
82
+
83
+ > O prepare imprime o caminho absoluto do diretório de briefs e cada brief traz o
84
+ > `outputPath` do JSON que o subagente deve gravar. Briefs e contexto também ficam
85
+ > persistidos no storage para auditoria; o staging é limpo após o `--finalize`.
81
86
 
82
87
  **Excluídos automaticamente:** lock files, `dist/`, `build/`, `.env*`, imagens, source
83
88
  maps (padrões do projeto em `.houndsman/exclusions.ts`).
@@ -111,17 +116,20 @@ as regras atômicas dos watchdogs. Respostas acima do limiar viram **candidatos*
111
116
 
112
117
  ### Review incremental (da 2ª revisão em diante)
113
118
 
114
- Cada `--finalize` grava o **commit revisado** (`reviewed.headSha` no `state.json`). No prepare
119
+ Cada `--finalize` grava o **commit revisado** (`reviewedSha` da review no storage). No prepare
115
120
  seguinte, se o `HEAD` descende desse commit (sem rebase), o motor revisa **só o delta** — os
116
121
  arquivos alterados desde a última revisão — e **carrega** os findings dos arquivos inalterados
117
122
  (carry-over), sem re-revisá-los. O `manifest.json` traz o bloco `incremental` (`from`,
118
123
  `changedFiles`, `carried`) e o `review.md` abre com um aviso.
119
124
 
120
- - Sem mudanças desde a última revisão → **no-op** (nada a revisar; o estado é preservado).
125
+ - Sem mudanças desde a última revisão → **no-op**: o prepare não gera briefs nem reescreve
126
+ artefatos (classification, manifest, review.md), e o `--finalize` também vira no-op — pare o
127
+ fluxo aí (nenhum subagente é despachado).
121
128
  - Rebase/force-push (histórico reescrito) → cai automaticamente no **review completo**.
122
129
  - Forçar completo: `houndsman --full` (ou `--clean`, que também descarta a triagem anterior).
123
130
 
124
131
  > Custo: o LLM só é gasto nos arquivos que mudaram desde a última revisão — não na PR inteira.
132
+ > Re-rodar `/houndsman` no mesmo commit **não** re-revisa a PR; use `--full` para isso.
125
133
 
126
134
  ---
127
135
 
@@ -130,12 +138,16 @@ arquivos alterados desde a última revisão — e **carrega** os findings dos ar
130
138
  Um subagente por brief. Despache em **ondas** (ex.: até 8 subagentes por bloco de tool
131
139
  calls) — evita estourar limites de taxa quando há muitos watchdogs. O prompt é o próprio brief:
132
140
 
141
+ > **Heartbeat:** antes de despachar cada onda, rode `houndsman status ping`. A UI usa esse
142
+ > sinal (e não `updatedAt`) para saber que a execução está viva; sem ping por 10 min ela
143
+ > mostra "Timeout na revisão".
144
+
133
145
  ```
134
- Leia e execute o brief: .houndsman/.runs/<branch-slug>/briefs/<watchdog-id>.md
146
+ Leia e execute o brief: <caminho absoluto impresso pelo prepare>/briefs/<watchdog-id>.md
135
147
  Você é o watchdog <watchdog-id> do {{projectName}}.
136
148
  ```
137
149
 
138
- Cada subagente grava `findings/<watchdog-id>.json` (schema `.houndsman/core/skill/OUTPUT-FORMAT.md`).
150
+ Cada subagente grava o `outputPath` indicado no brief (schema `.houndsman/core/skill/OUTPUT-FORMAT.md`).
139
151
  Sem achados → `"findings": []` (arquivo obrigatório). Arquivos na seção **Fora do orçamento**
140
152
  não são lidos: registre-os em `skipped`.
141
153
 
@@ -150,18 +162,21 @@ não são lidos: registre-os em `skipped`.
150
162
  houndsman --finalize
151
163
  ```
152
164
 
153
- Falha com mensagem clara se faltar algum `findings/<watchdog>.json`. Quando todos existem:
165
+ Falha com mensagem clara se faltar algum `findings/<watchdog>.json` no staging. Quando todos existem:
154
166
  1. Valida o schema de cada JSON
155
167
  2. Deduplica achados por `(file, line, rule)` mesclando watchdogs sobrepostos
156
- 3. Agrupa por severidade: ❌ blocking > ⚠️ attention > 💡 suggestion > 🔎 nit
157
- 4. Grava `.houndsman/.runs/<branch-slug>/review.md` + tabela de cobertura
158
- 5. Anexa os candidatos Jev não confirmados em `🔎 Candidatos não verificados` (não bloqueiam)
159
- 6. Agrupa os achados **por arquivo** dentro de cada severidade (navegabilidade em PRs grandes)
160
- 7. Grava um `review.<watchdog>.md` por watchdog com achados e indexa no `review.md`
168
+ 3. Grava um `review.<watchdog>.md` por watchdog com achados e indexa no `review.md`
161
169
  (**Relatórios por domínio**) — mantém o relatório consolidado enxuto
162
- 8. Grava `.houndsman/.runs/<branch-slug>/state.json` — a **triagem**: um `id` curto e um
163
- `fingerprint` de conteúdo por finding, preservados entre execuções
164
-
170
+ 4. Grava o `review.md` abrindo pelo **sumário**: contexto, relatórios por domínio, cobertura e
171
+ conclusão — antes dos achados
172
+ 5. Agrupa os achados por severidade (❌ blocking > ⚠️ attention > 💡 suggestion > 🔎 nit) e
173
+ **por arquivo** dentro de cada severidade (navegabilidade em PRs grandes)
174
+ 6. Anexa os candidatos Jev não confirmados em `🔎 Candidatos não verificados` ao final
175
+ (não bloqueiam)
176
+ 7. Persiste a **triagem** no storage — um `id` curto e um `fingerprint` de conteúdo por
177
+ finding, preservados entre execuções9. Marca como **`done`** os findings que sumiram do relatório (corrigidos manualmente entre
178
+ revisões) e **resolve as conversas correspondentes no GitHub** — só as ainda abertas, e
179
+ falha-aberto (sem `gh`/PR o relatório segue igual)
165
180
  Após finalizar, corrija os achados com a capability **`fix`** (`fix.md`): a UI ou os
166
181
  comandos `findings` levam do achado à correção.
167
182
 
@@ -183,14 +198,6 @@ comandos `findings` levam do achado à correção.
183
198
  **Resumo das alterações:**
184
199
  - ...
185
200
 
186
- ## ❌ blocking
187
- ### `src/routes/order-route.ts`
188
- - **<regra>** — `src/routes/order-route.ts:5` · _<watchdogs>_
189
- <mensagem>
190
- **Ação:** <ação>
191
-
192
- ## 🔎 Candidatos não verificados (Jev) ← se houver
193
-
194
201
  ## Relatórios por domínio
195
202
  | Watchdog | Achados | Revisados | Relatório |
196
203
  |---|---|---|---|
@@ -201,8 +208,19 @@ comandos `findings` levam do achado à correção.
201
208
 
202
209
  ## Conclusão
203
210
  **Status:** ✅ Aprovado / ⚠️ Aprovado com Ressalvas / ❌ Mudanças Necessárias
211
+
212
+ ## ❌ blocking
213
+ ### `src/routes/order-route.ts`
214
+ - **<regra>** — `src/routes/order-route.ts:5` · _<watchdogs>_
215
+ <mensagem>
216
+ **Ação:** <ação>
217
+
218
+ ## 🔎 Candidatos não verificados (Jev) ← se houver, sempre ao final
204
219
  ```
205
220
 
221
+ > O **sumário** (relatórios por domínio, cobertura e conclusão) vem **antes** dos achados;
222
+ > os pontos específicos ficam no fim.
223
+
206
224
  ---
207
225
 
208
226
  ## Fluxo Completo
@@ -212,15 +230,15 @@ houndsman context (gh) ──► context.json ──► subagente ─
212
230
  ↓
213
231
  git diff --name-status (base...head)
214
232
  ↓
215
- [1] houndsman ──► classification.json + candidates.json + briefs/ + manifest.json
233
+ [1] houndsman ──► storage (classification/candidates/manifest) + briefs/ no staging
216
234
  ↓
217
- [2] N subagentes em paralelo ──► findings/<watchdog>.json
235
+ [2] N subagentes em paralelo ──► findings/<watchdog>.json no staging
218
236
  ↓
219
- [3] houndsman --finalize ──► review.md + state.json + run.json (review_done)
237
+ [3] houndsman --finalize ──► review.md + triagem no storage (review_done)
220
238
  ↓
221
239
  [4] server (UI) ──► validar a revisão + marcar decision: execute
222
240
  ↓
223
- [5] fix ──► correções + state.json/run.json (fix_done)
241
+ [5] fix ──► correções + triagem/status no storage (fix_done)
224
242
  ```
225
243
 
226
244
  ---
@@ -241,12 +259,17 @@ Se a branch não for informada, detecta com `git branch --show-current`. Base do
241
259
  |---|---|
242
260
  | `houndsman context` | Passo 0 — contexto da PR via `gh` |
243
261
  | `houndsman` | Passo 1 — preparar (briefs + manifesto; incremental quando possível) |
262
+ | `houndsman status ping` | Passo 2 — heartbeat da execução (antes de cada onda) |
244
263
  | `houndsman --finalize` | Passo 3 — gerar o relatório |
245
264
  | `houndsman watchdog <id>` | Contexto de um watchdog (`--json`, `--rules`) |
246
265
 
247
- Flags do review: `--base` · `--head` · `--branch` · `--dir` · `--clean` · `--full` (força
266
+ Flags do review: `--base` · `--head` · `--branch` · `--clean` · `--full` (força
248
267
  completo) · `--no-jev` · `--fail-on-blocking` (com `--finalize`).
249
268
 
269
+ > Persistência: SQLite global em `<HOUNDSMAN_HOME>/houndsman.db`. O staging dos subagentes
270
+ > (`briefs/`, `findings/`, contexto) vive em `<HOUNDSMAN_HOME>/work/<reviewId>/` e é limpo
271
+ > depois do `--finalize`.
272
+
250
273
  ---
251
274
 
252
275
  ## Anti-padrões
@@ -118,7 +118,7 @@ Cada informação tem o seu campo — não espelhe a regra em vários lugares:
118
118
  |---|---|
119
119
  | `.houndsman/watchdogs/<id>.ts` | **Fonte de verdade**: `defineWatchdog` com `rules` (severidade + texto), `scope`, `description`, `reviewFocus`, `exclude`, `breakingChange`, `contextFiles`, `classify` |
120
120
  | `.houndsman/watchdogs/index.ts` | `WATCHDOG_DEFINITIONS` — as **chaves definem os ids** (`WatchdogId`); `watchdogIds` é derivado |
121
- | `houndsman.config.ts` | `houndsmanConfig` do projeto — `projectName`, `artifactDir`, `watchdogs`, `exclusions`, `docMappings` (descoberto em runtime) |
121
+ | `houndsman.config.ts` | `houndsmanConfig` do projeto — `projectName`, `storage`, `watchdogs`, `exclusions`, `docMappings` (descoberto em runtime) |
122
122
  | `.houndsman/exclusions.ts` | `EXCLUSION_PATTERNS` + `isExcluded` |
123
123
  | `.houndsman/doc-mappings.ts` | `DOC_MAPPINGS` (path → docs) |
124
124
  | `.houndsman/core/types.ts` | Snapshot gerado dos tipos + helpers (autocontido) |
@@ -4,15 +4,15 @@
4
4
  > (`.agents/skills/houndsman/SKILL.md` e `.claude/skills/houndsman/SKILL.md`).
5
5
 
6
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.
7
+ PR**. Invocação: `/houndsman verify`. Consome a triagem persistida pelo `hunt`; não revisa nem
8
+ altera regras.
9
9
 
10
10
  **Quando usar:**
11
11
 
12
12
  - Depois de corrigir achados (`fix`), para confirmar que as violações sumiram.
13
13
  - As violações foram resolvidas? · confere se ainda está lá · valida o fix.
14
14
 
15
- > **Pré-requisito:** existe `.houndsman/.runs/<branch-slug>/state.json` (gerado no `--finalize`).
15
+ > **Pré-requisito:** existe uma review com findings persistidos (gerada no `--finalize`).
16
16
 
17
17
  ---
18
18
 
@@ -38,12 +38,13 @@ completa.
38
38
  ```bash
39
39
  bun run houndsman findings verify # relatório (não altera o estado)
40
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)
41
+ bun run houndsman findings verify --apply # marca os resolvidos como done (ping no status)
42
42
  ```
43
43
 
44
- - Sem `--apply`: **só relatório** (grava `verify.md` na pasta da run). Nada muda no `state.json`.
44
+ - Sem `--apply`: **só relatório** (grava o artefato `verify.md` no storage). Nada muda na triagem.
45
45
  - Com `--apply`: os findings com status **`resolved`** viram `execState: done` (histórico
46
- `by: "verify"`). `persisting` e `uncertain` **não** são tocados.
46
+ `by: "verify"`) e a **thread correspondente é resolvida no GitHub** (quando há comentário e a
47
+ conversa ainda está aberta; fail-open). `persisting` e `uncertain` **não** são tocados.
47
48
 
48
49
  Filtros (como no `findings list`): `--severity`, `--watchdog`, `--file`, `--decision`. `--all`
49
50
  inclui ausentes. `--no-jev` desliga o tier LLM. `--fail-on-persisting` sai com código 1 se algum
@@ -4,7 +4,7 @@ exports[`baseline — brief defaultRenderBrief (contexto, churn, overflow, candi
4
4
  "# Brief — Alpha (\`alpha\`)
5
5
 
6
6
  **Branch:** feature/x
7
- **Output obrigatório:** \`.houndsman/.runs/feature-x/findings/alpha.json\`
7
+ **Output obrigatório:** \`/workspace/work/review-x/findings/alpha.json\`
8
8
  **Schema do output:** \`.houndsman/core/skill/OUTPUT-FORMAT.md\`
9
9
 
10
10
  ## Objetivo
@@ -88,23 +88,6 @@ exports[`baseline — relatório renderReport consolidado 1`] = `
88
88
  - Faz A
89
89
  - Remove B
90
90
 
91
- ## ❌ blocking
92
-
93
- ### \`src/alpha/a.ts\`
94
-
95
- - **Nunca usar \`any\`.** — \`src/alpha/a.ts:1\` · _Alpha_ · \`id-alpha\`
96
- any detectado
97
- **Ação:** tipar
98
- **Evidência:** \`export const a: any = 1;\`
99
-
100
- ## ⚠️ attention
101
-
102
- ### \`src/alpha/b.ts\`
103
-
104
- - **Promover: validar a entrada.** — \`src/alpha/b.ts:2\` · _Alpha, Beta_ · \`id-beta\`
105
- sem validação
106
- **Ação:** adicionar schema
107
-
108
91
  ## Relatórios por domínio
109
92
 
110
93
  | Watchdog | Achados | Revisados | Relatório |
@@ -121,7 +104,25 @@ exports[`baseline — relatório renderReport consolidado 1`] = `
121
104
  ## Conclusão
122
105
 
123
106
  **Status:** ❌ Mudanças Necessárias
124
- **Resumo:** 1 violações bloqueantes, 1 pontos de atenção, 0 sugestões e 0 nits."
107
+ **Resumo:** 1 violações bloqueantes, 1 pontos de atenção, 0 sugestões e 0 nits.
108
+
109
+ ## ❌ blocking
110
+
111
+ ### \`src/alpha/a.ts\`
112
+
113
+ - **Nunca usar \`any\`.** — \`src/alpha/a.ts:1\` · _Alpha_ · \`id-alpha\`
114
+ any detectado
115
+ **Ação:** tipar
116
+ **Evidência:** \`export const a: any = 1;\`
117
+
118
+ ## ⚠️ attention
119
+
120
+ ### \`src/alpha/b.ts\`
121
+
122
+ - **Promover: validar a entrada.** — \`src/alpha/b.ts:2\` · _Alpha, Beta_ · \`id-beta\`
123
+ sem validação
124
+ **Ação:** adicionar schema
125
+ "
125
126
  `;
126
127
 
127
128
  exports[`baseline — relatório renderDomainReport isolado 1`] = `
@@ -382,10 +383,16 @@ export type HoundsmanConcurrency = {
382
383
  jev?: number;
383
384
  };
384
385
 
386
+ /** Backend de persistência (reviews, findings e artefatos). */
387
+ export type HoundsmanStorage = {
388
+ provider?: "sqlite" | "file";
389
+ path?: string;
390
+ };
391
+
385
392
  /** Contrato de configuração do motor. */
386
393
  export type HoundsmanConfig<TId extends string = string> = {
387
394
  projectName: string;
388
- artifactDir?: string;
395
+ storage?: HoundsmanStorage;
389
396
  watchdogIds?: readonly TId[];
390
397
  watchdogs: Record<TId, WatchdogDefinition>;
391
398
  exclusions: readonly RegExp[];
@@ -412,10 +419,9 @@ export function defineHoundsmanConfig<TId extends string>(
412
419
  "/**
413
420
  * Mapeamento de padrões nos paths → documentação relevante.
414
421
  * Consumido pelo motor via \`HoundsmanConfig.docMappings\`.
415
- */
416
- export const DOC_MAPPINGS: readonly (readonly [RegExp, readonly string[]])[] = [
417
- [/^src\\//, ["AGENTS.md"]],
418
- ];
422
+ */\`core/\` é regenerado por \`houndsman update\`.
423
+ # Runs, findings e artefatos vivem no storage global (fora do projeto).
424
+ core
419
425
  "
420
426
  ,
421
427
  ".houndsman/exclusions.ts":
@@ -486,9 +492,9 @@ import type { HoundsmanConfig } from "./.houndsman/core/types";
486
492
  /**
487
493
  * Configuração do houndsman para acme.
488
494
  *
489
- * Caminhos são resolvidos pela camada: artefatos em .houndsman/.runs e schema de
490
- * output em .houndsman/core/skill/OUTPUT-FORMAT.md. Ajuste watchdogs, exclusões e mapeamentos de
491
- * docs conforme o projeto.
495
+ * Runs, findings e artefatos vivem no storage global (SQLite por default) —
496
+ * fora do projeto. O schema de output fica em .houndsman/core/skill/OUTPUT-FORMAT.md. Ajuste
497
+ * watchdogs, exclusões e mapeamentos de docs conforme o projeto.
492
498
  */
493
499
  export const houndsmanConfig = {
494
500
  projectName: "acme",
@@ -511,47 +517,47 @@ exports[`baseline — camada gerada setup gera os mesmos arquivos e conteúdos 3
511
517
  },
512
518
  {
513
519
  "file": ".houndsman/core/skill/OUTPUT-FORMAT.md",
514
- "sha256": "3c6f261de0ca6d31",
520
+ "sha256": "06aedccd5688aaa8",
515
521
  },
516
522
  {
517
523
  "file": ".houndsman/core/skill/README.md",
518
- "sha256": "7cc26ec5e1917a62",
524
+ "sha256": "0c1514669d044033",
519
525
  },
520
526
  {
521
527
  "file": ".houndsman/core/skill/SETUP.md",
522
- "sha256": "5d6a4b56b1033970",
528
+ "sha256": "7ce23b97d9609ac2",
523
529
  },
524
530
  {
525
531
  "file": ".houndsman/core/skill/example-review.md",
526
- "sha256": "a2627e99ac5caead",
532
+ "sha256": "d9e75054cc9811dc",
527
533
  },
528
534
  {
529
535
  "file": ".houndsman/core/skill/fix.md",
530
- "sha256": "f16c0383ad1767fb",
536
+ "sha256": "9f10b2d846dc7db5",
531
537
  },
532
538
  {
533
539
  "file": ".houndsman/core/skill/hunt.md",
534
- "sha256": "7e7d7e5535381b9b",
540
+ "sha256": "c978287603f4e088",
535
541
  },
536
542
  {
537
543
  "file": ".houndsman/core/skill/train.md",
538
- "sha256": "564a1fd38d8e4836",
544
+ "sha256": "d774215c68d15159",
539
545
  },
540
546
  {
541
547
  "file": ".houndsman/core/skill/verify.md",
542
- "sha256": "f8fcf8e12b142482",
548
+ "sha256": "29bfdeb7def2298e",
543
549
  },
544
550
  ]
545
551
  `;
546
552
 
547
553
  exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, review e state 1`] = `
548
554
  "Discovery: 1 watchdog(s) ativado(s), 3 arquivo(s), 1 deletado(s).
549
- Briefs: .houndsman/.runs/main/briefs/
555
+ Briefs: <cwd>/.home/work/<uuid>/briefs/
550
556
  Deletado (breaking change): src/alpha/old.ts
551
557
  Jev: pulado (desativado (--no-jev)).
552
558
  Sem contexto da PR (rode \`bun run houndsman context\` antes, se houver PR).
553
559
 
554
- Próximo passo: despachar os sub-agentes (um por brief em .houndsman/.runs/main/briefs/).
560
+ Próximo passo: despachar os sub-agentes (um por brief em <cwd>/.home/work/<uuid>/briefs/).
555
561
  Quando os findings estiverem gravados: bun run houndsman --finalize"
556
562
  `;
557
563
 
@@ -631,8 +637,8 @@ exports[`baseline — artefatos de prepare/finalize gera classification, brief,
631
637
  "src/alpha/b.ts"
632
638
  ],
633
639
  "overflow": 0,
634
- "brief": ".houndsman/.runs/main/briefs/alpha.md",
635
- "findings": ".houndsman/.runs/main/findings/alpha.json",
640
+ "brief": "<cwd>\\\\.home\\\\work\\\\<uuid>\\\\briefs\\\\alpha.md",
641
+ "findings": "<cwd>\\\\.home\\\\work\\\\<uuid>\\\\findings\\\\alpha.json",
636
642
  "status": "pending"
637
643
  }
638
644
  ],
@@ -657,7 +663,7 @@ exports[`baseline — artefatos de prepare/finalize gera classification, brief,
657
663
  "# Brief — Alpha (\`alpha\`)
658
664
 
659
665
  **Branch:** main
660
- **Output obrigatório:** \`.houndsman/.runs/main/findings/alpha.json\`
666
+ **Output obrigatório:** \`<cwd>\\.home\\work\\<uuid>\\findings\\alpha.json\`
661
667
  **Schema do output:** \`.houndsman/core/skill/OUTPUT-FORMAT.md\`
662
668
 
663
669
  ## Objetivo
@@ -697,8 +703,8 @@ src/alpha/**
697
703
  `;
698
704
 
699
705
  exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, review e state 2`] = `
700
- "Triagem: .houndsman/.runs/main/state.json — 1 finding(s).
701
- Relatório: .houndsman/.runs/main/review.md — 1 bloqueante(s), 0 atenção."
706
+ "Triagem: sqlite:<cwd>\\houndsman.db#<uuid> — 1 finding(s).
707
+ Relatório: sqlite:<cwd>\\houndsman.db#<uuid> — 1 bloqueante(s), 0 atenção."
702
708
  `;
703
709
 
704
710
  exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, review e state: review.md 1`] = `
@@ -708,15 +714,6 @@ exports[`baseline — artefatos de prepare/finalize gera classification, brief,
708
714
  **Watchdogs ativos:** alpha
709
715
  **Achados:** 1 bloqueantes · 0 atenção · 0 sugestões · 0 nits
710
716
 
711
- ## ❌ blocking
712
-
713
- ### \`src/alpha/a.ts\`
714
-
715
- - **Nunca usar \`any\`.** — \`src/alpha/a.ts:1\` · _Alpha_ · \`<id>\`
716
- any detectado
717
- **Ação:** tipar
718
- **Evidência:** \`export const a: any = 1;\`
719
-
720
717
  ## Relatórios por domínio
721
718
 
722
719
  | Watchdog | Achados | Revisados | Relatório |
@@ -733,6 +730,16 @@ exports[`baseline — artefatos de prepare/finalize gera classification, brief,
733
730
 
734
731
  **Status:** ❌ Mudanças Necessárias
735
732
  **Resumo:** 1 violações bloqueantes, 0 pontos de atenção, 0 sugestões e 0 nits.
733
+
734
+ ## ❌ blocking
735
+
736
+ ### \`src/alpha/a.ts\`
737
+
738
+ - **Nunca usar \`any\`.** — \`src/alpha/a.ts:1\` · _Alpha_ · \`<id>\`
739
+ any detectado
740
+ **Ação:** tipar
741
+ **Evidência:** \`export const a: any = 1;\`
742
+
736
743
  "
737
744
  `;
738
745
 
@@ -764,10 +771,6 @@ exports[`baseline — artefatos de prepare/finalize gera classification, brief,
764
771
  "order": [
765
772
  "<id>"
766
773
  ],
767
- "reviewed": {
768
- "headSha": "<sha>",
769
- "at": "<timestamp>"
770
- },
771
774
  "findings": {
772
775
  "<id>": {
773
776
  "id": "<id>",
@@ -796,19 +799,29 @@ exports[`baseline — artefatos de prepare/finalize gera classification, brief,
796
799
  "updatedAt": "<timestamp>",
797
800
  "history": []
798
801
  }
802
+ },
803
+ "reviewed": {
804
+ "headSha": "<sha>",
805
+ "at": "<timestamp>"
799
806
  }
800
- }
801
- "
807
+ }"
802
808
  `;
803
809
 
804
810
  exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, review e state: run.json 1`] = `
805
811
  "{
806
- "version": 1,
807
- "slug": "main",
812
+ "id": "<uuid>",
813
+ "repoKey": "path:<cwd>",
814
+ "repoRoot": "<cwd>",
808
815
  "branch": "main",
816
+ "slug": "main",
817
+ "base": "<sha>",
818
+ "head": "HEAD",
819
+ "headSha": "<sha>",
820
+ "reviewedSha": "<sha>",
821
+ "reviewedAt": "<timestamp>",
809
822
  "status": "review_done",
810
823
  "startedAt": "<timestamp>",
824
+ "createdAt": "<timestamp>",
811
825
  "updatedAt": "<timestamp>"
812
- }
813
- "
826
+ }"
814
827
  `;