# Handoff 2026-07-03 — PIX: queda do HSM, prova de leitura, e mandato frontend/i18n/fluxos ICOM

Sessão longa. Este handoff existe para a próxima sessão continuar sem se perder, sem inferir e sem marcar como entregue o que não foi. Tudo abaixo é aterrado em evidência (arquivo:linha, banco vivo, log, sonda). O plano de execução detalhado está em `docs/plans/2026-07-03-pix-frontend-i18n-icom-flows-plano.md`.

## 1. Estado vivo (conferido hoje)

- `origin/main` = f79e17fa. HML: pix-api task-def **:112** (PIX assina no HSM com CPIA UID T011 `oe1ZQyCUK4CwYFfbRaiX`, pub `pTpK+MRCTxjYPZcPnrA5`), core-api :77, spb-api :25, pix-admin-ui :10.
- Login admin: `admin@monetarie.com.br` (senha em Secrets Manager / não escrever aqui).
- Wrapper AWS: `awsmon` (profile `vulcimonetarie`, acct 990933657879, sa-east-1). ECS exec NÃO herda secrets → ler `/proc/1/environ`; rpc = base64 → `Code.eval_file` (helper usado o dia todo, ver §6).

## 2. O que foi PROVADO hoje (contra hipóteses do dono)

### 2.1 A leitura da pacs.002 NÃO é lenta (25 ms). Rejeições são do RECEBEDOR.
O dono insistia que falhávamos em LER a pacs.002 de retorno (envio demorava 40s + AB03). Medido no vivo em `monetarie_spi.icom_received` (CreDtTm do BACEN → nosso received_at): **READ_LAG = 24-28 ms** nas 6 mensagens. Os 40s do tx 364 foram o BACEN esperando o recebedor e emitindo AB03 (BACEN carimbou o RJCT 40s após o envio; lemos 26ms depois).
- Outbound recentes = RJCT(8): parceiro **52833288 (LB PAY)** → **ED05** com `<AddtlInf>Pagamento rejeitado pelo PSP do recebedor</AddtlInf>` em ~3s; `10664513` → **AB03** "Timeout na liquidação" ~40s.
- Nosso pacs.008 é XSD-válido e ACEITO pelo BACEN (`bacen_outbound.return_code=201`, problem=nil). CNPJ do recebedor sob `<Cdtr><Id><PrvtId>` é VÁLIDO (XSD `PICpfCnpj` = CPF ou CNPJ; `OrgId` = `PICnpj` só CNPJ). NÃO é defeito de formato.
- Pool de leitura saudável: `ICOM_MAX_SLOTS=4` (proposital), 4 slots CPM abertos, 2 conns de folga p/ envio. 429 no histórico são de 9 dias (anteriores a esse ajuste).
- Money-safe: os 6 RJCT tiveram `balance_blocks.status='released'` reason `transaction_rejected` em ms (`status_updater.credit_back_and_release` → `Balances.revert_block`).
- **Conclusão:** para um PIX-out VERDE em HML, o recebedor precisa ACEITAR (LB PAY provisionar chave/conta, ou testar chave homolog que auto-confirma, ou testar INBOUND parceiro→nós). Memória `monetarie-pixout-read-latency-proof`.

### 2.2 HSM RTM CAIU (bloqueia envio). "Pendente" = fail-closed correto, dinheiro seguro.
Duas txns em "Pendente" (tx 397 20:40, tx 398 20:49) NÃO estão em `bacen_outbound` (nunca saíram). Log do `OutboundSender`: `XMLDSig signing failed ... {:signing_failed, "RTM HSM signing failed: {:http_status, 504}"}` em loop (NAK backoff). Sonda ao vivo do HSM `monetarie-hsm-hml.priv.rtmcloud.net.br`: `health`=timeout transporte 8s, `sign`/`get_attributes`=504 (~3s). Assinava às 20:22 (tx 365 saiu 201); caiu entre 20:22 e 20:40.
- É infra da **RTM** (compartilhado com SPB). O `/v1/health` (sem sessão/UID) também dá timeout → não é chave T011, não é sessão, não é código nosso.
- Comportamento correto: fail-closed (nunca manda pacs.008 sem assinatura), segura hold do pagador (block `active`), reenvia com backoff → sai sozinho quando o HSM voltar. Memória `monetarie-pix-crypto-hsm-vs-mtls`.

### 2.3 Receber NÃO usa HSM; só ASSINAR usa. (Dúvida do dono sobre DICT.CID 200.)
Dois caminhos de cripto, provados no código: assinar mensagem (XMLDSig) = HSM (`RtmHsm.sign` em UM lugar: `xml_signer.ex:360`); mTLS = keyfile em disco (`application.ex:202`); verificar inbound = chave pública (`xml_verifier.ex:140`). Por isso DICT.CID GET volta 200 com o HSM caído. `<Cdtr>`… (dado do dono: "recebendo via GET = HSM ok" é FALSO).

### 2.4 GAP de governança: a chave de CONEXÃO (CPIC) está em disco E no Secrets.
Provado: container tem `/tmp/pix/certs/client_key.pem` (`BEGIN PRIVATE KEY`, 0600); secret `monetarie/homolog/pix/cert/CPIC-46026562` ainda tem `key_pem`. A CPIA (assinatura) foi removida do Secrets (mandato aplicado só à assinatura). O dono exige "toda chave privada no HSM". mTLS-via-HSM precisa de **PKCS#11** da RTM (o EcosCryptoServer é gateway REST/KMIP, o `:ssl` do Erlang não chama REST no handshake) OU verificar se o OTP suporta `sign_fun` callback na opção `key`. Mitigação parcial sem RTM: manter a CPIC só em memória (DER na opção `key`, sem `keyfile`) — tira do disco, não põe no HSM. **NÃO FEITO.** Memória `monetarie-pix-crypto-hsm-vs-mtls`.

## 3. Mandato desta sessão (pedido do dono): frontend + i18n + fluxos ICOM

Três auditorias read-only aterradas geraram os inventários (resumidos no plano). Números:
- **Cores/dark:** ~630 ocorrências de "gap do shim" em 110/145 arquivos; hex arbitrário/inline = 0. Raiz do "status quebrado" = bordas coloridas `border-*-200/300` não remapeadas no dark (`style.css` shim 170-292) + bucket `orange`=`purple` (chip "Envio" vira roxo). Conserto é CENTRAL no `style.css`, não nos 110 arquivos.
- **i18n:** ~180 strings pt-br hardcoded em 28 arquivos (security/* = 53%); 27 namespaces ausentes por inteiro nos 4 locales secundários (transactions 319, balance 298, keys 108, reda 91, ...); `@` já 100% escapado.
- **Fluxos ICOM:** wired OK = pacs.008→pacs.002, reda.*→reda.016/admi.002, admi.002→original. Lacunas P1 = pacs.004 saída sem tracking/correlação; camt.052 sem handler (generic); camt.060→camt.053/052 sem correlação req↔resp (só por ISPB). P3 = pibr.001→pibr.002 sem correlação.

Detalhe completo com arquivo:linha e prioridades: `docs/plans/2026-07-03-pix-frontend-i18n-icom-flows-plano.md`.

## 4. Follow-ups numerados (para a próxima sessão)

1. **[bloqueador externo] HSM RTM** — cobrar a RTM restabelecer `monetarie-hsm-hml.priv.rtmcloud.net.br` (504/timeout desde ~20:22 de 2026-07-03). Sem ele não há envio PIX/SPB nem validação viva. Re-sondar antes de qualquer teste (helper §6).
2. **[teste do parceiro]** Para PIX-out VERDE: alinhar com LB PAY (52833288) para aceitarem o recebimento, OU testar INBOUND (parceiro→nós), OU chave homolog que auto-confirma. O ED05 é do recebedor, não nosso.
3. **[governança] CPIC → HSM** — verificar viabilidade (PKCS#11 da RTM vs `sign_fun` do OTP); enquanto isso, tirar a CPIC do disco (só memória). Não fingir que a assinatura de mensagem está em risco: ela já é 100% HSM.
4. **[frontend A0 P0]** fechar gaps do shim em `src/style.css` (bordas coloridas -200/-300, orange≠purple, cyan/lime, texto -400/-500). Validar Transações no dark por screenshot.
5. **[layout B1]** overflow-x-auto nas tabelas de `DictReportsView.vue:114/143/172`.
6. **[i18n C1]** extrair hardcoded pt-br começando por `security/*`.
7. **[fluxo D1/D2/D3]** pacs.004 saída tracking; camt.052 handler; camt.060↔camt.053 correlação. Aterrar em `mwbank/LegadoPIX`.
8. **[higiene]** `.scratch/` e inventários temporários em `/private/tmp/.../scratchpad/inv_*.md` (i18n, cores/layout, ICOM) — não versionar; regenerar se necessário.

## 5. O que NÃO fazer (para não repetir erro)

- Não afirmar que a leitura da pacs.002 é lenta (é 25ms, provado).
- Não tratar CNPJ sob `<PrvtId>` como defeito (XSD `PICpfCnpj` permite).
- Não trocar milhares de `bg-white`/`text-gray-900` (o shim já cobre; não quebram dark).
- Não mexer no escape de `@` (já correto).
- Não marcar UI como pronta sem screenshot dark+light; não marcar fluxo como pronto sem prova viva do par ida/volta.

## 6. Helper de rpc no HML (reuso)

```bash
awsmon() { env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN AWS_PROFILE=vulcimonetarie AWS_REGION=sa-east-1 aws "$@"; }
TASK=$(awsmon ecs list-tasks --cluster monetarie-greenfield-homolog --service-name pix-api --desired-status RUNNING --query 'taskArns[0]' --output text)
# escreve um .exs local, base64, e roda no nó vivo (Repo/HSM já up):
B64=$(base64 < /caminho/diag.exs | tr -d '\n')
awsmon ecs execute-command --cluster monetarie-greenfield-homolog --task "$TASK" --container pix-api --interactive \
  --command "/bin/sh -lc 'echo $B64 | base64 -d > /tmp/diag.exs && /app/bin/monetarie_pix rpc \"Code.eval_file(\\\"/tmp/diag.exs\\\")\"'"
```
Sonda rápida do HSM: `RtmHsm.sign_base64("46026562","probe",:sha256)` — se `{:http_status,504}` ou timeout, HSM ainda caído.
