# Plano unico do ecossistema Monetarie: best-of-breed em ondas (PIX, SPB, Core)

Data: 2026-07-02. Fase D (sintese final) do mandato de paridade e best-of-breed, tudo aprovado pelo dono.

Este documento consolida os tres relatorios de paridade ja escritos e commitados numa unica fila de execucao:

- `docs/reports/2026-07-02-paridade-pix-legadopix.md` (PIX cabine vs LegadoPIX vs AutBank, 160 itens, 5 P0 + 18 P1)
- `docs/reports/2026-07-02-paridade-spb-legadospb.md` (SPB cabine vs Evolution SPB vs AB_MGI, 155 itens, 4 P0 + 11 P1)
- `docs/reports/2026-07-02-paridade-core-coreproviders.md` (Core vs coreproviders/AvivPay, 193 itens, 9 P0 + 15 P1)

Mais duas investigacoes empiricas read-only feitas nesta fase (duplo-debito no PIX-OUT e quantificacao do vazamento de saldo PI), verificadas no codigo vivo e no `mon_pix` desta sessao.

Estado do repositorio: `origin/main` = `c236b619`; deploys HML `pix-api:92`, `spb-api:26`, `core-api:79`; money-path parcial (`reason_code` + `revert_block`) ja deployado. Este plano parte desse estado.

Regra de leitura: todo item traz sistema, esforco (S/M/L), risco, dependencias e a marca money-path quando toca saida de dinheiro (exige teste automatizado, revisor e validacao viva regra #11 antes de declarar entregue). Nenhum item deste plano pode alterar os INTOCAVEIS da secao 2 sem prova empirica de nao regressao.

---

## 1. Resumo executivo do ecossistema

### 1.1 Principio-base

A base Monetarie e a verdade viva, validada empiricamente contra o BACEN de homologacao. Os legados (LegadoPIX/AutBank, Evolution SPB/AB_MGI) e o coreproviders/AvivPay sao fonte de regras de negocio e de correcoes ja pagas em producao, nao substitutos da base. Toda absorcao entra por cima do que ja esta vivo, nunca por baixo. Quando o BACEN responde diferente do esperado, o defeito e nosso e precisa ser provado (regra permanente do dono).

### 1.2 Onde cada sistema esta forte e fraco

PIX (cabine). Forte: nucleo nativo com o BACEN (mTLS verify_peer, XMLDSig via HSM RTM 443, CID sync com sync-verification, canal ICOM com persistencia antes do ACK, DICT v2.11.0, camt.060 6/7), debit-then-send com estorno atomico, MED 2.0 com bloqueio parcial e em cadeia, dedup inbound em 3 camadas, rate limit inbound por categoria. Fraco: duplo-debito sistematico no saldo espelho PI (money-path, detalhe na secao 3.1), todo o lado inbound do DICT sem polling (reivindicacoes, relatos de infracao e MED recebidos), automacoes construidas porem sem gatilho (timers de claim, MED respondente, OTP de posse stub 501), transferencia interna mesmo-ISPB inexistente, pipeline do arquivo de extrato ausente (tx 199 presa), kills cronicos do CPM, overlap de 3 tabelas para o mesmo fluxo.

SPB (cabine). Forte: ciclo de vida com timeline R0/COA/COD/R1/R2/R3, grade horaria auto-ingerida e enforcada, cripto v3 AES-256-GCM com chave so no HSM, self-service de certificados (trilhas A e B) com T010 ativado no BACEN, MQ SPB01 vivo, STR0008 inbound com credito automatico, contrato de saldo por mensagem portado do Evolution, catalogo com 1.766 tipos. Fraco: dupla autorizacao nao enforcada no envio (qualquer usuario dispara ao BACEN em 1 passo), CancellationEngine sem call-site, subsistema Liquidante decidindo contra saldos fabricados, 3 defeitos de catalogo (financial_flag "S" inexistente, value_tag com colchetes, semantica GEN0014-0018 invertida), LPI0006 apenas registrado sem espelhar a Conta PI, 49 legs de resposta ausentes.

Core. Forte: profundidade bancaria de SCD participante direto (razao PG `account_entries` ao centavo, COSIF com A=P+Resultado, overdraft com juros/IOF, tarifas com vedacoes BACEN e pacotes, SISBAJUD fim a fim, e-Financeira transmissivel, tesouraria BCB, Partner API OAuth2 versionada com OpenAPI, materializacao PIX fonte-unica NATS, cabine PIX como motor de BR Code). Fraco: fixes de producao que o coreproviders ja fez e o Core ainda nao (PIX-OUT/TED sem enforcement de limites, CRC do parser BR Code errado, geracao de QR do IB invalida, cobranca de parceiro nao persistida, idempotency de parceiro em escopo global, PLD que nunca roda, TimeBlock/IP whitelist inertes, export de tarifas que finge sucesso).

### 1.3 Direcao best-of-breed

Manter o Monetarie como base canonica (inclusive a cabine PIX, superior ao caminho via provedor OnZ do coreproviders) e absorver do coreproviders os fixes de conformidade BR Code, enforcement de limites e janelas na saida, hardening de webhooks, conciliacao por external_id, o pacote MED de backoffice e a durabilidade da trilha de auditoria. Dos legados PIX/SPB, portar as regras de negocio que faltam (transferencia interna, devolucao automatica pacs.004, alcada no envio, cancelamento protocolar, LPI0006, arquivo de extrato) e corrigir os defeitos de catalogo provados por banco. O proprio coreproviders confirma a direcao: o `MELHORIAS.md` deles registra que o admin regulatorio e contabil foi portado do core Cecresa (nossa linhagem).

### 1.4 Regra de port permanente (unidade monetaria)

O coreproviders usa subcentavos (1 BRL = 10.000 MoneyUnit) em parse EMV e saidas de API; o contrato Monetarie e CENTAVOS na borda (commit `f79e17fa`). Nenhum codigo de valores pode ser copiado sem conversao de unidade e teste; e a mesma familia do bug de comprovante 100x ja corrigido no IB em 2026-06-30. Da mesma forma, qualquer port que toque saida de dinheiro entra pelo caminho locked existente, com teste e prova viva; novos dispatchers de webhook nascem com indice de dedup e guard fail-closed; a geracao/validacao EMV fica consolidada na cabine (encoder IN-508), o Core roteia via behaviour e NATS e nunca duplica EMV em controller.

---

## 2. INTOCAVEIS consolidados (a implementacao NAO pode quebrar)

Estes caminhos foram validados empiricamente contra o BACEN de homologacao e sao a base do mandato. Nenhum item das ondas pode altera-los sem validacao empirica de nao regressao (regra #11). Consolidacao dos intocaveis dos tres relatorios:

Cripto, canais e certificados
1. HSM RTM 443: assinatura e decifra de PIX e SPB exclusivamente via `https://monetarie-hsm-hml.priv.rtmcloud.net.br` (HTTPS 443, vHSM 60042). Proibido reintroduzir `:6443`; chave privada nunca em repositorio ou arquivo (o `OurCertStore` rejeita PEM com bloco privado por design).
2. mTLS verify_peer com cadeia ICP-Brasil pinada, `customize_hostname_check`, depth 5 e `partial_chain` (`shared/application.ex:194-241`); `Host` sem porta no canal BACEN (root-cause fix validado vivo).
3. Assinatura XMLDSig com normalizacao xmllint e chave privada no HSM por chamada (`xml_signer.ex`); verificacao inbound fail-closed DS01.
4. Cert T010 ativado no BACEN via GEN0006/GEN0006R1 (2026-06-30), `BACEN_CERT_PEM_FILE=monetarie_spb_t010.pem`, `BACEN_CONTROL_PREFIX=MON`, certs reais T068 (SPB01) e T069 (MES01) da AC SERPRO. Self-service de certificados (trilhas A e B), pickup em runtime sem restart, GEN0006 dual-key dormente.

Transporte e mensageria
5. MQ SPB01 vivo: sidecar `spb-mq-sidecar` na task do `spb-api` (`:26`), `IBM_MQ_ENABLED=true`, canal APP.SVRCONN `:1514` com MCAUSER `spb_server`, trafego real comprovado. Contrato commit-apos-persistencia do `InboundAudit` preservado (zero janela de perda).
6. Invariante persistencia antes do ACK no long-poll ICOM, com dedup por message_id, republish no boot e eleicao de lider por advisory lock (`icom/cpm/worker.ex`, `ack_tracker.ex`, `coordinator.ex`). O fix dos kills do CPM muda so o sinal de vida, nao o protocolo pull-next.
7. CID sync completo (full 6h + eventos 5min + POST /sync-verifications) e GetEntry com `PI-EndToEndId`, validados vivos.
8. Mapa camt.060 das 7 acoes (6/7 vivo) e materializacao SADP/SABK com proveniencia honesta; cadeia de gates do outbound (validate, sanctions, sign, XSD pos-assinatura, fail-closed).

Dinheiro e contabilidade
9. TigerBeetle 0.17.3 com overdraft em software (SCD): flag `debits_must_not_exceed_credits=false` por design, limite por `BalanceGuard.verify_with_overdraft`. Nao regredir para o modelo IP do coreproviders (flag true, sem credito).
10. Razao PG `account_entries` validada ao centavo pos-ETL (saldo de clientes R$ 1.795.946,61 conferido vivo): fonte canonica do extrato.
11. COSIF com periodos contabeis e A=P+Resultado ao centavo (R$ 2.103.031,84 conferido), balancete e DRE, vedacoes SCD (conta de pagamento 4.9.8, nunca 4.1).
12. Debit-then-send com estorno atomico fail-closed na cabine e `void_and_fail` atomico e idempotente no Core (hold TigerBeetle); correlacao multi-estrategia de pacs.002/admi.002; guard de estado terminal; dedup em 3 camadas do inbound.
13. STR0008 inbound com credito automatico em conta de pagamento (classificador CtPgtoCredtd, fix 79ae2077), validado vivo. O gate de alcada da onda 1 atua no OUTBOUND, antes do RealDispatcher; o inbound nao e tocado.
14. Diretorio SPB automatico (140 para 547 participantes, commit 75e3feb9, vivo em `:26`).

Plataforma e integracao
15. NATS JetStream + outbox ADR-008: eventos duraveis da cabine (qrcode generated/paid, settlement) e materializacao PIX no Core (fonte unica, guard monotonico, Oban */15, reprocesso admin). Comprovante, extrato e status leem so o Core; lookup pontual por E2E na cabine; sem fallback SQL.
16. Cabine PIX como motor unico de BR Code e cobranca: encoder IN-508, CobV com `CobvCalculator` fiel ao LegadoPIX, payload JWS CERTQRC fail-closed e `/qrc/jwks`, gate AG03/AC03/AM09/DUPL.
17. Partner API validada com a Vulci: OAuth2 client_credentials com scope intersection, `/api/partner/v1` versionado, OpenAPI/Swagger vivo, segredo de webhook cifrado e server-minted com rotate/test/replay, escopos method-keyed, TED e onboarding de clientes via API.
18. Retencao regulatoria de 10 anos fixa em codigo com particionamento e purge automaticos (nao regredir para retencao configuravel em dados BACEN).

Observacao de fronteira: os itens de onda que tocam modulos vizinhos do caminho inbound vivo (semantica do CoaCodHandler, destino do Liquidante, alcada no envio) exigem plano de validacao empirica (reproduzir STR0008 e GEN0006R1 em HML antes e depois) como criterio de aceite.

---

## 3. Backlog unificado em ONDAS

Deduplicado entre os tres relatorios e agrupado por tema. A referencia entre parenteses aponta o item de origem (ex.: PIX P0-1, SPB P1-5, Core P0-4).

### 3.1 Nota tecnica sobre o duplo-debito (base da onda 1, item 1)

Confirmado no codigo vivo (`pix/backend/apps/spi_service`) e no `mon_pix` desta sessao. Todo PIX-OUT decrementa o `available` da conta espelho PI (ISPB 46026562) DUAS vezes:

1. `CoreEventProcessor.check_and_block_balance` chama `Balances.create_block`, que faz `available -X` e `blocked +X` (`balances.ex`, bloco de `create_block`; a atualizacao de saldo confirmada por leitura direta).
2. No aceite HTTP/ICOM, `OutboundSender` chama `debit_pi_balance` (`outbound_sender.ex:87` no ramo BACEN e `:318` no ramo simulador), que faz `update_balance(:debit)`, ou seja `available -X` de novo, e em seguida `confirm_block`, que so faz `blocked -X` sem creditar `available` (a propria docstring de `confirm_block` afirma "does NOT credit available").

Resultado liquido no aceite: `available -2X`, `blocked 0`. A propria docstring de `revert_block` documenta a sequencia de dois debitos. O `revert_block` recem-deployado credita apenas `+X` no ramo `:confirmed`, entao corrige so metade do rejeitado e nada do liquidado.

Magnitude medida ao vivo (read-only): understatement do espelho de R$ 4,08 (camt.053 do BACEN R$ 9.160.772.444,16 vs `available` local R$ 9.160.772.440,08); R$ 2,04 presos em 6 blocks `confirmed` nunca revertidos (inclui as 2 tx rejeitadas 232 e 233); perna do debito nao estornada das 4 tx rejeitadas com bloco `confirmed` = R$ 1,03, e a restauracao total do `available` dessas 4 tx = R$ 2,06 (perna do debito + perna do hold). Ressalva importante: `balances.available` esta hoje com `source=camt.053` (sobrescrito pela posicao do BACEN as_of 2026-07-02), entao o dano nao e um buraco no `available` ao nivel BACEN (foi realinhado a verdade do BACEN), e sim integridade do ledger local (blocks presos + history duplicado) e o make-whole do cliente no Core. As 7 rejeicoes anteriores (msgs 100-104, 133, 134, R$ 0,01 cada) ja foram estornadas em 2026-07-02 e net = 0; nao entram no backfill. Itens adjacentes: 10 blocks `active` orfaos de 2026-06-25 (R$ 10,00 em hold, tambem debitados) e a msg 199 em ACSP nao terminal (ja duplo-debitada, monitorar por camt.060).

Fix (item 1 da onda 1): remover `debit_pi_balance` dos 2 callsites do OutboundSender, pois `create_block` ja e o debito de `available` e `confirm_block` finaliza pelo `blocked`; mover a trava de reserva minima PI para dentro do `create_block` (hoje mora no `update_balance(:debit)`); corrigir o `Map.put_new` do credit-back (`status_updater.ex:328-332` e `handle_timeout:425`); backfill rastreavel dos R$ 2,04 presos + reconciliar os 10 orfaos; reconciliacao periodica `available` vs camt.060/053. E o item mais critico da onda porque e minusculo em valor (massa R$ 0,01 a R$ 1,00 em HML) mas SISTEMATICO em 100% dos PIX-OUT que chegam a status 2.

### 3.2 ONDA 1: dinheiro, risco e honestidade (fazer primeiro)

Criterio da onda: defeito confirmado de dinheiro, seguranca ou honestidade. Nada de feature nova antes de fechar esta onda.

| # | Item | Sistema | Esforco | Money-path | Risco | Dependencias |
|---|---|---|---|---|---|---|
| 1 | Duplo-debito PIX-OUT: remover `debit_pi_balance` dos 2 callsites do OutboundSender; mover trava de reserva minima para o `create_block`; corrigir `Map.put_new` do credit-back (`status_updater.ex:328-332` e `:425`); backfill rastreavel dos R$ 2,04 presos em 6 blocks confirmed + reconciliar os 10 orfaos de 06-25; reconciliacao periodica `available` vs camt.060/053 (PIX P1-2 aprofundado + investigacoes) | PIX cabine | M | Sim | Medio (toca o saldo espelho; nao toca o caminho SPI validado) | Nenhuma |
| 2 | Limites PIX-OUT/TED: portar `Limits.{LimitCheck,FlowLimits,TransactionLimits,UsageCache}` e chamar `LimitCheck.verify` dentro do caminho locked do outbound (`outbound_orchestrator`/`transaction_pipeline`), como `cp/.../pix_out/balance_check.ex:348` (Core P0-1) | Core | M | Sim | Medio (converter unidade cp->centavos; testes obrigatorios) | Nenhuma |
| 3 | TimeBlock enforcement: portar `Admin.TimeBlocks.Check` e invocar no gate outbound (Core P0-8) | Core | S | Sim | Baixo | Nenhuma |
| 4 | CRC do parser BR Code: `mon/use_cases/pix/brcode/parser.ex:32` computa `compute_crc16("#{payload}6304")` com payload que ja termina em 6304; trocar por `compute_crc16(payload)` + teste com payload real (Core P0-2) | Core | S | Nao | Quase nulo | Nenhuma |
| 5 | Geracao de QR do v2: substituir o BR Code hardcoded sem CRC (`monweb/v2/pix_controller.ex:588-590`) adicionando callback `generate_qrcode` ao behaviour de provedores + action NATS reusando o encoder IN-508 da cabine (Core P0-3) | Core + PIX cabine | M | Nao | Baixo (rotear para a cabine, nao duplicar EMV) | Nenhuma |
| 6 | Resolver de QR dinamico de terceiros: handler NATS `consult_qrcode` na cabine + cliente HTTP que busca a location URL e valida o JWS contra o JWKS do PSP recebedor (Core P0-5) | PIX cabine + Core | L | Nao | Baixo (so leitura + validacao JWS) | Item 5 (callback no behaviour) |
| 7 | Persistir a cobranca do Partner `create_charge` como linha em `qr_codes` (status active + `expires_at` real) antes do 201 e despachar `pix.charge.created` (Core P0-4). Confirmado 07-02: `create_charge` monta brcode e responde 201 sem nenhum `Repo.insert` | Core | M | Sim (conciliacao) | Baixo | Nenhuma |
| 8 | Idempotency-Key da Partner API: escopar a chave Redis por `api_key.client_id`/partner_id (hoje cai em `idempotency:anonymous:<key>`, permitindo replay cruzado entre parceiros); nao copiar o plug do cp (defeito analogo) (Core P0-6) | Core | S | Sim (cross-tenant) | Baixo | Nenhuma |
| 9 | Export de detalhe de tarifas: portar o pipeline real (worker Oban + S3) OU remover as rotas e a tela stub que responde `ready` falso com UUID fake (`admin/coreproviders_parity_controller.ex:1306-1312`) (Core P0-7) | Core | S remover / M portar | Nao | Baixo | Decisao do dono (portar ou remover) |
| 10 | Gate de dupla autorizacao no envio SPB: ligar `AlcadaEngine` no `MessagesController.send` (e em todo funil que chame `process_outgoing`), estado `awaiting_approval` antes do dispatch, envio automatico pos-aprovacao e trava `approver != created_by`; entra ANTES do RealDispatcher (SPB P0-1) | SPB cabine | M | Sim (retem envio) | Medio (exige flag de rollout) | Pendencia D: alcada e da cabine ou do Core |
| 11 | Destino do subsistema Liquidante: desativar atras de flag ou remover o `Processor` + `BalanceManager` que decidem contra saldos ETS fabricados (R$ 100M/50M) e auto-respondem LDL0002/LTR0002/CMP0002/SLC0002; resolve a dupla reivindicacao de LDL0001/0021/LTR0001/CMP0001 (SPB P0-4) | SPB cabine | M | Sim | Medio (caminho inbound vivo; validar STR0008/T010/MQ antes e depois) | Pendencia D: ativar ou remover |
| 12 | Fiar o `CancellationEngine` ao `POST /api/operations/:id/cancel` e bulk-cancel: emitir a mensagem protocolar por grupo (STR0011R1/SEL1400/CIR/RDC/ECR/DDA0400) e reverter saldo, em vez do UPDATE local atual (`operations_controller.ex:384-427`); grep confirma zero call-site hoje (SPB P1-1) | SPB cabine | M | Sim | Medio (divergencia de estado com o BACEN se ficar so local) | Nenhuma |
| 13 | Investigacao AB03 sistematico: 2/2 outbound em HML aceitas (HTTP 200) e rejeitadas com AB03 ~40s depois; comparar a pacs.008 assinada real vs Catalogo 5.12 (PmtId/TxId presente, AppHdr Fr/To pos-assinatura) + pareamento E2E consulta-pagamento; encerrar so com uma pacs.008 liquidada (ACSC) viva (PIX P1-3) | PIX cabine | M | Sim (PIX-OUT nao liquida) | Baixo (leitura + eventual fix de builder) | Nenhuma |

### 3.3 ONDA 2: paridade de regras de negocio

Criterio da onda: regra de negocio ausente ou defeito de catalogo provado, sem o carater de vazamento imediato de dinheiro da onda 1 (embora varios toquem money-path novo).

| # | Item | Sistema | Esforco | Money-path | Risco | Dependencias |
|---|---|---|---|---|---|---|
| 1 | Transferencia interna mesmo-ISPB: short-circuit book-transfer no `CoreEventProcessor`/Core quando `creditor_ispb = 46026562` (hoje PIX intra-Monetarie vai ao BACEN e consome ficha DICT), + redirect PIX intra-instituicao no IB via `channel=tef` (commit `9e12e3c3` do cp) (PIX P0-1 + Core P1-6) | PIX cabine + Core | M | Sim (money-path novo) | Medio (nao toca o caminho SPI) | Nenhuma |
| 2 | Devolucao automatica pacs.004 quando o credito settled nao puder ser aplicado (conta encerrada/bloqueada pos-validacao), reusando o `ReturnProcessor` (PIX P0-2) | PIX cabine | M | Sim | Medio (reusa fluxo de return existente) | Nenhuma |
| 3 | DICT inbound cluster: worker Oban por dominio para reivindicacoes recebidas, relatos de infracao recebidos e refunds MED recebidos, usando os clients ja prontos (`dict_client.ex:432/660/923`), materializando local + evento NATS; ligar os timers do ciclo de claim (consumer dos subjects donor/claimer timeout ou Oban cron chamando `auto_confirm`/`auto_cancel`, hoje codigo morto em `claims.ex:421/462`); conectar o gatilho MED respondente (poller aciona `create_fraud_claim` + `apply_cautelar_block`/`apply_partial_block`, maquina completa sem chamadores) (PIX P0-3 + P0-4 + P0-5) | PIX cabine | M | Parcial (MED bloqueia saldo de cliente) | Medio (prazo regulatorio de acknowledge; exigir testes no ramo MED) | Nenhuma |
| 4 | Validacao de posse de chave (OTP email/SMS) nos 5 endpoints hoje stub 501 (`ownership_controller.ex`) + amarracao a `create_entry` e ao `complete_claim` (obrigacao do Manual DICT) (PIX P1-17) | PIX cabine | M | Nao | Baixo | Item 3 (mesmo dominio inbound DICT) |
| 5 | Reason code do pacs.002 fim a fim: extrair `StsRsnInf/Rsn/Prtry` no parser (`message_parser.ex:378-399`, hoje so `RjctgPtyRsn`/`RsnDesc` que nao existem no pacs.002 RJCT) + Core passar `reason_code`/`reason_description` ao `move_to_failed`; + estado seguro para TxSts desconhecido (gravar MessageHistory + flag de revisao em vez de drop com warning, `inbound_processor.ex:1450-1452`) (PIX P1-1 + P1-12) | PIX cabine + Core | S | Nao | Baixo | Nenhuma |
| 6 | Semantica do `CoaCodHandler`: GEN0014/0015 = requisicao/aviso de arquivo, GEN0017/0018 = arquivo via prestador / data de ativacao de certificado (provado por `AB_MGI.EVENTOS`); hoje usados como abertura/fechamento de dia, em conflito com o proprio `file_transfer/orchestrator.ex`. Nao acionar esse fluxo vivo antes do fix (SPB P0-2) | SPB cabine | S | Nao | Medio (modulo vizinho do inbound vivo; validar GEN0006R1 antes e depois) | Nenhuma |
| 7 | LPI0006 segunda onda: materializar `spb_operation`, postar no grupo 43 via `Posting.post` e espelhar o saldo da Conta PI; avaliar LPI0007/0008 na mesma frente; reprocessar as mensagens reais acumuladas em HML como evidencia; + handler LPI minimo no PIX (classificar por MsgDefIdr, persistir, alertar, LPI0006 ~2/dia) (SPB P0-3 + PIX P1-13) | SPB cabine + PIX cabine | M | Sim (espelho de reserva) | Baixo | Nenhuma |
| 8 | Politica de backout/poison no sidecar MQ: ler `JMSXDeliveryCount` e acima de N entregas mover para quarentena commitando a sessao, mantendo commit-apos-2xx no caminho feliz; hoje falha permanente de webhook gera loop de redelivery a cada 5s (SPB P1-5) | SPB sidecar | M | Nao | Baixo | Nenhuma |
| 9 | Defeitos de catalogo SPB provados por banco: trocar `financial_flag == "S"` (dominio real F/N/D/T/A/C, zero linhas "S") pelo par correto ("F" e "D") em `message_type_driver.ex:64,77`; normalizar colchetes do `value_tag` no `extract_amount` (`[VlrTit]` em 39 tipos, etc.) (SPB P1-2 + P1-3) | SPB cabine | S | Sim (previsao de saldo/contabilizacao) | Baixo | Nenhuma |
| 10 | Semear os 49 legs de resposta ausentes: 43 R-legs do catalogo 5.11 + 6 SCG R1 do DDA, com `direction_flag='R'`, grid/flags herdados do leg base e tag definitions correspondentes (SPB P1-4) | SPB cabine | S | Nao | Baixo | Nenhuma |
| 11 | Pipeline do arquivo de extrato BACEN: handler camt.052 + download mTLS + unzip + parse `RELACAO_LANCAMENTOS.csv` + log de downloads; desbloqueia a tx 199 (arquivo de extrato); + tela/API de downloads (PIX P1-7 + P2-19) | PIX cabine | L | Nao | Medio | Nenhuma |
| 12 | Conciliacao diaria real: 3 vias contra `monetarie_spi.messages` (nao a tabela paralela vazia) + conciliacao de saldo persistida por data com alerta (SPB tem o esqueleto; PIX precisa da fonte certa) (PIX P1-8) | PIX cabine | M | Nao | Baixo | Item 11 (arquivo de extrato) |
| 13 | Remover overlap de 3 tabelas: apontar `transaction_controller`/`return_controller`/`statements`/`balances` para `monetarie_spi.messages`, corrigir a fonte dos statements da cabine e o opening balance 0,00; aposentar `monetarie_spi.transactions` (PIX P1-14 + P2-13) | PIX cabine | M | Nao | Medio (toca leituras de API, nao a escrita canonica) | Nenhuma |
| 14 | Refund UX segura no Core: endpoint refund-info por E2E (lendo a cabine) + validacao `direction=inbound`/ownership no `return_pix` antes de segurar fundos; a cabine ja protege o dinheiro, a UX permite tentativas invalidas (Core P1-5) | Core | M | Sim | Baixo | Nenhuma |
| 15 | Conciliacao do parceiro: aceitar `external_id` no envio + GET por E2E e por external_id/ref + reason codes BACEN estruturados (dicionario central compartilhado com webhooks) (Core P1-4 + reason codes) | Core | M | Nao | Baixo | Nenhuma |
| 16 | ReceivingBlacklist PIX-IN: schema + use case fail-open ETS + tela admin + gate no credito PIX-IN (portar do cp; casa com os casos MED) (Core P1-10) | Core | M | Sim (barra credito) | Baixo | Nenhuma |
| 17 | Substituir o mock do StatisticsController por `get_person_statistics`/`get_key_statistics` reais e usar na decisao antifraude (dados falsos sao pior que ausencia) (PIX P1-16) | PIX cabine | S | Nao | Baixo | Item 3 (dominio DICT) |

### 3.4 ONDA 3: operacao, UX e compliance

Criterio da onda: robustez operacional, experiencia e compliance que nao vaza dinheiro hoje mas fecha risco regulatorio, promessa de produto e trilha probatoria. O item 1 (PLD) e um P0 regulatorio no relatorio Core; foi colocado aqui por ser assincrono pos-liquidacao (nao bloqueia money path), mas o dono pode puxa-lo para a onda 1 se a exposicao COAF/BCB pesar mais.

| # | Item | Sistema | Esforco | Money-path | Risco | Dependencias |
|---|---|---|---|---|---|---|
| 1 | PLD vivo: portar `TransactionMonitorWorker` (Oban queue compliance) e enfileirar na materializacao PIX/TED do Core (hoje `evaluate_transaction` tem zero chamadores); no mesmo PR, adicionar regra de sancao por transacao e aplicar `PiiMask` nos logs do monitor (Core P0-9) | Core | M | Nao (async pos-settlement) | Regulatorio alto se nao fizer | Nenhuma |
| 2 | Webhooks honestos e hardening: adicionar `pix.return.received`, `pix.payout.queued/held`, `pix.infraction.*`, `webhook.test` a `@valid_events`; limpar/ligar os eventos aspiracionais (boleto/account/transfer/sta sem dispatcher); ligar dispatchers de payout a partir da materializacao; dedup por UNIQUE INDEX parcial, eager deliver pos-commit, guard fail-closed `transaction_is_settled?` antes de evento terminal, WebhookRetryChecker + sweeper de backstop (Core P1-1 + P1-2) | Core | M | Nao | Baixo | Nenhuma |
| 3 | Expiracao ativa de QR: agendar `expire_dynamic_qr_codes` (hoje sem caller, `qr_codes.ex:985`) + publicar NATS expired/cancelled + dispatch `pix.charge.expired`/`cancelled` no Core (Core P1-3) | PIX cabine + Core | M | Nao | Baixo | Item 2 (whitelist de eventos) |
| 4 | Repositorio de feriados nacionais/municipais: tabela + tela + import das 384 linhas do staging + trilha; destrava CobV dia-util, alcada por dia-util e limites por janela (PIX P1-11 + Core P2-19 + SPB) | PIX cabine + Core | S/M | Nao | Baixo | Nenhuma |
| 5 | Motor de alertas operacionais persistente: catalogo + limiares + destinatarios + historico + email Swoosh + ack real; inclui vencimento de certificado diario, `StuckOutboundChecker` publicando alerta e echo pibr.001 periodico (5min) com evidencia + probe alimentando o CircuitBreaker (PIX P1-5 + P1-9) | PIX cabine | L | Nao | Baixo | Item 4 (dia-util para email so em dia util) |
| 6 | PIX agendado one-off: schema `pix_scheduled` + worker de execucao (cron 1min) + POST create + opcao de data futura no `PixSendView`, no Core/IB reusando `payment_request` (Core P1-8 + PIX P1-15, dedupe) | Core + PIX cabine | M | Sim | Medio | Nenhuma |
| 7 | SMS real no onboarding PJ: ligar `Step4SmsView` aos endpoints `/auth/mfa/sms/send` e `/verify` ja existentes no backend; unico ponto de verificacao simulada do IB (Core P1-7) | Core (IB) | S | Nao | Baixo | Nenhuma |
| 8 | Trilha de auditoria probatoria: `AuditBuffer` com spill em disco + `SpillRecoveryWorker`; `entity_id` + particionamento por `inserted_at` em `audit_logs`; export + meta-auditoria de VIEW/EXPORT; anexar `AuditPlug`/`audit_context` a pipeline `partner_authenticated`; trilha before/after de parametros (configs, alcada, fees, jobs, certs) (Core P1-13 + P1-11 + SPB/PIX P2-17) | Core (+ cabines) | L | Nao | Baixo | Nenhuma |
| 9 | Self-service de limites (apos decisao do dono): leitura real nas telas `PixLimitsView`/`LimitsView` + endpoint persistido de solicitacao com aprovacao no admin (reducao imediata, aumento com espera) (Core P2-10 + P1 telas) | Core (IB + admin) | M | Sim (define limite) | Baixo | Pendencia D (self-service de limites) + onda 1 item 2 (pacote de limites) |
| 10 | Kills do CPM: heartbeat via ETS antes e depois do `Finch.request` (ou pull em Task supervisionada) para o `HealthMonitor` deixar de julgar liveness por `GenServer.call` de 5s enquanto o long-poll legitimo dura ate 60s; nao mexer no protocolo pull-next/pre-ACK (PIX P1-4) | PIX cabine | S/M | Nao | Medio (toca o canal ICOM) | Nenhuma |
| 11 | Postura de acesso: IP whitelist do admin com enforcement (plug + access log append-only + modo `preview_would_deny`) e IP whitelist fail-closed por key na Partner API (ou opt-out explicito aprovado); ambas hoje sao regra inerte com tela (Core P1-12 + P1-11) | Core | M | Nao | Baixo (preview evita lockout do time) | Nenhuma |
| 12 | MED backoffice: `manual_cautelar_block` + parametrizacao/enriquecimento de infracao + `OrphanHoldReconciler` (void por `user_data_128` real do TB) + blocked-breakdown cruzando TB `debits_pending` com MED/in-transit/judicial; exigencia dura de dono white-label (Core P1-9) | Core | M | Sim (hold de cliente) | Baixo | Nenhuma |
| 13 | Corrigir alvo do `KycReviewWorker` (consulta `cooperative_members` da heranca cooperativa; apontar para a base de clientes SCD) (Core P1-14) | Core | S | Nao | Baixo | Nenhuma |
| 14 | Acoes de mesa de destravamento no SPB: bloqueio/desbloqueio manual de transacao individual (status 45/2000-2002 catalogados), voltar-status controlado (reusa `validate_transition`) e SOS-envio com alcada propria; endpoint admin + tela gravando `operation_events` (SPB P1-7) | SPB cabine | M | Nao | Baixo | Pendencia D (escopo SOS/PAG) |
| 15 | Ingestao automatica de certs de participantes BACEN (reusar a trilha A do SPB: `bacen_domain_certificates` + refresh sem restart); antes, provar em HML um inbound assinado por outro PSP para medir risco DS01 (PIX P1-6) | PIX cabine | M | Nao | Medio | Nenhuma |
| 16 | Orcamento client-side dos baldes DICT: contador Redis por balde relevante + penalidade + restituicao de ficha no settled (PIX P1-18) | PIX cabine | M | Nao | Baixo | Item 3 (dominio DICT) |
| 17 | Remover mocks de monitoracao: logs sinteticos de `build_service_log_entries` (crypto rand) e ack no-op de alertas por fonte real ou vazio honesto; viola a regra do dono de zero dado fabricado (PIX P2-18) | PIX cabine | S | Nao | Baixo | Item 5 (motor de alertas) |
| 18 | AccountAccess + SubcontaCreator: acesso delegado PJ com permissions map, daily_limit por operador e expiracao (Core P1-15) | Core | L | Sim (limite por operador) | Baixo | Nenhuma |

### 3.5 Cauda de fundo (P2/P3 nao mexer agora no caminho validado)

Sem detalhamento por item; entram apos as tres ondas ou junto quando houver sinergia. Principais grupos:

- Escala Core: `BalanceCheckpoint` com prefold noturno, `BalanceCache`/`TxStatusCache` de display, `Settings.Registry` tipado runtime (mover tetos hardcoded R$ 10M e thresholds de compliance), rate limit por key persistido, `Statements.Reconciliation` linha a linha PG vs TB, sandbox publica da Partner API, contrato monetario da Partner 100% centavos, suite E2E Playwright do IB, gestao admin de QR paginada, dispatcher diario do interest_accrual de poupanca, notificacao por transacao in-app, sessoes ativas com revogacao por sessao, maker-checker unificado por faixa, CCS legacy_import, behaviour de provedor KYC com fallback, OTP persistido, importador automatico de sancoes.
- Robustez PIX/SPB: idempotency duravel em tabela unique, popular `status_details`/`return_data`, `Audit.log` no `AtomicPaymentHandler`, retencao do Oban `nats_publish`, remuneracao da Conta PI (camt.053 CRE), snapshot EOD de saldo, read-model de consultas DICT, selecao de cert por validade + CreDt, rotacao quente da CPIC, gzip/multipart/TPS atras de flag, dicionario DOMINIOS no pipeline SPB, XSD real no SPB via xmllint, fonte unica da maquina de estados, consolidar os 3 validadores SPB, catalogo self-service no admin SPB, versionamento de manual.
- Higiene e overlaps a remover (apos confirmacao): tabela paralela `monetarie_spi.transactions`, evento `monetarie.spi.status.rejected` sem consumidor, netting sessions da cabine PIX (sem contraparte regulatoria), tabelas `settlements`/`str_transfers` orfas do SPB, facade `mq/connection_pool.ex`, views de boleto orfas do IB, fixar imagem do spb-mq-sidecar por digest, moduledoc do LpiHandler.

---

## 4. Pendencias DIVERGENTE_VALIDAR (decisao do dono ANTES de implementar)

Consolidadas dos tres relatorios. As seis primeiras bloqueiam itens de onda diretamente.

| # | Pendencia | Bloqueia | Pergunta ao dono |
|---|---|---|---|
| D1 | Limite noturno PIX (Res. BCB 142) | Onda 1 item 2 (limites) e onda 3 item 9 | Ligar limite noturno diferenciado? O tipo existe no schema (`global_limit.ex:31-36`) com zero enforcement; o cp desligou por ser IP, mas a Monetarie e SCD participante direto do SPI. Nao duplicar cabine vs Core: o Core cobre o noturno? |
| D2 | Self-service de limites pelo cliente | Onda 3 item 9 | Permitir o cliente reduzir limite imediato e pedir aumento com espera 24-48h no IB? Hoje as telas exibem valores estaticos sem API nos dois cores |
| D3 | SCD opera PAG (CIP) alem de STR? E SLB, RCO de compensacao, CAM (cambio)? | Onda 3 item 14 (SOS), conversao PAG<->STR (P1-8 SPB), telas de mesa | Confirmar as familias que a Monetarie efetivamente opera; define a relevancia da conversao PAG<->STR e do SOS-envio |
| D4 | Destino do subsistema Liquidante | Onda 1 item 11 | Desativar atras de flag (reversivel) ou remover de vez? Decide como fechar a dupla reivindicacao LDL/LTR/CMP |
| D5 | Restaurar `EvolutionPro.bak`, `EvolutionCrypto.bak`, `CRKSecurityAdmin.bak` (em `LegadoSPB/DB`, nao restaurados por regra da tarefa) | Conferencia fina de de-paras, modelo cripto e permissoes/alcadas reais do SPB | Autorizar restauracao pontual read-only em container isolado? Sem eles nao da para re-conferir os 495+89 de-paras na origem nem as permissoes reais (GRUPO_PERMISSAO=0 no MGI) |
| D6 | DDA: ativar ou congelar | Onda de fundo (homologacao E2E do DDA/PCR) | 89 modulos, handler e 12 telas prontos e dormentes; o backup do cliente tem zero trafego DDA (ESTOQUE_TITULOS=0). A Monetarie SCD precisa aderir ao DDA? Se nao, registrar como decisao definitiva |
| D7 | Alcada: responsabilidade da cabine ou do Core a montante | Onda 1 item 10 | Se o dono decidir que a autorizacao e do Core, documentar e rebaixar as telas de alcada/visto da cabine SPB a monitoracao |
| D8 | Trilha contabil da cabine PIX/SPB | Onda 2 item 7 e contabilidade | Semear COSIF fail-fast na cabine OU remover a trilha e deixar o Core como contabilidade unica (preferivel)? Nunca deixar o modo silencioso `else _ -> :ok` |
| D9 | Contrato monetario da Partner API | Onda de fundo (padronizacao) e escalar parceiros | Padronizar tudo em centavos inteiros (entrada E saida) antes de mais parceiros integrarem? Hoje a saida mistura reais decimais |
| D10 | HMAC de corpo nas requisicoes de parceiro | Seguranca da Partner API | Requisito comercial (clientes ex-Simpay) existe? Se sim, assinar bytes crus, nao JSON re-encodado |
| D11 | Redesconto (H/I/J) e deposito de garantia (op V) fora de escopo SCD? | Congelar RdcHandler | A SCD nao e elegivel a redesconto no BACEN; confirmar para congelar o handler como esta |
| D12 | SELIC e SILOC/CIP como contrapartes futuras | Roteamento por contraparte no SPB | O escopo vai incluir camaras? Hoje so existe o par com o BACEN |
| D13 | Fonte e recarga das listas de sancoes | Onda de fundo (importador) | Manter o modelo DB administravel do Monetarie e adicionar importador automatico (OFAC/UN/EU/BCB/COAF) com recarga periodica? |
| D14 | Aprovacao em duas etapas de cash-out de parceiro via API | Produto BaaS | Payout de parceiro acima de limite exige segunda aprovacao? Nenhum dos dois cores entrega limpo hoje |
| D15 | Multi-IF white-label na cabine SPB | Estrutural | Ha plano de white-label no SPB (como na Partner API do Core)? O modelo hoje e single-institution |
| D16 | Netting sessions da cabine PIX | Onda de fundo (remocao) | Remover o aparato (sem contraparte regulatoria para participante direto) ou documentar proposito interno? |
| D17 | Higiene de extrato e regras pos-fork do cp | Onda 3 (validacao regra #11) | Rodar o IB Monetarie contra a lista paga do `MELHORIAS.md` e o `AJUSTES CORE AVIVPAY.docx` como roteiro de validacao empirica; auditar defeitos de linhagem (numero de conta aleatorio, senha vazia na criacao de merchant, timezone do extrato) |
| D18 | Device binding e dark mode no IB | Produto | Entram no roadmap? Exigem backend novo (device binding) ou sao decisao de design (dark mode removido no rebrand) |

---

## 5. Sequencia de execucao e criterio de pronto por onda

### 5.1 Sequenciamento recomendado

1. Antes de comecar a onda 1, coletar do dono as decisoes que bloqueiam itens: D4 (Liquidante), D7 (alcada cabine ou Core) e a escolha portar-ou-remover do export de tarifas (onda 1 item 9). As demais decisoes podem correr em paralelo.
2. Onda 1 em duas frentes paralelas por serem sistemas distintos: frente PIX/cabine (itens 1, 13), frente Core (itens 2, 3, 4, 5, 6, 7, 8, 9) e frente SPB (itens 10, 11, 12). Dentro do Core, os itens 4 (CRC, 1 linha) e 8 (idempotency) sao quick wins imediatos; o item 6 (resolver dinamico) depende do item 5 (callback no behaviour) e pode fechar por ultimo. O item 1 (duplo-debito) e pre-requisito do backfill: primeiro corrigir o codigo, depois rodar o backfill dos R$ 2,04 + 10 orfaos, depois religar a reconciliacao periodica.
3. Onda 2 comeca apos a onda 1 estar deployada e validada viva. Ordem interna: primeiro os itens de menor esforco e sem dependencia (5, 6, 9, 10), depois o cluster DICT inbound (3 e 4), o LPI0006 (7) e as devolucoes/transferencia interna (1, 2, 14). O arquivo de extrato (11) destrava a conciliacao (12), entao 11 vem antes de 12. O overlap de tabelas (13) toca leituras de API, fazer com flag e validacao de nao regressao.
4. Onda 3 e a mais larga; priorizar PLD (1) e webhooks (2) por risco regulatorio e de produto, depois feriados (4) que destrava CobV/alcada/limites, depois o motor de alertas (5) e a trilha probatoria (8). Self-service de limites (9) so apos D2. O restante entra por valor conforme a agenda do dono.
5. Cauda de fundo (P2/P3) entremeada quando houver sinergia (ex.: CCS legacy_import junto do ETL AB/GX/MGI em curso; contrato monetario da Partner junto da sandbox publica).

### 5.2 Criterio de pronto por item e por onda

Para cada item (Definition of Done):
- Codigo com teste automatizado cobrindo o caso corrigido; para money-path, teste do invariante de saldo (ex.: um PIX-OUT liquidado deve debitar exatamente 1X, um rejeitado deve voltar a 0).
- Revisor obrigatorio em qualquer item money-path (marcados "Sim" na coluna) e nos itens que tocam modulos vizinhos dos INTOCAVEIS.
- Build verde e deploy em HML na revisao de task-def correspondente (pix-api, spb-api, core-api), conferido por digest de imagem quando a tag for mutavel.
- Prova viva regra #11: screenshot/metadados e ausencia de erro no validador para telas; para fluxos BACEN, evidencia de mensagem real (ex.: uma pacs.008 liquidada ACSC para encerrar o AB03; o LPI0006 reprocessado espelhando a Conta PI; o STR0008 e o GEN0006R1 reproduzidos antes e depois nos itens vizinhos do inbound).
- Backfill e reconciliacao (quando aplicavel) executados e conferidos ao centavo, com o numero antes e depois anexado.

Para fechar cada onda:
- Onda 1: nenhum PIX-OUT debita mais o dobro (invariante provado em HML com uma tx liquidada e uma rejeitada), os R$ 2,04 presos foram estornados e reconciliados, o parser BR Code aceita um QR real conhecido, a cobranca de parceiro persiste e responde `show_charge`, o gate de alcada SPB retem uma mensagem ate a 2a aprovacao sem regredir STR0008/T010/MQ, o Liquidante esta desligado/removido sem quebrar o inbound vivo, e o export de tarifas nao mente mais. Regenerar os relatorios cliente/interno se houver mudanca de tela.
- Onda 2: transferencia intra-Monetarie nao consome mais ficha DICT, uma devolucao automatica pacs.004 provada, o poller inbound do DICT materializa uma reivindicacao/relato/MED recebido real, o LPI0006 espelha a Conta PI ao centavo, os 3 defeitos de catalogo SPB corrigidos com previsao de saldo/contabilizacao revalidada, a tx 199 destravada pelo arquivo de extrato.
- Onda 3: o PLD roda em toda transacao materializada, o catalogo de webhooks so anuncia eventos com dispatcher real, o repositorio de feriados destrava o CobV dia-util, o motor de alertas dispara e persiste ack, o SMS de onboarding usa os endpoints reais, e a trilha de auditoria sobrevive a crash com spill/recovery.

---

## 6. Nota de metodo

Os vereditos herdam a evidencia direta dos tres relatorios (arquivo:linha no monetarie, nos decompilados do vendor e no coreproviders; procedures e contagens reais nos containers de backup; logs e linhas vivas de HML). Os fatos mais carregados foram re-verificados no codigo nesta sintese: o duplo-debito (`create_block` + `debit_pi_balance` + `confirm_block` sem credito de `available`, com a docstring de `revert_block` documentando a sequencia), o CRC do parser BR Code (`compute_crc16("#{payload}6304")` no Monetarie vs `compute_crc16(payload)` no coreproviders) e o `create_charge` do Partner sem `Repo.insert`. As magnitudes de vazamento vem das duas investigacoes read-only no `mon_pix` vivo desta sessao, com a ressalva de que o `available` do PI esta hoje sob `source=camt.053` (realinhado a verdade do BACEN), entao o dano e integridade de ledger local e make-whole do cliente, nao um buraco no `available` ao nivel BACEN. Fatos com duvida residual foram rebaixados a DIVERGENTE_VALIDAR na secao 4 em vez de afirmados.
