# Paridade Core Monetarie x coreproviders (AvivPay): matriz unica, backlog e decisoes

Data: 2026-07-02. Fase C (sintese) do mandato de paridade e best-of-breed entre o Core Monetarie (`/Users/luizpenha/monetarie/core`) e o coreproviders/AvivPay (`/Users/luizpenha/coreproviders`). Consolida os 5 dominios auditados: (1) ledger/contas/saldos/tarifas/limites, (2) PIX no core, (3) API externa/parceiros/webhooks, (4) operacao/compliance/backoffice, (5) experiencia IB/merchant e jornadas de pagamento.

Convencao de referencias nesta matriz:

- `cp:` = `/Users/luizpenha/coreproviders/backend/lib/fluxiq`
- `cpweb:` = `/Users/luizpenha/coreproviders/backend/lib/fluxiq_web`
- `cpfront:` = `/Users/luizpenha/coreproviders/frontends`
- `mon:` = `/Users/luizpenha/monetarie/core/backend/lib/monetarie`
- `monweb:` = `/Users/luizpenha/monetarie/core/backend/lib/monetarie_web`
- `monfront:` = `/Users/luizpenha/monetarie/core/apps`
- `cabine:` = `/Users/luizpenha/monetarie/pix/backend/apps`

Vereditos: `PARIDADE_OK`, `MELHOR_NO_MONETARIE`, `MELHOR_NO_COREPROVIDERS`, `FALTA_NO_MONETARIE`, `DIVERGENTE_VALIDAR`, `OVERLAP_REMOVER`.

## 1. Resumo executivo

Os dois cores descendem do mesmo ancestral (Owem/fluxiq). O nucleo compartilhado (TigerBeetle double-entry, BalanceGuard min(TB,PG), pipeline outbound staged com recovery, MED holds, billing BaaS, webhooks HMAC com retry, RBAC, case management PLD, fronts Vue/PrimeVue e app Flutter) esta em paridade literal. A divergencia e clara e complementar:

**O Monetarie e superior em profundidade bancaria de SCD participante direto.** Razao PG `account_entries` validada ao centavo pos-ETL, COSIF com periodos contabeis e A=P+Resultado conferido vivo, overdraft com juros/IOF, pacotes de tarifas com franquia e vedacoes BACEN hardcoded, SISBAJUD fim-a-fim com investimentos, e-Financeira transmissivel com XMLDSig, DERE/FGCoop/Registrato, LGPD completo, tesouraria BCB (compulsorio/redesconto), agenda de liquidacao LDL, multi-moeda, Pix Automatico, boleto real via NPC, Partner API OAuth2 versionada com OpenAPI e onboarding BaaS. Nada disso existe no coreproviders.

**O coreproviders e superior em operacionalizacao e nas correcoes pos-fork.** Ele seguiu recebendo fixes de producao depois que o Monetarie forkou, e varios defeitos que ele ja corrigiu continuam vivos no Monetarie. Os achados mais graves, todos confirmados no codigo em 2026-07-02:

1. **PIX-OUT/TED sem limite nenhum**: no Monetarie so o PIX-IN tem LimitCheck; o pipeline outbound valida apenas saldo (`mon/use_cases/payments/` nao contem nenhuma chamada de LimitCheck/TimeBlock fora de `pix_in/`). Um cliente com limites configurados saca acima deles.
2. **Parser BR Code rejeita todo QR valido**: `mon/use_cases/pix/brcode/parser.ex:32` computa o CRC sobre `payload <> "6304"` sendo que o payload ja termina em 6304; o coreproviders corrigiu exatamente isso (`cp/use_cases/pix/brcode/parser.ex:29-32`).
3. **Geracao de QR do IB produz EMV invalido**: `monweb/controllers/v2/pix_controller.ex:588-590` monta BR Code hardcoded com comprimentos errados e termina em `6304` literal sem checksum (comentario `TODO: BRCode module not yet implemented` no proprio codigo).
4. **Cobranca de parceiro nao e persistida**: `create_charge` da Partner API so devolve JSON (nenhum insert), entao `show_charge` da 404, `link_payment` nao encontra a cobranca e nenhum `pix.charge.paid` dispara.
5. **Idempotency-Key de parceiro cai em escopo global**: o plug le `current_user`/Guardian, que a `PartnerBearerAuth` nao seta (ela so atribui `:api_key`), entao toda chamada de parceiro vira `idempotency:anonymous:<key>`, permitindo replay cruzado de respostas entre parceiros distintos.
6. **Monitoramento PLD nunca roda**: `evaluate_transaction` existe mas tem zero chamadores; no coreproviders o `TransactionMonitorWorker` e enfileirado pos-liquidacao PIX.
7. **Regras cadastradas que nao bloqueiam nada**: TimeBlock (janela de horario) e IP whitelist do admin tem CRUD e tela, mas nenhum plug/gate as aplica.
8. **UI que finge sucesso**: o export de detalhe de tarifas do admin e stub que responde `ready` falso com UUID fake (`monweb/controllers/admin/coreproviders_parity_controller.ex:1306-1312`).

A direcao best-of-breed e inequivoca: manter o Monetarie como base canonica (inclusive a cabine PIX, muito superior ao caminho via provedor OnZ do coreproviders) e absorver do coreproviders os fixes de conformidade BR Code, o enforcement de limites/janelas na saida, o hardening de webhooks, a conciliacao por external_id, o pacote MED de backoffice e a durabilidade da trilha de auditoria. O proprio coreproviders confirma a direcao: o MELHORIAS.md deles registra que o admin regulatorio e contabil foi portado "do core Cecresa" (nossa linhagem).

**Regra de port permanente**: 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; essa e a mesma familia do bug de comprovante 100x ja corrigido no IB em 06-30.

## 2. Matriz completa de paridade

Itens que apareceram em mais de um dominio foram deduplicados e constam uma unica vez, no dominio primario, com nota de cruzamento. Contagem pos-dedupe: 193 itens.

### 2.1 Dominio 1: ledger, contas, saldos, tarifas e limites

| Feature | coreproviders | Monetarie | Veredito | Acao |
|---|---|---|---|---|
| Ledger double-entry TigerBeetle (wallets, transfers, holds pending/post/void) | `cp/use_cases/wallet/wallet.ex:1-40` | `mon/use_cases/wallet.ex:1-50` | PARIDADE_OK | Nenhuma; modelo TB do Monetarie e intocavel por mandato |
| Razao PG por conta (`account_entries` assinado, lotes, reversao) validada ao centavo | AUSENTE (extrato via TB history + `transactions`) | `mon/schemas/accounts/account_entry.ex` + `use_cases/accounts/entries.ex`; saldo de clientes R$ 1.795.946,61 conferido em HML | MELHOR_NO_MONETARIE | Manter como fonte do extrato |
| Enforcement de limites transacional/diario/mensal em PIX-OUT e TED | `cp/use_cases/payments/pix_out/balance_check.ex:348` (LimitCheck.verify dentro do lock) + `limits/limit_check.ex:36-46` | AUSENTE no outbound: `mon/use_cases/payments/outbound_orchestrator.ex:59-73` e `transaction_pipeline.ex:98-108` so validam saldo (confirmado por grep em 07-02) | FALTA_NO_MONETARIE | **P0**: portar `Limits.{LimitCheck,FlowLimits,TransactionLimits,UsageCache}` e ligar no caminho locked |
| Resolver unificado de limites em 4 niveis (conta > primaria > GlobalLimit > default) com cache 15min p/ pix_in/pix_out/ted | `cp/use_cases/limits/transaction_limits.ex:1-70` + `flow_limits.ex` | `mon/use_cases/payments/pix_in/limit_resolver.ex` (so PIX-IN, sem cache) | FALTA_NO_MONETARIE | Portar junto com o item anterior (mesmo pacote) |
| Cache de uso diario/mensal na checagem PIX-IN (UsageCache TTL 15min) | `cp/use_cases/limits/usage_cache.ex:1-35` | `mon/use_cases/payments/pix_in/limit_check.ex:47-57` (SUM no PG a cada verificacao) | MELHOR_NO_COREPROVIDERS | Absorver o cache quando o pacote de limites for portado |
| Limite noturno PIX (Res. BCB 142) | Check inerte de proposito (`cp/use_cases/limits/limit_check.ex:20-25,66-71`, removido por diretiva) | Tipo existe no schema (`mon/schemas/limits/global_limit.ex:31-36`), zero enforcement | DIVERGENTE_VALIDAR | Decisao regulatoria com o dono (secao 5, item D1) |
| Gestao de limites self-service pelo cliente (reducao imediata, aumento com espera). Cruza com dominio 5 (PixLimitsView/LimitsView) | Merchant so leitura; UI de edicao local-only sem POST (`cpfront/banking/src/views/pix/PixLimitsView.vue:141-160`) | Ausente; telas exibem valores estaticos sem API (`monfront/banking/src/views/pix/PixLimitsView.vue`) | DIVERGENTE_VALIDAR | Decisao com o dono (D1); se aprovado, ler limites reais + solicitacao persistida com aprovacao no admin |
| Bloqueio operacional por janela de horario (TimeBlock). Cruza com dominio 4 | `cp/use_cases/payments/outbound_payment/orchestrator.ex:283-284` (verify no gate) + `admin/time_blocks/check.ex` | CRUD + tela existem (`mon/schemas/settings/time_block.ex`, `monweb/.../time_blocks_controller.ex`), enforcement AUSENTE (grep confirmado 07-02) | FALTA_NO_MONETARIE | **P0**: portar `TimeBlocks.Check` e invocar no outbound |
| GlobalLimit (9 tipos canonicos) com cache ETS e invalidacao em CRUD | `cp/schemas/limits/global_limit.ex` + `global_limit_cache.ex` | `mon/schemas/limits/global_limit.ex` + `global_limit_cache.ex` | PARIDADE_OK | Nenhuma (port literal) |
| Unidade monetaria canonica (MoneyUnit, conversao so em boundaries) | `cp/util/money_unit.ex:5-56` (subcentavos em varios pontos de saida) | `mon/util/money_unit.ex:6-61` + contrato CENTAVOS na borda (`f79e17fa`) | PARIDADE_OK | Regra de port da secao 6 se aplica a qualquer codigo copiado |
| BalanceGuard anti-phantom-credit: saldo seguro = min(TB, PG) | `cp/use_cases/payments/pix_out/balance_guard.ex:41` | `mon/use_cases/payments/balance_guard.ex:62-147` + `verify_with_overdraft:175-193` | PARIDADE_OK | Nenhuma; Monetarie generalizou e adicionou overdraft |
| Cheque especial / saldo devedor (juros bps, IOF diario+adicional, fatura, journal COSIF) | AUSENTE (IP nao concede credito; TB flag `debits_must_not_exceed_credits=true`) | `mon/use_cases/accounts/overdraft_engine.ex` + `overdraft.ex` + `overdraft_journal.ex` + `wallet.ex:29-38` | MELHOR_NO_MONETARIE | Nao regredir para o modelo IP |
| Flag TB `history: true` nas contas de cliente | `cp/use_cases/wallet/wallet.ex:14` | `mon/use_cases/wallet.ex:36-38` (sem history) | DIVERGENTE_VALIDAR | Decisao D2: flags TB sao imutaveis; decidir antes de criar volume de contas novas |
| BalanceCheckpoint (saldo canonico PG particionado com prefold noturno) | `cp/use_cases/payments/pix_out/balance_checkpoint.ex` + worker prefold | AUSENTE (`pg_net_available` soma summaries a cada verificacao) | FALTA_NO_MONETARIE | P2 (divida de escala, nao urgencia) |
| BalanceCache display (ETS 10s + invalidacao PubSub, para polling de API externa) | `cp/use_cases/payments/pix_out/balance_cache.ex` | AUSENTE | FALTA_NO_MONETARIE | P2, junto com TxStatusCache (dominio 3) |
| Breakdown de saldo bloqueado (TB pending = MED + in-transit + orfaos + judicial) | `cp/use_cases/admin/accounts/blocked_breakdown.ex:12-46` | `monweb/.../coreproviders_parity_controller.ex:577-610` (so MED por categoria, nao cruza TB) | MELHOR_NO_COREPROVIDERS | P1: enriquecer cruzando TB debits_pending |
| Reconciliador de holds MED orfaos (void por user_data_128 real do TB). Cruza com dominio 4 | `cp/use_cases/pix_compliance/med/orphan_hold_reconciler.ex` | AUSENTE (StaleHoldChecker cobre caso diferente) | FALTA_NO_MONETARIE | P1: portar; Monetarie carrega o mesmo modo de falha do ancestral sem o safety net |
| Extrato com saldo corrido + export | So CSV com BOM (`cp/use_cases/statements/csv_formatter.ex`) | CSV e OFX (`mon/use_cases/accounts/statements.ex:73-83`); front exporta PDF/XLSX/OFX | MELHOR_NO_MONETARIE | Absorver so refinamentos de UX (item de higiene de extrato, dominio 5) |
| Reconciliacao de extrato PG vs TB linha a linha com diff | `cp/use_cases/statements/reconciliation.ex` + `queries.ex` | AUSENTE no nivel extrato (existe reconciliacao de saldo agregado: `mon/workers/reconciliation/tb_pg_reconciliation_job.ex`) | FALTA_NO_MONETARIE | P2: ferramenta operacional pos-ETL |
| Motor de tarifas com vedacoes BACEN hardcoded (Res. 19/2020, Res. 3.919) + faixas + COSIF por tarifa | Motor generico sem vedacoes (`cp/use_cases/fees/fee_calculator.ex`) | `mon/use_cases/fees/fee_calculator.ex:119-217` + `schemas/fees/fee_config.ex` | MELHOR_NO_MONETARIE | Manter como canonico de SCD supervisionada |
| Override de tarifa por conta/cliente com hierarquia | Tabela dedicada + ETS 5min (`cp/schemas/fees/fee_override.ex` + `fee_resolver.ex`) | Escopo na propria `fee_configs` + CRUD admin (`mon/use_cases/fees/fee_calculator.ex:337-369`) | PARIDADE_OK | Se o volume crescer, adotar o cache, nao a tabela |
| Franquia gratuita mensal por tipo de tarifa | Contador dedicado (`cp/schemas/fees/free_tier_usage.ex`) | Contagem de posted no mes + franquia por pacote (`mon/use_cases/fees/fee_calculator.ex:119,210-217`) | PARIDADE_OK | Nenhuma; cobertura Monetarie mais rica com pacote |
| Pacotes de tarifas (cesta, cobranca recorrente com catch-up, cobrar-agora idempotente) | AUSENTE (so lote mensal de tipos fixos) | `mon/use_cases/fees/packages.ex` + `package_billing.ex` + schemas | MELHOR_NO_MONETARIE | Manter |
| Lote mensal de cobranca de tarifas | `cp/use_cases/fees/monthly_batch.ex` | `mon/workers/fees/monthly_batch_worker.ex` | PARIDADE_OK | Nenhuma |
| Split de tarifas (config, distribuicao, historico) | `cp/use_cases/fees/split_resolver.ex` + `split_distributor.ex` + `ensure_vulci_split.ex` | `mon/use_cases/fees/split_resolver.ex` + `split_distributor.ex` + CRUD admin | PARIDADE_OK | Avaliar se o BaaS Monetarie precisa de split de plataforma garantido (tipo `ensure_vulci_split`) |
| Export assincrono do detalhe de tarifas (Oban + S3 + status) | Pipeline real (`cp/use_cases/admin/fees/export_commands.ex` + worker + S3) | STUB confirmado 07-02: `monweb/.../coreproviders_parity_controller.ex:1306-1312` devolve lista vazia, `status: ready` falso e created com UUID fake | FALTA_NO_MONETARIE | **P0 de honestidade**: portar o pipeline real ou remover rotas/tela |
| TariffEngine por produto de conta | `cp/use_cases/accounts/tariff_engine.ex` | `mon/use_cases/accounts/tariff_engine.ex` + `tariff_charge.ex` | PARIDADE_OK | Nenhuma |
| Bloqueio judicial SISBAJUD (nucleo BLOCK/UNBLOCK via hold TB) | `cp/use_cases/judicial/processor.ex` (354 linhas, TRANSFER pendente) | `mon/use_cases/judicial/processor.ex` (1997 linhas) + `asset_iterator.ex` + PiiMask + remessa/resposta completas | MELHOR_NO_MONETARIE | Gap comum: ordem TRANSFER nao implementada nos dois |
| Bloqueio cautelar MED (hold TB + espelho passivo + obligation check no gate) | `cp/use_cases/pix_compliance/med/hold_legs.ex` + `balance_check.ex:360-395` | `mon/use_cases/med/hold_legs.ex` + `obligation_check.ex` + `passives/mirror.ex` | PARIDADE_OK | Falta so o reconciliador de orfaos (item proprio) |
| Acesso multiusuario a conta com permissoes e limite diario por operador (AccountAccess/subconta) | `cp/schemas/accounts/account_access.ex` + `subconta_creator.ex` + `ownership.ex` | AUSENTE (grep zero) | FALTA_NO_MONETARIE | P1: requisito tipico PJ |
| Regras de status de conta | Politica em codigo (`cp/use_cases/accounts/account_policy.ex`) | Maquina declarativa em DB (`mon/use_cases/accounts/status_machine.ex` + `account_status_rule.ex`) | MELHOR_NO_MONETARIE | Considerar absorver so o mapeamento explicito kind->TB code/flags testavel |
| Parametros operacionais runtime tipados com cache (Settings.Registry). Cruza com dominio 4 | `cp/settings/registry.ex` (7 secoes tipadas) + `cache.ex` | `mon/use_cases/settings.ex` (chave/valor) + tetos hardcoded (R$ 10M no Wallet, min/max do pipeline) | MELHOR_NO_COREPROVIDERS | P2: adotar o padrao e mover tetos e thresholds de compliance para runtime |
| Ciclo de vida outbound em estagios com recovery | `cp/schemas/transactions/xfer_stage.ex` + failed/pending | `mon/use_cases/payments/outbound_requests.ex` + `transaction_recovery_service.ex` | PARIDADE_OK | Nenhuma |
| Tesouraria: resumo TB x PG com regra de ouro (badge DIVERGENTE bloqueia numero nao confiavel) | `cp/use_cases/treasury/balances_summary.ex` + bank_reconciliation | `mon/workers/reconciliation/tb_pg_reconciliation_job.ex` + `integrity/balance_snapshot.ex` | DIVERGENTE_VALIDAR | Validar se o dashboard Monetarie tem gate de drift equivalente (D3) |
| Tesouraria BACEN de SCD (compulsorio 21%, redesconto, leiloes) | AUSENTE (IP indireta) | `mon/use_cases/treasury/reserves.ex` + `treasury_bcb/*` | MELHOR_NO_MONETARIE | Manter |
| Agenda de liquidacao (janelas, ordens, lotes LDL) | AUSENTE (liquidacao delegada ao provedor) | `mon/use_cases/settlement/*` + schemas LDL | MELHOR_NO_MONETARIE | Manter |
| Remuneracao de saldo (poupanca accrual/posting, CDI/SELIC/IPCA) | AUSENTE | `mon/workers/savings/interest_accrual_job.ex` + schemas de curvas | MELHOR_NO_MONETARIE | Ponta solta propria: accrual sem dispatcher diario (audit 2026-05-08); fechar antes de vender a feature (P2) |
| Multi-moeda / cambio com validacao BCB | AUSENTE | `mon/schemas/cambio/multi_currency_account.ex` + `use_cases/cambio/bcb_validation.ex` | MELHOR_NO_MONETARIE | Manter |
| COSIF (periodos contabeis, transicao, balancete/DRE, A=P+Resultado ao centavo) | 63 contas/19 mapeamentos sem accounting_period; tem `balance_direction.ex` e `inflated_journal_entry.ex` proprios | `mon/schemas/cosif/*` + `use_cases/cosif/accounting_reports.ex`, validado vivo em HML | MELHOR_NO_MONETARIE | Espiar `balance_direction`/`inflated_journal_entry` do cp por correcoes pontuais; conferencia reversa dos fixes contabeis do MELHORIAS.md:711-756 (D4) |
| Fee preview antes do envio PIX (backend + front com debounce). Cruza com dominios 2 e 5 | `cpweb/routers/merchant_router.ex:426` + `PixSendView.vue:97-173` | `monweb/router.ex:2864` + `monfront/banking/.../PixSendView.vue:101-185` | PARIDADE_OK | Ja portado, incl. contrato CENTAVOS na borda |
| Bloqueio de auto-transferencia. Cruza com dominios 2 e 5 | PIX apenas (`cp/use_cases/payments/outbound_payment/pix.ex`) | PIX + TED/TEF/boleto (`mon/use_cases/transactable/pix_out.ex:76`, `outbound/tef.ex:39-109`, `transaction_pipeline.ex:142`) | PARIDADE_OK | Nenhuma; Monetarie cobre mais canais |
| Higiene de extrato no IB (filtros default 7d, teto 180d, descricao amigavel, extrato clicavel, comprovante de tarifa TB-only). Cruza com dominio 5 | MELHORIAS.md itens 9-11, 22-23 (implementados) | Nao verificado tela a tela | DIVERGENTE_VALIDAR | Checar o IB contra a lista (D5) |
| Billing BaaS multi-tenant (planos, eventos billaveis, faturas) | `cp/use_cases/billing/billing.ex` | `mon/use_cases/billing/billing.ex` + `calculator.ex` | PARIDADE_OK | Nenhuma |
| Validacao de titularidade de conta no request | `cp/use_cases/accounts/ownership.ex` (3 ramos) | `mon/use_cases/banking/account_resolver.ex` + `accounts.ex` | DIVERGENTE_VALIDAR | Conferir ramos PF/PJ/legacy caso a caso antes de declarar paridade (D6) |

### 2.2 Dominio 2: PIX no core (BR Code, cobrancas, devolucoes, webhooks de PIX)

Dedupe: fee preview e self-transfer constam no dominio 1; suite E2E e jornadas de front no dominio 5; whitelist de eventos, assinatura HMAC e backstops de webhook consolidados no dominio 3.

| Feature | coreproviders | Monetarie | Veredito | Acao |
|---|---|---|---|---|
| Parser BR Code copia-e-cola: CRC-16 correto. Cruza com dominio 5 | Corrigido: CRC sobre payload que ja inclui 6304 (`cp/use_cases/pix/brcode/parser.ex:29-32`; MELHORIAS.md item 2) | BUG confirmado 07-02: `mon/use_cases/pix/brcode/parser.ex:32` computa `compute_crc16("#{payload}6304")` com payload que ja termina em 6304; todo QR valido rejeitado com `:invalid_crc` (rota POST /pix/pay-qrcode) | MELHOR_NO_COREPROVIDERS | **P0**: fix de 1 linha + teste com payload real conhecido |
| Builder BR Code estatico no Core (EMV, orcamento tag 26, NFD->ASCII, CRC16 CCITT-FALSE) | `cp/use_cases/pix/brcode.ex:37-65,126-152,173-213` | Confirmado 07-02: `monweb/controllers/v2/pix_controller.ex:588-590` monta payload hardcoded com comprimentos EMV fixos errados, termina em `6304` literal sem checksum, `qrcode_base64 = nil`, comentario TODO no codigo | MELHOR_NO_COREPROVIDERS | **P0**: portar `Fluxiq.UseCases.Pix.BRCode` ou rotear para o encoder IN-508 da cabine (`Shared.Pix.BRCode.Encoder`) |
| Persistencia da cobranca criada via API de parceiro (charge -> linha `qr_codes`) | `cpweb/controllers/external/pix/cash_in_controller.ex:73,137` (persiste com TTL/external_id/status) | Confirmado 07-02: `monweb/controllers/partner_v1/pix_controller.ex` (create_charge so monta brcode e responde 201; nenhum Repo.insert) vs `show_charge` que le `get_qrcode_by_tx_id` | MELHOR_NO_COREPROVIDERS | **P0**: persistir com status active + expires_at real antes do 201 |
| Resolucao de QR dinamico de TERCEIROS (consulta cob/cobv de outro PSP com validacao JWS) | `cp/use_cases/pix/qrcode_consult.ex:50-124` (via provedor OnZ checkBrCode) | Core envia action NATS `consult_qrcode` (`mon/services/pix_providers/in_house/adapter.ex:207-213`) que a cabine NAO implementa (`cabine/dict_service/.../dict_api_responder.ex`); nao existe cliente HTTP+JWS para location URL | FALTA_NO_MONETARIE | **P0**: implementar resolver HTTP + validacao JWS/JWKS na cabine + handler NATS |
| Hospedagem do payload dinamico proprio (JWS CERTQRC + JWKS, recebedor) | `cpweb/controllers/merchant/qrcodes/payload_controller.ex` + `cp/infra/certqrc/jws_signer.ex` + `/jwks.json` | `cabine/settlement_service/.../payload_controller.ex` (fail-closed 503 sem cert, 410/404) + `GET /qrc/jwks` | PARIDADE_OK | Validar dominio CERTQRC `qr.monetarie.com.br` em HML via STA (D7) |
| CobV (multa/juros/desconto/abatimento/devedor) fiel ao LegadoPIX | AUSENTE (so resolve cobv de terceiros via OnZ) | `cabine/settlement_service/.../qr_codes.ex:148-209` + `shared/pix/cobv_calculator.ex` + `encoder.ex:164` | MELHOR_NO_MONETARIE | Manter; unico dos dois com emissao completa |
| Calendario de dias uteis/feriados para CobV (modalidades dia-util) | AUSENTE | Guard fail-closed `{:error, :business_day_calendar_unavailable}` (`cobv_calculator.ex:57-70`); falta o repositorio de feriados | FALTA_NO_MONETARIE | P2: implementacao propria (tabela feriados nacionais+municipais); nao ha fonte de port |
| Regimes de txid por tipo (estatico <=25 / dinamico 26-35) | Dois geradores separados pos-bug (`cp/use_cases/pix/qrcodes.ex:490-515`) | Cabine valida/gera por tipo (`qr_codes.ex:74,122,183`) | PARIDADE_OK | Ao consolidar a geracao do Core na cabine, herdar os regimes |
| Gate de aceitacao PIX-IN pago por QR (reason codes BACEN) | Rejeita PIX-IN sem txid por default + blacklist de recebimento (`cp/use_cases/pix/acceptance_policy.ex` + validators tb_first) | Gate quando ha txid: AG03/DUPL/AC03/AM09 fail-closed (`cabine/.../qr_codes.ex:349-398`) | DIVERGENTE_VALIDAR | Politicas de produto distintas (adquirente vs banco); decidir se contas Monetarie precisam do modo "so recebe por cobranca" (D8) |
| `link_payment` aceitando status `expired` in-flight (liquidacao autoritativa) | `cp/use_cases/pix/qrcodes.ex:450-475` (WHERE inclui expired) | Core `mon/use_cases/pix/qrcodes.ex:54` e cabine `qr_codes.ex:418-434` so active/used | MELHOR_NO_COREPROVIDERS | P2: incluir expired nos dois link_payment |
| Expiracao ATIVA de QR + webhook pix.charge.expired | Worker cron */5 (`cp/workers/qr_expiration_checker.ex`) | `expire_dynamic_qr_codes` definido SEM nenhum caller (confirmado 07-02, `cabine/.../qr_codes.ex:985`); Core sem worker | FALTA_NO_MONETARIE | P1: agendar na cabine + publicar NATS + dispatch no Core |
| Webhook pix.charge.created na criacao | Despachado nos 2 pontos de criacao (`cash_in_controller.ex:37,143-146`) | Evento na whitelist mas nunca despachado | FALTA_NO_MONETARIE | P1: despachar na criacao (junto com o fix de persistencia) |
| Webhook pix.charge.cancelled no cancelamento | `cp/use_cases/pix/qrcodes.ex:389-422` (sessao 163) | Lifecycle da cabine sem evento para lojista; Core sem dispatcher | FALTA_NO_MONETARIE | P1: publicar do lifecycle da cabine -> Core |
| Webhook pix.charge.paid no assentamento (com fallback por reconciliador de orfaos) | pg_writer + orphan reconciliation + link_payment | `mon/use_cases/pix/tb_first/pg_writer.ex:200-231,310-330` + `workers/pix_in_orphan_reconciliation.ex:439-460` + cabine publica `qrcode.paid` | PARIDADE_OK | Depende do fix de persistencia do create_charge para cobrir cobrancas de parceiro |
| Devolucao pelo recebedor: superficie no Core (direction, ownership, refund-info/ceiling no IB) | `cpweb/controllers/merchant/pix/refund_info_controller.ex` + validate_ownership + filtro direction=inbound (MELHORIAS itens 26-30) | Dinheiro protegido na cabine (`spi_validator.ex:53` ceiling; `return_controller.ex:106-117`), mas Core nao valida direction/ownership antes de segurar fundos e IB sem refund-info (`monweb/controllers/v2/pix_controller.ex:438-530`) | MELHOR_NO_COREPROVIDERS | P1: portar refund-info (lendo a cabine) + validacao direction/ownership no Core |
| Devolucao: liberacao do hold TB em erro + atomicidade outbox | orchestrator + pilot_reconciliation | `monweb/.../pix_controller.ex:460-530` (release nos dois ramos de erro, fix `f90eefa1`) | PARIDADE_OK | Nenhuma; ambos money-safe |
| Ceiling de devolucao parcial cumulativa | `cp/use_cases/payments/outbound_payment/return.ex` | Cabine `spi_validator.ex:53` (camada certa: vale para pacs.004 de qualquer origem) + Core reporta remaining_refundable | PARIDADE_OK | Nenhuma |
| Conciliacao PIX-OUT preso (stale/quarantine vs reconciliador em lote) | Stale checker 1min + quarantine stage 5 + decisao manual do piloto atomica + retry workers | `mon/workers/pix_status_reconciliation.ex` (Oban */15, pointwise por E2E, guard anti-regressao) + StaleHoldChecker | DIVERGENTE_VALIDAR | Ambas funcionais; avaliar port do conceito de quarantine + decisao humana para casos que o reconciliador nao resolve (caso tx 199 da fase 5) (D9) |
| Conciliacao PIX-IN orfao | `cp/workers/pix_in_orphan_reconciliation.ex` | `mon/workers/pix_in_orphan_reconciliation.ex` (cron */15) | PARIDADE_OK | Nenhuma |
| Reconciliacao pos-deploy | Detecta mas nao despacha (stub) | `mon/workers/post_deploy_reconciliation.ex` + auto_fix no boot + despacha charge.paid | PARIDADE_OK | Nenhuma; Monetarie mais completo |
| Listagem/metricas admin de QR codes cross-cliente | `cp/use_cases/pix/qrcodes.ex:89-165` (paginado + metricas + reservoir p50/p95) | AUSENTE no Core (corte de escopo declarado no moduledoc) | FALTA_NO_MONETARIE | P2: portar quando o console admin precisar de gestao de cobrancas (atencao a licao de paginacao: conta com 758k QRs) |
| TTL de QR per-account + rollout `use_dynamic_qr` per-account | `cp/use_cases/pix/qrcodes.ex:296-312,365-387,539-561` | AUSENTE (grep vazio) | FALTA_NO_MONETARIE | P2: portar junto com a consolidacao da geracao |
| Callback `generate_qrcode` na abstracao de provedores PIX | `cp/services/pix_providers/behaviour.ex:118` | So `consult_qrcode` no behaviour (`mon/services/pix_providers/behaviour.ex:115`) | FALTA_NO_MONETARIE | Raiz arquitetural dos defeitos de geracao; adicionar callback + action NATS na cabine (parte do P0 do builder) |
| PIX cash-out por copia-e-cola na API de parceiro | Postman + `external/pix/cash_out_controller.ex` (aceita brCode) | `partner_v1/pix_controller.ex:312` so por chave/DICT | FALTA_NO_MONETARIE | P2 (depende dos P0 do parser e do resolver dinamico) |
| PIX agendado one-off (data futura). Cruza com dominio 5 | Schema `pix_scheduled` + worker de execucao cron 1min + POST create | So lista/cancela instrucoes de Pix Automatico (`monweb/router.ex:3094-3095`); sem schema nem worker one-off; sem UI de agendamento no PixSendView de nenhum dos dois | MELHOR_NO_COREPROVIDERS | P1: portar schema + worker + rota + expor data futura no PixSendView |
| Pix Automatico (recorrencia, mandatos, instrucoes) | `cp/use_cases/pix_automatico/*` | `mon/use_cases/pix_automatico.ex` (533 LOC) + schemas + rotas + jornada completa no IB (dominio 5) | PARIDADE_OK | Validar nos DOIS quem agenda `execute_due_instructions` (nao aparece no crontab de nenhum) (D10) |
| Split de pagamento PIX multi-recebedor | AUSENTE | AUSENTE (existe so split de tarifa) | PARIDADE_OK | Gap comum; feature nova se o produto exigir |
| Parse local de QR estatico no IB | `cpweb/controllers/banking/pix/parse_qrcode_controller.ex` (evitar provedor OnZ) | Parse local no pay_qrcode + consult via NATS | DIVERGENTE_VALIDAR | Motivacao do cp nao se aplica (cabine in-house); os dois caminhos do Monetarie dependem dos fixes P0 antes de discutir otimizacao |
| Unidade no parse de valores EMV | `round(f*10_000)` subcentavos (`cp/.../parser.ex:107`) | `round(f*100)` centavos (`mon/.../parser.ex:107`) | DIVERGENTE_VALIDAR | Nao e defeito (cada base consistente); regra de port da secao 6 |
| Pipeline PIX-IN two-phase (intent -> TB -> PG writer) | handler + pg_writer + acceptance/blacklist validators | handler + pg_writer + supervisor/worker pool + settled_publisher | PARIDADE_OK | Avaliar port pontual do receiving_blacklist_validator (consolidado no dominio 4) |
| Framework de certificacao BR Code/CERTQRC (checklists executaveis). Cruza com dominio 5 | `PIX BR Code Compliance.md` (549 linhas) + `_02.md` (577 linhas) | AUSENTE | FALTA_NO_MONETARIE | Adotar como gate de homologacao QR pos-fixes P0, antes do CERTQRC do BACEN |
| Telemetria de geracao de QR (reservoir p50/p95) | `cp/use_cases/pix/qrcodes.ex:126-155` | So `qrcode_paid` (`pg_writer.ex:200`) | MELHOR_NO_COREPROVIDERS | P2, junto com as metricas admin de QR |
| Eventos NATS de ciclo de vida de QR (outbox duravel na cabine) | AUSENTE (webhooks inline do monolito, remendados por sweepers) | `cabine/.../qr_codes.ex:80-92,131-145,193-208,436-448` (generated/paid via outbox ADR-008) | MELHOR_NO_MONETARIE | Completar expired/cancelled e consumir no Core; arquitetura superior, manter |
| Redirect de PIX intra-instituicao para transferencia interna (channel=tef). Item do dominio 5, listado aqui por ser regra de roteamento de pagamento | Commit `9e12e3c3` (2026-07-01): `cpfront/banking/src/composables/usePix.ts:20-21,167-168` | AUSENTE (grep channel/isInternal = 0) | FALTA_NO_MONETARIE | P1: cliente Monetarie pagando cliente Monetarie hoje segue caminho SPI e consome ficha DICT |

### 2.3 Dominio 3: API externa, parceiros, webhooks e seguranca de integracao

| Feature | coreproviders | Monetarie | Veredito | Acao |
|---|---|---|---|---|
| Autenticacao da API externa | ApiKey estatico `client_id:client_secret` em toda chamada (`cpweb/plugs/api_key_auth.ex`) | OAuth2 client_credentials, JWT 8h, scope intersection, revogacao imediata (`mon/partners/oauth.ex` + `monweb/router.ex:120-124`) | MELHOR_NO_MONETARIE | Manter |
| HMAC de corpo em POST (assinatura da requisicao) | HMAC-SHA512 do body normalizado obrigatorio (`cpweb/plugs/hmac_validation.ex`) | AUSENTE (Bearer + TLS) | DIVERGENTE_VALIDAR | Decisao D11: se requisito comercial exigir, implementar assinando bytes crus (nao JSON re-encodado) |
| IP whitelist por API key | Fail-closed: key sem whitelist e recusada (`api_key_auth.ex:164-165`) + CIDR + trusted proxy | Fail-open: `monweb/plugs/api_key_auth.ex:115` retorna `:ok` incondicional | MELHOR_NO_COREPROVIDERS | P1: exigir ao menos 1 CIDR por key de parceiro (ou opt-out explicito aprovado) |
| Enforcement de IP na borda (AWS WAF sync) | `cp/use_cases/security/aws_waf/api_key_bundle.ex` + CRUD admin | AUSENTE | FALTA_NO_MONETARIE | P1/P2: quando a Partner API for exposta publicamente |
| Idempotency-Key: mecanismo | ETS local por no, sem guard de concorrencia (`cpweb/plugs/idempotency.ex`) | Redis distribuido, TTL 24h, sentinel `__processing__` com 409 (`monweb/plugs/idempotency.ex`) | MELHOR_NO_MONETARIE | Manter o mecanismo |
| Idempotency-Key: escopo de tenant | Colide por {method, path, key} entre merchants | DEFEITO confirmado 07-02: `get_user_id` le `current_user`/Guardian, mas `PartnerBearerAuth` so seta `:api_key` (verificado em `partner_bearer_auth.ex:44-52`), entao parceiro cai em `idempotency:anonymous:<key>`: replay cruzado entre parceiros | DIVERGENTE_VALIDAR (defeito nos dois) | **P0**: escopar por `api_key.client_id`/partner_id no plug do Monetarie; nao copiar o do cp |
| Rate limiting da API externa | Per-IP ETS 90.000 req/min (so anti-DoS); campo `rate_limit` persistido mas nao enforcado | Per-key Redis sliding window 1000/min com headers padrao; POREM le `api_key.metadata["rate_limit"]` e o schema NAO tem campo metadata (confirmado 07-02: `rate_limiter_per_key.ex:62` vs `schemas/api_keys/api_key.ex`) | MELHOR_NO_MONETARIE | P2: persistir `rate_limit` na key e ler no plug (hoje config por key e codigo morto) |
| Versionamento de API | `/api/external` sem versao | `/api/partner/v1` | MELHOR_NO_MONETARIE | Manter |
| Paginacao | Offset page/per_page cru | Offset com meta.total e clamp 1..100; POREM statement pagina em memoria (Enum.drop/take) | DIVERGENTE_VALIDAR | Nenhum tem cursor; P2: query paginada no statement, ideal keyset nos dois extratos |
| Contrato de erro | Dois formatos legado Simpay misturados | Envelope unico documentado em OpenAPI | MELHOR_NO_MONETARIE | Manter |
| OpenAPI + Swagger UI | AUSENTE | OpenApiSpex + Swagger vivo (`monweb/api_spec/*`, router 104-114) | MELHOR_NO_MONETARIE | Manter |
| Documentacao de payloads de webhook e guia HMAC | `docs-site/webhooks-payloads.md` (1.015 linhas) + hmac.md + i18n 4 linguas | Portal do parceiro com 411 linhas totais | MELHOR_NO_COREPROVIDERS | P3: absorver o formato (payload real por evento + tabela de campos) para o portal Vulci |
| Sandbox/homologacao publica para o parceiro | `api-hml.avivpay.com.br` publico + `cloudpix_simulator` (68 endpoints) + campo environment na key | HML atras de VPN; sem campo environment; sem simulador exposto | MELHOR_NO_COREPROVIDERS | P2: sandbox publica da Partner API (maior atrito de integracao da Vulci hoje) |
| Assinatura de webhook (contrato criptografico) | X-AvivPay-Signature = HMAC-SHA256 de timestamp.body | X-Monetarie-Signature, mesmo esquema + headers Event-Id/Event-Type | PARIDADE_OK | Nenhuma |
| Retry/backoff e replay protection na entrega | 8 tentativas [0,30,120,600,1800,3600,7200,14400], 4xx permanente, stale 5min | Identico (`mon/workers/services/webhooks/delivery_job.ex`) + manual_replay | PARIDADE_OK | Nenhuma |
| Segredo do webhook em repouso | Texto claro no banco (`cp/schemas/webhooks/webhook.ex:10`) | Cifrado + hash + virtual (`mon/schemas/webhooks/webhook.ex:9-19` + secret_encryption) | MELHOR_NO_MONETARIE | Nao regredir ao absorver features de webhook |
| Origem do segredo + rotacao via API | Aceita secret do cliente; sem rotate externo | Server-minted + rotate-secret com exibicao unica | MELHOR_NO_MONETARIE | Manter |
| Superficie CRUD de webhooks para o parceiro | So POST/GET/DELETE | CRUD completo + catalogo + test + replay self-service (`monweb/router.ex:180-189`) | MELHOR_NO_MONETARIE | Manter |
| Hardening do dispatch (dedup UNIQUE INDEX parcial, eager delivery pos-commit, retry checker, sweeper de backstop, cleanup). Consolida itens dos dominios 2 e 3 | `cp/use_cases/webhooks/commands.ex:168-310` + `workers/pix_out_confirmed_webhook_sweeper.ex` + `webhook_retry_checker.ex` + cleanup | AUSENTE (so retries Oban do DeliveryJob) | MELHOR_NO_COREPROVIDERS | P1 (alto): portar o trio + indice `idx_webhook_deliveries_dedup` |
| Guard fail-closed antes de webhook terminal (transaction_is_settled?) | `cp/use_cases/webhooks/commands.ex:353-380` | AUSENTE | FALTA_NO_MONETARIE | P1: simples de portar sobre a materializacao PIX (metadata monotonica) |
| Catalogo de eventos honesto (todo evento anunciado tem dispatcher). Consolida item do dominio 2 (whitelist) | 20 eventos, 13 aspiracionais removidos na sessao 163; 16 com dispatch real | Confirmado 07-02: `@valid_events` com 23 eventos (`mon/schemas/webhooks/webhook.ex:27-35`); dispatchers reais = pix.charge.paid, pix.payout.returned e pix.return.received; sendo que pix.return.received NAO esta na whitelist (assinatura impossivel, dispatch no-op silencioso: `return_in_handler.ex:465`); boleto.*/account.*/transfer.*/sta.* sem nenhum dispatcher | MELHOR_NO_COREPROVIDERS | P1: adicionar pix.return.received (e payout.queued/held, infraction.*, webhook.test) a whitelist; remover ou ligar os eventos aspiracionais; ligar dispatchers de payout a partir da materializacao |
| Tenant scoping fail-closed no dispatch | resolve_merchant_id + filtro por account_id | Bloqueia dispatch sem account/merchant/entity_id (`mon/use_cases/webhooks.ex:110-155` + dispatcher) | PARIDADE_OK | Nenhuma |
| Consulta por external_id/tag/E2E + cache de status para polling | GET /transactions/e2e/:e2e, /tag/:tag, /ref/:external_id + `tx_status_cache.ex` (ETS+Redis, invalidacao PubSub) + /balance fora do rate limit | Status SO por transaction_id; send_pix nao aceita external_id | FALTA_NO_MONETARIE | P1: aceitar external_id no envio + lookup por E2E/ref; cache quando o volume da Vulci crescer (P2) |
| Reason codes BACEN estruturados nas falhas | `cpweb/controllers/external/pix/helpers.ex:10-44` + dicionario central compartilhado com webhooks | AUSENTE (erro como texto) | FALTA_NO_MONETARIE | P1: portar dicionario para render_status/refund e payloads de webhook |
| MED/infracoes exposto ao parceiro (list/detail/defense) + API de integracao com token dedicado | external_router:27,51-52 + `integration_router.ex` + med_defense_controller | AUSENTE na Partner API | FALTA_NO_MONETARIE | P2: canal programatico com prazo regulatorio de defesa; adotar desde ja a guarda anti double-debit do respond deles (nunca emitir pix_return com hold cautelar pendente) |
| Validacao de CPF via API externa | POST /cpf/validate + doc | Validador existe interno (onboarding), sem endpoint | FALTA_NO_MONETARIE | P2 (baixa): expor custa um controller |
| Aprovacao em duas etapas de cash-out via API | Documentada no Postman mas rota nao existe no router externo (fluxo no merchant console) | AUSENTE (send_pix executa direto apos hold) | DIVERGENTE_VALIDAR | Decisao D12: alcada para payout de parceiro acima de limite (padrao BaaS) |
| TED e transferencia interna na API de parceiro | AUSENTE | POST /transfers/ted, /internal, favoritos, GET /:id (`monweb/router.ex:168-173`) | MELHOR_NO_MONETARIE | Manter |
| Onboarding de clientes e abertura de contas via API (BaaS) | AUSENTE | POST /customers + /customers/:id/accounts (Q1 Vulci) | MELHOR_NO_MONETARIE | Manter |
| Granularidade de escopos por API key | 10 permissoes com emprestimos de escopo (webhook usa account:write) | 13 permissoes dedicadas + mapa central rota->escopo method-keyed (`monweb/plugs/permission_enforcer.ex`) | MELHOR_NO_MONETARIE | Manter |
| Unidade monetaria no contrato externo | Entrada centavos, saida subcentavos (dual-scale documentado como pegadinha) | Entrada centavos; saldo/extrato/comprovante em reais decimais | DIVERGENTE_VALIDAR | Decisao D13: padronizar TODA a Partner API em centavos inteiros antes de escalar parceiros |
| Auditoria de chamadas da API externa | `:audit_context` em todos os scopes externos | Pipeline partner = [:api, :partner_authenticated, :idempotent] SEM :audited (`monweb/router.ex:134`); AuditPlug so em admin | FALTA_NO_MONETARIE | P1: anexar auditoria a pipeline (regulatorio e forense) |
| White-label / multi-tenant | tenants + white_label_configs | Idem + partner_id-scoped + ledger por entidade (resposta Q4 Vulci) | PARIDADE_OK | Nenhuma |
| Teste de conectividade de webhook pelo parceiro | So no console | POST /webhooks/:id/test (webhook.test system event) | MELHOR_NO_MONETARIE | Manter |
| TLS estrito na entrega de webhook (workaround key_usage_mismatch) | verify_peer + excecao cirurgica + allow_insecure por webhook | Mesmo nucleo portado; parametro allow_insecure inalcancavel (schema sem campo) | PARIDADE_OK | Decidir explicitamente se quer o opt-out por webhook (util em homolog) |

### 2.4 Dominio 4: operacao, compliance e backoffice

Dedupe: TimeBlock enforcement e Settings.Registry constam no dominio 1; reconciliador de holds MED orfaos no dominio 1.

| Feature | coreproviders | Monetarie | Veredito | Acao |
|---|---|---|---|---|
| Monitoramento PLD ligado ao pipeline (gatilho pos-liquidacao) | `cp/workers/transaction_monitor_worker.ex:45` enfileirado em `pix/tb_first/handler.ex:986` | Confirmado 07-02: `evaluate_transaction` (delegate em `mon/use_cases/compliance/compliance.ex:33`) com ZERO chamadores em lib/ | FALTA_NO_MONETARIE | **P0 de compliance**: portar o worker e enfileirar na materializacao PIX/TED |
| Engine de regras PLD parametrizaveis (monitoring_rules) | `cp/use_cases/compliance/transaction_monitor.ex` (519 linhas) | `mon/use_cases/compliance/transaction_monitor.ex` (338 linhas; AMT_REPORTABLE refinado p/ cash_only) | PARIDADE_OK | O problema e o gatilho (item anterior) |
| Checagem de sancoes por transacao no monitor | SanctionsScreener no rule set (`transaction_monitor.ex:385-393`) | So PEP | FALTA_NO_MONETARIE | Adicionar rule_type de sancao no wiring do P0 |
| Mecanismo de screening de sancoes (fonte e recarga) | CSV BACEN/COAF/OFAC em ETS com reload 6h | Tabela administravel multi-fonte + Jaro-Winkler 0.85 + trilha persistida | DIVERGENTE_VALIDAR | Best-of-breed: manter modelo DB do Monetarie + adicionar importador/recarga automatica (D14) |
| Gate de screening fail-closed na ativacao de cliente da Partner API | AUSENTE | `mon/use_cases/onboarding/partner_kyc.ex:8-31` (sancoes+PEP antes de ativar, is_pep OR-ed) | MELHOR_NO_MONETARIE | Manter como padrao de onboarding programatico |
| Blacklist de recebimento PIX-IN (documento/ISPB/conta no hot path). Consolida validators do dominio 2 | `cp/use_cases/compliance/receiving_blacklist.ex` (ETS 60s, fail-open, money-safe) + schema + tela admin | AUSENTE (grep vazio) | FALTA_NO_MONETARIE | P1: portar schema + use case + tela + integracao no credito PIX-IN |
| Registro e consulta de PEP | pep_record + is_pep? | Idem + consumo no DecisionEngine e cambio | PARIDADE_OK | Nenhuma |
| EDD (diligencia reforcada para alto risco) | AUSENTE | `mon/schemas/compliance/edd_assessment.ex` | MELHOR_NO_MONETARIE | Manter |
| Relatorio COAF (XML) + SLA 24h | XML local + job agendado | Equivalente escopado por entity + `coaf_sla_worker.ex` (escala >24h, avisa >20h) | MELHOR_NO_MONETARIE | Absorver so o job agendado de geracao |
| Re-KYC periodico por risco (Circ. 3.978) | AUSENTE | `mon/workers/compliance/kyc_review_worker.ex` (high 1a/normal 2a/low 5a) | MELHOR_NO_MONETARIE | Defeito latente: consulta `cooperative_members` (heranca cooperativa) e nao a base SCD; corrigir o alvo (P1, S) |
| Gestao de casos de compliance (caso + acoes + evidencias + alertas) | compliance_case{,_action,_evidence} + commands | `mon/use_cases/compliance/compliance.ex:47-206` + schemas + UI | PARIDADE_OK | Nenhuma |
| Onboarding PF: motor de decisao de auto-aprovacao | Flag approval_mode=auto | DecisionEngine com 7 checks verificados + reasons auditaveis | MELHOR_NO_MONETARIE | Manter canonico |
| Etapas regulatorias do onboarding (BCB Res. 96/2021) | AUSENTE | `mon/use_cases/onboarding/regulatory_steps.ex` (15 etapas) | MELHOR_NO_MONETARIE | Manter |
| Abstracao de provedor KYC por entidade (behaviour + fallback manual + config admin) | `cp/use_cases/onboarding/kyc/provider.ex:14-45` + CRUD | Nextcode acoplado direto; config schema existe sem dispatcher | MELHOR_NO_COREPROVIDERS | P2: portar behaviour mantendo Nextcode default e DecisionEngine em cima |
| Auto-cadastro com OTP persistido e limites anti-abuso | pending_registration (otp_hash, contadores, expiry, unique email) | OTP em ETS volatil por no, TTL 10min (`contact_verification.ex`) | MELHOR_NO_COREPROVIDERS | P2: persistir OTP mantendo a API atual |
| KYC manual no backoffice (aprovar/rejeitar/baixar documento) | commands + view | kyc_controller + AdminKycDetailView | PARIDADE_OK | Nenhuma |
| Onboarding manual/pre-cadastro iniciado pelo admin | manual_create + pre_registration | promotion.ex existe; entrada manual pelo admin nao confirmada | DIVERGENTE_VALIDAR | Validar; se ausente, portar (D15) |
| Convite de colaboradores (multiusuario PJ) | collaborator_invite | `mon/schemas/collaborators/invite.ex` + use_cases | PARIDADE_OK | Nenhuma |
| Durabilidade do write path da auditoria (buffer + spill em disco + recovery) | `cp/infra/audit/audit_buffer.ex` + spill_recovery_worker + backfill/cutover | `mon/repo.ex` audita via Task.start (perda silenciosa possivel em crash) | MELHOR_NO_COREPROVIDERS | P1: portar AuditBuffer (trilha com valor probatorio) |
| Meta-auditoria (auditar quem LE/EXPORTA a trilha) + export | meta_audit.ex + export_controller | So index (`monweb/controllers/audit_log_controller.ex`) | FALTA_NO_MONETARIE | P1: portar export + meta-audit |
| audit_logs particionada e escopada por entity | entity_id + PK composta (id, inserted_at) | Sem entity_id, PK simples + purge por delete | MELHOR_NO_COREPROVIDERS | P1: entity_id (segregacao por parceiro) + particionamento por tempo (retencao via drop partition) |
| Mascaramento de PII nos logs de PLD | mask_document nos logs e matches | Loga document_number cru no monitor; PiiMask existe e ja e usado no SISBAJUD | MELHOR_NO_COREPROVIDERS | Correcao pontual junto do wiring P0 do PLD |
| RBAC granular do backoffice | permissions JSONB + permission_cache ETS | Module->Feature->Group com 7 flags, fail-closed, cache TTL 5min | PARIDADE_OK | Absorver so invalidate_for_user se o TTL for lento para revogacao |
| IP whitelist do admin com enforcement + access log + modo preview | Plug no pipeline + admin_ip_access_log (allow/deny/preview_would_deny) | CRUD + check existem; NENHUM plug de enforcement (confirmado 07-02 na listagem de `monweb/plugs/`) | FALTA_NO_MONETARIE | P1: portar plug + access log + preview (preview evita lockout do proprio time) |
| Primeiro acesso forcado (troca de senha + MFA) e lockout de login no backend | Plugs explicitos; TODO.md deles admite lockout so-frontend e primeiro-login quebrado | Pecas existem (must_change_password, ensure_mfa, distributed_rate_limiter) | DIVERGENTE_VALIDAR | Validar empiricamente lockout backend (429/403) e bloqueio de rotas ate completar troca+MFA; portar os 2 plugs se faltar (D16) |
| SISBAJUD fim-a-fim (remessa, dispatch por codigo, investimentos, resposta, retencao, auditoria PII) | Basico, TRANSFER pendente | Ciclo completo (processor 1997 linhas + file_processor 1004 + asset_iterator + PiiMask) | MELHOR_NO_MONETARIE | Manter canonico |
| CCS: ciclo de envio via STA (callback HMAC, poller, parsers, dicionario de erros) | generator/validator/response_processor/detail_responder/remittance_tracker | sta_submission lifecycle completo + parsers ACCS003/004/009 + simulador | MELHOR_NO_MONETARIE | Gap pontual a validar: resposta de detalhamento CCS (cp tem detail_responder; Monetarie so parsers) (D17) |
| CCS: importacao de base legada com staging auditavel | legacy_import + schemas staging linha a linha | AUSENTE | FALTA_NO_MONETARIE | P2: sinergia direta com o ETL AB/GX/MGI em curso |
| e-Financeira (evtMovOpFin, lotes cripto, XMLDSig, webservice, importador) | 3 arquivos (registro simplificado) | ~30 arquivos + 14 schemas (transmissivel de verdade) | MELHOR_NO_MONETARIE | Manter |
| Cobertura regulatoria ampla (SCR, CADOC, DIMP, DRSAC, IRPF, MCC, PGV, RC6, SIMBA, SVR) | Inclui svr_9800/9805/9810 + cadoc cross_validator | Superset em DERE/FGCoop/Registrato/compulsorios; SVR sem 9800/9810; sem cross_validator (so validator_4010) | MELHOR_NO_MONETARIE | Conferir SVR 9800/9810 e cross_validator de CADOC (D18) |
| MED backoffice: bloqueio cautelar manual, config/enriquecimento de infracao | manual_cautelar_block + infraction_config + enrichment + report | Nucleo MED presente; sem manual_cautelar_block nem parametrizacao de infracao (grep vazio) | FALTA_NO_MONETARIE | P1: portar (exigencia dura de dono white-label, cf. AJUSTES docx) |
| LGPD (consentimento, exportacao, anonimizacao, retencao) | Arquivo unico (consents + export basico) | 4 schemas + anonymizer/exporter + 3 workers | MELHOR_NO_MONETARIE | Manter |
| Alcadas/aprovacoes (maker-checker vs multi-voto por faixa) | approval_engine por faixa de valor (0/1/2 aprovadores) | Maker-checker Fineract-style com handlers + expiry + threshold por tenant | DIVERGENTE_VALIDAR | Unificar: manter maker-checker e adicionar required_approvals por faixa com tabela de votos (D19) |
| Admin regulatorio/contabil portado "do core Cecresa" (confissao de direcao) | MELHORIAS.md:656-707 | Superset em `monfront/admin/src/views/regulatory/` e `accounting/` | MELHOR_NO_MONETARIE | Conferencia reversa dos fixes contabeis deles (balancete hierarquico, resultado no balanco, razao D/C, dupla contagem) (D4) |
| Dores do dono white-label (AJUSTES CORE AVIVPAY.docx) como checklist de QA | Lista de exigencias reais (KYC vinculado, limites persistidos, MED fim-a-fim, webhooks por cliente, API keys mascaradas, anexos de onboarding) | Cobertura nao validada tela a tela | DIVERGENTE_VALIDAR | Transformar em roteiro de validacao empirica regra #11 do admin (D20) |
| Higiene de dados (TODO.md deles: Rand.uniform em numero de conta, senha vazia na criacao de merchant, timestamps fora de convencao) | Confessados no TODO.md:8-16,103-121; cp criou account_number/account_sequence para sanar | Mesma linhagem; presenca dos defeitos nao verificada | DIVERGENTE_VALIDAR | Auditar os 3 pontos no Monetarie (barato de checar, caro em producao) (D21) |
| Plugs de robustez (key_case, require_json, token_blocklist, security_headers) | Presentes | Presentes (incl. correlation_id) | PARIDADE_OK | Nenhuma |
| Auditoria HTTP de leituras sensiveis (GETs auditados) | audit_plug + audit_context | `monweb/plugs/audit_plug.ex:40-49` com @audit_read_paths explicitos | PARIDADE_OK | Nenhuma (na Partner API falta, ver dominio 3) |

### 2.5 Dominio 5: experiencia IB/merchant e jornadas de pagamento

Dedupe: CRC do parser, redirect intra-instituicao, PIX agendado one-off, fee preview, self-transfer, limites self-service e frameworks BR Code constam nos dominios 1 e 2.

| Feature | coreproviders | Monetarie | Veredito | Acao |
|---|---|---|---|---|
| Jornada PIX Out no IB (send, confirm, MFA TOTP por transacao, receipt) | PixSendView + PixSendConfirmView (TOTP real) | Mesma base + validada viva em HML 06-28 | PARIDADE_OK | Nao existe "2FA simulado de 5s" no envio em nenhum dos dois |
| Enforcement de MFA server-side nas rotas de saida | pipeline require_mfa + idempotent (merchant_router:366-369) | pipeline ensure_mfa (`monweb/router.ex:42,2142`) | PARIDADE_OK | Validar se ensure_mfa cobre TODAS as rotas money-out (D22) |
| Verificacao SMS no onboarding PJ (Step 4) | Chama /auth/mfa/sms/send e /verify reais | SIMULADO confirmado 07-02: `Step4SmsView.vue` tem `sendCode = () => { codeSent.value = true }` e `verify = () => { router.push(...) }`; backend Monetarie JA TEM sms_send/sms_verify (mfa_controller.ex:150,174) | MELHOR_NO_COREPROVIDERS | P1: ligar o front aos endpoints reais (unico ponto de verificacao fake achado no IB) |
| PIX copia-e-cola (consulta de payload antes de pagar) | Consulta backend + parse local p/ estatico | Consulta backend (cabine via NATS) | PARIDADE_OK | Depende dos fixes P0 do parser/resolver para funcionar de fato |
| Pagamento de boleto/convenio pelo IB | MOCK: dados hardcoded + toast "Em desenvolvimento" (PaymentsConfirmView.vue:85-90) | REAL via NPC: validate + pay + receipt (`monfront/banking/views/payments/*` + `boleto_controller_v2.ex:50`) | MELHOR_NO_MONETARIE | Manter |
| Views de boleto orfas no IB Monetarie | n/a | `monfront/banking/src/views/boleto/BoletoPayView.vue` e `BoletoReceiptView.vue` sem rota nem import | OVERLAP_REMOVER | Higiene: remover ou consolidar na jornada de payments |
| Recarga de celular / top-up | AUSENTE (so string i18n) | AUSENTE (so string i18n) | PARIDADE_OK | Decisao de produto; nada a portar |
| Recorrencia PIX (Pix Automatico) no IB | AUSENTE | Jornada completa (PixAutomaticoView/Create/Detail) | MELHOR_NO_MONETARIE | Manter |
| Favoritos/contatos PIX | View + rotas | View + rotas + dialog de favorito manual | PARIDADE_OK | Nenhuma |
| Favoritos de transferencia TED/TEF | Presente | Presente | PARIDADE_OK | Nenhuma |
| Tela de limites gerais da conta (LimitsView) | GET /limits real + fee-preview | Valores regulatorios hardcoded em i18n, sem API | MELHOR_NO_COREPROVIDERS | P2: ler /limits (junto do pacote de limites) |
| Central de notificacoes in-app no IB web | Backend existe, SEM view web | View completa + composable + rotas (`NotificationsView.vue`) | MELHOR_NO_MONETARIE | Manter |
| Notificacao por transacao (push/email quando dinheiro entra/sai) | AUSENTE | AUSENTE (handlers NATS nao criam notificacao de usuario) | PARIDADE_OK (gap comum) | P2: gerar notificacao in-app do evento NATS settled (incremento pequeno, alto valor) |
| Push mobile real (FCM/APNs) | AUSENTE (so local notifications) | AUSENTE (identico) | PARIDADE_OK (gap comum) | Fase seguinte da notificacao por transacao |
| Sessoes ativas do usuario | Lista GET /auth/sessions com fallback; logout-all deles e stub vazio | Sem listagem; logout-all REAL | DIVERGENTE (complementares) | P2 best-of-breed: listagem deles + revogacao real nossa + revogacao por sessao (nenhum tem) |
| Dispositivos vinculados/confiaveis (device binding) | So esqueleto visual (lista sempre vazia, sem backend) | AUSENTE no web | DIVERGENTE_VALIDAR | Decisao D23: exige backend novo nos dois |
| 2FA TOTP de login (setup QR, backup codes) | TwoFactorAuthView + Verify2FA | Idem + OTPSetupView guiado (TOTP/SMS reais) + i18n | PARIDADE_OK | Nenhuma |
| Onboarding PF completo no IB web (9 etapas + socket de status) | Subconjunto | Jornada completa + Nextcode + socket | MELHOR_NO_MONETARIE | Manter |
| Maker-checker no canal (aprovacoes de operacao do merchant) | Rotas backend approvals (list/count/approve/reject); sem UI | AUSENTE no canal (so i18n) | FALTA_NO_MONETARIE | P2/P3: portar dominio + construir UI (falta nos dois); casa com team/capabilities que o IB Monetarie ja tem |
| Comprovantes (ReceiptView, impressao via iframe) | Base original | Paridade visual feita 06-28 + testes unitarios | PARIDADE_OK | Nenhuma |
| Marca d'agua de tenant no comprovante (white-label) | receipt-watermark com logo do tenant | AUSENTE (grep 0) | FALTA_NO_MONETARIE | P3: delta pequeno, relevante para BaaS |
| Exportacao de extrato (formatos) | So CSV | PDF + XLSX + OFX | MELHOR_NO_MONETARIE | Manter |
| Regras de extrato (dia-calendario BR, filtro credito/debito, teto 30d no export) | Fixes pos-fork (commits 1bc53c74, 801d7d87) | Filtros presentes; timezone e teto nao evidenciados | DIVERGENTE_VALIDAR | Validar e portar o que faltar (D24) |
| Busca global de transacoes | TransactionSearchView | TransactionSearchView | PARIDADE_OK | Nenhuma |
| Multi-conta (seletor + escopo por conta + ocultar saldo) | localStorage | Store Pinia (mais limpo) + balanceVisible | PARIDADE_OK | Nenhuma |
| Capability gating (menu/rotas por capacidade do operador) | hasCapability | Mesma logica | PARIDADE_OK | Nenhuma |
| Acessibilidade (tela de preferencias) | 378 linhas, textos hardcoded | 343 linhas, 100% i18n | PARIDADE_OK | Nenhum dos dois evidencia auditoria WCAG |
| Dark mode no IB | Classes dark: presentes | Removidas no fork (tema claro com tokens) | DIVERGENTE_VALIDAR | Decisao de design D25 |
| Cobertura E2E Playwright do IB | 26 specs (pix, transfer, payments, security, idempotency, flows) | 1 smoke spec | MELHOR_NO_COREPROVIDERS | P2: absorver/adaptar a suite (pega regressao de fluxo) |
| Testes unitarios do frontend IB | 1 arquivo | 14 arquivos (views, stores, composables) | MELHOR_NO_MONETARIE | Manter |
| App mobile Flutter | 21 dominios | 24 dominios (+ capital, investments, loans) | PARIDADE_OK (superset) | Pendencia propria: launcher icon + splash do rebrand |
| Jornadas exclusivas do IB Monetarie (pix/dispute MED self-service, pix/manual, investimentos, emprestimos, credito com simulacao, capital, assembleia, cards detalhados) | AUSENTES | Rotas + views + backend real (ex. POST /credit/simulate) | MELHOR_NO_MONETARIE | Manter ligadas a backend real |
| Merchant portal: withdrawal, contas virtuais com chaves PIX, counterparties, KYC, MEDs | Sem withdrawal/contas virtuais | Superset (`monfront/merchant/src/router/index.ts:175-198`) | MELHOR_NO_MONETARIE | Manter |
| Fila "em transito" (acompanhar + reprocessar) | InTransitView + useInTransit | Mesma base + i18n | PARIDADE_OK | Nenhuma |
| Docs de compliance BR Code + harness de QA de jornadas | Compliance*.md + qa/ + vorcarotests/ + cloudpix_simulator | AUSENTE equivalente consolidado | MELHOR_NO_COREPROVIDERS | Absorver como referencia dos fixes P0 e da suite E2E |
| Troca de senha logado | View propria | View reutilizada no fluxo forcado e no settings | PARIDADE_OK | Nenhuma |
| Geracao de QR de recebimento (unidade do contrato) | Passa reais | Passa CENTAVOS (Math.round(amount*100)) | DIVERGENTE_VALIDAR | Regra de port da secao 6; nao reintroduzir a classe de bug 100x |

## 3. Backlog priorizado

Esforco: S (ate 1 dia), M (2 a 5 dias), L (1 a 3 semanas). Risco = o que acontece se nao fizer / risco de execucao.

### P0 (defeitos confirmados de dinheiro, seguranca ou honestidade; fazer antes de qualquer nova feature)

| # | Item | Esforco | Risco |
|---|---|---|---|
| P0-1 | Limites em PIX-OUT/TED: portar `Limits.{LimitCheck,FlowLimits,TransactionLimits,UsageCache}` do coreproviders e chamar `LimitCheck.verify` dentro do caminho locked do outbound (`outbound_orchestrator`/`transaction_pipeline`), como em `cp/.../pix_out/balance_check.ex:348` | M | Sem fix: cliente saca acima do limite transacional/diario/mensal; campos de limite das contas e global_limits sao letra morta na saida (exposicao a fraude e PLD). Execucao: money path, exigir testes + validacao HML regra #11; atencao a unidade (cp em subcentavos) |
| P0-2 | CRC do parser BR Code: remover o `6304` duplicado em `mon/use_cases/pix/brcode/parser.ex:32` + teste com payload real | S | Sem fix: POST /pix/pay-qrcode rejeita todo QR valido com 422; pagamento por copia-e-cola inoperante. Execucao: trivial (1 linha), risco quase nulo com teste |
| P0-3 | Geracao de QR do v2: substituir o BR Code hardcoded sem CRC (`monweb/v2/pix_controller.ex:588-590`) portando `Fluxiq.UseCases.Pix.BRCode` OU adicionando callback `generate_qrcode` ao behaviour + action NATS reusando o encoder IN-508 da cabine | M | Sem fix: QR gerado pelo IB/merchant e EMV-invalido, rejeitado por qualquer app bancario. Preferir rotear para a cabine (motor unico, evita duplicar EMV no Core) |
| P0-4 | Persistir a cobranca do Partner `create_charge` como linha em `qr_codes` (status active + expires_at real) antes do 201 | M | Sem fix: charge de parceiro e orfa (show_charge 404, sem link_payment, sem webhook pix.charge.paid); quebra a conciliacao da Vulci. Despachar tambem pix.charge.created aqui |
| P0-5 | Resolver de QR dinamico de terceiros no InHouse: handler NATS `consult_qrcode` na cabine + cliente HTTP que busca a location URL (tag 26/25) e valida o JWS contra o JWKS do PSP recebedor | L | Sem fix: pagamento de cobranca dinamica/cobv de outro PSP quebrado fim a fim. Execucao: seguir Manual de Seguranca PIX; a cabine ja tem a infra de certs |
| P0-6 | Idempotency-Key da Partner API: escopar a chave Redis por `api_key.client_id`/partner_id (hoje cai em `idempotency:anonymous:<key>`) | S | Sem fix: replay cruzado de respostas entre parceiros distintos (vazamento cross-tenant + supressao de transacao legitima). Nao copiar o plug do cp (defeito analogo) |
| P0-7 | Export de detalhe de tarifas: portar o pipeline real (FeeDetailExport + worker Oban + S3Uploader) ou remover rotas/tela stub | S (remover) / M (portar) | Sem fix: admin acredita que exportou e nada existe; viola a regra do dono de nada declarado sem ser real |
| P0-8 | TimeBlock enforcement: portar `Admin.TimeBlocks.Check` e invocar no gate outbound (como `cp/.../orchestrator.ex:283`) | S | Sem fix: operador cadastra bloqueio de horario que nao bloqueia nada (regra inerte com tela) |
| P0-9 | PLD vivo: portar `TransactionMonitorWorker` (Oban queue compliance) e enfileirar na materializacao PIX/TED do Core; no mesmo PR, adicionar regra de sancao por transacao e aplicar `PiiMask` nos logs do monitor | M | Sem fix: monitoramento PLD do Monetarie nunca roda em nenhuma transacao (risco regulatorio COAF/BCB). Async pos-settlement, nao bloqueia money path |

### P1 (confiabilidade, compliance operacional e promessas de produto)

| # | Item | Esforco | Risco |
|---|---|---|---|
| P1-1 | Webhooks confiaveis: (a) adicionar pix.return.received, pix.payout.queued/held, pix.infraction.*, webhook.test a `@valid_events`; (b) limpar/ligar eventos aspiracionais (boleto/account/transfer/sta sem dispatcher); (c) ligar dispatchers de payout a partir da materializacao PIX | M | Hoje o catalogo promete 23 eventos e emite 2 entregaveis; devolucao recebida nunca notifica o lojista (dispatch no-op silencioso) |
| P1-2 | Hardening do dispatch de webhook: dedup por UNIQUE INDEX parcial, eager_deliver pos-commit, guard fail-closed `transaction_is_settled?` antes de evento terminal, WebhookRetryChecker + sweeper de backstop | M | Perda/duplicidade silenciosa de webhook terminal (o cp pagou esse aprendizado em producao); risco de anunciar payout confirmado nao liquidado |
| P1-3 | Expiracao ativa de QR: agendar `expire_dynamic_qr_codes` (hoje sem caller) + publicar NATS expired/cancelled + dispatch pix.charge.expired/cancelled no Core | M | QR nunca muda para expired no banco; lojista nao recebe eventos de ciclo de vida |
| P1-4 | Conciliacao do parceiro: aceitar `external_id` no envio + GET por E2E e por external_id/ref + reason codes BACEN estruturados (dicionario central) | M | Vulci nao concilia programaticamente; retry logic do parceiro sem codigo maquina-legivel |
| P1-5 | Refund UX segura no Core: endpoint refund-info por E2E (lendo a cabine) + validacao direction=inbound/ownership no return_pix antes de segurar fundos | M | Core segura fundos sem validar nada; IB sem saldo de devolucao (a cabine protege o dinheiro, mas a UX permite tentativas invalidas) |
| P1-6 | Redirect PIX intra-instituicao (channel=tef, commit 9e12e3c3 do cp): expor channel/isInternal no usePix e redirecionar para transferencia interna | M | Cliente Monetarie pagando cliente Monetarie consome ficha DICT e liquida via SPI sem necessidade |
| P1-7 | SMS real no onboarding PJ: ligar Step4SmsView aos endpoints /auth/mfa/sms/send e /verify ja existentes | S | Unico ponto de verificacao simulada do IB; hoje aceita qualquer codigo de 6 digitos |
| P1-8 | PIX agendado one-off: schema pix_scheduled + worker de execucao + POST create + opcao de data futura no PixSendView | M | Feature padrao de mercado ausente; telas atuais so mostram instrucoes de Pix Automatico |
| P1-9 | MED: OrphanHoldReconciler (void por user_data_128 no TB) + blocked-breakdown cruzando TB debits_pending com MED/in-transit/judicial + manual_cautelar_block + parametrizacao de infracao + guarda anti double-debit do respond | M | Dinheiro de cliente preso sem diagnostico (mesmo modo de falha do ancestral sem safety net); exigencia dura de dono white-label |
| P1-10 | ReceivingBlacklist PIX-IN (schema + use case fail-open ETS + tela admin + gate no credito) | M | Compliance sem ferramenta para barrar pagador/ISPB/conta reincidente (casos MED) |
| P1-11 | Postura de acesso da Partner API: IP whitelist fail-closed por key (ou opt-out explicito) + anexar AuditPlug/audit_context a pipeline partner_authenticated | S/M | Key sem whitelist passa; mutacoes de dinheiro de parceiro sem trilha de auditoria (forense/regulatorio) |
| P1-12 | Admin IP whitelist com enforcement: plug + access log append-only + modo preview_would_deny | M | Regra inerte com tela; preview evita lockout do proprio time ao ligar |
| P1-13 | Trilha de auditoria probatoria: AuditBuffer com spill em disco + SpillRecoveryWorker; entity_id + particionamento por inserted_at em audit_logs (cp tem backfill/cutover prontos); export + meta-auditoria de VIEW/EXPORT | L | Perda silenciosa de log em crash; sem segregacao por parceiro na trilha; consulta a trilha nao auditada |
| P1-14 | Corrigir alvo do KycReviewWorker (consulta cooperative_members; apontar para a base de clientes SCD) | S | Re-KYC periodico anunciado nao roda contra a base real |
| P1-15 | AccountAccess + SubcontaCreator (acesso delegado com permissions map, daily_limit por operador, expiracao) | L | PJ nao consegue delegar acesso financeiro com limite proprio (requisito tipico de conta empresa) |

### P2 (escala, ferramentas e paridade de superficie)

| # | Item | Esforco |
|---|---|---|
| P2-1 | Settings.Registry/Cache tipado runtime: mover tetos hardcoded (R$ 10M do Wallet, min/max do pipeline) e thresholds de compliance (Jaro-Winkler 0.85, face match 95.0, janelas de structuring) | M |
| P2-2 | BalanceCheckpoint com prefold noturno + BalanceCache de display com invalidacao PubSub + TxStatusCache (guardar para quando o volume vier; battle-tested no cp) | L |
| P2-3 | Statements.Reconciliation linha a linha PG vs TB (ferramenta operacional pos-ETL) | M |
| P2-4 | Sandbox publica da Partner API (campo environment na key + base URL de homolog sem VPN; inspiracao api-hml.avivpay.com.br + cloudpix_simulator) | L |
| P2-5 | MED na Partner API (list/detail/defense com validacao de evidencias) + eventos pix.infraction.* | M |
| P2-6 | Contrato monetario da Partner API 100% em centavos inteiros (entrada E saida), documentado (decisao D13 antes) | M |
| P2-7 | CCS legacy_import com staging auditavel (sinergia com ETL AB/GX/MGI) + validar detail_responder | M |
| P2-8 | Onboarding: behaviour de provedor KYC com fallback manual (Nextcode default) + OTP persistido no padrao pending_registration | M |
| P2-9 | Suite E2E Playwright do IB (adaptar as 26 specs do cp; manter os 14 testes unitarios proprios) | M/L |
| P2-10 | Limites self-service best-of-breed: leitura real nas telas PixLimitsView/LimitsView + endpoint persistido de solicitacao com aprovacao no admin (apos decisao D1) | M |
| P2-11 | Sessoes ativas: listagem (GET /auth/sessions) + revogacao por sessao individual, mantendo logout-all real | M |
| P2-12 | Notificacao por transacao in-app a partir dos eventos NATS settled/rejected (push FCM como fase seguinte) | S/M |
| P2-13 | Gestao admin de QR (admin_list paginado + metricas + reservoir de latencia) + TTL per-account + use_dynamic_qr per-account | M |
| P2-14 | Cash-out por copia-e-cola na Partner API (depende de P0-2 e P0-5) | M |
| P2-15 | Incluir `expired` no WHERE dos dois link_payment (liquidacao autoritativa sobre expiracao in-flight) | S |
| P2-16 | Dispatcher diario do interest_accrual de poupanca (scanner de contas ativas; follow-up do audit 2026-05-08) | S |
| P2-17 | Rate limit por key real: persistir campo rate_limit no schema api_keys (hoje o plug le metadata inexistente) | S |
| P2-18 | Maker-checker unificado: required_approvals por faixa de valor com tabela de votos + UI de aprovacoes no canal (falta nos dois) | M/L |
| P2-19 | Repositorio de feriados nacionais/municipais para destravar as modalidades dia-util do CobV (hoje fail-closed correto) | M |
| P2-20 | Importador/recarga automatica de listas de sancoes sobre o modelo DB do Monetarie | M |
| P2-21 | Higiene: remover views de boleto orfas do IB; marca d'agua de tenant no comprovante; CPF validate na Partner API; job agendado de geracao COAF; portal do parceiro com payloads por evento (formato webhooks-payloads.md); split de plataforma garantido estilo ensure_vulci_split se o BaaS exigir | S cada |

Processo transversal: adotar os 2 frameworks `PIX BR Code Compliance*.md` do coreproviders como gate de homologacao QR do Monetarie (rodar contra cabine + core apos os P0; validar o dominio CERTQRC `qr.monetarie.com.br` via STA) e transformar `AJUSTES CORE AVIVPAY.docx` + `TODO.md` deles em roteiro de validacao empirica regra #11 do admin.

## 4. Intocaveis (nao regredir; base canonica Monetarie)

Por mandato do dono e por validacao empirica viva, os itens abaixo sao a base sobre a qual tudo e absorvido. Nenhum port do coreproviders pode substitui-los ou rebaixa-los:

1. **TigerBeetle double-entry 0.17.3** com overdraft em software (SCD): flag `debits_must_not_exceed_credits=false` por design, limite imposto por `BalanceGuard.verify_with_overdraft`. Nao regredir para o modelo IP do coreproviders (TB flag true, sem credito).
2. **Razao PG `account_entries`** validada ao centavo pos-ETL Autbank (saldo de clientes R$ 1.795.946,61 conferido vivo em HML): fonte canonica do extrato.
3. **COSIF com periodos contabeis** e A=P+Resultado ao centavo (R$ 2.103.031,84 conferido), balancete/DRE, vedacoes SCD (conta de pagamento 4.9.8, nunca 4.1).
4. **NATS JetStream + outbox ADR-008**: eventos duraveis da cabine (qrcode generated/paid, settlement) e materializacao no Core. Arquitetura superior ao dispatch inline do coreproviders (que precisa de sweepers para remendar).
5. **Partner API validada com a Vulci**: OAuth2 client_credentials com scope intersection, `/api/partner/v1` versionado, OpenAPI/Swagger vivo, segredo de webhook cifrado + server-minted + rotate/test/replay, escopos method-keyed, TED + onboarding de clientes via API.
6. **Materializacao + reconciliacao PIX no Core** (fonte unica NATS, guard monotonico, Oban */15, reprocesso admin): comprovante/extrato/status leem so o Core, lookup pontual por E2E na cabine, sem fallback SQL.
7. **Cabine PIX como motor unico de BR Code/cobranca**: encoder IN-508, CobV com CobvCalculator fiel ao LegadoPIX, payload JWS CERTQRC fail-closed + /qrc/jwks, gate AG03/AC03/AM09/DUPL. O Core consome a cabine, nao duplica EMV em controllers.
8. **ETL Autbank e ETL legado PIX/SPB**: dados migrados e conferidos ao centavo; gates documentados (upsert destrutivo de balances, schemas cecresa_*) permanecem.
9. Profundidade regulatoria propria: SISBAJUD com AssetIterator e PiiMask, e-Financeira transmissivel, DERE/FGCoop/Registrato, LGPD completo, tesouraria BCB, agenda LDL, motor de tarifas com vedacoes BACEN hardcoded e pacotes com franquia, DecisionEngine + 15 etapas BCB 96/2021, partner_kyc fail-closed.

## 5. Pendencias DIVERGENTE_VALIDAR (decisoes para o dono)

| # | Pendencia | Contexto e pergunta |
|---|---|---|
| D1 | Limite noturno PIX (Res. BCB 142) e gestao de limites self-service pelo cliente | Inertes/ausentes NOS DOIS cores. O coreproviders desligou o noturno por diretiva do dono deles (IP); o Monetarie e SCD participante direto do SPI, a resposta pode ser outra. Definir: (a) ligar limite noturno diferenciado; (b) permitir cliente reduzir limite imediato / pedir aumento com espera 24-48h no IB |
| D2 | Flag TB `history: true` para contas novas | Imutavel pos-criacao. Se o extrato canonico continuar sendo account_entries, ok nao ter; decidir antes de criar volume de contas novas (habilitaria extrato TB-first futuro) |
| D3 | Gate de drift no dashboard de tesouraria | O cp bloqueia o numero "disponivel de clientes" com badge DIVERGENTE quando TB x PG nao batem; validar se o dashboard Monetarie tem gate equivalente ou exibe saldo mesmo com drift |
| D4 | Conferencia reversa dos fixes contabeis do cp | Ao portar o admin contabil "do core Cecresa", eles corrigiram: consolidacao hierarquica do balancete, resultado do exercicio no balanco, razao com natureza D/C, dupla contagem no fechamento (MELHORIAS.md:711-756). Conferir se os mesmos bugs existem na origem (Monetarie) |
| D5 | Higiene de extrato do IB | Checar o IB Monetarie contra a lista paga do MELHORIAS.md (filtros default 7d, teto 180d, descricoes amigaveis, extrato clicavel, comprovante para tarifa TB-only) |
| D6 | Titularidade de conta no request | Conferir ramos PF/PJ/legacy do account_resolver Monetarie contra os 3 ramos do Ownership.validate do cp antes de declarar paridade |
| D7 | Dominio CERTQRC | Registrar/validar `qr.monetarie.com.br` em HML via STA (como a AvivPay fez com qrcode.avivpay.com.br) |
| D8 | Politica de aceitacao PIX-IN | O cp (modelo adquirente) rejeita PIX-IN sem txid por default com opt-in por conta. Contas Monetarie (modelo banco) precisam do modo "so recebe por cobranca" e de blacklist de recebimento por conta? |
| D9 | Quarantine + decisao do piloto para PIX-OUT preso | O reconciliador em lote do Monetarie funciona; o caso real da fase 5 (tx 199 sem resposta da cabine) sugere avaliar o conceito de quarentena com decisao humana auditada (settle/reject atomico) do cp para os casos que o reconciliador nao resolve |
| D10 | Agendador do Pix Automatico | `execute_due_instructions` nao aparece no crontab de NENHUM dos dois; validar quem dispara as instrucoes vencidas no Monetarie |
| D11 | HMAC de corpo nas requisicoes de parceiro | Defesa em profundidade que o cp exige (esquema Simpay). O requisito comercial (clientes ex-Simpay) existe para o Monetarie? Se sim, implementar assinando bytes crus |
| D12 | Alcada/aprovacao de cash-out de parceiro via API | Padrao de mercado em BaaS (payout acima de limite exige segunda aprovacao). Nenhum dos dois entrega limpo hoje; decidir se entra no produto |
| D13 | Contrato monetario da Partner API | Padronizar tudo em centavos inteiros (entrada e saida) com campo de formato explicito, antes de mais parceiros integrarem. Hoje a saida mistura reais decimais |
| D14 | Fonte e recarga das listas de sancoes | Manter modelo DB administravel do Monetarie e adicionar importador automatico (OFAC/UN/EU/BCB/COAF) com recarga periodica? |
| D15 | Onboarding manual/pre-cadastro pelo admin | Validar se existe entrada manual de cliente pelo backoffice; se ausente, portar (dor comum de operacao) |
| D16 | Primeiro acesso forcado + lockout de login no backend | Validar empiricamente: lockout por conta/IP com 429/403 no backend e bloqueio de rotas operacionais ate completar troca de senha + MFA. O TODO.md do cp confessa que o deles e fraco; portar os plugs se faltar no Monetarie |
| D17 | Resposta de detalhamento CCS | O cp tem detail_responder (juiz pede detalhes de relacionamento); no Monetarie localizamos so parsers. Conferir cobertura |
| D18 | SVR 9800/9810 e cross_validator de CADOC | O cp tem os dois; Monetarie tem SVR + 9805 e so validator_4010. Conferir se sao exigidos para o perfil SCD |
| D19 | Modelo de alcadas | Unificar: maker-checker com handlers (Monetarie) + required_approvals por faixa de valor com votos (cp)? |
| D20 | Checklist do dono white-label | Rodar AJUSTES CORE AVIVPAY.docx como roteiro de validacao empirica do admin Monetarie (vinculo KYC, persistencia de limites/overrides, webhooks por cliente com reprocesso, API keys mascaradas, anexos do onboarding) |
| D21 | Higiene de dados herdada | Auditar no Monetarie: geracao de numero de conta (Rand.uniform?), criacao de usuario com senha vazia na criacao de merchant, convencoes de timestamps (defeitos confessados no TODO.md do cp, mesma linhagem) |
| D22 | Cobertura do ensure_mfa | Validar se o pipeline ensure_mfa cobre TODAS as rotas money-out do IB como o require_mfa+idempotent do cp cobre as dele |
| D23 | Device binding / dispositivos confiaveis | Exige backend novo nos dois (a UI do cp e esqueleto sem dados). Entra no roadmap? |
| D24 | Regras de extrato pos-fork | Validar dia-calendario BR (America/Sao_Paulo) e teto/paginacao de export no extrato Monetarie; portar os fixes 1bc53c74/801d7d87 se faltar |
| D25 | Dark mode no IB | O cp mantem; o Monetarie removeu no rebrand. Requisito de produto? |

## 6. Regras de port (obrigatorias em qualquer absorcao do coreproviders)

1. **Unidade monetaria**: o cp usa subcentavos (1 BRL = 10.000 MoneyUnit) em parse EMV (`round(f*10_000)`), saidas da API externa e varios composables; o contrato Monetarie e CENTAVOS na borda (`f79e17fa`). Todo valor copiado exige conversao e teste; e a mesma familia do bug de comprovante 100x ja corrigido (06-30).
2. **Nao regredir seguranca**: segredo de webhook cifrado (o cp guarda em texto claro), OAuth2 (o cp manda client_secret cru), escopos dedicados (o cp empresta escopos).
3. **Money path**: qualquer port que toque saida de dinheiro (limites, timeblock, MED) entra pelo caminho locked existente, com testes e validacao viva em HML (regra #11) antes de declarar entregue.
4. **Motor unico de BR Code**: geracao/validacao EMV consolidada na cabine (encoder IN-508); o Core roteia via behaviour + NATS, nunca duplica EMV em controller.
5. **Idempotencia e dedupe**: novos dispatchers de webhook nascem com o indice de dedup e o guard fail-closed; nada de dispatch inline sem durabilidade.
6. **BACEN e verdade**: divergencia com o BACEN e defeito nosso, provado empiricamente antes de qualquer hipotese (regra permanente do dono).

## 7. Fatos validados no codigo nesta sintese (2026-07-02)

Todos os achados P0 foram re-verificados por leitura direta antes desta consolidacao:

1. `mon/use_cases/pix/brcode/parser.ex:32`: `compute_crc16("#{payload}6304")` com payload que ja termina em 6304 (bug); `cp/use_cases/pix/brcode/parser.ex:29-32` computa sobre o payload puro com o comentario "payload already includes 6304 tag+length" (fix).
2. `monweb/controllers/v2/pix_controller.ex:588-590`: BR Code hardcoded terminando em `6304` literal, `qrcode_base64 = nil`, comentario `TODO: Monetarie.Pix.BRCode module not yet implemented`.
3. `monweb/controllers/partner_v1/pix_controller.ex` (create_charge): monta brcode e responde 201 sem nenhum insert; `show_charge` le `get_qrcode_by_tx_id` (sempre 404 para charges criadas ali).
4. Grep em `mon/use_cases/payments/`: nenhuma chamada de LimitCheck/TimeBlock fora de `pix_in/`; o outbound so referencia BalanceGuard/LimitCheckContext.
5. Grep em `mon/`: `evaluate_transaction` sem nenhum chamador alem da definicao/delegate.
6. `monweb/plugs/idempotency.ex` (get_user_id): fallback `"anonymous"`; `monweb/plugs/partner_bearer_auth.ex:44-52` atribui apenas `:api_key`/`:api_key_merchant_id`/`:api_key_partner_id`, nunca `current_user`.
7. `monweb/controllers/admin/coreproviders_parity_controller.ex:1306-1312`: `account_fee_detail_exports` devolve `%{data: []}`, `account_fee_detail_export` devolve `status: "ready"` fixo, `create_...` devolve UUID gerado na hora.
8. `mon/schemas/webhooks/webhook.ex:27-35`: `@valid_events` com 23 eventos, sem `pix.return.received`; dispatchers reais encontrados: `pix.charge.paid` (pg_writer, orphan reconciliation, post-deploy), `pix.return.received` e `pix.payout.returned` (return_in_handler:465-470). `pix.payout.returned` esta na whitelist e funciona; `pix.return.received` nao esta (assinatura impossivel).
9. `monfront/banking/src/views/business-onboarding/Step4SmsView.vue`: `sendCode` so seta flag local e `verify` so navega (nenhuma chamada de API).
10. `cabine/settlement_service/.../qr_codes.ex:985`: `expire_dynamic_qr_codes` definido, unico hit no grep (sem caller).
11. Listagem de `monweb/plugs/`: nao existe plug de IP whitelist do admin (so CRUD/controller).
12. `monweb/plugs/rate_limiter_per_key.ex:62` le `api_key.metadata["rate_limit"]`, mas `mon/schemas/api_keys/api_key.ex` nao tem campo `metadata` (config por key e codigo morto).

Fontes dos 5 dominios: auditorias da Fase C sobre `/Users/luizpenha/monetarie/core` e `/Users/luizpenha/coreproviders` (backend `lib/fluxiq*`, frontends, `MELHORIAS.md`, `TODO.md`, `PIX BR Code Compliance*.md`, `AJUSTES CORE AVIVPAY.docx`, postman da API Externa, `cloudpix_simulator`).
