product-runner 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.
- package/README.md +165 -0
- package/common/agents/README.md +68 -0
- package/common/agents/agente-conceituacao.md +141 -0
- package/common/agents/agente-documentacao-funcional.md +107 -0
- package/common/agents/agente-gerador-spec.md +106 -0
- package/common/agents/agente-kickoff.md +121 -0
- package/common/agents/agente-prod-runner.md +107 -0
- package/common/agents/agente-review-code.md +97 -0
- package/common/agents/agente-review-llm.md +94 -0
- package/common/agents/agente-review-product.md +98 -0
- package/common/agents/agente-user-review.md +99 -0
- package/common/agents/protocolo-de-gates.md +51 -0
- package/common/claude-md.template.md +210 -0
- package/common/design-principles.md +229 -0
- package/common/lessons-learned.md +440 -0
- package/common/pipeline.md +143 -0
- package/common/spec-guide.md +327 -0
- package/common/specs/_open-issues.md +46 -0
- package/common/specs/_overview.md +75 -0
- package/dist/cli.js +187 -0
- package/dist/migrations.js +147 -0
- package/dist/scaffold.js +276 -0
- package/dist/update.js +400 -0
- package/migrations/0.3.0.md +54 -0
- package/migrations/0.4.0.md +76 -0
- package/migrations/0.5.0.md +55 -0
- package/migrations/README.md +68 -0
- package/package.json +41 -0
- package/profile-cli/README.md +54 -0
- package/profile-cli/claude-md.extension.md +102 -0
- package/profile-cli/code-patterns.md +363 -0
- package/profile-ssr/DESIGN-SYSTEM.md +795 -0
- package/profile-ssr/README.md +51 -0
- package/profile-ssr/api-patterns.md +70 -0
- package/profile-ssr/claude-md.extension.md +113 -0
- package/profile-ssr/code-patterns.md +175 -0
- package/profile-ssr/ui-patterns.md +97 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Protocolo de Gates
|
|
2
|
+
|
|
3
|
+
> Regras de gate e de calibragem por stakes, **comuns a todos os agentes do pipeline**. Cada agente referencia este arquivo em vez de redefinir as regras localmente — fonte de verdade única, sem drift entre agentes. Mantenha este arquivo na mesma pasta dos agentes.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Por que este arquivo existe
|
|
8
|
+
|
|
9
|
+
Os agentes erravam o mesmo ponto: **declaravam rigor de gate e depois cediam a um "ok" genérico em ponto de alto risco.** Regra em prosa que o agente "lembra" é insuficiente — é o mesmo aprendizado dos critérios meta do `spec-guide` (checklist binário vence atenção textual). Este protocolo troca autocontrole por procedimento.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Stakes calibram tudo
|
|
14
|
+
|
|
15
|
+
Antes de cada decisão, classifique: errar aqui é **caro/irreversível (alto risco)** ou **barato/reversível (baixo risco)**? A classificação calibra três coisas: profundidade de investigação, rigor de gate, e exigência de confirmação.
|
|
16
|
+
|
|
17
|
+
A **classificação** é discricionária — é o julgamento do agente. A **execução** depois dela não é (ver §2). Investigação que não reduz risco e só cansa o humano é falha, não virtude.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 2. Procedimento de gate
|
|
22
|
+
|
|
23
|
+
- **Baixo risco:** declare a interpretação/suposição e **siga**. Sem turno de confirmação dedicado. Mantém o fluxo leve.
|
|
24
|
+
- **Alto risco:** emita uma **lista numerada** dos itens que precisam de confirmação. O gate **só fecha** quando cada item recebe confirmação que o referencia.
|
|
25
|
+
- Resposta genérica ("ok", "está ok", "sim", "pode seguir") a um gate de alto risco **não fecha o gate**. Você **não tem discrição** para aceitá-la: a classificação de risco já foi feita; genérico é, por definição, gate aberto.
|
|
26
|
+
- Ao receber genérico, **re-apresente os itens numerados e peça confirmação por item** (uma vez, sem repetir indefinidamente).
|
|
27
|
+
- Silêncio nunca é aprovação.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 3. Validação diferencial (valores verificáveis)
|
|
32
|
+
|
|
33
|
+
Se um artefato contém **valores verificáveis** — contas, números, critérios de aceite binários — esses valores são **automaticamente itens de alto risco** (§2), porque serão consumidos a jusante como referência de comportamento.
|
|
34
|
+
|
|
35
|
+
- Mostre a conta/derivação explicitamente.
|
|
36
|
+
- No gate, conduza o humano a confirmar **os valores**, não só "o documento parece bom". Peça confirmação do resultado, não da aparência.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Anti-padrões
|
|
41
|
+
|
|
42
|
+
- Declarar rigor ("ok genérico não fecha aqui") e depois fechar com ok genérico.
|
|
43
|
+
- Aceitar "está ok" sobre artefato com contas sem que os números tenham sido confirmados.
|
|
44
|
+
- Usar a classificação de risco como desculpa para pular a checklist no que já foi classificado como alto.
|
|
45
|
+
- Aplicar a checklist pesada a **tudo**, inclusive baixo risco — isso reintroduz o "massivo" e treina o humano a carimbar.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Limite honesto
|
|
50
|
+
|
|
51
|
+
Este protocolo é **mais forte que regra em prosa, não à prova de falha**. Um LLM ainda pode violar regra explícita. A única validação real é rodar e observar — trate como hipótese até ter evidência de runs.
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# {PROJECT_NAME}
|
|
2
|
+
|
|
3
|
+
{Descrição curta do projeto — 1-2 frases.}
|
|
4
|
+
|
|
5
|
+
> **Este é um template.** Ao usar, mescle com `profile-{cli|ssr}/claude-md.extension.md`
|
|
6
|
+
> da pasta de templates. Substitua valores entre `{}` pelos do projeto.
|
|
7
|
+
|
|
8
|
+
## Stack
|
|
9
|
+
|
|
10
|
+
- **Runtime:** {ex: Node.js + TypeScript}
|
|
11
|
+
- **Validação:** Zod (schemas como fonte de verdade única)
|
|
12
|
+
- **Testes:** Vitest
|
|
13
|
+
- **Formatter:** Prettier + lint-staged + husky (desde dia zero)
|
|
14
|
+
- {Outras deps específicas do projeto}
|
|
15
|
+
|
|
16
|
+
## Arquitetura
|
|
17
|
+
|
|
18
|
+
### Princípio central
|
|
19
|
+
|
|
20
|
+
{Descrever em 2-3 linhas o princípio arquitetural do projeto.
|
|
21
|
+
Exemplos:
|
|
22
|
+
- "Lógica de domínio desacoplada do framework. Services são
|
|
23
|
+
TypeScript puro. Camada de orquestração é casca fina que delega."
|
|
24
|
+
- "Loop infinito em casca fina. Lógica de trade vive em services
|
|
25
|
+
testáveis com mock de broker."}
|
|
26
|
+
|
|
27
|
+
### Estrutura de pastas
|
|
28
|
+
|
|
29
|
+
{Definir conforme perfil do projeto. Ver `profile-{cli|ssr}/code-patterns.md`
|
|
30
|
+
pra estrutura recomendada.}
|
|
31
|
+
|
|
32
|
+
## Docs de referência
|
|
33
|
+
|
|
34
|
+
Antes de implementar uma spec, consultar o doc relevante:
|
|
35
|
+
|
|
36
|
+
- [design-principles](./docs/design-principles.md) — princípios técnicos, princípios LLM-first, valores
|
|
37
|
+
- [code-patterns](./docs/code-patterns.md) — schemas Zod, services, padrões de código
|
|
38
|
+
- [spec-guide](./docs/spec-guide.md) — como ler, escrever e implementar specs
|
|
39
|
+
(inclui critérios meta M1, M2, M3 — e M4 em specs de UI)
|
|
40
|
+
- [pipeline](./docs/pipeline.md) — como uma ideia vira spec **e código**: discovery → conceituação →
|
|
41
|
+
doc-funcional → geração de spec → implementação → **review** (Review.Code →
|
|
42
|
+
User Review → Review.Product → Review.LLM). Agentes em
|
|
43
|
+
[agents/](./docs/agents/README.md); gates em [protocolo-de-gates](./docs/agents/protocolo-de-gates.md).
|
|
44
|
+
Para descobrir em que etapa o projeto está, ver "Em que etapa o projeto está" abaixo
|
|
45
|
+
- {Outros docs do perfil — [api-patterns](./docs/api-patterns.md) / [ui-patterns](./docs/ui-patterns.md) no SSR}
|
|
46
|
+
|
|
47
|
+
## Padrão de dados
|
|
48
|
+
|
|
49
|
+
Zod entity como raiz. Tipos derivam via `z.infer`. Validação na
|
|
50
|
+
fronteira (boot, resposta de I/O externo, leitura de arquivo).
|
|
51
|
+
Dentro dos services, dados são tipados e confiáveis.
|
|
52
|
+
|
|
53
|
+
Detalhes em [code-patterns](./docs/code-patterns.md).
|
|
54
|
+
|
|
55
|
+
## Convenções de código
|
|
56
|
+
|
|
57
|
+
### Geral
|
|
58
|
+
|
|
59
|
+
- TypeScript strict mode: começar `false`, migrar gradualmente.
|
|
60
|
+
- Arquivos novos em `kebab-case.ts`. Arquivos legados ficam até
|
|
61
|
+
serem refatorados.
|
|
62
|
+
- Exportar funções nomeadas, não default exports.
|
|
63
|
+
- Sem `any` em código novo. Em código legado, manter até refactor
|
|
64
|
+
da spec correspondente.
|
|
65
|
+
|
|
66
|
+
### Services e lógica
|
|
67
|
+
|
|
68
|
+
- Funções puras quando possível (input → output, sem side-effects).
|
|
69
|
+
- Services nunca importam módulos de I/O ou framework
|
|
70
|
+
(`fs`, `dotenv`, `process`, libs externas com side-effects).
|
|
71
|
+
- Services nunca chamam `console.log` direto. Logs estruturados
|
|
72
|
+
via logger dedicado quando aplicável.
|
|
73
|
+
- Side-effects (IO, integração externa, log) ficam em camada
|
|
74
|
+
dedicada (persistence/, integrations/, ou orquestrador).
|
|
75
|
+
|
|
76
|
+
### Erros
|
|
77
|
+
|
|
78
|
+
- Lançar classe específica do domínio (ex: `DomainError` ou
|
|
79
|
+
subclasses), nunca `Error` puro em código de domínio.
|
|
80
|
+
- Preservar stack trace: `throw error` ou `throw new XxxError(msg, { cause: error })`,
|
|
81
|
+
nunca `throw error.message`.
|
|
82
|
+
|
|
83
|
+
### Validação
|
|
84
|
+
|
|
85
|
+
- Toda leitura de I/O externa passa por `Schema.safeParse()`.
|
|
86
|
+
- Resposta de lib externa passa por schema parse antes de chegar
|
|
87
|
+
na lógica.
|
|
88
|
+
- Dentro de services: zero revalidação. Os dados já estão tipados.
|
|
89
|
+
|
|
90
|
+
## Workflow de desenvolvimento
|
|
91
|
+
|
|
92
|
+
Spec-first: cada mudança não-trivial passa por uma spec antes
|
|
93
|
+
da implementação.
|
|
94
|
+
|
|
95
|
+
### Onde mora cada coisa
|
|
96
|
+
|
|
97
|
+
| Etapa | Ferramenta |
|
|
98
|
+
| ----------------------------------------- | ------------------------------------------------ |
|
|
99
|
+
| Análise, decisão, escrita de spec, review | Cowork (Claude.ai com acesso aos arquivos) |
|
|
100
|
+
| Implementação | Claude Code (sessão dedicada apontando pro repo) |
|
|
101
|
+
|
|
102
|
+
### Ciclo
|
|
103
|
+
|
|
104
|
+
1. Cowork analisa, escreve spec, grava em `specs/`.
|
|
105
|
+
2. Claude Code implementa e preenche "Decisões de implementação" na própria
|
|
106
|
+
spec (critério M1).
|
|
107
|
+
3. **Review** (sub-cadeia, por incremento): Review.Code cruza cada critério
|
|
108
|
+
com o código real → User Review (usabilidade) → Review.Product (roteia
|
|
109
|
+
feedback) → Review.LLM (corrige o pipeline). Detalhe em
|
|
110
|
+
[pipeline](./docs/pipeline.md) §5.
|
|
111
|
+
4. Próxima spec.
|
|
112
|
+
|
|
113
|
+
> Nota: preencher "Decisões de implementação" é rastro do passo 2
|
|
114
|
+
> (implementação), **não** do passo 3 (review). O review deixa rastro
|
|
115
|
+
> próprio (veredito do Review.Code). Ver "Em que etapa o projeto está".
|
|
116
|
+
|
|
117
|
+
### Ao implementar uma spec (Claude Code)
|
|
118
|
+
|
|
119
|
+
1. Ler a spec inteira antes de começar.
|
|
120
|
+
2. Verificar "Depende de" — se a dependência não está implementada, parar.
|
|
121
|
+
3. Consultar `docs/` referenciados.
|
|
122
|
+
4. Implementar mudanças.
|
|
123
|
+
5. Rodar critérios de aceite — confirmar cada um.
|
|
124
|
+
6. Reportar: critérios ✅/❌/⚠️ + decisões de implementação + notas.
|
|
125
|
+
|
|
126
|
+
### Regras operacionais
|
|
127
|
+
|
|
128
|
+
- **3 strikes.** Se uma abordagem falhou 3 vezes, parar e relatar.
|
|
129
|
+
Não entrar em loop tentando variações.
|
|
130
|
+
- **Spec vs realidade.** Se a spec tem um tradeoff técnico significativo
|
|
131
|
+
na implementação, PARAR e apresentar o caso. Spec é guia, não lei.
|
|
132
|
+
- **Menor superfície.** Preferir solução que altera menos arquivos.
|
|
133
|
+
- **Não adivinhar.** Se a spec não cobre, perguntar.
|
|
134
|
+
- **Mudanças adjacentes vão pra outra spec.** Bug ou refactor tentador
|
|
135
|
+
observado durante implementação não entra na spec atual. Anotar
|
|
136
|
+
em "Decisões de implementação", abrir spec separada se relevante.
|
|
137
|
+
Detalhe em [spec-guide](./docs/spec-guide.md).
|
|
138
|
+
- **Leitura consolidada de arquivos grandes.** Antes de fazer
|
|
139
|
+
múltiplos `Read` do mesmo arquivo com offsets diferentes, considerar
|
|
140
|
+
1 leitura com `limit` alto (ex: `limit: 2000` cobre arquivos até
|
|
141
|
+
~2000 linhas). Custo de tokens da leitura única é menor que custo
|
|
142
|
+
de round-trips fragmentados.
|
|
143
|
+
- **Decisões de implementação são obrigatórias.** Toda spec implementada
|
|
144
|
+
termina com essa seção preenchida — escolhas, divergências, tentações
|
|
145
|
+
não feitas. Sem isso, spec está incompleta. Reforçado pelo critério
|
|
146
|
+
meta **M1** (ver [spec-guide](./docs/spec-guide.md)).
|
|
147
|
+
|
|
148
|
+
### Fixes diretos (sem spec)
|
|
149
|
+
|
|
150
|
+
Se altera contrato (schema, função pública, comportamento observável
|
|
151
|
+
de fora), spec. Se é correção do que já deveria funcionar (typo,
|
|
152
|
+
parêntese, condição invertida, ajuste de mensagem), fix direto.
|
|
153
|
+
|
|
154
|
+
## Comandos úteis
|
|
155
|
+
|
|
156
|
+
{Definir conforme perfil do projeto.}
|
|
157
|
+
|
|
158
|
+
## Configuração
|
|
159
|
+
|
|
160
|
+
{Tabela de arquivos de config + se vão pra git ou não.}
|
|
161
|
+
|
|
162
|
+
| Arquivo | Conteúdo | Comitado? |
|
|
163
|
+
| -------------- | --------------------------------- | --------- |
|
|
164
|
+
| `.env` | Segredos | ❌ NUNCA |
|
|
165
|
+
| `.env.example` | Mesmas chaves sem valor | ✅ |
|
|
166
|
+
| {outros} | ... | ... |
|
|
167
|
+
|
|
168
|
+
## Estado do refactor / desenvolvimento
|
|
169
|
+
|
|
170
|
+
> **Índice derivado, não fonte.** Esta tabela e o [_overview](./specs/_overview.md) são
|
|
171
|
+
> conveniência e **drift-am**. O estado real de cada spec mora **no conteúdo
|
|
172
|
+
> da spec** (critérios marcados, veredito de review), não aqui. Mesmo
|
|
173
|
+
> princípio LDoc→HDoc. Se a tabela diverge da spec, a **spec ganha**.
|
|
174
|
+
|
|
175
|
+
Roadmap completo em [_overview](./specs/_overview.md).
|
|
176
|
+
|
|
177
|
+
| # | Spec | Status |
|
|
178
|
+
| --- | --------------------------- | -------------------------- |
|
|
179
|
+
| 00 | {Primeira spec} | {⏳ pendente / ✅ feito} |
|
|
180
|
+
| ... | ... | ... |
|
|
181
|
+
|
|
182
|
+
### Em que etapa o projeto está
|
|
183
|
+
|
|
184
|
+
Antes de dizer "qual a próxima etapa" ou "X está pronto?": **descubra pelo
|
|
185
|
+
rastro no conteúdo das specs**, não pela tabela acima.
|
|
186
|
+
|
|
187
|
+
- Cada estágio do pipeline deixa rastro detectável na spec/artefato; o
|
|
188
|
+
**primeiro estágio sem rastro é o próximo passo**. Tabela de rastros em
|
|
189
|
+
[pipeline](./docs/pipeline.md) ("Em que estágio estou?").
|
|
190
|
+
- **Cuidado:** "Decisões de implementação" preenchidas são rastro da
|
|
191
|
+
**implementação** (estágio 4, critério M1), **não** do review. O review
|
|
192
|
+
deixa rastro próprio (veredito do Review.Code). Não confunda — se não há
|
|
193
|
+
veredito de review, o próximo passo é **rodar os fluxos de review**.
|
|
194
|
+
- A spec é a fonte; `_overview` e a tabela acima são índice derivado que
|
|
195
|
+
drift-a. Nunca responda status a partir de leitura truncada (`head -N`).
|
|
196
|
+
|
|
197
|
+
## Manutenção dos protocolos de doc
|
|
198
|
+
|
|
199
|
+
Estes docs e este `CLAUDE.md` vieram de `product-runner` (manifesto em
|
|
200
|
+
`docs/.product-runner.json`). O protocolo completo de manutenção
|
|
201
|
+
— diagnóstico do projeto, verificação de versão, `update`, migrations e handoffs —
|
|
202
|
+
vive no agente [agente-prod-runner](./docs/agents/agente-prod-runner.md).
|
|
203
|
+
|
|
204
|
+
**No início de uma sessão de trabalho, ≤ 1×/dia:** siga a *Verificação de
|
|
205
|
+
atualização* do [agente-prod-runner](./docs/agents/agente-prod-runner.md) — ele compara a versão
|
|
206
|
+
publicada com a do manifesto e, havendo novidade, conduz o `update` com você.
|
|
207
|
+
Nunca aplica nada (nem `--force`) sem sua aprovação.
|
|
208
|
+
|
|
209
|
+
> **Gitignore:** mantenha `docs/.prod-runner-update/` no `.gitignore` — é área de
|
|
210
|
+
> trabalho efêmera do `update`, não versionada.
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Design principles
|
|
2
|
+
|
|
3
|
+
Princípios que guiam decisões neste projeto, organizados por
|
|
4
|
+
o que ajudam: estrutura técnica do código, ou trabalho da LLM.
|
|
5
|
+
|
|
6
|
+
Princípios não são "boas práticas genéricas" — são regras
|
|
7
|
+
acionáveis com critério claro de violação.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Princípios técnicos
|
|
12
|
+
|
|
13
|
+
### 1. Fonte de verdade única
|
|
14
|
+
|
|
15
|
+
Uma definição. Tudo deriva dela. Se um campo muda na fonte,
|
|
16
|
+
o que depende dele quebra em compile-time.
|
|
17
|
+
|
|
18
|
+
**Na prática:**
|
|
19
|
+
|
|
20
|
+
- `ConfigValuesSchema` (Zod) é a raiz. `type ConfigValues = z.infer<typeof ConfigValuesSchema>`.
|
|
21
|
+
- Inputs derivam por `pick`/`extend`. Outputs derivam por `omit`/`extend`.
|
|
22
|
+
- Zero `interface` ou `type` escritos à mão que duplique algo do schema.
|
|
23
|
+
|
|
24
|
+
**Anti-pattern:**
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
// ❌ tipo paralelo ao schema, vai sair de sincronia
|
|
28
|
+
const ConfigValuesSchema = z.object({ id: z.string(), ... });
|
|
29
|
+
interface ConfigValues { id: string; ... }
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Por que importa pra LLM:** ela lê 1 schema e sabe todos os tipos.
|
|
33
|
+
Não precisa cruzar definições espalhadas.
|
|
34
|
+
|
|
35
|
+
### 2. Lógica de domínio isolada do framework e libs externas
|
|
36
|
+
|
|
37
|
+
Funções de cálculo, decisão e regras nunca importam
|
|
38
|
+
`@binance/connector`, `dotenv`, `fs`, `process`. Recebem
|
|
39
|
+
inputs tipados, retornam outputs tipados.
|
|
40
|
+
|
|
41
|
+
**Na prática:**
|
|
42
|
+
|
|
43
|
+
- `recalculateLimits(state, prices, config)` — função pura.
|
|
44
|
+
- Acesso à Binance via `BrokerClient` (interface), implementado por `BinanceBroker`.
|
|
45
|
+
- Persistência via funções dedicadas (`load`, `save`), nunca dentro da lógica de trade.
|
|
46
|
+
|
|
47
|
+
**Anti-pattern:**
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
// ❌ lógica chamando broker direto
|
|
51
|
+
function recalculateLimits(...) {
|
|
52
|
+
const price = await client.tickerPrice(...);
|
|
53
|
+
...
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Por que importa pra LLM:** função pura é caixa fechada com
|
|
58
|
+
contexto reduzido. LLM consegue raciocinar/testar/refatorar
|
|
59
|
+
sem carregar contexto da Binance.
|
|
60
|
+
|
|
61
|
+
### 3. Fronteira é onde valida
|
|
62
|
+
|
|
63
|
+
Valida UMA vez, na entrada do sistema. Dentro da lógica,
|
|
64
|
+
dados são tipados e confiáveis.
|
|
65
|
+
|
|
66
|
+
**Na prática:**
|
|
67
|
+
|
|
68
|
+
- Boot: `ConfigValuesSchema.safeParse(JSON.parse(arquivo))`. Se inválido, fail-fast com mensagem clara.
|
|
69
|
+
- Resposta da Binance: `BinanceTickerResponseSchema.parse(response.data)` antes de chegar na lógica.
|
|
70
|
+
- Reload de estado: `BotStateSchema.parse(json)` em vez de `Object.setPrototypeOf` cego.
|
|
71
|
+
- Dentro de services: zero revalidação. Os dados já estão tipados.
|
|
72
|
+
|
|
73
|
+
**Anti-pattern:**
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
// ❌ confiar em forma sem validar
|
|
77
|
+
const price = Number(response.data.price); // se .data ou .price mudar, quebra silencioso
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
// ❌ revalidar dentro de service
|
|
82
|
+
function buyAndSell(state) {
|
|
83
|
+
if (!state.config.tradeSymbol) throw ...; // já validado na entrada
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 4. Casca fina na borda
|
|
88
|
+
|
|
89
|
+
A camada de orquestração (loop principal, entrypoint) não pensa.
|
|
90
|
+
Recebe, delega, responde.
|
|
91
|
+
|
|
92
|
+
**Na prática:**
|
|
93
|
+
|
|
94
|
+
- `index.ts` ≤ 100 linhas. Carrega config, instancia broker, dispara `tradingLoop`.
|
|
95
|
+
- Loop em `services/trading/loop.ts`. Decisões em `services/trading/decisions.ts`. Etc.
|
|
96
|
+
- Aninhamento máximo no entrypoint: 2 níveis.
|
|
97
|
+
|
|
98
|
+
**Anti-pattern:**
|
|
99
|
+
|
|
100
|
+
- `index.ts` com 800 linhas misturando loop, lógica, ordens e persistência. (estado atual — refactor planejado em refactor/06)
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Princípios LLM-first
|
|
105
|
+
|
|
106
|
+
Regras que existem porque LLM como executor tem limitações
|
|
107
|
+
específicas: tende a fazer mais que pedido, entra em loops,
|
|
108
|
+
"esquece" decisões anteriores.
|
|
109
|
+
|
|
110
|
+
### 1. Critérios de aceite binários
|
|
111
|
+
|
|
112
|
+
Toda spec termina com checklist. Cada item passa ou não passa.
|
|
113
|
+
Verificável por comando ou observação direta.
|
|
114
|
+
|
|
115
|
+
**Na prática:**
|
|
116
|
+
|
|
117
|
+
- `git grep -E '(eNls3mjIoTZ|vIE3NutkqUq6)'` retorna vazio. ✅/❌
|
|
118
|
+
- Rodar `npm run start` sem `.env` termina com exit code != 0. ✅/❌
|
|
119
|
+
|
|
120
|
+
**Anti-pattern:**
|
|
121
|
+
|
|
122
|
+
- "Implementar de forma robusta" — não verificável.
|
|
123
|
+
- "O bot funciona corretamente" — não verificável sem critério.
|
|
124
|
+
|
|
125
|
+
**Por que importa:** elimina "parcialmente implementado". LLM tem
|
|
126
|
+
sinal claro pra parar.
|
|
127
|
+
|
|
128
|
+
### 2. Escopo travado por não-objetivos explícitos
|
|
129
|
+
|
|
130
|
+
Toda spec lista "Não-objetivos" antes do checklist.
|
|
131
|
+
Sem isso, LLM tende a fazer mais que pedido.
|
|
132
|
+
|
|
133
|
+
**Na prática:**
|
|
134
|
+
|
|
135
|
+
```markdown
|
|
136
|
+
## Não-objetivos
|
|
137
|
+
|
|
138
|
+
Esta spec NÃO faz:
|
|
139
|
+
|
|
140
|
+
- tsconfig.json (vem em setup/01)
|
|
141
|
+
- Vitest, testes (setup/01)
|
|
142
|
+
- Fix do bug aritmético em makeTradingTurnLog (refactor/03)
|
|
143
|
+
|
|
144
|
+
Se aparecer tentação, não fazer. Anotar em "Decisões de implementação".
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Por que importa:** lista de "não fazer" é mais eficaz que aviso
|
|
148
|
+
genérico. Ancoragem específica trava escopo.
|
|
149
|
+
|
|
150
|
+
### 3. Reportar decisões na própria spec
|
|
151
|
+
|
|
152
|
+
Após implementação, preencher seção "Decisões de implementação"
|
|
153
|
+
da spec. Documentar:
|
|
154
|
+
|
|
155
|
+
- Divergências do plano original.
|
|
156
|
+
- Escolhas entre alternativas (qual e por quê).
|
|
157
|
+
- Tentações de escopo que apareceram (não feitas, anotadas).
|
|
158
|
+
|
|
159
|
+
**Na prática:** ver final de `specs/setup/00-hardening.md`.
|
|
160
|
+
|
|
161
|
+
**Por que importa:** próxima sessão (humana ou LLM) lê a spec e
|
|
162
|
+
sabe o estado real, não o estado planejado. Sem isso, divergência
|
|
163
|
+
silenciosa acumula.
|
|
164
|
+
|
|
165
|
+
### 4. Guardrail dos 3 strikes
|
|
166
|
+
|
|
167
|
+
Se uma abordagem falhou, tentou variação, falhou de novo,
|
|
168
|
+
tentou outra: PARA na 3ª tentativa. Reporta o que tentou
|
|
169
|
+
e pede orientação.
|
|
170
|
+
|
|
171
|
+
**Na prática:** em problemas técnicos novos (erro estranho,
|
|
172
|
+
config que não funciona, comportamento inesperado), LLM
|
|
173
|
+
não fica iterando indefinidamente.
|
|
174
|
+
|
|
175
|
+
**Por que importa:** sem isso, sessão entra em loop e acumula
|
|
176
|
+
confusão. Vide o caso `searchVector/Prisma` no DocManager.
|
|
177
|
+
|
|
178
|
+
### 5. Documentar o porquê, não só o quê
|
|
179
|
+
|
|
180
|
+
Toda decisão arquitetural tem nota explicando o motivo.
|
|
181
|
+
CLAUDE.md, docs e specs sempre têm "porquê".
|
|
182
|
+
|
|
183
|
+
**Na prática:**
|
|
184
|
+
|
|
185
|
+
- "Usamos `Object.setPrototypeOf` em vez de factory `fromPlain` PORQUE é a substituição mais direta da reanexação manual sem expandir escopo desta spec."
|
|
186
|
+
- "Loop sequencial em vez de paralelo PORQUE rate-limit da Binance e simplifica raciocínio sobre estado."
|
|
187
|
+
|
|
188
|
+
**Anti-pattern:** comentário que descreve o óbvio (`// incrementa contador`)
|
|
189
|
+
em vez de explicar a decisão.
|
|
190
|
+
|
|
191
|
+
**Por que importa:** sem o porquê, decisões são revisitadas a cada
|
|
192
|
+
sessão. LLM "redebate" coisas já decididas.
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Valores não-acionáveis
|
|
197
|
+
|
|
198
|
+
Estes não são princípios — são valores culturais. Influenciam
|
|
199
|
+
mentalidade mas não dão critério binário.
|
|
200
|
+
|
|
201
|
+
### Evolução aditiva
|
|
202
|
+
|
|
203
|
+
**Como cultura:** preferir mudanças que estendem em vez de quebrar.
|
|
204
|
+
Campos novos nullable, schemas antigos continuam parseando.
|
|
205
|
+
|
|
206
|
+
**Como regra acionável:** "Adicionar campo: nullable. Renomear:
|
|
207
|
+
criar novo + deprecar. Remover: marcar deprecated em comentário,
|
|
208
|
+
remover só após 1 ciclo de uso."
|
|
209
|
+
|
|
210
|
+
Quando esta segunda forma estiver consolidada, vira princípio
|
|
211
|
+
técnico. Por enquanto, é nota.
|
|
212
|
+
|
|
213
|
+
### Pragmatismo sobre purismo
|
|
214
|
+
|
|
215
|
+
**Como cultura:** se ferramenta não suporta algo nativamente,
|
|
216
|
+
contornar com escape hatch mais simples e documentar.
|
|
217
|
+
|
|
218
|
+
**Aviso de dívida:** LLM aceita escape hatches com facilidade.
|
|
219
|
+
O risco é normalizar `as any`, `// @ts-ignore`, dado mockado em
|
|
220
|
+
produção, "deixa pra depois".
|
|
221
|
+
|
|
222
|
+
**Regra de uso:** qualquer escape hatch (cast, ignore, hack)
|
|
223
|
+
DEVE ser documentado em "Decisões de implementação" da spec
|
|
224
|
+
com motivo. Sem isso, vira dívida invisível.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
_Este documento é vivo. Princípios entram por observação prática
|
|
229
|
+
de problema, não por importação de "boas práticas"._
|