# Handoff — Deep audit de paridade PIX: LegadoPIX (CRK/Corner) vs cabine Monetarie

Data: 2026-07-23. Sessao 100% auditoria (read-only) + documentacao. NENHUMA alteracao de codigo de producao.

## Estado canonico

- Branch: `deepaudit/paridade-legadopix-2026-07-23`, commit `73796cd0` (+ este handoff). NAO pushada. `main` intocada.
- Deliverables versionados so em `docs/reports/` e `docs/handoff/` (42 + 1 arquivos). Nada de `LegadoPIX/`, PDF ou screenshots entrou no commit.
- Regra reforcada: sem push sem OK do dono; sem deploy pix/spb com o dono operando money-path.

## O que foi feito (6 fases)

1. Inventario do dump `LegadoPIX/` (5 sistemas legados CRK/Corner): SPI (cabine + ~20 workers por fila), DICT, MED/GID, Multiliquidacao (lote), AdmWeb (usuarios/alcadas/MFA). E dump de BINARIOS publicados (0 fonte .NET; 43.900 DLLs, 184 de negocio) + fonte Angular + 207 scripts SQL + 18 backups SQL Server.
2. Restauracao de 18 DBs SQL Server no container `monetarie-bak-mssql`.
3. Decompilacao de 184 assemblies .NET (`ilspycmd`).
4. Mapeamento dos frontends Angular do legado e da nossa cabine (Elixir/Vue).
5. Deep audit via WORKFLOW multi-agente (94 agentes, 0 erro, ~20,7M tokens, ~80 min): 31 dossies comparando legado x nosso com prova nos dois lados, cada gap por 2 lentes adversariais (confirmar/refutar), sintese no registro-mestre.
6. Re-verificacao do item duvidoso (camt.055/camt.025) por leitura direta do codigo: CONFIRMADO.

## Deliverables (versionados na branch)

- `docs/reports/2026-07-23-deepaudit-gap-register.md` — REGISTRO-MESTRE de gaps (~261 acionaveis, 19 temas alto, tabela priorizada, detalhe por area, apendice de cobertos, split produto x defeito). LER PRIMEIRO.
- `docs/reports/2026-07-23-paridade-legadopix-matriz.md` — matriz da 1a passada (mais rasa, superada pelo registro-mestre; mantida por rastreabilidade).
- `docs/reports/2026-07-23-deepaudit-dossies/` — 31 dossies detalhados (um por mensagem/fluxo/tela/tabela) + `_mapas-de-apoio/` (9 mapas da fase de inventario, incl. os 2 laudos de verificacao 11/12).

## Foto honesta do resultado

O nucleo de mensageria money-path esta em PARIDADE FORTE e em varios pontos e mais seguro que o legado (pacs.008 in/out, pacs.002 terminal-safe sem duplo-credito, pacs.004 com RtrId de queima estrutural, camt.052/053 sem o bug de sinal do legado, DICT chaves/claims/MED, CID sync, REDA, LPI0006, 4-olhos da alcada, idempotencia, RBAC+MFA). Os buracos se concentram em 4 baldes:

1. Camadas de CONTROLE ausentes/inertes (alcada universal no money-path automatico, motor antifraude externo, antivarredura DICT, CheckFraud).
2. Subsistemas de PRODUTO inteiros (Multiliquidacao/lote, PIX Automatico lado pagador, tarifa por CdMsg, contabil configuravel por evento).
3. Lacunas de FLUXO/OPERACAO (conciliacao so detecta e nao repara, expurgo/retencao ausente, ReqSaldo/reserva sem backend, janelas de horario DICT).
4. DEFEITOS REAIS em trilhos que existem mas estao quebrados (abaixo).

## Defeitos reais (balde 4) — prontos para corrigir, por risco

| # | Defeito | Impacto | Prova | Nota |
|---|---|---|---|---|
| 1 | Hold preso: admi.002/camt.060 not_found nao encerra a operacao presa | dinheiro bloqueado indefinidamente (re-consulta a cada 5min, hold nunca liberado) | `inbound_processor.ex:1856-1888` | **CORRIGIDO 23/07 (TDD, commit nesta branch, SEM deploy)**: admi.002 "nao existe lancamento" da camt.060 op_status encerra a operacao presa (decisoes do dono: limiar 15min via `ADMI002_NOT_FOUND_REJECT_AFTER_MINUTES`, escopo amplo pacs.008 OUT + pacs.004 nas 2 direcoes, automatico sem flag). Guardas fail-closed: motivo normalizado, so action op_status, idade minima anti-corrida, linha nao-terminal. Saida (pacs.008/004 OUT) = claim rejected + status_update "rejected" pelo trilho provado (Core libera hold); devolucao recebida (004 IN) = RJCT local sem publicar ao Core. Bonus: reconciler agora consulta pacs.004 OUTBOUND presa e backoff conta not_found (antes re-consultava a cada tick de 30s). Testes: `inbound_processor_admi002_notfound_close_test.exs` (9) + reconciler (9); spi_service 1011/0, shared 1871/0 |
| 2 | Limite diario quebrado: `get_daily_spent` le `transactions.debtor_account_id` (coluna inexistente, tabela nao-canonica) | checagem de limite diario nao funciona | `limits.ex:125` | **CORRIGIDO 23/07 (TDD, commit nesta branch)**: acumulado do dia BRT vem do modelo canonico messages+payments (conta = payments.debtor_account, valor REAIS->CENTAVOS, exclui RJCT/CANC, query no Shared.Repo); BONUS: `nighttime?` corrigido para hora de BRASILIA (antes olhava hora UTC crua — 03:00 BRT passava como dia). Testes: limits_daily_spent_test (10) + limits_test reescrito p/ BRT; spi_service 1021/0. Deploy pix-api pendente da proxima janela |
| 3 | trck.002 de PJ emite `<OrgId>` invalido no XSD + grafo de rastreamento serve STUB fabricado | reporte MED de CNPJ e rejeitado pelo BACEN | `message_builder.ex:1553-1555`, `dict_proxy_controller.ex:874-915` | **CORRIGIDO 23/07 (TDD, commit nesta branch)**: g1 = build_trck_party FORCA PrvtId sempre (XSD Party38Choice; paridade legado Book.v111), party_id_type removido do core_event_processor, prova por validacao XSD viva com CNPJ nos 2 lados; g5 = POST tracking-graph delega ao refresh_tracking_graph REAL do dict_service (seam :tracking_graph_refresh_fun + apply runtime, padrao cid_sync), INSERT fabricado ('GRAPH-',COMPLETED,hop=1) REMOVIDO, erros honestos 404/422/503. Teste legado que assertava OrgId corrigido. Suites: shared 1878/0, settlement 1020/0. Deploy pix-api na proxima janela (junto com #2) |
| 4 | camt.055 recebida nao gera camt.029 (approve/deny orfaos) + camt.025 nao fecha trck.002 | PSP solicitante nunca recebe desfecho; status da trck.002 nao avanca | `med.ex:451,462`, `inbound_processor.ex:2579` | **EM ANDAMENTO 23/07 por etapas (decisao do dono: tela operador + flag auto OFF). ETAPA A FEITA (TDD)**: camt.029 outbound consertada — OrgnlPmtInfCxlId = PmtCxlId da camt.055 ORIGINAL (persistido estruturado em claim.evidence junto com processing_type/OrgnlPmtInfId), CxlPrcgTp DHAC/DHRC pelo desfecho, CxlStsRsnInf com codigo do whitelist do legado (AB09..RC10, fail-closed) em deny_claim/3; notificacao de auditoria 'cancellation_request' agora E gravada (era descartada em silencio) + log de descarte no record_notification. Provas: validacao XSD viva camt.029.spi.1.1 (3/0) + med_camt055_resolution_test (5/0); spi 1026/0, shared 1881/0. **ETAPA B FEITA (TDD)**: camt.025 agora e o recibo AUTORITATIVO da trck.002 — linha nasce ACSP (era ACSC fixo; attrs extraidos em internal_settlement_message_attrs public-for-test) e o InboundProcessor.resolve_trck002_from_receipt correlaciona pelo OrgnlMsgId (resource_id) e fecha ACPT->ACSC / RJCT->RJCT + MessageHistory CAMT025 (escopo restrito a trck.002; veredito sobrepoe linha pre-fix ACSC; fail-soft). Testes: inbound_processor_camt025_trck002_test (5/0) + settlement (4/0); spi 1031/0, settlement 1021/0. **ETAPA C FEITA (TDD)**: endpoints do operador no spi_service — GET /api/v1/med/cancellations (lista claims camt.055 com identificadores + whitelist p/ o select), POST .../:id/approve (camt.029 ACCR) e .../:id/deny (RJCR, rejection_code validado fail-closed, 422 com valid_codes; UUID invalido/inexistente = 404) — + proxy fino no gateway 4003 (SpiProxyController via call_spi, rotas /api/v1/med/cancellations*). Flag CAMT055_AUTO_RESPONSE_ENABLED (default OFF, runtime.exs): ON = auto-approve ACCR no claim aberto e RJCR FF08 SEM claim quando a original e desconhecida (solicitante nunca fica sem resposta, paridade legado); falha do auto NUNCA perde o pedido (claim segue open p/ operador). Testes: med_cancellation_controller_test (4/0) + cancellation_consumer_auto_response_test (3/0); spi 1038/0, settlement 1021/0. **ETAPA D FEITA**: tela `/med/cancellations` no pix-admin (CancellationListView: tabs por status, tabela com E2E/PmtCxlId/solicitante/valor/motivo, modais Aprovar (ACCR) e Rejeitar (RJCR com select do whitelist vindo do backend), i18n nos 5 idiomas, botao no hub MED). vue-tsc 0, vitest 126/126, build ok. **DEFEITO #4 COMPLETO (4 etapas, cada uma commitada+pushada); deploy pix-api + pix-admin-ui na proxima janela (junto com #2 e #3)** |
| 5 | QR originado pelo Core gera pacs.008 QRDN sem `<TxId>` | inconsistencia ao BACEN | `core_event_processor.ex:679-707` | **CORRIGIDO 23/07 (TDD)**: os campos de iniciacao eram VALIDADOS mas nao passados ao builder; agora `payment_request_initiation_params/1` (public-for-test) leva tx_id/purpose/InitgPty/descricao(Ustrd) ao MessageBuilder no fluxo automatico (mesmos nomes do caminho manual). Teste prova o fio payload->params->XML no builder real (QRDN com TxId; sem campos = sem TxId/Ustrd espurio). initiation_contract_test 11/0, settlement 1024/0. Deploy na proxima janela pix. Residual documentado: G2 (bloco Strd saque/troco) e G3 (validacao de CNPJ do InitgPty) seguem no registro |
| 6 | TariffMonitor manda camelCase que o changeset descarta | configuracao de tarifa some em silencio | `frontend .../services/monitors.ts:110-116` | **CORRIGIDO 23/07 (TDD)**: create/updateTariff agora falam o contrato snake_case do FeeSchedule (fee_type/flat_fee/valid_from/valid_until/active, updates parciais so com o que veio) e o READ-side (espelho do mesmo bug: lista lia amount/effective_date/status e o serializer devolve flat_fee/valid_from/active — valor 0 e status sempre ativo na tela) tambem foi consertado. monitors.spec.ts (3/0, body exato + mapeamento); vitest 129/129, vue-tsc 0. Deploy pix-admin-ui na proxima janela |
| 7 | Telas de reserva: credito/debito/aporte 404, admin inject/adjust 500 | gestao de reserva inoperante pela tela | `spi_proxy_controller.ex:502`, `balance_operation_controller.ex:200-225` | rota `POST /balance/requests` nao existe no spi_service |
| 8 | PIX Automatico com wiring invertido (update->cancelamento, cancel->aceite) + ACTIVE no ACK e nao no aceite | recorrencia mente estado | `recurrences.ex:511-516` | **CORRIGIDO 23/07 (TDD)**: pain.009 ACK NAO ativa mais (segue PENDING_APPROVAL; so grava original_message_id); update NAO emite mensagem BACEN (antes um amendment local mandava MndtCxlReq = CANCELAVA no pagador!); cancel envia pain.011 correto (antes saia pain.012/MndtAccptncRpt, a RESPOSTA do pagador, como comando); pain.012 INBOUND ganhou handler (process_mandate_acceptance -> Recurrences.apply_mandate_acceptance: Accptd true = ACTIVE, false = CANCELLED+motivo, MndtSts CCLD = confirmacao do cancel); send_pain012 outbound REMOVIDO (morto e errado); seam :recurrence_spi_client p/ teste. pain_wiring_test 7/0; spi 1045/0. Residual do dossie segue: lado PAGADOR inteiro do PIX Automatico (T4, decisao de produto) |

## Decisoes do dono pendentes (destravam frentes)

- Defeito #4 (JA DECIDIDO pelo dono 2026-07-23): resposta ao cancelamento MED (camt.055 -> camt.029) e por TELA do operador (aprovar/rejeitar), COM uma flag opcional para habilitar resposta AUTOMATICA (default OFF). Implementar as duas pernas: ligar `approve_claim`/`deny_claim` a endpoint + tela (operador-driven, padrao) e um modo automatico atras de flag. Nao fica mais como pergunta em aberto.
- A SCD adota ALCADA UNIVERSAL no money-path automatico (hoje flag `ALCADA_PIPELINE_ENABLED` OFF e o caminho do Core e isento)?
- A SCD adota MOTOR ANTIFRAUDE externo pre-envio (T2)?
- Exigencia regulatoria de ANTIVARREDURA DICT / CheckFraud (T8/T9)?
- Categoria de HORARIO da Monetarie no BACEN (define se precisamos das janelas DICT A/B/C/D, T11 — hoje INCONCLUSIVO)?
- Politica de EXPURGO/RETENCAO com arquivamento (T13 — hoje so Oban Pruner de 7d; regulatorio exige 10a ICOM / 2a DICT; NAO copiar QtdDiasManter=2 do legado as cegas)?
- Construir MULTILIQUIDACAO MVP (T3)? PIX Automatico lado pagador (T4)? Tarifa por CdMsg (T5)?

## Ambiente e artefatos EFEMEROS (como regenerar)

Os deliverables (docs) sao persistentes. Os insumos abaixo NAO estao no git e podem precisar de regeneracao numa sessao nova:

- Decompilado: `.scratch/legado-pix-decompiled/*.decompiled.cs` (184 assemblies). Regenerar: `bash .scratch/decompile_legado.sh` (~2-3 min). Precisa de `ilspycmd`: `dotnet tool install -g ilspycmd` (dotnet 10 ja instalado; binario em `~/.dotnet/tools`).
- DBs legados restaurados: container `monetarie-bak-mssql` em `/tmp/mssqldata` (18 DBs). EFEMERO: `/tmp` e overlay do container, perde no restart do container. Regenerar: `bash .scratch/restore_legado.sh` (~2-5 min, container tem que estar `running`).
- `.bak` hardlinkados em `/Users/luizpenha/Downloads/exportdbs/legadopix/` (visiveis no container em `/backups/legadopix/`).
- Acesso mssql: `docker exec monetarie-bak-mssql /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P 'LocalOnly#Bak2026' -C -N -h -1 -W -Q "SET NOCOUNT ON; ..."`. DBs: crk_spi, CRK_SPIDOMINIO, CRK_SPIMENSAGERIA, CRK_SPIFILAS, CRK_SPICONTABIL, CRK_SPIHIST, CRK_SPISEEDS, des_4dict, gid, crk_multtiliquidacao, CRK_MULTILIQINTEGCONTA, crksecurityadminBKP (+ CRK_SPILOG/MOCK/SIMULADOR/APIBACEN, crk_multiliquidacao_hist, dict_simulador).
- Dossies fonte tambem em `.scratch/legado-pix-map/deepaudit/` (gitignorado) alem da copia versionada em `docs/reports/2026-07-23-deepaudit-dossies/`.

## Gotchas descobertos nesta sessao

- OrbStack/virtiofs recusa a pre-alocacao grande dos `.mdf` no bind-mount de dados do mssql (OS error 2). Solucao: restaurar em `/tmp` (overlay do container), nao em `/var/opt/mssql/data`.
- O `RESTORE FILELISTONLY` do sqlcmd devolve `LogicalName` com CRLF; sem `strip \r` o `MOVE` do RESTORE quebra. O `restore_legado.sh` ja trata.
- `LegadoPIX/` e dump de binarios publicados (0 fonte .NET); decompilar e o caminho (autorizado pelo dono).
- Angular do SPI tem fonte (`LegadoPIX/Pix/SPI/angular/src`); o AdmWeb esta buildado (so bundles, sem `src/`).
- Convencao de unidade: legado guarda REAIS decimais `numeric(18,2)`; nossa cabine base_units/centavos. Toda comparacao de valor exige conversao.

## Proximo passo recomendado

Auditar-tudo-primeiro ja cumprido. Corrigir o balde 4 por ordem de risco, comecando pelo #1 (hold preso), cada um com TDD (teste que falha primeiro -> fix -> verde) e sem deploy sem OK. As frentes de controle e produto viram planos a parte depois das decisoes do dono acima.

## Comando de retomada (copiar e colar em sessao nova)

Ver o bloco no fim da mensagem que acompanha este handoff (ou reproduzir apontando para este arquivo + o registro-mestre).
