@payconductor/houndsman 0.2.0 → 0.3.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/package.json +1 -1
- package/src/cli/arg-parser.ts +8 -0
- package/src/cli/commands/command.ts +23 -0
- package/src/cli/commands/context-command.ts +38 -0
- package/src/cli/commands/doctor-command.ts +55 -0
- package/src/cli/commands/findings-command.ts +28 -0
- package/src/cli/commands/help-command.ts +13 -0
- package/src/cli/commands/registry.ts +34 -0
- package/src/cli/commands/review-command.ts +22 -0
- package/src/cli/commands/server-command.ts +37 -0
- package/src/cli/commands/setup-command.ts +34 -0
- package/src/cli/commands/watchdog-command.ts +34 -0
- package/src/cli/help.ts +43 -0
- package/src/cli/index.ts +58 -266
- package/src/core/arg-parser.ts +48 -0
- package/src/core/commands/findings.ts +34 -144
- package/src/core/commands/review.ts +18 -35
- package/src/core/commands/scaffold.ts +174 -64
- package/src/core/commands/setup.ts +16 -11
- package/src/core/commands/update.ts +7 -7
- package/src/core/commands/watchdog.ts +8 -80
- package/src/core/config.ts +9 -19
- package/src/core/defaults.ts +20 -0
- package/src/core/diff-source.ts +1 -13
- package/src/core/doc-discoverer.ts +25 -15
- package/src/core/domain/budget.ts +42 -0
- package/src/core/domain/classification.ts +94 -0
- package/src/core/domain/diff.ts +53 -0
- package/src/core/domain/watchdog.ts +96 -0
- package/src/core/engine/carryover.ts +67 -0
- package/src/core/engine/houndsman-engine.ts +51 -0
- package/src/core/engine/review-scope.ts +95 -0
- package/src/core/engine/review-session.ts +51 -0
- package/src/core/file-classifier.ts +11 -67
- package/src/core/findings-state.ts +170 -38
- package/src/core/git-revision.ts +14 -40
- package/src/core/git-runner.ts +46 -0
- package/src/core/github-review.ts +4 -33
- package/src/core/orchestrator.ts +116 -337
- package/src/core/paths.ts +9 -0
- package/src/core/pr-context.ts +28 -54
- package/src/core/project-config.ts +57 -0
- package/src/core/renderers/batch-presenter.ts +40 -0
- package/src/core/renderers/brief-renderer.ts +23 -0
- package/src/core/renderers/findings-presenter.ts +74 -0
- package/src/core/renderers/manifest-writer.ts +112 -0
- package/src/core/renderers/report-renderer.ts +66 -0
- package/src/core/renderers/verify-presenter.ts +50 -0
- package/src/core/renderers/watchdog-presenter.ts +100 -0
- package/src/core/report-builder.ts +12 -7
- package/src/core/run-layout.ts +108 -0
- package/src/core/run-status.ts +6 -11
- package/src/core/services/clock.ts +12 -0
- package/src/core/services/file-classifier.ts +34 -0
- package/src/core/services/fix-batch-builder.ts +13 -0
- package/src/core/services/gh-client.ts +54 -0
- package/src/core/services/git-repository.ts +123 -0
- package/src/core/services/project-files.ts +79 -0
- package/src/core/services/verifier.ts +58 -0
- package/src/core/verify.ts +2 -1
- package/src/core/watchdog-registry.ts +58 -16
- package/src/index.ts +31 -1
- package/src/server/index.ts +64 -234
- package/src/server/run-repository.ts +291 -0
- package/src/tests/__snapshots__/baseline.test.ts.snap +814 -0
- package/src/tests/baseline.test.ts +513 -493
- package/src/tests/domain.test.ts +328 -0
- package/src/tests/infrastructure.test.ts +210 -0
|
@@ -0,0 +1,814 @@
|
|
|
1
|
+
// Bun Snapshot v1, https://bun.sh/docs/test/snapshots
|
|
2
|
+
|
|
3
|
+
exports[`baseline — brief defaultRenderBrief (contexto, churn, overflow, candidatos e deletados) 1`] = `
|
|
4
|
+
"# Brief — Alpha (\`alpha\`)
|
|
5
|
+
|
|
6
|
+
**Branch:** feature/x
|
|
7
|
+
**Output obrigatório:** \`.houndsman/.runs/feature-x/findings/alpha.json\`
|
|
8
|
+
**Schema do output:** \`.houndsman/core/skill/OUTPUT-FORMAT.md\`
|
|
9
|
+
|
|
10
|
+
## Objetivo
|
|
11
|
+
|
|
12
|
+
Watchdog baseline.
|
|
13
|
+
|
|
14
|
+
## Escopo
|
|
15
|
+
|
|
16
|
+
src/alpha/**
|
|
17
|
+
|
|
18
|
+
## Contexto da PR
|
|
19
|
+
|
|
20
|
+
**Objetivo:** Entregar X
|
|
21
|
+
**Motivação:** Reduzir Y
|
|
22
|
+
|
|
23
|
+
**Resumo das alterações:**
|
|
24
|
+
|
|
25
|
+
- Faz A
|
|
26
|
+
- Remove B
|
|
27
|
+
|
|
28
|
+
## Regras (por severidade)
|
|
29
|
+
|
|
30
|
+
- ❌ **blocking** — Nunca usar \`any\`.
|
|
31
|
+
- ⚠️ **attention** — Promover: validar a entrada.
|
|
32
|
+
|
|
33
|
+
## Docs de contexto (carregar sob demanda)
|
|
34
|
+
|
|
35
|
+
- \`AGENTS.md\`
|
|
36
|
+
- \`README.md\`
|
|
37
|
+
|
|
38
|
+
## Arquivos do seu domínio (2)
|
|
39
|
+
|
|
40
|
+
- \`src/alpha/a.ts\` (modified, +3/−1)
|
|
41
|
+
- \`src/alpha/b.ts\` (added, +2/−0)
|
|
42
|
+
|
|
43
|
+
## Fora do orçamento (NÃO revisar)
|
|
44
|
+
|
|
45
|
+
> 1 arquivo(s) do seu domínio ficaram fora do orçamento
|
|
46
|
+
> (menor churn). Não os leia: registre-os em \`skipped\` com o motivo
|
|
47
|
+
> "budget" para que a cobertura do relatório fique honesta.
|
|
48
|
+
|
|
49
|
+
- \`src/alpha/c.ts\`
|
|
50
|
+
|
|
51
|
+
## Candidatos pré-analisados (Jev) — confirme ou refute
|
|
52
|
+
|
|
53
|
+
> Indícios automáticos com confiança calibrada. **NÃO** são achados:
|
|
54
|
+
> confirme (virando finding, com a \`rule\` abaixo) ou ignore se for falso positivo.
|
|
55
|
+
|
|
56
|
+
- [ ] \`src/alpha/a.ts\` · **blocking** · confiança 0.82
|
|
57
|
+
Regra: Nunca usar \`any\`.
|
|
58
|
+
|
|
59
|
+
## Deletados — checar breaking change
|
|
60
|
+
|
|
61
|
+
- \`src/alpha/old.ts\`
|
|
62
|
+
|
|
63
|
+
## Procedimento
|
|
64
|
+
|
|
65
|
+
1. **FILTER** — descarte o que não for do seu domínio (ver *Prioridade de leitura* e *Não carregar*).
|
|
66
|
+
2. **READ HEAD** — leia os arquivos seletivamente (primeiras ~30 linhas). NUNCA o diff completo.
|
|
67
|
+
3. **GREP** — use as regras críticas/anti-padrões como heurística para localizar violações.
|
|
68
|
+
4. **DEEP-READ** — aprofunde apenas os arquivos com suspeita de violação.
|
|
69
|
+
5. **CONCLUDE** — grave o JSON no caminho de output, com \`reviewedFiles\` preenchido. Sem achados → \`"findings": []\` (arquivo obrigatório). Não escreva markdown livre."
|
|
70
|
+
`;
|
|
71
|
+
|
|
72
|
+
exports[`baseline — relatório renderReport consolidado 1`] = `
|
|
73
|
+
"# PR Review — feature/x
|
|
74
|
+
|
|
75
|
+
**Data:** <date>
|
|
76
|
+
**Watchdogs ativos:** alpha, beta
|
|
77
|
+
**Achados:** 1 bloqueantes · 1 atenção · 0 sugestões · 0 nits
|
|
78
|
+
|
|
79
|
+
## Contexto da PR
|
|
80
|
+
|
|
81
|
+
**PR:** #42 Entrega X — https://example.test/pull/42
|
|
82
|
+
**Branch:** \`feature/x\` → \`main\`
|
|
83
|
+
**Objetivo:** Entregar X
|
|
84
|
+
**Motivação:** Reduzir Y
|
|
85
|
+
|
|
86
|
+
**Resumo das alterações:**
|
|
87
|
+
|
|
88
|
+
- Faz A
|
|
89
|
+
- Remove B
|
|
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
|
+
## Relatórios por domínio
|
|
109
|
+
|
|
110
|
+
| Watchdog | Achados | Revisados | Relatório |
|
|
111
|
+
|---|---|---|---|
|
|
112
|
+
| Alpha | 2 | 2/2 | [\`review.alpha.md\`](review.alpha.md) |
|
|
113
|
+
|
|
114
|
+
## Cobertura
|
|
115
|
+
|
|
116
|
+
| Watchdog | Arquivos revisados | Findings |
|
|
117
|
+
|---|---|---|
|
|
118
|
+
| Alpha | 2 | 2 |
|
|
119
|
+
| Beta | 1 | 0 |
|
|
120
|
+
|
|
121
|
+
## Conclusão
|
|
122
|
+
|
|
123
|
+
**Status:** ❌ Mudanças Necessárias
|
|
124
|
+
**Resumo:** 1 violações bloqueantes, 1 pontos de atenção, 0 sugestões e 0 nits."
|
|
125
|
+
`;
|
|
126
|
+
|
|
127
|
+
exports[`baseline — relatório renderDomainReport isolado 1`] = `
|
|
128
|
+
"# Review — Alpha (\`alpha\`) — feature/x
|
|
129
|
+
|
|
130
|
+
**Data:** <date>
|
|
131
|
+
**Arquivos revisados:** 2/2
|
|
132
|
+
**Achados:** 2
|
|
133
|
+
|
|
134
|
+
## Contexto da PR
|
|
135
|
+
|
|
136
|
+
**PR:** #42 Entrega X — https://example.test/pull/42
|
|
137
|
+
**Branch:** \`feature/x\` → \`main\`
|
|
138
|
+
**Objetivo:** Entregar X
|
|
139
|
+
**Motivação:** Reduzir Y
|
|
140
|
+
|
|
141
|
+
**Resumo das alterações:**
|
|
142
|
+
|
|
143
|
+
- Faz A
|
|
144
|
+
- Remove B
|
|
145
|
+
|
|
146
|
+
## ❌ blocking
|
|
147
|
+
|
|
148
|
+
### \`src/alpha/a.ts\`
|
|
149
|
+
|
|
150
|
+
- **Nunca usar \`any\`.** — \`src/alpha/a.ts:1\` · _Alpha_ · \`id-alpha\`
|
|
151
|
+
any detectado
|
|
152
|
+
**Ação:** tipar
|
|
153
|
+
**Evidência:** \`export const a: any = 1;\`
|
|
154
|
+
|
|
155
|
+
## ⚠️ attention
|
|
156
|
+
|
|
157
|
+
### \`src/alpha/b.ts\`
|
|
158
|
+
|
|
159
|
+
- **Promover: validar a entrada.** — \`src/alpha/b.ts:2\` · _Alpha, Beta_ · \`id-beta\`
|
|
160
|
+
sem validação
|
|
161
|
+
**Ação:** adicionar schema
|
|
162
|
+
|
|
163
|
+
## Não revisados
|
|
164
|
+
|
|
165
|
+
- \`src/alpha/c.ts\`
|
|
166
|
+
"
|
|
167
|
+
`;
|
|
168
|
+
|
|
169
|
+
exports[`baseline — camada gerada setup gera os mesmos arquivos e conteúdos 1`] = `
|
|
170
|
+
[
|
|
171
|
+
".agents/skills/houndsman/SKILL.md",
|
|
172
|
+
".claude/skills/houndsman/SKILL.md",
|
|
173
|
+
".houndsman/.gitignore",
|
|
174
|
+
".houndsman/core/skill/AUDIT-PROTOCOL.md",
|
|
175
|
+
".houndsman/core/skill/OUTPUT-FORMAT.md",
|
|
176
|
+
".houndsman/core/skill/README.md",
|
|
177
|
+
".houndsman/core/skill/SETUP.md",
|
|
178
|
+
".houndsman/core/skill/example-review.md",
|
|
179
|
+
".houndsman/core/skill/fix.md",
|
|
180
|
+
".houndsman/core/skill/hunt.md",
|
|
181
|
+
".houndsman/core/skill/train.md",
|
|
182
|
+
".houndsman/core/skill/verify.md",
|
|
183
|
+
".houndsman/core/types.ts",
|
|
184
|
+
".houndsman/doc-mappings.ts",
|
|
185
|
+
".houndsman/exclusions.ts",
|
|
186
|
+
".houndsman/watchdogs/example.ts",
|
|
187
|
+
".houndsman/watchdogs/index.ts",
|
|
188
|
+
"houndsman.config.ts",
|
|
189
|
+
]
|
|
190
|
+
`;
|
|
191
|
+
|
|
192
|
+
exports[`baseline — camada gerada setup gera os mesmos arquivos e conteúdos 2`] = `
|
|
193
|
+
{
|
|
194
|
+
".agents/skills/houndsman/SKILL.md":
|
|
195
|
+
"---
|
|
196
|
+
name: houndsman
|
|
197
|
+
description: 'Revisa Pull Requests com watchdogs especializados por domínio de negócio e mantém essas regras alinhadas ao projeto. Use para revisar/code review de PR, atualizar as regras de revisão dos watchdogs e corrigir/verificar os findings da revisão. Capabilities: \`hunt\` (revisar a PR), \`train\` (atualizar regras), \`fix\` (corrigir achados), \`verify\` (violações resolvidas?).'
|
|
198
|
+
argument-hint: 'Capability: hunt | train | fix | verify (default: hunt)'
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
# houndsman — acme
|
|
202
|
+
|
|
203
|
+
O **houndsman** revisa Pull Requests com **watchdogs** — agentes especialistas por domínio de
|
|
204
|
+
negócio. Cada watchdog audita a parte do diff que é sua e grava **findings** (achados); o motor
|
|
205
|
+
consolida tudo num relatório. O motor é o CLI **\`houndsman\`**; as regras do projeto vivem em
|
|
206
|
+
\`houndsman.config.ts\` + \`.houndsman/\`.
|
|
207
|
+
|
|
208
|
+
**Terminologia:** **houndsman** = orquestrador/treinador (CLI + motor) · **watchdog** = agente
|
|
209
|
+
especialista por domínio · **finding** = um achado da revisão · **Jev** = pré-análise opcional.
|
|
210
|
+
|
|
211
|
+
## Capabilities
|
|
212
|
+
|
|
213
|
+
| Capability | Objetivo | Documento |
|
|
214
|
+
|---|---|---|
|
|
215
|
+
| **\`hunt\`** | Revisar uma Pull Request e produzir o relatório de achados. | \`.houndsman/core/skill/hunt.md\` |
|
|
216
|
+
| **\`train\`** | Manter as regras dos watchdogs alinhadas ao que o projeto aplica. | \`.houndsman/core/skill/train.md\` |
|
|
217
|
+
| **\`fix\`** | Corrigir os achados de uma revisão já finalizada. | \`.houndsman/core/skill/fix.md\` |
|
|
218
|
+
| **\`verify\`** | Conferir se as violações foram resolvidas, sem re-revisar a PR. | \`.houndsman/core/skill/verify.md\` |
|
|
219
|
+
|
|
220
|
+
## Invocação
|
|
221
|
+
|
|
222
|
+
\`\`\`
|
|
223
|
+
/houndsman → hunt (default)
|
|
224
|
+
/houndsman hunt → revisar a Pull Request
|
|
225
|
+
/houndsman train → atualizar as regras dos watchdogs
|
|
226
|
+
/houndsman fix → corrigir os findings
|
|
227
|
+
/houndsman verify → conferir se as violações foram resolvidas
|
|
228
|
+
\`\`\`
|
|
229
|
+
|
|
230
|
+
Um argumento extra é o alvo da capability (ex.: \`/houndsman hunt feature/minha-branch\`).
|
|
231
|
+
Escolha a capability pelo que o usuário quer, leia o documento correspondente em
|
|
232
|
+
\`.houndsman/core/skill/<capability>.md\` e siga-o.
|
|
233
|
+
|
|
234
|
+
> **Depois de revisar (\`hunt\`), valide na UI:** \`bun run houndsman server --open\` — revise os
|
|
235
|
+
> achados e marque os que devem ser executados (\`execute\`) antes de rodar \`fix\`.
|
|
236
|
+
|
|
237
|
+
## Referências
|
|
238
|
+
|
|
239
|
+
- \`.houndsman/core/skill/OUTPUT-FORMAT.md\` — schema do JSON de saída dos watchdogs.
|
|
240
|
+
- \`.houndsman/core/skill/AUDIT-PROTOCOL.md\` — taxonomia da auditoria de regras (Modo B do \`train\`).
|
|
241
|
+
- \`.houndsman/core/skill/SETUP.md\` · \`.houndsman/core/skill/README.md\` — configuração e visão geral.
|
|
242
|
+
- \`.houndsman/core/skill/example-review.md\` — exemplo de relatório.
|
|
243
|
+
"
|
|
244
|
+
,
|
|
245
|
+
".claude/skills/houndsman/SKILL.md":
|
|
246
|
+
"---
|
|
247
|
+
name: houndsman
|
|
248
|
+
description: 'Revisa Pull Requests com watchdogs especializados por domínio de negócio e mantém essas regras alinhadas ao projeto. Use para revisar/code review de PR, atualizar as regras de revisão dos watchdogs e corrigir/verificar os findings da revisão. Capabilities: \`hunt\` (revisar a PR), \`train\` (atualizar regras), \`fix\` (corrigir achados), \`verify\` (violações resolvidas?).'
|
|
249
|
+
argument-hint: 'Capability: hunt | train | fix | verify (default: hunt)'
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
# houndsman — acme
|
|
253
|
+
|
|
254
|
+
O **houndsman** revisa Pull Requests com **watchdogs** — agentes especialistas por domínio de
|
|
255
|
+
negócio. Cada watchdog audita a parte do diff que é sua e grava **findings** (achados); o motor
|
|
256
|
+
consolida tudo num relatório. O motor é o CLI **\`houndsman\`**; as regras do projeto vivem em
|
|
257
|
+
\`houndsman.config.ts\` + \`.houndsman/\`.
|
|
258
|
+
|
|
259
|
+
**Terminologia:** **houndsman** = orquestrador/treinador (CLI + motor) · **watchdog** = agente
|
|
260
|
+
especialista por domínio · **finding** = um achado da revisão · **Jev** = pré-análise opcional.
|
|
261
|
+
|
|
262
|
+
## Capabilities
|
|
263
|
+
|
|
264
|
+
| Capability | Objetivo | Documento |
|
|
265
|
+
|---|---|---|
|
|
266
|
+
| **\`hunt\`** | Revisar uma Pull Request e produzir o relatório de achados. | \`.houndsman/core/skill/hunt.md\` |
|
|
267
|
+
| **\`train\`** | Manter as regras dos watchdogs alinhadas ao que o projeto aplica. | \`.houndsman/core/skill/train.md\` |
|
|
268
|
+
| **\`fix\`** | Corrigir os achados de uma revisão já finalizada. | \`.houndsman/core/skill/fix.md\` |
|
|
269
|
+
| **\`verify\`** | Conferir se as violações foram resolvidas, sem re-revisar a PR. | \`.houndsman/core/skill/verify.md\` |
|
|
270
|
+
|
|
271
|
+
## Invocação
|
|
272
|
+
|
|
273
|
+
\`\`\`
|
|
274
|
+
/houndsman → hunt (default)
|
|
275
|
+
/houndsman hunt → revisar a Pull Request
|
|
276
|
+
/houndsman train → atualizar as regras dos watchdogs
|
|
277
|
+
/houndsman fix → corrigir os findings
|
|
278
|
+
/houndsman verify → conferir se as violações foram resolvidas
|
|
279
|
+
\`\`\`
|
|
280
|
+
|
|
281
|
+
Um argumento extra é o alvo da capability (ex.: \`/houndsman hunt feature/minha-branch\`).
|
|
282
|
+
Escolha a capability pelo que o usuário quer, leia o documento correspondente em
|
|
283
|
+
\`.houndsman/core/skill/<capability>.md\` e siga-o.
|
|
284
|
+
|
|
285
|
+
> **Depois de revisar (\`hunt\`), valide na UI:** \`bun run houndsman server --open\` — revise os
|
|
286
|
+
> achados e marque os que devem ser executados (\`execute\`) antes de rodar \`fix\`.
|
|
287
|
+
|
|
288
|
+
## Referências
|
|
289
|
+
|
|
290
|
+
- \`.houndsman/core/skill/OUTPUT-FORMAT.md\` — schema do JSON de saída dos watchdogs.
|
|
291
|
+
- \`.houndsman/core/skill/AUDIT-PROTOCOL.md\` — taxonomia da auditoria de regras (Modo B do \`train\`).
|
|
292
|
+
- \`.houndsman/core/skill/SETUP.md\` · \`.houndsman/core/skill/README.md\` — configuração e visão geral.
|
|
293
|
+
- \`.houndsman/core/skill/example-review.md\` — exemplo de relatório.
|
|
294
|
+
"
|
|
295
|
+
,
|
|
296
|
+
".houndsman/.gitignore":
|
|
297
|
+
"# Diretórios gerados pelo houndsman — \`core/\` é regenerado por \`houndsman update\`
|
|
298
|
+
# e \`.runs/\` guarda os artefatos de revisão.
|
|
299
|
+
core/
|
|
300
|
+
.runs/
|
|
301
|
+
"
|
|
302
|
+
,
|
|
303
|
+
".houndsman/core/types.ts":
|
|
304
|
+
"/**
|
|
305
|
+
* Tipos e helpers locais do houndsman (GERADO — não edite).
|
|
306
|
+
*
|
|
307
|
+
* Snapshot do contrato público, para tipar a camada de projeto sem depender de um
|
|
308
|
+
* install local do pacote. Sincronize com \`houndsman update\`.
|
|
309
|
+
*/
|
|
310
|
+
|
|
311
|
+
export type Severity = "blocking" | "attention" | "suggestion" | "nit";
|
|
312
|
+
|
|
313
|
+
/** Tipo de pergunta aceito pela API Jev. */
|
|
314
|
+
export type JevQuestionType = "noul" | "choice" | "score";
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Spec de pré-análise Jev (opcional) — sempre um objeto; \`kind\` é obrigatório.
|
|
318
|
+
* \`criteria\`: objeto para \`choice\`, lista para \`score\`.
|
|
319
|
+
*/
|
|
320
|
+
export type JevRuleSpec = {
|
|
321
|
+
kind: JevQuestionType;
|
|
322
|
+
instructions?: string;
|
|
323
|
+
criteria?: string[] | Record<string, string>;
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
/** Regra do watchdog: severidade + texto — o texto declara a polaridade
|
|
327
|
+
* (\`Promover:\` = deve acontecer; \`Evitar:\`/\`Não\`/\`Nunca\` = não deve acontecer). */
|
|
328
|
+
export type Rule = {
|
|
329
|
+
severity: Severity;
|
|
330
|
+
text: string;
|
|
331
|
+
jev?: JevRuleSpec;
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
/** Como o watchdog casa um arquivo alterado. \`value\` é sempre regex. */
|
|
335
|
+
export type ClassifyRule = {
|
|
336
|
+
type?: "filename" | "content";
|
|
337
|
+
value: string;
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
export type WatchdogMeta = {
|
|
341
|
+
name: string;
|
|
342
|
+
scope: string;
|
|
343
|
+
classify?: readonly ClassifyRule[];
|
|
344
|
+
rules: readonly Rule[];
|
|
345
|
+
contextFiles: string[];
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
/** Definição completa de um watchdog — 1 por arquivo em \`.houndsman/watchdogs/\`. */
|
|
349
|
+
export type WatchdogDefinition = WatchdogMeta & {
|
|
350
|
+
id: string;
|
|
351
|
+
description: string;
|
|
352
|
+
breakingChange?: boolean;
|
|
353
|
+
reviewFocus?: readonly string[];
|
|
354
|
+
exclude?: readonly string[];
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
export type FileStatus =
|
|
358
|
+
| "added"
|
|
359
|
+
| "modified"
|
|
360
|
+
| "deleted"
|
|
361
|
+
| "renamed"
|
|
362
|
+
| "copied"
|
|
363
|
+
| "unknown";
|
|
364
|
+
|
|
365
|
+
export type FileStatusMap = Record<string, { status: FileStatus; oldPath?: string }>;
|
|
366
|
+
|
|
367
|
+
/** Linhas adicionadas/removidas de um arquivo no diff (churn). */
|
|
368
|
+
export type FileChurn = { additions: number; deletions: number };
|
|
369
|
+
|
|
370
|
+
/** Churn por caminho de arquivo. */
|
|
371
|
+
export type ChurnMap = Record<string, FileChurn>;
|
|
372
|
+
|
|
373
|
+
/** Limites de triage para PRs grandes. */
|
|
374
|
+
export type HoundsmanBudgets = {
|
|
375
|
+
/** Máx. de arquivos por brief (default: 40). Excedente vai para "fora do orçamento". */
|
|
376
|
+
maxFilesPerBrief?: number;
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
/** Concorrência das fases paralelas internas. */
|
|
380
|
+
export type HoundsmanConcurrency = {
|
|
381
|
+
/** Chamadas Jev simultâneas (default: 5). */
|
|
382
|
+
jev?: number;
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
/** Contrato de configuração do motor. */
|
|
386
|
+
export type HoundsmanConfig<TId extends string = string> = {
|
|
387
|
+
projectName: string;
|
|
388
|
+
artifactDir?: string;
|
|
389
|
+
watchdogIds?: readonly TId[];
|
|
390
|
+
watchdogs: Record<TId, WatchdogDefinition>;
|
|
391
|
+
exclusions: readonly RegExp[];
|
|
392
|
+
docMappings: readonly (readonly [RegExp, readonly string[]])[];
|
|
393
|
+
alwaysIncludeDocs?: readonly string[];
|
|
394
|
+
budgets?: HoundsmanBudgets;
|
|
395
|
+
concurrency?: HoundsmanConcurrency;
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
/** Helper de autoria (identidade) — apenas tipagem. */
|
|
399
|
+
export function defineWatchdog(definition: WatchdogDefinition): WatchdogDefinition {
|
|
400
|
+
return definition;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/** Helper de autoria — deriva \`watchdogIds\` das chaves de \`watchdogs\`. */
|
|
404
|
+
export function defineHoundsmanConfig<TId extends string>(
|
|
405
|
+
input: Omit<HoundsmanConfig<TId>, "watchdogIds">,
|
|
406
|
+
): HoundsmanConfig<TId> {
|
|
407
|
+
return { ...input, watchdogIds: Object.keys(input.watchdogs) as TId[] };
|
|
408
|
+
}
|
|
409
|
+
"
|
|
410
|
+
,
|
|
411
|
+
".houndsman/doc-mappings.ts":
|
|
412
|
+
"/**
|
|
413
|
+
* Mapeamento de padrões nos paths → documentação relevante.
|
|
414
|
+
* Consumido pelo motor via \`HoundsmanConfig.docMappings\`.
|
|
415
|
+
*/
|
|
416
|
+
export const DOC_MAPPINGS: readonly (readonly [RegExp, readonly string[]])[] = [
|
|
417
|
+
[/^src\\//, ["AGENTS.md"]],
|
|
418
|
+
];
|
|
419
|
+
"
|
|
420
|
+
,
|
|
421
|
+
".houndsman/exclusions.ts":
|
|
422
|
+
"/** Arquivos que nunca entram na revisão — gerados, locks, builds. */
|
|
423
|
+
export const EXCLUSION_PATTERNS: readonly RegExp[] = [
|
|
424
|
+
/bun\\.lockb?$/,
|
|
425
|
+
/^package-lock\\.json$/,
|
|
426
|
+
/^dist\\//,
|
|
427
|
+
/^build\\//,
|
|
428
|
+
];
|
|
429
|
+
|
|
430
|
+
/** \`true\` se o caminho é excluído da revisão. */
|
|
431
|
+
export function isExcluded(filePath: string): boolean {
|
|
432
|
+
return EXCLUSION_PATTERNS.some((pattern) => pattern.test(filePath));
|
|
433
|
+
}
|
|
434
|
+
"
|
|
435
|
+
,
|
|
436
|
+
".houndsman/watchdogs/example.ts":
|
|
437
|
+
"import { defineWatchdog } from "../core/types";
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Watchdog de exemplo — substitua pelas regras reais do projeto.
|
|
441
|
+
* Um watchdog declara seus arquivos via \`classify\` (regex de path ou conteúdo).
|
|
442
|
+
* O texto de cada regra começa com a polaridade: \`Promover:\` (DEVE acontecer)
|
|
443
|
+
* ou \`Evitar:\`/\`Não\`/\`Nunca\` (NÃO DEVE acontecer).
|
|
444
|
+
*/
|
|
445
|
+
export const exampleWatchdog = defineWatchdog({
|
|
446
|
+
id: "example",
|
|
447
|
+
name: "Exemplo",
|
|
448
|
+
description: "Watchdog de exemplo — descreva o propósito em uma frase.",
|
|
449
|
+
scope: "Todo o repositório (ajuste o escopo)",
|
|
450
|
+
classify: [{ value: "^src/" }],
|
|
451
|
+
rules: [
|
|
452
|
+
{
|
|
453
|
+
severity: "attention",
|
|
454
|
+
text: "Promover: descreva aqui um padrão do projeto (algo que DEVE acontecer).",
|
|
455
|
+
jev: { kind: "noul" },
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
severity: "nit",
|
|
459
|
+
text: "Evitar: descreva aqui um anti-padrão (algo que NÃO DEVE acontecer).",
|
|
460
|
+
},
|
|
461
|
+
],
|
|
462
|
+
contextFiles: ["AGENTS.md"],
|
|
463
|
+
});
|
|
464
|
+
"
|
|
465
|
+
,
|
|
466
|
+
".houndsman/watchdogs/index.ts":
|
|
467
|
+
"import { exampleWatchdog } from "./example";
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Definições dos watchdogs — as chaves definem o union \`WatchdogId\`.
|
|
471
|
+
* Adicionar um watchdog = criar \`<id>.ts\` e registrá-lo aqui.
|
|
472
|
+
*/
|
|
473
|
+
export const WATCHDOG_DEFINITIONS = {
|
|
474
|
+
example: exampleWatchdog,
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
export type WatchdogId = keyof typeof WATCHDOG_DEFINITIONS;
|
|
478
|
+
"
|
|
479
|
+
,
|
|
480
|
+
"houndsman.config.ts":
|
|
481
|
+
"import { DOC_MAPPINGS } from "./.houndsman/doc-mappings";
|
|
482
|
+
import { EXCLUSION_PATTERNS } from "./.houndsman/exclusions";
|
|
483
|
+
import { WATCHDOG_DEFINITIONS } from "./.houndsman/watchdogs";
|
|
484
|
+
import type { HoundsmanConfig } from "./.houndsman/core/types";
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Configuração do houndsman para acme.
|
|
488
|
+
*
|
|
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.
|
|
492
|
+
*/
|
|
493
|
+
export const houndsmanConfig = {
|
|
494
|
+
projectName: "acme",
|
|
495
|
+
watchdogs: WATCHDOG_DEFINITIONS,
|
|
496
|
+
exclusions: EXCLUSION_PATTERNS,
|
|
497
|
+
docMappings: DOC_MAPPINGS,
|
|
498
|
+
} satisfies HoundsmanConfig;
|
|
499
|
+
|
|
500
|
+
export default houndsmanConfig;
|
|
501
|
+
"
|
|
502
|
+
,
|
|
503
|
+
}
|
|
504
|
+
`;
|
|
505
|
+
|
|
506
|
+
exports[`baseline — camada gerada setup gera os mesmos arquivos e conteúdos 3`] = `
|
|
507
|
+
[
|
|
508
|
+
{
|
|
509
|
+
"file": ".houndsman/core/skill/AUDIT-PROTOCOL.md",
|
|
510
|
+
"sha256": "190bc9f6417f54d0",
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
"file": ".houndsman/core/skill/OUTPUT-FORMAT.md",
|
|
514
|
+
"sha256": "3c6f261de0ca6d31",
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
"file": ".houndsman/core/skill/README.md",
|
|
518
|
+
"sha256": "7cc26ec5e1917a62",
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
"file": ".houndsman/core/skill/SETUP.md",
|
|
522
|
+
"sha256": "5d6a4b56b1033970",
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
"file": ".houndsman/core/skill/example-review.md",
|
|
526
|
+
"sha256": "a2627e99ac5caead",
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
"file": ".houndsman/core/skill/fix.md",
|
|
530
|
+
"sha256": "f16c0383ad1767fb",
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
"file": ".houndsman/core/skill/hunt.md",
|
|
534
|
+
"sha256": "7e7d7e5535381b9b",
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
"file": ".houndsman/core/skill/train.md",
|
|
538
|
+
"sha256": "564a1fd38d8e4836",
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
"file": ".houndsman/core/skill/verify.md",
|
|
542
|
+
"sha256": "f8fcf8e12b142482",
|
|
543
|
+
},
|
|
544
|
+
]
|
|
545
|
+
`;
|
|
546
|
+
|
|
547
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, review e state 1`] = `
|
|
548
|
+
"Discovery: 1 watchdog(s) ativado(s), 3 arquivo(s), 1 deletado(s).
|
|
549
|
+
Briefs: .houndsman/.runs/main/briefs/
|
|
550
|
+
Deletado (breaking change): src/alpha/old.ts
|
|
551
|
+
Jev: pulado (desativado (--no-jev)).
|
|
552
|
+
Sem contexto da PR (rode \`bun run houndsman context\` antes, se houver PR).
|
|
553
|
+
|
|
554
|
+
Próximo passo: despachar os sub-agentes (um por brief em .houndsman/.runs/main/briefs/).
|
|
555
|
+
Quando os findings estiverem gravados: bun run houndsman --finalize"
|
|
556
|
+
`;
|
|
557
|
+
|
|
558
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, review e state: classification.json 1`] = `
|
|
559
|
+
"{
|
|
560
|
+
"watchdogs": {
|
|
561
|
+
"alpha": [
|
|
562
|
+
"src/alpha/a.ts",
|
|
563
|
+
"src/alpha/b.ts"
|
|
564
|
+
]
|
|
565
|
+
},
|
|
566
|
+
"files": {
|
|
567
|
+
"src/alpha/a.ts": {
|
|
568
|
+
"status": "modified"
|
|
569
|
+
},
|
|
570
|
+
"src/alpha/b.ts": {
|
|
571
|
+
"status": "added"
|
|
572
|
+
},
|
|
573
|
+
"src/alpha/old.ts": {
|
|
574
|
+
"status": "deleted"
|
|
575
|
+
}
|
|
576
|
+
},
|
|
577
|
+
"churn": {
|
|
578
|
+
"src/alpha/a.ts": {
|
|
579
|
+
"additions": 2,
|
|
580
|
+
"deletions": 1
|
|
581
|
+
},
|
|
582
|
+
"src/alpha/b.ts": {
|
|
583
|
+
"additions": 1,
|
|
584
|
+
"deletions": 0
|
|
585
|
+
},
|
|
586
|
+
"src/alpha/old.ts": {
|
|
587
|
+
"additions": 0,
|
|
588
|
+
"deletions": 1
|
|
589
|
+
}
|
|
590
|
+
},
|
|
591
|
+
"unclassified": [],
|
|
592
|
+
"excluded": [],
|
|
593
|
+
"deleted": [
|
|
594
|
+
"src/alpha/old.ts"
|
|
595
|
+
],
|
|
596
|
+
"stats": {
|
|
597
|
+
"alpha": 2
|
|
598
|
+
},
|
|
599
|
+
"excludedCount": 0,
|
|
600
|
+
"base": "<sha>",
|
|
601
|
+
"head": "HEAD",
|
|
602
|
+
"headSha": "<sha>",
|
|
603
|
+
"mode": "full"
|
|
604
|
+
}
|
|
605
|
+
"
|
|
606
|
+
`;
|
|
607
|
+
|
|
608
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, review e state: manifest.json 1`] = `
|
|
609
|
+
"{
|
|
610
|
+
"branch": "main",
|
|
611
|
+
"slug": "main",
|
|
612
|
+
"base": "<sha>",
|
|
613
|
+
"head": "HEAD",
|
|
614
|
+
"headSha": "<sha>",
|
|
615
|
+
"generatedAt": "<timestamp>",
|
|
616
|
+
"outputFormat": ".houndsman/core/skill/OUTPUT-FORMAT.md",
|
|
617
|
+
"budget": {
|
|
618
|
+
"maxFilesPerBrief": 40,
|
|
619
|
+
"filesOverBudget": 0
|
|
620
|
+
},
|
|
621
|
+
"churn": {
|
|
622
|
+
"additions": 3,
|
|
623
|
+
"deletions": 2
|
|
624
|
+
},
|
|
625
|
+
"watchdogs": [
|
|
626
|
+
{
|
|
627
|
+
"id": "alpha",
|
|
628
|
+
"name": "Alpha",
|
|
629
|
+
"files": [
|
|
630
|
+
"src/alpha/a.ts",
|
|
631
|
+
"src/alpha/b.ts"
|
|
632
|
+
],
|
|
633
|
+
"overflow": 0,
|
|
634
|
+
"brief": ".houndsman/.runs/main/briefs/alpha.md",
|
|
635
|
+
"findings": ".houndsman/.runs/main/findings/alpha.json",
|
|
636
|
+
"status": "pending"
|
|
637
|
+
}
|
|
638
|
+
],
|
|
639
|
+
"context": {
|
|
640
|
+
"summarized": false,
|
|
641
|
+
"source": null
|
|
642
|
+
},
|
|
643
|
+
"jev": {
|
|
644
|
+
"available": false,
|
|
645
|
+
"reason": "desativado (--no-jev)"
|
|
646
|
+
},
|
|
647
|
+
"deleted": [
|
|
648
|
+
"src/alpha/old.ts"
|
|
649
|
+
],
|
|
650
|
+
"unclassified": [],
|
|
651
|
+
"excludedCount": 0
|
|
652
|
+
}
|
|
653
|
+
"
|
|
654
|
+
`;
|
|
655
|
+
|
|
656
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, review e state: briefs/alpha.md 1`] = `
|
|
657
|
+
"# Brief — Alpha (\`alpha\`)
|
|
658
|
+
|
|
659
|
+
**Branch:** main
|
|
660
|
+
**Output obrigatório:** \`.houndsman/.runs/main/findings/alpha.json\`
|
|
661
|
+
**Schema do output:** \`.houndsman/core/skill/OUTPUT-FORMAT.md\`
|
|
662
|
+
|
|
663
|
+
## Objetivo
|
|
664
|
+
|
|
665
|
+
Watchdog baseline.
|
|
666
|
+
|
|
667
|
+
## Escopo
|
|
668
|
+
|
|
669
|
+
src/alpha/**
|
|
670
|
+
|
|
671
|
+
## Regras (por severidade)
|
|
672
|
+
|
|
673
|
+
- ❌ **blocking** — Nunca usar \`any\`.
|
|
674
|
+
- ⚠️ **attention** — Promover: validar a entrada.
|
|
675
|
+
|
|
676
|
+
## Docs de contexto (carregar sob demanda)
|
|
677
|
+
|
|
678
|
+
- \`README.md\`
|
|
679
|
+
|
|
680
|
+
## Arquivos do seu domínio (2)
|
|
681
|
+
|
|
682
|
+
- \`src/alpha/a.ts\` (modified, +2/−1)
|
|
683
|
+
- \`src/alpha/b.ts\` (added, +1/−0)
|
|
684
|
+
|
|
685
|
+
## Deletados — checar breaking change
|
|
686
|
+
|
|
687
|
+
- \`src/alpha/old.ts\`
|
|
688
|
+
|
|
689
|
+
## Procedimento
|
|
690
|
+
|
|
691
|
+
1. **FILTER** — descarte o que não for do seu domínio (ver *Prioridade de leitura* e *Não carregar*).
|
|
692
|
+
2. **READ HEAD** — leia os arquivos seletivamente (primeiras ~30 linhas). NUNCA o diff completo.
|
|
693
|
+
3. **GREP** — use as regras críticas/anti-padrões como heurística para localizar violações.
|
|
694
|
+
4. **DEEP-READ** — aprofunde apenas os arquivos com suspeita de violação.
|
|
695
|
+
5. **CONCLUDE** — grave o JSON no caminho de output, com \`reviewedFiles\` preenchido. Sem achados → \`"findings": []\` (arquivo obrigatório). Não escreva markdown livre.
|
|
696
|
+
"
|
|
697
|
+
`;
|
|
698
|
+
|
|
699
|
+
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."
|
|
702
|
+
`;
|
|
703
|
+
|
|
704
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, review e state: review.md 1`] = `
|
|
705
|
+
"# PR Review — main
|
|
706
|
+
|
|
707
|
+
**Data:** <date>
|
|
708
|
+
**Watchdogs ativos:** alpha
|
|
709
|
+
**Achados:** 1 bloqueantes · 0 atenção · 0 sugestões · 0 nits
|
|
710
|
+
|
|
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
|
+
## Relatórios por domínio
|
|
721
|
+
|
|
722
|
+
| Watchdog | Achados | Revisados | Relatório |
|
|
723
|
+
|---|---|---|---|
|
|
724
|
+
| Alpha | 1 | 2/2 | [\`review.alpha.md\`](review.alpha.md) |
|
|
725
|
+
|
|
726
|
+
## Cobertura
|
|
727
|
+
|
|
728
|
+
| Watchdog | Arquivos revisados | Findings |
|
|
729
|
+
|---|---|---|
|
|
730
|
+
| Alpha | 2 | 1 |
|
|
731
|
+
|
|
732
|
+
## Conclusão
|
|
733
|
+
|
|
734
|
+
**Status:** ❌ Mudanças Necessárias
|
|
735
|
+
**Resumo:** 1 violações bloqueantes, 0 pontos de atenção, 0 sugestões e 0 nits.
|
|
736
|
+
"
|
|
737
|
+
`;
|
|
738
|
+
|
|
739
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, review e state: review.alpha.md 1`] = `
|
|
740
|
+
"# Review — Alpha (\`alpha\`) — main
|
|
741
|
+
|
|
742
|
+
**Data:** <date>
|
|
743
|
+
**Arquivos revisados:** 2/2
|
|
744
|
+
**Achados:** 1
|
|
745
|
+
|
|
746
|
+
## ❌ blocking
|
|
747
|
+
|
|
748
|
+
### \`src/alpha/a.ts\`
|
|
749
|
+
|
|
750
|
+
- **Nunca usar \`any\`.** — \`src/alpha/a.ts:1\` · _Alpha_
|
|
751
|
+
any detectado
|
|
752
|
+
**Ação:** tipar
|
|
753
|
+
**Evidência:** \`export const a: any = 1;\`
|
|
754
|
+
|
|
755
|
+
"
|
|
756
|
+
`;
|
|
757
|
+
|
|
758
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, review e state: state.json 1`] = `
|
|
759
|
+
"{
|
|
760
|
+
"version": 2,
|
|
761
|
+
"branch": "main",
|
|
762
|
+
"slug": "main",
|
|
763
|
+
"updatedAt": "<timestamp>",
|
|
764
|
+
"order": [
|
|
765
|
+
"<id>"
|
|
766
|
+
],
|
|
767
|
+
"reviewed": {
|
|
768
|
+
"headSha": "<sha>",
|
|
769
|
+
"at": "<timestamp>"
|
|
770
|
+
},
|
|
771
|
+
"findings": {
|
|
772
|
+
"<id>": {
|
|
773
|
+
"id": "<id>",
|
|
774
|
+
"fingerprint": "<fingerprint>",
|
|
775
|
+
"watchdogIds": [
|
|
776
|
+
"alpha"
|
|
777
|
+
],
|
|
778
|
+
"rule": "Nunca usar \`any\`.",
|
|
779
|
+
"severity": "blocking",
|
|
780
|
+
"file": "src/alpha/a.ts",
|
|
781
|
+
"line": 1,
|
|
782
|
+
"message": "any detectado",
|
|
783
|
+
"action": "tipar",
|
|
784
|
+
"evidence": "export const a: any = 1;",
|
|
785
|
+
"anchor": {
|
|
786
|
+
"snippet": "export const a: any = 1;",
|
|
787
|
+
"line": 1,
|
|
788
|
+
"contextAfter": "export const b = 2;"
|
|
789
|
+
},
|
|
790
|
+
"foundAtSha": "<sha>",
|
|
791
|
+
"count": 1,
|
|
792
|
+
"present": true,
|
|
793
|
+
"decision": "pending",
|
|
794
|
+
"execState": "pending",
|
|
795
|
+
"createdAt": "<timestamp>",
|
|
796
|
+
"updatedAt": "<timestamp>",
|
|
797
|
+
"history": []
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
"
|
|
802
|
+
`;
|
|
803
|
+
|
|
804
|
+
exports[`baseline — artefatos de prepare/finalize gera classification, brief, manifest, review e state: run.json 1`] = `
|
|
805
|
+
"{
|
|
806
|
+
"version": 1,
|
|
807
|
+
"slug": "main",
|
|
808
|
+
"branch": "main",
|
|
809
|
+
"status": "review_done",
|
|
810
|
+
"startedAt": "<timestamp>",
|
|
811
|
+
"updatedAt": "<timestamp>"
|
|
812
|
+
}
|
|
813
|
+
"
|
|
814
|
+
`;
|