# E15 — Backtest pós-eleição (pledge vs. resultado; calibração de limiares)
Status: rascunho
Atualizado em: 2026-07-24 (refs sincronizadas pós-remodelagem Municípios + hardening)
Item do roadmap: [docs/roadmap.md](../roadmap.md) (seção "Inteligência de campanha", E15; plano-mestre [inteligencia-campanha.md](inteligencia-campanha.md))
Impeccable: A — N/A (sem superfície UI de produto neste ciclo; saída é relatório/dado)
Appetite: ~1 dia eng; janela pós-04/10 (sem pressa, sem migration própria)
Responsável: —
## Contexto
"Cada campanha que não compara pledge com voto realizado joga fora o experimento que pagou caro para rodar" (relatório C4). O backtest é a única calibração real de: fator de desconto de pledges (declarado × estimado × realizado), limiares da classificação relativa (E10), critérios de nível (E14), e a leitura ex-ante do motor (E11 — sugestões aceitas/descartadas vs. desfecho). Depende de dois lados: o lado TSE (resultado 2026 por município×zona — chega via extensão do seed `pnpm db:seed:tse` para 2026) e o lado campanha, que **só existe se C12 registrar durante o ciclo** (trajetória de pledges com datas, decisões com snapshot, sinais datados, esforço/origem de visitas). Este plano é deliberadamente pequeno: a fundação é C12; aqui é a leitura.
## Objetivos
- Import do resultado 2026 (extensão do seed TSE existente para `year=2026`, mesmo formato `electionTally`/`electionCandidateVote`).
- **Análises do backtest** (script/utility, saída em markdown versionado em `docs/research/` como apêndice do ciclo):
1. Pledge → voto: por município, trajetória de comprometido (fotos em 15/08, 15/09, véspera) vs. nominal realizado; fator de conversão global e por assessor/liderança-fonte (com o cuidado anti-punição de K-C/G4 — leitura agregada, não ranking individual público).
2. Limiares: quais cortes de LQ/captura teriam separado ex-ante os municípios onde o candidato cresceu (calibra E10/E14 para 2030).
3. Decisões: `allocationDecision` aceitas/descartadas vs. desfecho do município — o motor acertou onde? a leitura alternativa descartada era a certa?
4. Sinais: sinal registrado (invasão/esfriamento) previu queda? lead time médio.
5. Roll-off: municípios I-A trabalhados vs. não trabalhados — o diferencial se moveu?
- Tudo com o estatuto honesto: n=1 eleição, sem contrafactual — é calibração, não prova causal.
## Decisões travadas
- **Saída é documento versionado + dados derivados, não dashboard.** Pós-eleição não há usuário sob pressão; o consumidor é o planejamento 2030 e a plataforma white-label. **Rejeitado:** UI de produto para o backtest (custo sem usuário no ciclo).
- **Nenhuma análise individual punitiva.** Fatores por liderança existem para desconto futuro, não para ranking — G4 (punição ensina a inflar). Saída pública interna só agregada.
- **i18n e naming:** `backtest2026.ts` (script na família dos seeds), leituras `pledgeConversion`, `thresholdCalibration`, `decisionAudit`.
## Questões em aberto
- **Fotos da trajetória em quais datas?** Opções: fixas (15/08, 15/09, 03/10) | todas as semanas. **Recomendação:** semanais com destaque às três âncoras — versions do C12 permitem qualquer recorte.
- **Onde roda?** **Recomendação:** script CLI com guard de banco local (padrão dos seeds), lendo prod via `db:pull` — nunca análise pesada contra o banco de produção.
## Abordagem proposta
```mermaid
flowchart LR
TSE26["seed TSE 2026
(electionTally/CandidateVote)"]
Hist["pledgeHistory (C12 versions)"]
Dec["allocationDecision + sinais"]
Bt["backtest2026
(5 leituras)"]
Doc["docs/research/backtest-2026.md
+ calibração E10/E14"]
TSE26 --> Bt
Hist --> Bt
Dec --> Bt
Bt --> Doc
```
Componentes:
- **`scripts/seed-tse-results.mjs`**: aceitar 2026 quando o TSE publicar (mesma família de flags de E2).
- **`src/utilities/backtest2026.ts`** (ou script em `scripts/`): as 5 leituras sobre `pledgeHistory` (C12), `allocationDecision`, sinais e tallies; saída markdown.
- **Sem migration** (dado 2026 usa as collections existentes).
## Dependências
- Duras: **C12** (sem registro não há backtest — é por isso que C12 é não-cortável), resultado TSE 2026 publicado (externo, ~nov/2026). Suaves: E10/E14 (consumidores da calibração), E11 (auditoria de decisões só se o motor rodou).
## Não escopo
- Previsão/modelo para 2030 (só calibração descritiva); relatório público externo; qualquer análise de dados pessoais além do agregado interno (LGPD — pledges são dados de campanha, tratamento segue o mesmo regime de acesso staff).
## Rabbit holes
- **Virar paper.** 5 leituras, um markdown, cortes sugeridos — não análise econométrica.
- **Rodar contra produção.** Guard de banco local obrigatório (padrão `assertLocalDatabase` dos seeds); dados de campanha via `db:pull` com PII já excluída onde aplicável.
## Adiado com gatilho
- **Backtest contínuo durante a campanha** (mini-calibrações mensais). Gatilho: coordenação pedir leitura intermediária + C12 com ≥6 semanas de série.
## Referências
- `docs/roadmap.md` (Inteligência de campanha, E15) · [plano-mestre](inteligencia-campanha.md)
- `docs/research/relatorio-entrevista-persona-campanha.md` C4 (calibração), FU4 (registro ex-ante), D4 (limiar por backtest), G4 (anti-punição)
- `scripts/seed-tse-results.mjs`, `scripts/db-pull.mjs`, `tests/helpers/assertTestDatabase.ts` (família de guards)
- [registro-fundacao.md](registro-fundacao.md) (C12 — a fundação)
- AGENTS.md — guards de banco, seeds TSE