# Mapeamento AVIV (coreproviders) vs cabine Monetarie: sintese executiva

Data: 2026-07-09. Mandato do dono: mapear de forma extensa e exaustiva `/Users/luizpenha/coreproviders/*` (AVIV, recorde de 1,53M transacoes PIX em um dia em 08/07) contra a cabine Monetarie, cobrindo o money path completo (recepcao OnZ vs BACEN direto, PIX-in, PIX-out, MED e infracoes, PostgreSQL, TigerBeetle e o tb-gateway em Go, escala). Meta: a Monetarie aguentar muito mais volume com latencia menor.

Metodo: 7 trilhas paralelas de pesquisa read-only, cada afirmacao com evidencia arquivo:linha nos dois repositorios, sem chamadas AWS (prova de runtime fica registrada como pergunta aberta quando necessaria). Relatorios detalhados:

| Trilha | Arquivo |
|---|---|
| Conectividade OnZ vs BACEN direto | `01-conectividade-onz-vs-bacen.md` |
| PIX-in money path | `02-pix-in.md` |
| PIX-out money path | `03-pix-out.md` |
| MED, infracoes, devolucoes | `04-med-infracoes-devolucoes.md` |
| PostgreSQL, particionamento, consistencia | `05-postgres-dados.md` |
| TigerBeetle e tb-gateway Go | `06-tigerbeetle-tb-gateway.md` |
| Escala e performance (1,53M tx/dia) | `07-escala-performance.md` |

## 1. ACHADO CRITICO P0 (verificado pelo orquestrador, alem das trilhas)

**Com o codigo vivo em `origin/main` (76b1dc17, mesmo lineage de pix-api:20 e core-api:8 em producao), o primeiro PIX-in organico NAO credita o cliente no Core automaticamente.** Cadeia de evidencia, conferida linha a linha:

1. A cabine, com flag OFF, publica `monetarie.spi.transaction.created` via outbox duravel (`pix/backend/apps/spi_service/lib/spi_service/workers/inbound_processor.ex:931`; `pacs008_event_type/0` em :2858 retorna `"created"` quando `two_phase_pix_in_enabled` e false). Nenhum evento `settled` e publicado para entrada: `advance_inbound_credit_to_accc/1` (:2472) e apenas `Repo.update` local, e o recebedor nunca recebe pacs.002 (canonico 09/07), entao o `StatusUpdater` nunca dispara para essa linha.
2. O Core roteia o evento em `core/backend/lib/monetarie/infra/nats/consumers/pix_consumer.ex:174-184`: `AtomicPaymentHandler.maybe_handle/2` retorna `:not_found` para entrada (nao existe `outbound_request`) e cai em `PixHandler.handle_transaction(payload, "created")`.
3. Essa clausula e **audit-only desde o commit `7c6957c5` de 25/06** (`core/backend/lib/monetarie/infra/nats/handlers/pix_handler.ex:53-65`): loga, grava audit `PIX_TRANSACTION_CREATED` e retorna `:ok` sem tocar ledger. O credito untracked so existe na clausula `"settled"` (:112-116, flag OFF leva a `handle_transaction_ledger`), evento que ninguem emite para PIX-in.

Consequencia pratica: a cabine credita a Conta PI, responde ACSP e avanca a linha a ACCC (o BACEN fica satisfeito), mas TB, `account_entries`, extrato do IB e tarifa nao acontecem no Core. O cliente nao ve o dinheiro. A docstring da cabine ("When false -> created (legacy, Core catch-all credits immediately)", inbound_processor.ex:2853-2854) descreve um contrato que deixou de existir em 25/06. O handoff canonico de 09/07 (linha 23) e o runbook do primeiro PIX (pernas 5 a 8) afirmam o caminho antigo; os "6 audits PIX_TRANSACTION_REJECTED_UNTRACKED" provam o transporte NATS vivo, nao o caminho de credito. No incidente de 09/07 o credito foi manual (`Wallet.deposit`), entao esse elo nunca foi exercitado em producao.

**Decisao do dono necessaria (nao aplicada por este mapeamento):**
- Opcao A: restaurar o credito untracked em `created` no PixHandler, mantendo as guardas F-07 (rejeicao nunca credita).
- Opcao B: a cabine emitir evento explicito de liquidacao de entrada (por exemplo `transaction.settled` com `direction: INBOUND` apos `advance_inbound_credit_to_accc`) e o Core creditar por ele. Mais correto semanticamente, exige mudanca nos dois lados.
- Em qualquer caso: teste de contrato cross-repo cabine para Core (evento publicado vs clausula consumida), para essa classe de quebra nunca mais passar silenciosa; e enquanto nao fechar, o runbook do primeiro PIX deve tratar "audit PIX_TRANSACTION_CREATED sem credito TB" como desfecho esperado do codigo atual, com remediacao manual pronta (caminho provado do incidente).

## 2. Modelo mental: os dois desenhos

| Dimensao | AVIV (coreproviders) | Monetarie |
|---|---|---|
| Participacao PIX | Indireta (ISPB 04838403, liquidante 05684234) via OnZ CloudPIX | Direta no BACEN (ISPB 46026562) |
| Transporte | HTTP porta 80 sem TLS via VPC peering, token de sessao 55min, long-poll 6 slots (lease Redis), p50 471ms / p99 737ms | mTLS ICP-Brasil (sidecar Go assina handshake no HSM), ICOM 6 slots CPM (idle 200ms, re-poll imediato) + 6 CSM, 24-28ms |
| PIX-in | Two-phase ACSP -> ACCC, deposito so em ACCC, 3+ round-trips HTTP por transacao | BACEN liquida ANTES da pacs.008; uma fase; TWO_PHASE_PIX_IN proibido |
| Broker | Nenhum (NATS descomissionado); sweepers compensam | NATS JetStream com outbox atomico (enforcement triplo) e DLQ/poison |
| Ledger | TigerBeetle 0.17.3 (tigerbeetlex) + tb-gateway Go gRPC (batching nativo; leitura ligada nos 4 ambientes, escrita pronta dormente) | TigerBeetle 0.17.3 (tigerbeetlex vendored), 1 transfer sincrono por evento, batching escrito porem morto |
| PG | Aurora 17.9, particao RANGE mensal, pools writer 100 / reader 50 / batch 10, read-split, checkpoint fold horario | Aurora, particoes equivalentes (8 tabelas no Core), pool unico 30 (Core) e 4x5 (cabine), checkpoint fold diario |
| Seguranca de mensagem | Nao valida assinatura nem XSD do que recebe da OnZ | XMLDSig verify inbound, HSM sign + gate XSD outbound, fail-CLOSED |

A vantagem estrutural da Monetarie e real e nao deve regredir: entrada 17x mais rapida, uma fase a menos no PIX-in, sem teto externo de provedor, cadeia regulatoria fail-closed e replay via JetStream (ja salvou R$50k no incidente NATS de 07/05). O que a AVIV tem de melhor e a malha operacional em volta do volume: medicao de envelope, batching de TB, segmentacao de pools, read-split, checkpoint horario, sweepers e monitores. E exatamente o que falta portar.

## 3. Prioridades consolidadas (dedup das 7 trilhas)

### P0 (antes de qualquer volume real)

1. **Elo do credito PIX-in no Core** (secao 1). Bloqueia a validacao do primeiro PIX real.
2. **Medir o envelope proprio**: portar a suite de benchmark da AVIV (projeto standalone, collector em telemetry spans, resultados versionados) e medir TPS sustentado do pipeline pacs.008 -> credito com breakdown por fase. Hoje nao existe nenhum numero de capacidade da Monetarie (trilha 07).
3. **Endurecer o consumo NATS do Core**: PixConsumer e irmaos em consumer duravel JetStream com redelivery e max_ack_pending (padrao ja existe no BaseWorker da cabine); consertar o pull do SpbConsumer que nunca e puxado. O incidente de 24h surdo (07/05) ja mostrou o custo (trilha 07).
4. **TigerBeetle hardening minimo**: (a) parar de achatar erro transiente em `:account_not_found` no lookup (mesma classe do laudo AVIV 2026-05-19; `core .../infra/tigerbeetle.ex:120-125`); (b) portar o ClientOwner (self-heal de eviccao) para o tigerbeetlex vendored; (c) `:telemetry.span` em todas as ops TB (trilha 06).
5. **PG quick wins de producao**: prefold HORARIO do BalanceCheckpoint (a AVIV pagou incidente de ACU em 08/07 para aprender); `application_name` em todos os pools + `statement_timeout` na cabine; Oban Reindexer + alarme de bloat do GIN de oban_jobs; defasar offsets dos crons (trilha 05).
6. **Sidecar mTLS: TLS session resumption** (`ClientSessionCache` em `pix/services/bacen_mtls_sidecar/main.go`), validando antes que o gateway RSFN aceita; corta uma viagem ao HSM por conexao nova (trilha 01).
7. **MED antes de haver trafego MED**: dispatch do DictConsumer do Core quebrado (mismatch subject vs clausula), subject `monetarie.dict.infractions.response` sem consumidor na cabine, colisao de semantica de `blocked_amount` entre processor legado e drainer portado, e auto-DISAGREED por saldo insuficiente (pior desfecho regulatorio; portar cenarios partial/zero da AVIV) (trilha 04).
8. **Medir a saturacao da task lider do ICOM** (12 workers numa unica task via advisory lock) sob carga sintetica em HML; se saturar, portar o modelo de lease por slot (trilha 01).
9. **PIX-out: nunca `Repo.delete` em erro ambiguo do TB** no orquestrador do Core (deixa stage 0 + sweeper idempotente; a AVIV teve exatamente esse incidente em 01/07) (trilha 03).

### P1 (escala e resiliencia)

- **Batching TB**: adotar o tb-gateway Go em fases identicas as da AVIV (Fase 1 leitura com fallback NIF, Fase 2 escrita com contrato not_sent/ambiguo), recalibrando deadlines para o ANS 1,6s; ou, como ponte, portar o DepositCoalescer (provado em prod AVIV: p99 TB de 1561ms para 219ms). Tratar o BatchAccumulator dormente como codigo a substituir. Nunca escalar subindo TB_POOL_SIZE as cegas (teto hard clients_max=64) (trilha 06).
- **Split de sessao TB** `:tb_bulk` (reconcilers e dashboards fora do money path) com breaker dedicado (trilha 06).
- **Reconciliacao de orfaos de PIX-in dirigida pela verdade BACEN** (camt.054 CRDT persistidas vs creditos aplicados por E2E): teria pego o incidente de 09/07 em minutos (trilha 02).
- **PG**: BatchRepo (pool separado), ReadRepo com read-split por dominio (exige reader Aurora em prod), COSIF fora do hot path do PIX-in, rollups por conta para admin, purga batelada com cap para tabelas unbounded (trilha 05).
- **PIX-out**: fila de retentativa com TTL + VoidGuard (evidencia camt.060/053 antes de estornar), StuckOutboundChecker de deteccao para resolucao assistida, kill switch global + teto por transacao, atacar a serializacao do espelho PI (linha unica por ISPB) com medicao antes (trilha 03).
- **Observabilidade de money path**: monitor de OK-rate do PIX-in, janela rolante de lag ICOM com alerta, profundidade de DLQ/poison; consolidar PERF logs num painel p50/p95/p99 por fase com SLO interno de cauda abaixo de 500ms (trilhas 01, 02, 07).
- **WAL de estado do credito no Core** (row por E2E: recebido / tb_done / pg_done + recovery idempotente) cobrindo crash entre TB e PG (trilha 02).
- **Sweep de inbox ICOM** (cron 1min para IcomReceived nao publicado) e classes de prioridade no DictBudget (trilha 01).
- **MED**: ligar ObligationCheck/DrainHelper no caminho de saida, unificar os dois cautelares (claim da cabine dispara hold no Core), watchdogs de prazo de defesa (trilha 04).
- **Deploy zero-5xx em producao** como padrao Terraform: desired >= 3, minHealthy 66 / maxPct 117, grace 120s, slow_start (trilha 07).

### P2

IDs semanticos TB derivados do E2E (lookup reverso O(1)); breaker TB lock-free (atomics); AuditBuffer com spill; retencao por DETACH/DROP de particao em trilhas; tarifa do PIX-in no mesmo batch TB do credito; formalizar a disciplina "nunca resetar TB, compensacao via code dedicado" (estilo 9116 da AVIV); unificar as 3 fontes divergentes de TB_POOL_SIZE; proto v1 do gateway com two-phase pending/post/void (escrow usa pending).

### NAO PORTAR (temos melhor)

- Long-poll, slots de provedor, cursor/MGMT-fallback e token de sessao: nossa entrada direta e estruturalmente superior.
- Two-phase PIX-in (TWO_PHASE_PIX_IN segue PROIBIDO; gatilho settled so existe no simulador).
- Remocao do broker: endurecer o consumo NATS, nao remover (a AVIV perdeu replay ao descomissionar).
- Deadlines da AVIV copiados sem recalibrar: nosso budget e o ANS BACEN de 1,6s.
- Limite noturno Res.142: a AVIV removeu o enforcement; o nosso fica.

## 4. Perguntas abertas que exigem runtime ou decisao do dono

1. Decisao Opcao A vs Opcao B do elo de credito PIX-in (secao 1).
2. Valores vivos em task-def (TB_POOL_SIZE, concurrency de consumers, flags) em HML e prod; 3 fontes divergem no repo.
3. Tamanho real dos lotes multipart do ICOM sob carga e latencia por chamada sign-rsa do HSM (derivar dos PERF logs de prod).
4. O gateway RSFN aceita TLS session resumption (pre-requisito da P0.6).
5. Saturacao real: task lider ICOM, linha unica do espelho PI, transacoes PG por credito (a AVIV mediu ~30 por deposito e declarou teto estrutural).
6. O recorde de 1,53M tx/dia (08/07) nao consta nos docs versionados da AVIV (maiores numeros no repo: 561k/dia em 01/07 e 670k PIX-in/24h em 07/07); a fonte e a medicao AWS da sessao Monetarie de 04/07 registrada no handoff.

Cada trilha mantem a propria lista de NAO VERIFICADO no relatorio correspondente.
