# Changelog — IronDome

Antes do 1.0.0 o sistema se chamava "Aviator Signals" e não era versionado.

## [1.26.0] — 2026-04-29
- **Gap-fill (rodadas 1.00× invisíveis)**: detecta gaps temporais > 50s entre
  crashes consecutivos e insere placeholders 1.00× com flag `inferred=1`.
  Resolve o problema do `.payouts-block` da Spribe não exibir 1.00 (instant
  crash), que ficava perdido na captura DOM.
  - Schema: nova coluna `crashes.inferred INTEGER DEFAULT 0` (SQLite local +
    Postgres VPS).
  - Hook em `register_crash()`: chama `_maybe_fill_gap()` antes do append no
    deque. Cap de 3 placeholders por gap detectado.
  - `cloud_sync.enqueue_crash` propaga a flag pra cloud.
  - VPS API: `CrashIn.inferred: bool = False`, INSERT/SELECT/broadcast
    incluem o campo.
  - Cloud UI: pill com hachura diagonal + "?" pra distinguir inferidos de
    reais. Tail-detector e pattern-gate ignoram inferidos (consultam
    `WHERE inferred=0`).
- Backfill retroativo dos últimos 30d: 11622 placeholders inseridos a
  partir de gaps reais no histórico local.
- `restart.sh` ganhou bloco `source .env.cloud` (mesmo que `start.sh`) —
  bug que silenciosamente desativava o cloud_sync após updater.

## [1.25.1] — 2026-04-28
- **Catálogo de estratégias 25 → 27**:
  - **ZETAPRIME** (29 rodadas, 1790u + 6370u = 8160u total) — banca alta,
    stakes elevados desde R1 (10u + 30u). Targets 4× e 10×.
  - **ZETAPRIME_RESEARCH** (27 rodadas, 27u + 516u = 543u total) — modelo
    de pesquisa: B1 fixo em 1u, toda alavancagem em B2 (3u → 60u).
- Mantém targets uniformes 4×/10× das demais. Carrega no boot do
  `_load_strategy_catalog()`, sem mudança de schema/endpoint.

## [1.25.0] — 2026-04-27
- **Toggles independentes por painel** no auto-bet do detector — checkbox
  P0 (4×) e P1 (10×). Você pode apostar nos dois (default), só no 4×, só
  no 10×, ou em nenhum (= mesma coisa que desligar auto-bet).
- Quando um painel está desmarcado, fica `enabled=False` e o daemon
  ignora; o outro continua entrando normalmente.

## [1.24.1] — 2026-04-27
- **Fix:** detector dispararia novo sinal na MESMA call que resolveu o anterior,
  causando bets em rodadas consecutivas. Agora pula detecção de novo padrão
  quando acabou de resolver um pending — gap mínimo de 1 rodada entre bets.

## [1.24.0] — 2026-04-27
- **Removida a função "rejogo"** do detector de cauda. Cada sinal agora gera
  exatamente uma entrada (P0 + P1) e encerra. Sinais consecutivos seguem
  disparando normalmente conforme detector encontra padrões.
- Removido: input "Rejogo" no card, lógica de `is_retry`/`retry_idx`/
  `retries_left` no `pending_signal`, `next_pending_from_retry`, banner
  laranja+rosa de retry, eventos `🔁 Rejogo`.

## [1.23.3] — 2026-04-27
- **Fix:** mudar `rejogo` no UI agora cancela cadeias em curso na rodada
  seguinte. Antes, o `retries_left` era congelado no `pending_signal` no
  momento do disparo — alterar a config no meio não tinha efeito até a
  cadeia terminar. Agora o decisor lê `cfg.rejogo` dinamicamente: se
  `retry_idx + 1 > rejogo_max`, para imediatamente.
- Comportamento: pôr rejogo=0 cancela retries futuros; a UM bet já promised
  (do retry decidido na rodada anterior) ainda completa.

## [1.23.2] — 2026-04-27
- **Fix crítico:** UnboundLocalError em `prob` quando tail_override pulava o
  gate da IA. Daemon clicava o botão de aposta mas crashava ANTES de registrar
  `active_bets` — então o cashout nunca disparava (sintoma: bot entra mas
  não sai, leva crash). Inicializa `prob = None` antes do gate.

## [1.23.1] — 2026-04-27
- **Fix:** auto-bet do detector estava sendo abortado por race-guard do cenário.
  Em modo Pós-10x os painéis raw ficam desativados (`enabled=False`) — só o
  tail-override liga dinamicamente. O guard relia a config fresca e via os
  painéis off, abortando a aposta. Agora pula o guard quando tail_override
  está ativo.

## [1.23.0] — 2026-04-27
- **Rejogo no auto-bet do detector de cauda** — campo configurável que define
  quantas vezes o bot repete a aposta após o sinal se P0 (4×) errar.
  - Sinal dispara → bot aposta P0 R$1@4× + P1 R$2@10×
  - Crash ≥ 4× → P0 ganhou → para (recuperou custo, aguarda próximo sinal)
  - Crash < 4× → P0 errou → repete a aposta (mesmo stake/target) até bater 4× ou esgotar N
  - Novo sinal durante rejogos pendentes **reseta** o contador
- Ambos os painéis (P0 e P1) repetem juntos em cada rejogo
- Banner do sinal vira laranja+rosa em modo rejogo, mostra "🔁 REJOGO R2 — restantes 3"
- Eventos do log diferenciam sinal original `[DDF]` vs rejogo `[DDF] [R1]`

## [1.22.2] — 2026-04-27
- **Fix:** modo Pós-10x agora pula a calibração inicial (20 rodadas
  observando antes de apostar). Em pos10x a IA é bypassada — calibração
  era apenas pra IA, então sem propósito.
- Se a calibração já estava rodando antes de trocar pra pos10x, daemon
  cancela imediatamente e loga "calibração cancelada".

## [1.22.1] — 2026-04-27
- **Fix:** modal "Nenhum painel ativo" não bloqueia mais o bot quando modo
  é Pós-10x. Em Pós-10x os painéis ficam desligados na config raw porque o
  tail-override liga dinamicamente quando o sinal dispara.
- Badge de status no card detector mostra: ⚠ BOT DESLIGADO / ✓ BOT ON aguardando
  / 🎯 ENTRADA EXECUTADA — visualização clara do que o bot está fazendo.

## [1.22.0] — 2026-04-27
- **Modo de operação** (mutex Hedge / Pré-setup / Pós-10x / Manual) — dropdown
  no topo da OPERACIONAL. Selecionar um modo desativa os outros automaticamente.
  - **Manual** (default): config livre dos painéis P0/P1
  - **Hedge**: ativa hedge_enabled (config na aba CENÁRIO)
  - **Pré-setup**: abre modal pra escolher estratégia + unidade R$
  - **Pós-10x**: ativa detector + auto-bet
- **Auto-bet do Pós-10x** — quando detector dispara em modo Pós-10x:
  - P0 com stake editável (default R$1.00) @ target 4×
  - P1 com stake editável (default R$2.00) @ target 10×
  - **Override total**: ignora stop-loss diário, parada técnica, schedule
    de janela quente, cooldown pós-loss, IA do IronDome
  - Respeita DRY-RUN (simula nesse modo)
  - Respeita o **bot master toggle** (off no botão superior = desliga tudo)
- Sinal vale apenas pra próxima rodada — após resolução, volta a observar
- Endpoints: `GET/POST /api/operation_mode`. Daemon usa `_tail_override`
  flag nos panels_cfg pra bypassar safety checks.

## [1.21.0] — 2026-04-27
- **🎯 DETECTOR DE CAUDA** — sinal pós-10x baseado em padrão N-gram
  validado em 211k crashes (sequências contíguas, edges +39 a +59pp):
  - **DDF** (3-5x, 3-5x, 10x) → próx ≥10x em **68%**
  - **BBF** (1.5-2x, 1.5-2x, 10x) → 61%
  - **CCF** (2-3x, 2-3x, 10x) → 59%
  - **AAF** (qualquer baixo + 10x) → 48%
  - **F** (só vendo o último 10x) → 28% (opt-in)
- Card "DETECTOR DE CAUDA" na aba OPERACIONAL: chips das últimas 3
  rodadas + sinal ativo destacado + stats W/L + histórico dos últimos
  12 sinais. Atualiza a cada 4s.
- Endpoints: `GET /api/tail/state`, `POST /api/tail/config`,
  `POST /api/tail/reset_stats`. Persistência em `data/tail.json`.
- Hook em `register_crash`: cada crash novo (1) resolve sinal pendente
  e (2) avalia se cria novo. Sinal vale apenas pra próxima rodada.
- **Não auto-aposta ainda** — só sinaliza pra você decidir manualmente.
  Auto-bet pode ser adicionado em release futuro.

## [1.20.1] — 2026-04-27
- **Manual das estratégias** (`STRATEGIES_MANUAL.md`) — descrição prática
  em PT-BR de cada um dos 25 modelos: filosofia, quando usar, perfil de
  risco, dica de uso, métricas (drawdown, lucro R1, lucro RN). Inclui guia
  por banca recomendada.
- Botão **📖 Manual das estratégias** na aba ESTRATÉGIA abre o manual em
  modal (parser de markdown leve, sem dependências externas).
- Manual também publicado em https://irondome-site.vercel.app/STRATEGIES_MANUAL.md

## [1.20.0] — 2026-04-27
- **Aba ESTRATÉGIA** com presets de progressão (BOLADOTRON, MAXIMUS10/20,
  OPTIMUS, AURORA300, 007 cumulative, etc — 25 modelos do catálogo
  `static/strategies.json`).
- Quando uma estratégia está ativa, o daemon sobrescreve P0/P1 com
  `stake × stake_unit` e `target` da rodada atual do schedule.
- Progressão automática: **win em qualquer painel reseta** o índice; **ambos
  perdem avança** o índice. Estouro do schedule = parada técnica.
- Estado persistido em `data/strategy.json`. Endpoints novos:
  `/api/strategy/{state,catalog,load,clear,reset,outcome}`.
- Prioridade de override: Hedge > Strategy > panels do cfg. Hedge ON
  desliga o efeito da estratégia (mas mantém ativa pra retomar quando
  desligar Hedge).

## [1.19.3] — 2026-04-26
- **Fix:** parada técnica voltou a ser por **tempo da config** (`techPauseMinutes`).
  Banner mostra `MM:SS` regressivo até o fim da pausa; sem mais "X/Y rodadas".
  Bug visível: pausa por 3 perdas consecutivas mostrava `0/999999` porque
  herdava o sentinela do schedule. Resolvido.
- Daemon agora envia o valor real de `techPauseMinutes` no `trigger_tech_pause`
  (antes mandava 1.000.000 e a saída dependia de watchdog de rodadas).
- Watchdog de rodadas removido. Pausa por janela quente continua sem contador
  (saída controlada exclusivamente pelo schedule_watchdog).

## [1.19.2] — 2026-04-26
- Rebatizado **janela ótima → janela quente** (UI + logs + pause_reason).
- Parada técnica por janela quente **sem contador**: schedule controla a saída,
  não faz sentido mostrar X/Y rodadas. Banner exibe "Aguardando próxima janela
  quente" e esconde o chip numérico. As demais paradas técnicas (perdas
  consecutivas) seguem com o contador como antes.

## [1.19.1] — 2026-04-26
- Aba CENÁRIO agora rola verticalmente quando o conteúdo passa do viewport
  (com os cards de schedule + hedge ela cresceu além da tela).

## [1.19.0] — 2026-04-26
- **Schedule de janelas ótimas** (descoberta de melhores horários):
  - Análise rolling 28d em SP timezone, edge ≥ +5pp, n ≥ 30
  - Recompute horário, check de janela atual a cada 1 min
  - Quando hora atual NÃO está em janela boa: aciona parada técnica
    formal "fora da janela ótima" (libera quando entra na próxima)
  - Heatmap dia × hora × target + ranking top-20 na aba CENÁRIO
  - Toggle ON/OFF independente
- **Modo Hedge** (2 painéis cobrindo riscos):
  - Define stake total + lucro alvo + T_A (default 2x)
  - Sistema calcula automaticamente S_A, S_B, T_B
  - 4 cenários: ambos vencem (alto lucro), só seguro (defendido),
    só alvo (lucro), ambos perdem (perda total)
  - Toggle ON/OFF independente do schedule
  - Ambos painéis apostam mesma rodada
- Schedule e hedge são **independentes**: toggle paralelo. Pode usar
  combinações: schedule on/hedge off, schedule off/hedge on, ambos on.

## [1.18.0] — 2026-04-26
- **Aba CENÁRIO**: análise + gestão de risco baseada em saldo + objetivo.
  Calcula stake recomendado (Kelly fracionado ∩ stake viável ∩ teto 5%
  saldo), targets ótimos por hora atual + janela 300, calibração da IA.
- **Saldo lido automaticamente** da plataforma via CDP no iframe Spribe
  (seletor `app-header .balance .balance-amount`). Atualiza a cada 30s.
  Funciona em qualquer plataforma que embede Spribe (7K, Blaze, etc).
- **Gestão automatizada**: 2 gatilhos — variação de saldo > X% (default
  20%) ou a cada N rodadas (default 10). Re-analisa e aplica params
  silenciosamente, notifica via Telegram. Toggle + sliders na aba
  CENÁRIO. UI sincroniza automaticamente quando server aplica
  (cfg_revision tracking).
- **Aba "AUTO-CLICK" virou "OPERACIONAL"**. Botão "🤖 GESTÃO
  AUTOMATIZADA" aparece no header da aba quando toggle está on —
  clique força análise + apply imediato.
- **Parada técnica simplificada**: ao acionar, aguarda 20 rodadas e
  retoma. Sem mais janela de 8 sinais, shadow window, ou avaliação de
  hit rate. Banner mostra `X/20`.
- **Calibração de 10 rodadas** ao ligar bot: observa antes de apostar.
  Badge `🎯 CALIBRANDO 7/10` na aba OPERACIONAL.
- **Cooldown ancorado no snap da aposta** (não no `api_total` no momento
  da resolução). Cooldown de N rodadas = exatamente N, sem off-by-one.
- **Race condition fix**: re-checa enabled imediatamente antes de
  clicar bet, pra evitar clique quando watchdog desabilitou painel
  durante o jitter delay.
- **Recomendação nunca propõe stake R$0**. Se Kelly + viável calc
  retornam 0, força MIN_STAKE=R$1 (ou desativa o painel se edge
  negativo).
- **Persistência do cenário**: config + baseline em `data/cenario.json`,
  sobrevive restart do server.
- **Server agora roda em python3.12** (start.sh) — python3 system
  estava com libexpat quebrada e o `websocket-client` (necessário pro
  balance reader CDP) não instalava.

## [1.17.0] — 2026-04-25
- **Aba CENÁRIO** com análise automática a cada N rodadas (configurável,
  default 100). Server roda em background — não depende do dashboard
  estar aberto.
- Análise usa: saldo (auto-detectado da plataforma via CDP, editável),
  objetivo (manual), últimas 300 rodadas e calibração da IA. Calcula
  stake recomendado por Kelly fracionado ∩ stake viável pro objetivo ∩
  teto de 5% do saldo (pega o menor — mais seguro).
- Popup só aparece quando há mudança significativa (stake/target/stop
  fora do recomendado). Telegram envia resumo sempre que popup aparece.
- Botão **"Aplicar melhorias"** mostra diff completo e aplica tudo de
  uma vez (stake, target, stop-loss, parada por streak, criterio IA,
  painéis ativos).
- Novo módulo `cenario.py` encapsula a matemática.
- Endpoints novos: `POST /api/cenario/analyze`, `POST /api/cenario/apply`,
  `GET/POST /api/cenario/config`.

## [1.16.3] — 2026-04-25
- **Shadow agora dispara por crash detectado, não por fase do browser.**
  Diagnóstico: durante parada técnica longa, o `daemon_dom` continua
  detectando crashes via DOM, mas a detecção de fase via CDP do
  `autoclick_daemon` começa a ficar inconsistente (iframe/Spribe
  reset interno). O shadow antigo dependia de `phase=='betting'` pra
  abrir e do crash subsequente pra resolver — quando o phase ficava
  preso, o shadow parava após 1 sinal.
- Novo modelo: a cada incremento de `api_total` (= novo crash chegou
  no DB), simula uma entrada usando o target do painel e o crash
  recém-coletado como resultado. Pega 1 sinal por rodada por painel
  enabled, sem depender do CDP.
- Probabilidade e padrão da IA continuam capturados pra logging
  quando `useIA=true`.

## [1.16.2] — 2026-04-25
- **Shadow agora amostra o mercado, não o filtro da IA.** Durante parada
  técnica, a abertura de shadow bet **bypassa o gate de IA + entry
  trigger** — abre 1 sinal por rodada no target do painel. Antes, o
  shadow só fazia entrada quando IA aprovava (~5% das rodadas em
  target alto), o que (a) demorava ~70 min pra completar 8 sinais e
  (b) selecionava apostas que a IA achava ganhar, mascarando derrotas
  que aconteciam fora do filtro.
- Agora 8 sinais saem em ~3-4 min e o hit rate medido reflete o
  mercado bruto naquele target. Decisão de retomar/reiniciar fica mais
  rápida e mais honesta.
- Probabilidade e pattern continuam sendo capturados pra logging
  quando `useIA` está ligado (alimentando calibração), só não filtram
  mais a abertura.

## [1.16.1] — 2026-04-25
- **Fix nos cooldowns após ganho/perda**: ancorando no `snap` da aposta
  (rodada efetiva) em vez de `api_total` no momento da resolução. Antes,
  a duração do cooldown variava conforme latência de detecção:
  - Win: hit resolve só APÓS crash inserido, `api_total` já incrementou
    → cooldown ficava 1 rodada a mais que configurado.
  - Loss detectada tarde (`api_total >= snap+2`) somava ainda mais
    rodadas (~3-4) em vez das 2 configuradas.
- Agora `cooldown_until = snap + N + 1` é determinístico:
  configurou 2, pula exatamente 2 rodadas após a aposta, independente
  de quando o daemon detectou o resultado.
- Aplica nos 4 caminhos: win real, miss real, win DRY-RUN, miss DRY-RUN.
- **Banner da parada técnica mostra cada sinal simulado**: chip por sinal
  com o valor do crash daquela rodada e fundo verde (vitória) ou
  vermelho (derrota). Lista é mantida no server (`shadow_results`),
  resetada junto com a janela. Facilita ver que perdas estão sendo
  contadas — era confuso porque a janela resetava sem aviso visual.

## [1.16.0] — 2026-04-25
- **Parada técnica vira contador de janela**, não cronômetro. Quando
  acionada, o bot abre uma simulação silenciosa de **8 sinais**. Ao
  fechar a janela:
  - Acertou **≥4/8** → libera, retoma operação real, reseta stats.
  - Acertou **<4/8** → reinicia o contador (nova janela de 8) sem sair
    da parada técnica.
- Sem mais "extensão de N minutos". O bot fica em parada **até a IA
  provar 50% de acerto numa janela de 8 sinais**.
- Botão **Retomar agora** segue cancelando imediatamente
  (`paused_until=0`). Avaliação automática roda no server side a cada
  POST `/api/autoclick/shadow`.
- UI: banner mostra `INTERV. X/8 · Y vitórias (mín 4)` em vez de
  cronômetro `MM:SS`.

## [1.15.0] — 2026-04-25
- **IronDome Cloud — Fase 1+2 plugadas.** Backend FastAPI+Postgres na VPS
  Hostinger (RLS multi-tenant) + Vercel proxy em
  `https://irondome-cloud.vercel.app` + dashboard read-only com KPIs,
  heatmap hour×target, V/D/IA por painel e calibração da IA.
- Novo módulo `cloud_sync.py`: fila in-memory + thread daemon que espelha
  cada `insert_crash`/`insert_bet`/`resolve_last_open_bet` pro cloud em
  batch. Fire-and-forget — falhas não quebram o app local.
- Hooks plugados em `db.py`. `server.py` chama `cloud_sync.start()` no boot.
- `start.sh` agora carrega `.env.cloud` automaticamente quando presente,
  ativando o sync sem ação manual.
- Backfill one-shot via `backfill_to_cloud.py` (já rodou: 7374 crashes
  históricos importados pra Postgres).

## [1.14.6] — 2026-04-24
- **V/D/IA agora é DB-authoritative**: endpoint `/api/autoclick/status`
  computa `panels_stats` por SQL agregado em `bets` filtrado por
  `ts >= last_reset AND amount > 0 AND resolved_ts IS NOT NULL`.
- Elimina a classe inteira de "eventos perdidos" (timeouts/erros de
  rede no `post_event`). Qualquer aposta que chegou no DB conta;
  qualquer que não chegou, não conta — e sempre consistente.
- **PnL mantém comportamento atual**: contador in-memory que zera só
  quando usuário clica Reset.
- Novo helper `db.panels_stats_since(ts)` agrega V/D/IA direto do DB.

## [1.14.5] — 2026-04-24
- **Fix "derrota imediata ao ligar bot em simulação"**: a margem de
  tolerância de 0.5s no timestamp da resolução DRY/shadow estava
  capturando o crash ANTERIOR à aposta. Se usuário clicava BOT ON
  logo após uma rodada ter crashado, ambos painéis marcavam miss
  imediato (mesmo sem rodada nova ter ocorrido).
- Troca de `>= placed_at - 0.5` por `> placed_at` estrito: crash usado
  pra resolver a aposta tem que ser ESTRITAMENTE posterior à colocação.

## [1.14.4] — 2026-04-24
- **Badge de shadow por painel durante parada técnica** — cada painel
  ganha um contador dedicado âmbar mostrando `X/Y (min 50% p/ retomar)`
  quando em pausa. Cor da taxa muda pra verde (≥50%) ou vermelho (<50%,
  amostra ≥3).
- Visível APENAS em parada técnica. Fora da pausa, badge some (counter
  V/D/IA principal já reflete só apostas reais desde v1.14.3).

## [1.14.3] — 2026-04-24
- **Contador V/D/IA agora reflete SOMENTE apostas reais**. Reversão da
  decisão de v1.8.4 (shadow bets bumpavam panels_stats "pra IA aprender
  durante pausa"). User pediu: parada técnica = bot observando, NÃO
  gravando histórico.
- Shadow bets na parada técnica agora:
  - Atualizam APENAS `shadow_stats` (banner de simulação).
  - NÃO incrementam `panels_stats` (V/D/IA).
  - NÃO inserem mais em `bets` (DB fica limpo de amount=0).
- Faça Reset na aba AUTO-CLICK pra zerar o contador atual que estava
  inflado por shadows de versões anteriores.

## [1.14.2] — 2026-04-24
- **Bug fix shadow bets duplicando** durante parada técnica: enquanto
  `phase='betting'` (5-15s por rodada), daemon rodava a cada 150ms e
  abria/resolvia N shadows na mesma rodada, todos contra o mesmo crash.
  Contador inflava (5/14, 8/21, etc) sem refletir performance real.
- Fix: flag `shadow_ready[p_idx]` que só volta a True quando a fase sai
  de `betting`. Garante **1 shadow bet por rodada**, igual aposta real.

## [1.14.1] — 2026-04-24
- **Bug fix crítico DRY-RUN/SHADOW marcando derrota antes da rodada**:
  race condition onde o `api_total` avançava por snippet atrasado
  (registrando crash da rodada ANTERIOR à aposta) e a resolução
  disparava usando `crashes[-1]` errado, marcando miss imediato contra
  o crash que aconteceu ANTES do bet.
- Resolução trocou `api_total >= snap + 1` por busca pelo **primeiro
  crash com `at >= placed_at − 0.5s`** — imune à race, só tempo real.
  Aplicado no DRY-RUN e nas shadow bets da parada técnica.

## [1.14.0] — 2026-04-23
- **Refatoração do aprendizado da IA** — simplificação radical da cascata:
  - ❌ **Removida** camada CALIBRAÇÃO por faixa de probabilidade.
  - ❌ **Removida** penalidade GLOBAL por painel baseada em win rate.
  - ❌ **Removido** AUTO-AJUSTE que escalava margem/piso por pnl_per_unit.
  - ✅ **Mantido** pattern matching + suavização bayesiana (estimativa direta).
  - ✅ **Mantido** aprendizado causal por padrão (pattern_bet_history).
  - ✅ **Novo**: **PATTERN BLACKLIST**. Se o padrão da cauda atual perdeu
    3× seguidas nas últimas 2h em apostas reais, o bot **só bloqueia esse
    padrão por 2h** — continua operando nos outros. Aprendizado granular
    que isola o problema sem travar o bot inteiro.
- **Critério previsível**: `teórico × (1 + margem_modo)` fixo. Sem
  feedback loop ("perde → aperta → para → não aprende → nunca relaxa").
- **Piso absoluto 32% → 25%**: menos restritivo em targets altos.
- Reasoning da UI fica mais curto e claro (4 linhas em vez de 8).

## [1.13.3] — 2026-04-23
- **Detecção de miss mais rápida**: quando a fase do jogo volta pra
  `betting` vindo de `waiting_flight/flight/unknown` (indicando que a
  rodada terminou), daemon registra miss imediatamente em vez de
  esperar `api_total +2` ou `timeout 90s`. Caso útil pra rodadas
  curtas onde o daemon não vê a fase `flight` direito. Antes do miss,
  checa armed result pra cobrir cashout tardio.

## [1.13.2] — 2026-04-23
- **Bug fix critério do status**: `pollIaGate` no frontend não passava
  o parâmetro `margin`, então o critério mostrado no status usava
  sempre a margem default (18%) em vez da escolhida no dropdown.
  Resultado: dropdown funcionava pro bot apostar mas a tela mostrava
  um critério mais alto que o real. Agora passa a margem do modo.

## [1.13.1] — 2026-04-23
- Aba **CONTROLE removida** (dashboard cockpit).
- **Dropdown de "Modo de operação"** movido pros painéis da aba
  AUTO-CLICK (Conservador / Equilibrado / Agressivo), abaixo do status
  box de cada painel. Mudança salva instantaneamente.
- PAINEL 10x volta a ser a aba default ao carregar.

## [1.13.0] — 2026-04-23
- **Modo de operação por painel** no cockpit — dropdown no topo de
  cada painel da aba CONTROLE:
  - **Conservador**: margem +15% sobre break-even (menos entradas, EV
    folgado).
  - **Equilibrado** (default): margem +10%.
  - **Agressivo**: margem +5% (mais entradas, risco maior).
- Config persiste em `panels[i].operationMode`. Daemon envia como
  parâmetro `margin=X` no `GET /api/intelligence/gate`. Server usa
  como `MARGIN_BASE` no lugar do fixo 18%.
- Tetos do AUTO-AJUSTE agora escalam relativo à margem base (±7pp pra
  cima / ±3pp pra baixo), em vez de fixos — assim o modo Agressivo
  não é anulado pelo teto mínimo.
- Mudar o dropdown salva config no backend imediatamente (sem precisar
  apertar SALVAR). Status IA do painel re-consulta e mostra o novo
  critério.

## [1.12.4] — 2026-04-23
- **Bug fix crítico "ganho marcado como perda"**: race entre JS arm
  (clicou cashout no browser) e daemon (ainda não leu o armed result).
  Acontece em rodadas curtas onde plane crasha logo após atingir o
  target. Fluxo antigo: daemon detectava `saw_flight + phase != flight`
  e registrava MISS, mesmo o casino tendo pago.
- Agora: **antes de registrar miss, daemon checa uma última vez
  `checkArmedResult`**. Se o JS disparou cashout com sucesso, converte
  em pending_hit (hit) em vez de miss. Log mostra `[arm tardio]`.

## [1.12.3] — 2026-04-23
- Heatmap de crashes: ordem invertida — **crash mais recente aparece
  primeiro** (canto superior esquerdo). Legenda removida.

## [1.12.2] — 2026-04-23
- **Heatmap com as cores oficiais do Aviator**: azul (< 2x), roxo
  (2–10x), rosa (≥ 10x). Valor da rodada aparece dentro da célula em
  fonte monospace. Legenda atualizada.
- Glow suave no rosa (≥ 10x) pra destacar as rodadas premium.
- Hover na célula dá zoom leve + outline branco.

## [1.12.1] — 2026-04-23
- **Cockpit responsivo**: layout em CSS Grid em vez de flex-direction
  column. Breakpoints corrigidos (1100px e 700px) pra manter layout
  horizontal em telas comuns de 1024-1366px.
- KPI cards mais compactos (22px vs 32px no número).
- Heatmap cells com altura fixa 14px (vs aspect-ratio quadrado que
  estourava) — 10 linhas × 30 colunas cabem em ~180px de altura.

## [1.12.0] — 2026-04-23
- **Nova aba CONTROLE** — cockpit widescreen com visão consolidada:
  - **4 KPIs** (targets 2x, 5x, 10x, 50x) com prob **observada**
    (últimas 300 rodadas) + **IA atual** por target.
  - **Heatmap 30×10** dos últimos 300 crashes, coloridos por bucket
    (BAIXO<1.3 verde, MÉDIO<2 amarelo, ALTO<5 laranja, TOPO≥5 vermelho).
  - **Painéis em tempo real** com status (ENTRADA/AGUARDAR/COOLDOWN),
    target, aposta efetiva, última aposta (hora, valor, target, ✓/✗,
    crash) e mini-gráfico das 20 últimas apostas.
  - **Gráfico SVG de P&L** da sessão (linha + área preenchida).
  - **Barras por hora** mostrando taxa de acerto por hora do dia
    (verde ≥60%, vermelho <40%).
  - **Stats**: apostas hoje, apostas total, gap médio entre entradas.
  - Refresh 2s uniforme via novo endpoint `GET /api/control`.
- Aba **PAINEL** renomeada pra **PAINEL 10x** (continua tendo o
  termômetro + status snippet + conteúdo original).
- **CONTROLE** vira a aba default ao carregar o dashboard.

## [1.11.3] — 2026-04-23
- **Removidas 2 regras espúrias** que eram variantes da falácia do
  jogador e estavam travando bons setups:
  - `−8pp se última rodada ≥5x` (pseudo "cooldown após alto").
  - `+4.5 a +8pp se N crashes <target seguidos` (pseudo "momentum").
  Aviator é provably-fair (rodadas independentes). O pattern matching
  e a CALIBRAÇÃO por faixa de prob já capturam qualquer relação real
  entre cauda e crash seguinte — sem double-counting.
- Efeito prático: no caso observado, prob subiu de 47.9% → 55.9%
  (o −8pp era o único motivo de rejeitar um padrão com hit rate
  histórico de 66%).

## [1.11.2] — 2026-04-23
- **AUTO-AJUSTE recalibrado pra lucro** baseado em diagnóstico dos
  203+ bets do P1:
  - Janela **25 → 75 apostas** (~1-2 dias em operação normal). Reage a
    tendências reais, não a azar curto.
  - Mínimo de apostas antes de ajustar: **5 → 15** (evita reação a
    ruído cedo demais).
  - Baseline: margem **15% → 18%**, piso **30% → 32%** (mais
    seletivo em cada entrada).
  - Tetos: margem max **30% → 22%**, piso max **45% → 38%**
    (evita travar o bot no máximo).
  - Pisos: margem min **10% → 15%**, piso min **25% → 28%**
    (mesmo no melhor cenário mantém filtro seguro).
- Resultado esperado: mais entradas que o cenário travado (margem 25%
  + piso 40%), menos entradas que o cenário frouxo do início do dia
  (margem 15% + piso 30%), com critérios calibrados pra só aprovar
  entradas com convicção real.

## [1.11.1] — 2026-04-23
- **Admin UI** hospedado em <https://irondome-site.vercel.app/admin>:
  - Login com senha admin (salva em sessionStorage).
  - **Emitir** chave nova: nome do cliente + duração (dias) →
    `POST /api/admin/issue` → exibe chave + botão Copiar.
  - **Renovar** chave existente: cola a chave atual, UI busca
    `/api/admin/parse` pra validar e extrair owner_id, emite nova key
    com o mesmo owner_id e validade extendida.
  - **Histórico da sessão** em sessionStorage: log de emissões/renovações
    recentes com data e chave.
  - **Revogação emergencial** documentada via env var `BLACKLIST` no
    Vercel dashboard (em regra, basta não renovar — chave expira
    sozinha).
- Novo endpoint `POST /api/admin/parse` decompõe uma chave (owner_id,
  expires_at, signature_valid, expired, revoked) — protegido pela senha
  admin; usado pela UI pra validação e renovação.
- `genKey` aceita `reuseOwnerId` pra manter identidade entre renovações.

## [1.11.0] — 2026-04-23
- **Sistema de licenciamento online** — sistema trava se não tiver chave
  válida do distribuidor:
  - Módulo novo `license.py`: ativação via `/api/license/verify` no
    servidor Vercel, token JWT-like assinado com HMAC (TTL 24h), cache
    em `data/license.json`.
  - Gate `_guard_licensed()` bloqueia TODAS as rotas `/api/*` (exceto
    versão, updates e ativação) com 403 se licença ausente/expirada.
  - Revalidação automática a cada 6h; grace period de 24h offline.
  - Splash de ativação fullscreen quando não-licenciado — UI paralisa
    até a chave correta ser colada.
  - Backend Vercel (`api/license/verify.js`, `api/admin/issue.js`)
    usa chaves assinadas formato `IRDM-{owner}-{exp_ts}-{sig16}`.
  - Chave é self-contained: servidor verifica assinatura sem precisar
    de DB — válida pelo HMAC+expiração.

## [1.10.0] — 2026-04-23
- **Auto-updater**: IronDome agora atualiza sozinho. Banner na aba SOBRE
  mostra "Nova versão disponível" quando o manifesto do Vercel tiver um
  release mais recente. Clicar **Atualizar agora**:
  - Baixa ZIP do site (`/irondome-latest.zip`).
  - Faz snapshot de rollback em `_snapshots/pre-update-vX.Y.Z-...`
  - Copia os arquivos novos por cima, preservando **`data/`,
    `_snapshots/`, `cert.pem`, `key.pem`** (zero perda de DB/configs).
  - Spawna `restart.sh` que mata e sobe server + daemon de novo.
  - UI recarrega automaticamente após 4s.
- Novo módulo `updater.py`, novos endpoints `GET /api/updates/check`
  e `POST /api/updates/install`.
- Frontend checa atualizações no load e a cada 30 min.
- Novo `restart.sh` pra restart controlado pós-update.

## [1.9.5] — 2026-04-23
- Linha "✈️ Crash: Xx" removida da mensagem de ganho/perda do Telegram
  enquanto o valor certo não fica confiável. Target e P&L continuam.

## [1.9.4] — 2026-04-23
- **Crash no Telegram resolvido definitivo**: troca a lógica de índice
  (`crashes[-k]` ou `crashes[-1]`) por busca por TIMESTAMP. Daemon passa
  `placed_at` (momento da aposta/cashout) nos eventos hit/miss; server
  varre o feed e pega o **primeiro crash com `at >= placed_at - 0.5s`**.
  Imune a race de contagem e a atraso do snippet — tempo real como
  fonte da verdade.
- Fallback em cascata: se não achar crash por timestamp →
  `crashes[-1]` se recente (<10s) → valor enviado pelo daemon.

## [1.9.3] — 2026-04-23
- **Janela de análise 300 → 1000 rodadas** (`evaluate_target_probability`).
  Capacidade já existia: deque maxlen=2000, DB com 2800+ persistidos.
- **Cauda máxima k=5 → k=6**: pattern matching testa agora sequências de
  tamanho 6,5,4,3,2 (score seleciona o melhor). Com janela 1000, k=6
  passa a ter suporte estatístico minimamente utilizável (~0.25 oc.
  média por padrão vs 0.07 na janela 300).
- Reasoning da UI mostra cauda atual de 6 buckets quando o histórico
  tem ≥ 7 rodadas.

## [1.9.2] — 2026-04-23
- **Crash no Telegram = último detectado se recente**: regra simples —
  se `crashes[-1]['at']` tem < 10s, é o crash que acabou de ser
  registrado (mesmo valor do card "ÚLTIMO NÚMERO DETECTADO" do painel)
  e é o crash da rodada da aposta. Caso o feed esteja parado há mais
  de 10s, cai pro valor que o daemon enviou. Abandonei a indexação
  `crashes[-k]` pelo snap porque podia pegar crash anterior quando o
  snippet estava atrasado no momento da aposta.

## [1.9.1] — 2026-04-23
- **Crash exato da rodada da aposta no Telegram**, indexado pelo `snap`
  (api_total no momento da aposta). Server calcula
  `k = crashes_total - snap` e pega `crashes[-k]` — o crash da rodada
  apostada, mesmo que várias rodadas tenham passado entre o cashout e
  o envio do Telegram (que é assíncrono via fila). Daemon passou a
  enviar `snap` em todos os eventos hit/miss (real + DRY).

## [1.9.0] — 2026-04-23
- **Cashout confiável via JS armado no browser**: o antigo "polling a
  cada 150ms via CDP" deixava o cashout passar em rounds curtos (o
  avião cruzava o target entre dois polls). Agora, ao colocar aposta
  real, o daemon executa `armCashout(panel, target, betAmount)` no
  iframe — um loop de 20ms no navegador que clica instantaneamente
  assim que o valor do botão / bet ≥ target.
- Daemon consome `checkArmedResult` e registra o mult em que o clique
  aconteceu. Fallback via CDP segue ativo pra raros casos onde o arm
  falha.
- `cancelArmed(panel)` é chamado ao registrar miss ou ao final da
  aposta pra não deixar timers pendentes.
- Polling principal aumentado pra 50ms quando algum painel está em
  flight com aposta aberta (antes 150ms fixo) — reduz atraso do
  fallback.

## [1.8.9] — 2026-04-23
- **Crash no Telegram agora sempre = última detecção do feed**, igual
  ao card "ÚLTIMO NÚMERO DETECTADO" da aba PAINEL. O server ignora o
  campo `crash` enviado pelo daemon e usa `state['crashes'][-1]` no
  momento da composição — mesmo valor visível pro usuário. Fallback
  pro valor do daemon só se o feed estiver vazio.

## [1.8.8] — 2026-04-23
- **Bug fix crash no Telegram (hit e miss)**: antes pegava
  `crashes[-1]` (último crash do feed) — quando o daemon atrasava um
  tick, `api_total` já tinha pulado +2 e o último crash era de uma
  rodada POSTERIOR. Agora o índice é exato: `crashes[-k]` onde
  `k = api_total - snap_da_aposta`. Assim, mesmo se o loop pula
  rodadas, pega o crash da rodada em que a aposta foi colocada.

## [1.8.7] — 2026-04-23
- **Crash correto no Telegram em hit real**: antes o daemon enviava
  `mult` (o multiplicador do cashout) como crash — estava errado. Agora
  o hit é adiado (`pending_hits[p_idx]`): daemon aguarda a rodada
  terminar (`api_total > snap`), pega o último crash do feed e só
  então posta o evento `info hit=True` com o crash REAL da rodada.
  Fallback pro cashout_mult só em caso de timeout de 60s.
- **Mensagem do Telegram enxuta**: removida a linha `[P1] hit: ...` /
  `[P1] miss: ...`. O formato agora é só:
  ```
  ✅ GANHO +R$2,00
  🎯 Target: 2.00x
  ✈️ Crash: 2.83x
  P&L hoje: ...
  ```
- Sub-label do status box de cooldown mais explícito:
  "cooldown após perda" / "cooldown após ganho" / "cooldown".
- `cooldownAfterWin` agora é aplicado quando o `pending_hit` resolve,
  não no instante do cashout (mantém consistência com o novo fluxo).

## [1.8.6] — 2026-04-23
- **Status box mostra cooldown** quando o bot não pode apostar por
  estar em cooldown (após perda, após ganho ou cooldown geral): label
  muda pra **"AGUARDANDO X RODADAS"** em **amarelo**, sublinha indica
  a causa (após perda / após ganho / cooldown). Prioridade: cooldown
  sobrepõe IA e trigger.
- Daemon reporta o estado via novo endpoint
  `POST /api/autoclick/panel_state` (só quando valor muda — evita
  tráfego). `GET /api/autoclick/status` expõe `panel_cooldowns`.
- UI puxa a cada 2 s no pollAutoStatus e re-renderiza o status box
  dos painéis.

## [1.8.5] — 2026-04-23
- Mensagens do Telegram de ganho/perda agora incluem **Target apostado**
  e **Crash da rodada** em 2 linhas extras:
  ```
  ✅ GANHO +R$2,00
  🎯 Target: 2.00x
  ✈️ Crash: 2.05x
  [P1] hit: +R$2,00
  P&L hoje: ...
  ```
- Daemon passa `target` e `crash` em todos os eventos hit/miss (real
  e DRY). Para miss real, pega `crash` do último crash do feed do
  backend.

## [1.8.4] — 2026-04-23
- **Bug fix "Retomar agora"**: botão não estava funcionando porque o
  daemon detectava `paused→unpaused` e rodava checagem de shadow,
  estendendo a pausa imediatamente. Agora distingue:
  - `paused_until == 0` → cancelamento manual → retoma direto.
  - `paused_until > 0` mas < now → expirou natural → avalia shadow.
- **IA continua aprendendo durante parada técnica**: shadow bets agora
  gravam linha em `bets` com `amount=0` (pra não sujar P&L real) e
  incrementam `panels_stats` (V/D/IA sobem no placar do painel).
  - Alimenta `pattern_bet_history` e CALIBRAÇÃO por faixa de prob.
  - AUTO-AJUSTE (pnl_per_unit) ignora linhas com `amount=0`, então
    shadow não afeta threshold dinâmico — só o aprendizado causal.
- Daemon `post_shadow_result` envia target, pattern e probability;
  server persiste junto com o hit.

## [1.8.3] — 2026-04-23
- Pill "ATIVO — CLICANDO" / "SIMULAÇÃO" agora **só aparece quando o
  bot está de fato operando**. Some quando bot desligado ou em parada
  técnica (nesse caso o banner âmbar no topo já comunica o estado).
- pollAutoStatus re-renderiza o pill a cada 2 s pra refletir transições
  de parada/retomada.

## [1.8.2] — 2026-04-23
- Status box dos painéis (AGUARDAR/ENTRADA) com **dobro da altura**
  (min-height 96px) e segunda linha mostrando a **aposta efetiva** em
  R$, com badge do tier (BASE / MÉDIA ×2 / ALTA ×5) quando a "aposta
  dinâmica por confiança" está ativa. Atualiza em tempo real conforme
  a prob. da IA muda ou o usuário edita os parâmetros.
- Threshold de retomada da parada técnica **70% → 50%**. Simulação
  agora precisa acertar ≥ 50% dos sinais pra bot voltar a operar.
  UI do banner e logs atualizados.

## [1.8.1] — 2026-04-23
- **UI dos painéis de auto-click minimalista**: só fica exposto `Aposta`,
  `Target` e uma caixa grande de status `ENTRADA` (verde) ou
  `AGUARDAR` (vermelho). Todas as demais opções (Usar IA, aposta
  dinâmica, entry trigger, cooldowns, horário) vão pra uma seção
  colapsável aberta via botão **"Avançado ▾"** no pé de cada painel.
- Nenhuma lógica mudou — só reorganização visual. Toggle do botão é
  independente por painel. Pressionar ou alterar qualquer campo dentro
  do Avançado continua disparando o dirty-tracking normal.
- Status box reflete: painel desativado → AGUARDAR; painel ativo sem
  IA → ENTRADA; painel com IA → aprovação do gate.

## [1.8.0] — 2026-04-23
- **Shadow evaluation durante parada técnica**: bot continua avaliando
  o mercado em **simulação silenciosa**, acumulando acertos/erros por
  painel em `shadow_stats` (zerado a cada nova pausa, preservado em
  extensões). Usa o mesmo gate IA + entryTrigger + janela de horário.
- **Retomada condicionada a 70% de acerto**: ao expirar a pausa, o
  daemon verifica:
  - Se a simulação teve < 5 sinais → estende 10 min (poucos dados).
  - Se hit rate em simulação < 70% → estende 10 min com motivo
    "Performance em simulação X% — mantendo parada".
  - Se ≥ 70% e ≥ 5 sinais → retoma operação real com log
    "✓ Retomando: simulação X/Y = Z% de acerto".
- Novo endpoint `POST /api/autoclick/shadow` (daemon reporta resultado
  simulado). `GET /api/autoclick/status` agora inclui `shadow_stats`.
- Pause POST aceita `extend: true` pra acumular shadow em vez de
  resetar; `trigger_tech_pause` do daemon usa isso nas extensões.
- Banner da UI mostra terceira linha em simulação:
  "Simulação: 4/8 = 50.0% acerto (mínimo 70% pra retomar)" — cor muda
  pra verde/vermelho conforme está acima/abaixo do limite.

## [1.7.0] — 2026-04-23
- **Probabilidade estimada persiste por aposta** (`bets.probability`) e
  alimenta uma nova camada de aprendizado.
  - Migração adiciona coluna `probability REAL` + índice
    `(panel, target, probability)` (backward compatível, apostas
    antigas ficam NULL).
  - Daemon envia `probability=prob` nos eventos `bet` e `dry`.
  - Handler persiste em `bets.probability`.
- **Nova camada de aprendizado — CALIBRAÇÃO por faixa de prob**: a IA
  cruza a prob. estimada com apostas passadas de mesmo painel+target e
  prob. parecida (±5pp). Se a IA é overconfident na faixa, corrige pra
  baixo; se é underconfident, corrige pra cima. Ativa a partir de 5
  apostas na faixa, peso cresce até 100% aos 10+.
- Reasoning da UI ganha linha "CALIBRAÇÃO: na faixa X–Y% a IA acertou
  H/N = Z% de verdade. Ajuste ±Npp".
- Novo endpoint `GET /api/analytics/ia` retorna top padrões por hit
  rate, hit rate por faixa de probabilidade (decis 0–100%) e hit rate
  por painel+target, com `count`, `hits`, `pnl` e `rate`.

## [1.6.1] — 2026-04-23
- Texto do motivo da parada técnica por streak trocado de
  "streak de N perdas seguidas" → **"Tivemos N perdas consecutivas"**.
- Banner reformatado em duas linhas: título "PARADA TÉCNICA" no topo e
  subtítulo explicativo abaixo (ex: "3 Perdas consecutivas — A Parada
  Técnica foi acionada com o objetivo de reduzir a elevada probabilidade
  de manipulação de mercado.").
- Estilo mantido na paleta âmbar, mas ícone maior e layout vertical
  no bloco central pra acomodar o texto.

## [1.6.0] — 2026-04-23
- **Parada técnica em vez de desligar o bot** (stop-loss, stop-win,
  streak de perdas): o bot fica inativo por um tempo configurável mas
  continua vivo observando o mercado — não desliga mais o toggle.
- Novo campo nos limites compartilhados: **"Duração da parada técnica
  (minutos)"** (default 30).
- Novo endpoint `POST /api/autoclick/pause` com `{minutes, reason}` e
  `{minutes: 0}` para cancelar.
- `/api/autoclick/status` agora retorna `paused_until`, `pause_reason`
  e `pause_remaining`.
- **Banner countdown no topo da tela** quando em parada técnica: mostra
  motivo, tempo restante no formato mm:ss, e botão "Retomar agora" pra
  encerrar manualmente.
- Ao ativar pausa, `loss_streak` é zerado pra não redisparar assim que
  sair. Reset de stats também limpa a pausa.

## [1.5.4] — 2026-04-23
- **PARADA AUTOMÁTICA agora desliga o bot** de verdade: ao bater
  stop-loss, stop-win ou streak máxima de perdas, o daemon imediatamente
  POSTa `enabled=false` em `/api/autoclick/config`. Antes só logava o
  evento e seguia tentando nas próximas rodadas.
- Novo evento no feed: `Bot desligado automaticamente (toggle OFF)` ou
  `Falha ao desligar bot via API — desligue manualmente` em caso de erro.

## [1.5.3] — 2026-04-23
- **Config do Telegram agora persiste em disco** (`data/telegram.json`).
  Antes ficava só em memória e voltava pro default (`enabled=false`) a
  cada restart do server, silenciando mensagens até o usuário salvar de
  novo. Boot carrega; update via UI salva.

## [1.5.2] — 2026-04-23
- **Bug fix aposta dinâmica**: UI salvava os thresholds em percentual
  (85, 70) enquanto o daemon comparava contra a probabilidade em fração
  (0.74). Resultado: comparação `0.74 ≥ 85` nunca era verdadeira e toda
  aposta caía na base. Agora o daemon normaliza (>1.5 divide por 100)
  antes de comparar.

## [1.5.1] — 2026-04-23
- **Telegram robusto**:
  - Envio assíncrono via fila + worker em thread (hot-path do handler
    não bloqueia mais por até 5 s esperando a API do Telegram).
  - **Retry automático 3× com backoff** (0.4s, 0.8s, 1.2s).
  - Timeout por tentativa subiu de 5 s → 10 s (rede lenta não dropa).
  - Falha persistente gera evento visível: `Telegram falhou (3x): ...`
    no feed do auto-click — antes era silencioso via `except: pass`.
  - `html.escape()` no texto da mensagem do evento antes de montar o
    HTML (evita erro 400 quando o `msg` tem `<`, `>` ou `&`).
  - Teste da aba Telegram continua síncrono (pra retornar status real
    imediato na UI); eventos do bot vão pela fila.

## [1.5.0] — 2026-04-23
- **Aposta dinâmica por confiança da IA** (por painel, requer `useIA`):
  novo toggle "Aposta dinâmica por confiança" com 2 tiers configuráveis:
  - Prob. alta ≥ X% → multiplica a base (default 85% → 5×).
  - Prob. média ≥ Y% → multiplica a base (default 70% → 2×).
  - Abaixo → aposta base normal.
  - Preview ao vivo no card: "≥85% → R$5 · ≥70% → R$2 · abaixo → R$1".
- Daemon loga tier e valor final: `[Px] confiança ALTA (91% ≥ 85%) ×5 →
  aposta R$5,00`.

## [1.4.1] — 2026-04-23
- **Bug fix cooldown após perda/ganho**: `loss_wait_until` e
  `win_wait_until` usavam `api_total + N` (sem o `+1` que o `cooldown`
  normal já tinha), então `cooldownAfterLoss=1` bloqueava só 0 rodadas
  efetivas. Agora vale `api_total + N + 1` — N significa exatamente
  "pular N rodadas antes de reanalisar". DRY miss também ganhou o log
  "aguardando N rodada(s) após perda" que faltava.

## [1.4.0] — 2026-04-23
- **IA agora auto-ajusta thresholds por painel** conforme resultado das
  últimas 25 apostas aprovadas. Calcula `pnl_per_unit` (retorno por R$
  apostado) e escala a margem (EV+) e o piso absoluto:
  - Perdendo muito (≥ −33% por R$): margem sobe até 25%, piso até 40%.
  - Ganhando muito (≥ +33% por R$): margem cai até 10% (mínimo seguro),
    piso até 25%.
  - Break-even: mantém 15% margem + 30% piso (baseline).
- Gate expõe `adaptive.{margin_pct, prob_floor, recent_ia}` no JSON pra
  a UI poder exibir em que regime está.
- Reasoning: linha **AUTO-AJUSTE** descreve pnl recente e os thresholds
  resultantes (ex: "últimas 25 apostas retornaram −R$12,40 sobre R$25,00
  → margem 25% · piso 40%").

## [1.3.1] — 2026-04-23
- **IA muito mais defensiva (resolve "aprova 10x com 15%")**:
  - Piso absoluto de **30%** na probabilidade final — nenhum target
    é aprovado abaixo disso, mesmo que o critério teórico permita.
  - Margem sobre break-even subiu **10% → 15%** (EV exigido mais gordo).
  - **Suavização Bayesiana** do hit rate de padrão e do hit rate causal
    (prior k=5 puxa amostras pequenas pra o teórico). Evita que 2/5 =
    40% em padrão raro vire estimativa inflada; mantém 2x estável sem
    histérese em 10x.
  - Reasoning da UI mostra "bruto X% · suavizado Y%" pra ficar claro de
    onde a probabilidade vem.

## [1.3.0] — 2026-04-23
- **Cooldown após ganho por painel**: novo campo `cooldownAfterWin`
  (default **2 rodadas**). Depois de cada hit, o painel espera N rodadas
  antes de reanalisar. Aplica tanto em produção quanto em simulação.
- Daemon: variável `win_wait_until[p_idx]` checada no gate de entrada.
  Log só na transição: `[Px] aguardando N rodada(s) após ganho pra
  reanálise`.

## [1.2.1] — 2026-04-23
- CSS: inputs de horário (`input[type=time]`) com fundo preto e texto
  branco (`color-scheme: dark` + ícone invertido) pra combinar com o
  tema escuro.

## [1.2.0] — 2026-04-23
- **Horário por painel**: cada painel ganhou campos "Ligar às" e
  "Desligar às" (HH:MM). Janela que cruza meia-noite é suportada
  (ex: 22:00–06:00). Quando os dois campos ficam vazios o painel opera
  24h (comportamento atual).
- UI mostra sob os campos: "Dentro do horário" (verde) ou "Fora do
  horário — em espera" (amarelo), atualizado a cada 30 s.
- Daemon checa a janela antes de apostar e loga `[Px] fora da janela
  HH:MM–HH:MM` só na transição (sem spam).

## [1.1.1] — 2026-04-22
- **Bug fix**: em DRY-RUN os contadores da IA ficavam `0/0` porque o
  handler só contava eventos `kind='bet'`. Agora contabiliza `'bet'` e
  `'dry'` (gatilhando apenas no evento com `amount > 0` pra não
  duplicar entre colocação e cashout simulado). Apostas em simulação
  também passam a gravar linha em `bets` com o padrão — aprendizado
  causal funciona em SIM, não só em real.

## [1.1.0] — 2026-04-22
- **IA agora aprende causalmente por padrão**: cada aposta grava o padrão
  (cauda quantizada) em `bets.pattern`. Em decisões futuras, a IA cruza
  esse padrão com o target e ajusta a probabilidade pelo hit rate REAL
  (apostas resolvidas). Causal supera observacional.
- **Margem obrigatória de 10% sobre o break-even**: aprovar só quando
  `p_adj ≥ teórico × 1.10`. Evita aprovar apostas de EV ≈ 0 (como o
  target 3.0 aprovando com 33.3% quando teórico é 33.0%).
- **Aprendizado global mais assertivo**: threshold cai de 5 → 3 decisões,
  penalidade máxima sobe de −30pp → −50pp, bônus máximo sobe de +10pp →
  +15pp.
- `/api/intelligence/gate` passa a retornar `pattern_bet_history`,
  `approve_threshold` e `pattern_bet_corr` no JSON.
- Migração DB: coluna nova `bets.pattern` (nullable, backward compatível)
  + índice em `(pattern, target)`.

## [1.0.2] — 2026-04-22
- **Bug fix DRY-RUN**: simulação agora resolve cada aposta baseada no
  crash real da rodada (`api_state.crashes[-1]`). Antes, o daemon lia o
  DOM do botão de cashout — que fica nulo em DRY-RUN — e toda rodada
  virava miss, inclusive acertos (daí "acertos negativos" no saldo).
- Apostas DRY são marcadas com flag `dry=True` e ignoram o caminho de
  cashout via CDP (que só faz sentido em aposta real).
- Delta simulado agora é `amount × (target − 1)` no hit e `−amount` no
  miss, refletindo um cashout exatamente no target.
- P&L pill do topbar ganha fundo cinza (+ sufixo "· SIM" no label)
  quando `dryRun` está ativo.

## [1.0.1] — 2026-04-22
- Scripts `install.sh` e `start.sh` atualizados com a marca **IRONDOME**.
- Preparado pacote de distribuição publicado em site público (Vercel).

## [1.0.0] — 2026-04-22
- Rebrand para **IronDome** (título, brand do topbar, notificações).
- Aba **SOBRE** ao lado de TELEGRAM com versão, data de release e changelog.
- Endpoint `/api/version` retornando `{version, release_name, release_date}`.
- A partir deste release toda alteração do sistema é versionada aqui.

## [0.x] — histórico pré-IronDome (resumo)
- Persistência SQLite em `data/aviator.db` (crashes + bets).
- Análise por padrão de sequência nas últimas 300 rodadas (quantização
  BAIXO/MÉDIO/ALTO/TOPO, cauda atual vs histórico).
- IA aprende com W/L por painel (penalidade após 5 resoluções).
- Contador V/D/IA no topo de cada painel.
- IA espera ≥50 rodadas antes de avaliar.
- Aba Telegram, bot toggle global, P&L pill, efeito GREEN, etc.
