# Handoff 2026-07-16 (noite) — fecho da auditoria money-path, deploy geral, reparos PROD, lastro do Construtor e análise das pacs.002 não entregues

Sessão que assumiu a fila de uma sessão anterior interrompida por 529 e a levou até o fim, em paralelo com a frente Partner API/submissão (outra sessão, mesma árvore). Retomar com `/retomar`; memórias novas: `monetarie-auditoria-fixes-r1-r10-0716`, `gotcha-ssm-tunnel-15432-core-tests`.

## 1. Estado do repositório

- `origin/main = da2a8b1c` no push desta sessão; depois disso a main local recebeu os commits da frente paralela (`67c03718..70dfc37b`) e o lastro do Construtor (`d7fdb520`). O push final desta sessão leva tudo — conferir `git log origin/main..HEAD` vazio ao retomar.
- Frente paralela (Partner API + submissão sem inferência): commits `67c03718`, `5bbb578e`, `ac5d1402`, `9d2256de`, `abf8f8f0`, `0c46f3f4`, `70dfc37b`. Relatórios em `docs/reports/2026-07-16-partner-api-auditoria-completa.md` e plano em `docs/plans/2026-07-16-partner-api-auditoria-fixes-design.md`. Estado dela ao encerrar: TED hold + webhook de timeout em andamento (`ted_controller.ex` + 2 testes novos; ver §6).

## 2. Deployado HOJE (validado vivo, health 100% nos 8 alvos)

Tags `homolog-/prod-da2a8b1c-moneypath-20260716`, MESMO digest homolog→prod (imagetools, MATCH conferido nos 4):

| Serviço | HML | PROD | Rollback PROD |
|---|---|---|---|
| pix-api | :176 | :53 | :52 |
| core-api | :152 | :56 | :55 |
| sta-api | :10 | :15 | :14 |
| core-banking-ui | :28 | :4 | :3 |

Migrations da cabine PIX aplicadas em HML e PROD via rpc e conferidas vivas: `20260716210000` (outbound_send_claims) e `20260716220000` (netting_operations.currency). Gate do STA preservado byte a byte (outbound ligado, necessário ao job do CCS).

Conteúdo do deploy: fixes R1-R5/R7/R8/R10bc da auditoria money-path (`94856e86..3eaec2a4`), CCS §5.5 no STA, PR #17 do Micael (API key IB + PI-PayerId). Relatório da auditoria: `docs/reports/2026-07-16-money-path-pix-aviv-vs-monetarie-auditoria.md`.

**NÃO deployado ainda** (commitado depois do build): o lastro do Construtor (`d7fdb520`) e os 7 commits da frente paralela. Próximo deploy de pix-api e core-api leva tudo; nenhuma migration nova nesses commits (conferir ao deployar).

## 3. Reparos executados em PROD (com OK do dono)

1. **DLQ MONETARIE_DLQ**: grupo A (netting 42703 currency) descartado por seq via `$JS.API.STREAM.MSG.DELETE` — 28 → 11 mensagens (14 do dossiê + 3 retries novos do dia). As 11 restantes = exatamente os grupos não-A do dossiê da sessão anterior (B nunca-replay, C descartáveis, D seq 14/15/18, BACEN_DLQ à parte). Dossiê completo recuperado em scratchpad da sessão `a6e89509` (subagentes).
2. **Conta 1644**: `account_daily_summaries` de 13/07 corrigido 2000000 → 20000 (base_units; a remediação de 13/07 corrigiu a entry e não o summary). Verificado vivo: TB == PG == safe == R$ 4,00.
3. **Conta 2031**: verificada SÃ — as 3 devoluções parciais (0,50+0,25+0,25) creditadas em 15/07, TB == PG; o drift de R$ 1,00 do reconcile fechou sozinho. Nenhum reparo.
4. **RESP bogus SISBAJUD: exclusão ABORTADA por fato novo.** Às 18:19:25 UTC (15:19 BRT) um admin humano (actor `044f7e23`, pela tela) ENVIOU o arquivo ao BACEN via STA: `regulatory_files 8a9ef4d7...` agora `delivered`, protocolo `433721199` (audit_logs: STA_FILE_SENT + STA_FILE_UPLOADED pelo nats_sta_consumer). A premissa de segurança do DELETE (nunca foi ao BCB) morreu. Recomendação registrada: MANTER a linha; avaliar efeito de um 5302 vazio de 15/07 (dia com 0 judicial_orders). Excluir agora é decisão nova do dono.

## 4. Análise: pacs.002 não entregues (2 operações de hoje) e fallback camt.060

Pergunta do dono respondida com todas as camadas fechadas (não afirmar além disto):

- Operações 14026 (11:23 BRT, R$ 20.167,77, Itaú) e 14125 (15:27 BRT): pacs.002 NUNCA entrou (sem linha no acervo, sem MSG_RECV, sem erro). Na 14125, as respostas dos camt.060 de 18:29 e 18:34 UTC também não vieram; a de 18:39 veio em 1s. Total: 4 mensagens devidas não entregues no dia; as outras 5 pacs.002 do dia chegaram em 1-3s.
- **Prova positiva do nosso lado**: sidecar com ~76 GETs de stream POR MINUTO contínuos nas duas janelas; zero erros de worker nas janelas (429 só nos swaps de deploy 16:09 e 21:00 UTC, task dupla, inofensivo); zero falhas de parse/persist/publish no dia; zero drops do AckTracker; zero 410/reabertura; pré-ACK persiste antes de avançar cursor (falha = não avança = retransmissão); heartbeats failed=0.
- **Hipótese do pacote multi-mensagem lido parcialmente (pedido do dono): testada e SEM sustentação.** Código: lote é tudo-ou-nada (parte inválida derruba o lote, cursor não avança). Dados: nenhum instante de entrega esperada tem parte irmã persistida (op1: zero linhas na lacuna; op2: camt.053 de 18:31 é um dos 8 extratos periódicos do dia, sem OrgnlBizQry e sem referência aos nossos msg_ids; demais linhas são mensagens completas de outras operações).
- **Janela teórica residual (follow-up de hardening)**: `MultipartParser` aceita corpo SEM `--boundary--` final quando todas as partes extraídas fecham XML — truncamento exato entre partes aceitaria N e perderia a N+1 (ainda exigiria o HTTP client entregar corpo incompleto como sucesso). Endurecer: recusar ou no mínimo alarmar corpo `:open`.
- **O que não dá para ver daqui**: a fila do lado do SPI e a semântica fina multi-slot do manual v1.12 §4 (NÃO VERIFICADO). Próximo passo de confronto factual: chamado ao BACEN/SPI como PERGUNTA documentada (dossiê: E2Es `E46026562202607161422tg6rmzz6nkq` e `E460265622026071618273mimcaj426x`, msg_ids dos camt.060 46565/46631, timestamps UTC, cadência de polls, zero-erros) — AGUARDA OK do dono.
- O fallback (`PaymentStatusReconciler`, ordem do dono de 14/07) resolveu as duas: dinheiro liquidado 1x, ACSC correto.

## 5. Lastro do Construtor (mandato do dono, implementado)

Commit `d7fdb520`: o Construtor NÃO transmite mais XML cru. pacs.008 (envio direto E aprovação de retida) delega ao funil `POST /api/v1/payments` do SPI: débito two-phase no Core fail-closed (`CoreDebitValidation.register`), E2E fresco + burn, linha rastreada com ciclo completo, autorização do OPERADOR encaminhada. XML da tela = prévia. Truth-table: pacs.008 = `:funnel`. Testes: lastro 3/3, truth-table 32/32, settlement 962 (1 falha da frente paralela em `core_event_processor`, caminho não tocado — reconferir após o merge dela).

Consequência operacional: pacs.008 do Construtor com `local_instrument=DICT` agora exige consulta DICT viva (mesma regra do envio manual); MANU segue direto.

## 6. Pendências (por dono e por próxima sessão)

**Aguardam decisão/OK do dono:**
1. Chamado BACEN/SPI sobre as 4 mensagens não entregues (dossiê pronto para montar; §4).
2. RESP SISBAJUD entregue ao BACEN: manter (recomendado) ou excluir (decisão nova).
3. Observações do dia seguinte: ciclo de netting 00:30 UTC (primeiro pós-fix da coluna currency) e job diário do CCS ~01:05 BRT (virada da numeração `202607170001`; veredito capturado se ECCS0003).

**Próxima sessão (ordem sugerida):**
1. Fechar a frente TED em voo (§1): `ted_controller.ex` + `stale_hold_checker_timeout_webhook_test.exs` + `ted_controller_hold_test.exs` (estado dos testes ao encerrar: ver commit/nota final desta sessão).
2. Deploy do acumulado (lastro + frente paralela) em pix-api e core-api quando a frente fechar; sem migrations novas até `d7fdb520`.
3. **R6 + ports 5-8 da auditoria (autorizado pelo dono)**: resolvedor de `outbound_requests` stage 1/2 dirigido por evidência (consulta cabine/camt.060/acervo) + quarentena explícita; alerta HUMANO (pacs.002 ausente, burns rejeitados, stuck, DLQ); teto cumulativo de devoluções; reserva persistida consulta-pagamento. O caso de hoje (§4) é o argumento vivo do port 6.
4. Follow-ups de tela apontados pelo dono: rotular camt.060 de operação como Consulta de Operação (hoje "Solicitação de Extrato"), dedup das 2 linhas camt.054 no histórico, correlacionar XMLs reais à transação (painel "Mensagens BACEN (XML)" mostrando 0).
5. Hardening do MultipartParser (corpo `:open`, §4) e re-query do reconciler mais rápido que 5min quando o camt.060 não responde.
6. Ressalva da sessão anterior que segue aberta: 429 nos swaps de deploy é esperado (task dupla) mas merece envelope de backoff mais gentil; replicação nats-3 do PROD com lag (observação do dossiê DLQ); `api.errors` alto no $G do JetStream.

## 7. Gotchas novos desta sessão

- **Túnel SSM em localhost:15432 sombreia o monetarie-pg de teste do Core** (porta do túnel para a Aurora HML). Sintoma: "connection not available ... 4000ms" intermitente no ecto.create. Checar `lsof -iTCP:15432 -sTCP:LISTEN`; workaround `DB_HOST=$(docker inspect monetarie-pg ... IPAddress) DB_PORT=5432`. NUNCA matar o túnel de outra sessão.
- **TigerBeetle de teste persiste entre runs**: ids de teste agora são run-unique (`Factory.transaction_id_sequence`, `tb_account_id_sequence`, `tb_int4_id_sequence` — este para ids que também vão a colunas PG int4). Receita de reset do container em caso extremo: format + start com `--security-opt seccomp=unconfined`.
- `mix test` na raiz do umbrella pix com CAMINHO DE APP (`apps/spi_service`) não roda nada; usar o diretório `apps/spi_service/test`.
- Leitura de DLQ/acervo em PROD: ECS exec + `bin/<app> rpc 'Code.eval_file("/tmp/q.exs")'` com o arquivo por base64 (canal SSM trunca ~8KB; gravar saída em /tmp do container e ler por partes). Mensagem NATS por seq: `Gnat.request("$JS.API.STREAM.MSG.GET.<STREAM>", %{seq: N})`; delete por seq idem com MSG.DELETE.
- `monetarie_spi.system_configs` é tabela legada que pode não existir; o lookup de reserva PI agora tolera via `to_regclass` (fix do 25P02 que matava TODA execução de recorrência em ambiente sem a tabela).

## 9. Adendo — frente Partner API + submissão sem inferência + dinheiro preso (fecho, `origin/main = 839eb572`)

Continuação da frente paralela citada em §1, levada até o fim e PUSHADA. Nada
deployado (money-path CONGELADO até domingo por autorização do cliente; retoma
segunda com o cliente rodando sequências de PIX e nós acompanhando 100%). O
próximo deploy de pix-api e core-api leva TUDO isto + o lastro do Construtor
(§5). Sem migrations novas nesta frente.

**Auditoria da Partner API (caso Herbeth/Vulci) — 12 defeitos, deployáveis:**
- dict_lookup do partner/merchant enviam o documento do pagador (DICT v2.11.0
  exige PI-PayerId; a chave da KANASTRA existe e não resolvia); send_pix leva
  sender_document/sender_name + pix_key/creditor_proxy (PIX-out do parceiro
  estava 100% quebrado); TED persiste recipient_*; extrato/comprovante/status
  com contraparte via Receipts.Payload canônico (+ alias sender_*); erros
  legíveis (fim do 200 "not_found" e do inspect() no JSON).
- REPARO HML: `users.partner_id` do user 25100 (Herbeth) restaurado + conta
  10024216 fundeada R$1 para teste. Relatório:
  `docs/reports/2026-07-16-partner-api-auditoria-completa.md`.

**Submissão PIX/TED sem inferência — 11 defeitos (commits `9d2256de`, `abf8f8f0`,
`0c46f3f4`; relatório `docs/reports/2026-07-16-money-path-submissao-taxonomia-falha.md`):**
motivo real da rejeição (nunca NULL) unindo transaction.rejected×transaction.error;
queima de E2E ATÔMICA com a transação (root do `:e2e_already_used` falso);
`{:tx_create_failed}` reconhecido (fim do NAK infinito do varchar); redelivery
idempotente por dono da queima; matching sem "última pendente" (PIX exige
amount exato; TED exige unicidade); SPB propaga motivo no R1/R2 vivo + fim do
duplo-débito em falha transitória (rejeição ao Core só em falha permanente).

**Dinheiro preso + TED merchant + agendamento (commits `30397aaf`, `f2bac264`,
`0fdac806`):**
- OutboundSender terminaliza (RJCT) + reverte bloqueio Conta PI da pacs.008 que
  falhou ANTES do envio (HSM/XSD/sanções/XML); o hold do cliente é liberado
  pelo reconciliador que consulta o status agora terminal. NÃO terminaliza ACSP
  às cegas (pode ter ido ao BACEN → fica com camt.060).
- Reconciliadores (que CONSULTAM o status real) veem "accepted", não só
  "processing" — seguro, não é timeout cego.
- Timeout de TED dispara `ted.failed` (antes só PIX).
- TedController do merchant segura+debita (paridade partner/v2; antes a TED
  saía com o saldo intocado).
- `BacenGateway.SettlementSchedule.decide/3`: base do fluxo de agendamento de
  TED por data de liquidação (hoje=envia, futura+dia útil=agenda,
  passado/fim-de-semana/feriado/inválida=rejeita).

**AGUARDA OK DO DONO (design pronto, `docs/plans/2026-07-16-money-path-design-para-aprovar.md`):**
fluxo de agendamento TED ponta a ponta (Core envia settlement_date, cabine
agenda/rejeita, watchdog respeita "scheduled"); outbox cross-repo;
sender_ispb/local_instrument heurísticos; event ausente descartado em silêncio;
transient? catch-all.

**GOTCHA:** `origin/main` ficou momentaneamente quebrada — `ff59b45d` subiu o
teste do webhook de timeout SEM a impl do `stale_hold_checker.ex`; o commit
`30397aaf` fechou. Suítes verdes no fecho: core 7761/0, spi_service 853/0,
shared 1738/0, SPB settlement 8/0 + consumers/nats 54/0 + lifecycle 61/0.

**Validação viva pós-deploy (roteiro):** como Herbeth, dict_lookup da chave
KANASTRA (200 com titular + E2E); PIX R$0,01 Herbeth→KANASTRA construindo a
pacs.008; TED com `recipient` no status/extrato/comprovante.

## 8. Rastreabilidade

- Auditoria money-path: `docs/reports/2026-07-16-money-path-pix-aviv-vs-monetarie-auditoria.md` (R6 e ports 5-8 pendentes; resto fechado).
- Dossiês da sessão interrompida (DLQ, verdade do E2E duplicado, RESP): subagentes em `~/.claude/projects/-Users-luizpenha-monetarie/a6e89509-*/subagents/` (finais extraídos no scratchpad desta sessão).
- CCS: `docs/handoff/2026-07-16-ccs-aceite-bacen-utf16be-handoff.md` (pendência 1 = job de 17/07).
