# Plano mestre 2026-07-19: fechamento de TODAS as frentes abertas

> **Para Claude:** SUB-SKILL OBRIGATÓRIA: superpowers:subagent-driven-development (execução task a task nesta sessão, com revisão de spec + revisão de qualidade por task).

**Objetivo:** fechar em definitivo tudo que estava aberto no handoff de 19/07: frente APIX (gerador oficial + números corretos de abril), os 4 desenhos P6, as decisões antigas implementáveis, os follow-ups P2 e o backlog P3 técnico. Tudo com TDD (RED primeiro), revisão dupla, e prova. Ações de PRD (deploy, flag, purge, publicação, retificação) ficam PRONTAS num pacote único para o OK do dono, conforme a regra vigente.

**Arquitetura da execução:** 3 trilhas de código paralelas entre si e seriais por dentro (Trilha A = core, Trilha B = cabine pix, Trilha C = scripts/validação/frontends), porque apps distintos não compartilham arquivos. Trilha D (docs/pacote) fecha por último. Nenhum push, nenhum deploy, nenhum terraform apply. Commits locais por task.

**Decisões tomadas nesta sessão (mandato do dono em 19/07: "decida pelas recomendações, finalize tudo"):**

1. APIX: gerador oficial = `Cadoc1201` do core (ciclo STA pronto, taxonomia 5/6 correta). Abril será gerado com números CORRETOS a partir da projeção do restore AutBank; dossiê de retificação (TipoEnvio S) pronto para o dono decidir o envio ao BACEN. Lacunas do gerador viram parâmetros do operador (sem inventar fonte que não existe).
2. E-mail: SES (branch `EMAIL_TRANSPORT=ses` com `Swoosh.Adapters.AmazonSES`, credencial pela IAM role da task, zero secret novo). SMTP permanece como alternativa e Logger como default fail-safe. Flip por env fica no pacote.
3. pacs.004 no 4xx-terminal: implementado atrás de flag `PIX_RETURN_4XX_TERMINAL_ENABLED` default OFF. Flip no pacote.
4. Retry do create de infração: sucesso idempotente (retorna o report existente com `already_reported: true`), não 422 cru.
5. COERCION no FraudMarkerEnumMapper: `COERCION -> OTHER` e `UNKNOWN -> UNKNOWN` (OTHER é o valor de submissão semanticamente seguro para coação; UNKNOWN existe no enum do BACEN).
6. AMES-SIMBA: o desenho estava desatualizado, o elo já está costurado ponta a ponta; NÃO criar endpoint novo. Corrigir o desenho + validar vivo local + cobrir com teste o caminho attach type=simba se faltar.
7. Natureza da ação judicial: preencher `@natureza_acao_map` SOMENTE se a tabela oficial for encontrada em fonte autoritativa (manual SISBAJUD/CNJ); senão o fallback honesto permanece e o dossiê aponta o insumo exato.
8. NettingResult.net_amount: fix no SCHEMA (`:decimal` + normalização para centavos inteiros no consumo), sem DDL em PRD (acervo legado pode ter fração; alterar coluna viva é risco desnecessário num aparato inerte).
9. R13 STA e o resto da Wave 2 (relatórios PIX/volumetria, SLB) seguem a ordem já decidida pelo dono no desenho da Wave 2: DEPOIS da remuneração SPI. Fora deste lote.
10. `diversos/`: mover fisicamente para fora do repo (`~/monetarie-diversos-sensivel/`), após conferir que nada no repo referencia o caminho. Chaves tratadas como expostas a tooling local (rotação = decisão do dono, documentada no pacote).

**Ordem BACEN das verdades usadas:** fact packs de 19/07 desta sessão (6 trilhas read-only, arquivo:linha), relatório `docs/reports/2026-07-19-batimento-apix042026-vs-restore-autbank.md`, relatório `docs/reports/2026-07-18-migracao-infracao-dict-212-validacao-viva.md`.

**ADENDO 19/07 (revisão adversarial da C1, fonte oficial BCB):** a instrução de preenchimento oficial do APIX001 v2.6 (`APIX001_2-6.xlsx` do BCB) prova que o grupo Transacoes do doc 1201 cobre SOMENTE liquidação FORA do SPI (código 5 = liquidante de indiretos fora do SPI, informado apenas pelo Liquidante; 6 = clientes próprios fora do SPI; 7 = rejeitadas por fraude pelo PSP pagador; transações iniciadas apenas, nunca recebidas). Consequências: (1) o arquivo do legado estava CORRETO nos baldes de transação; a tese "legado subnotificou" fica REFUTADA nos baldes e INDETERMINADA nas consultas (QtdConsultas oficial = consultas resolvidas na cópia local do DICT sem consultar o DICT); (2) o defeito de taxonomia é NOSSO, no `Cadoc1201` do core (balde 5 contando pix) e também na taxonomia 5/7 da cabine; (3) o XML "corrigido" da C1 NÃO pode ser transmitido; (4) a Task A5 passa a incluir o fix de taxonomia do gerador com re-verificação da fonte oficial; (5) nasce a Task C1b: refazer batimento e dossiê com a conclusão honesta (retificação provavelmente desnecessária) e retratar a tese no fecho (CLAUDE.md, memórias, relatório de batimento com errata).

---

## TRILHA A (core/backend + core/apps): serial

### Task A1: aceite do operador na transferência judicial (desenho P6-1, flag OFF)

**Design:** `docs/plans/2026-07-19-aceite-operador-transferencia-judicial-design.md` (âncoras verificadas 19/07; def real de `settle_blocks_and_respond/3` é `processor.ex:669`, o `:659` do desenho é call site).

**Files:**
- Modify: `core/backend/lib/monetarie/use_cases/judicial/processor.ex` (dispatch TRANSFER `:169`, `process_transfer/1` `:303`, `process_outbound_transfer/1` `:592`, `settle_blocks_and_respond/3` `:669`, `settle_one_block/2` `:765`)
- Modify: `core/backend/lib/monetarie/schemas/judicial/judicial_order.ex` (`@valid_statuses` `:53`; adicionar `awaiting_acceptance`; campos snapshot de aceite)
- Create: migration `add_judicial_acceptance_fields` (status novo é string, sem enum de banco; colunas de auditoria do aceite se o desenho exigir; verificar no desenho)
- Create: `core/backend/lib/monetarie/workers/judicial/judicial_transfer_escalation_worker.ex` (cron 5min)
- Modify: `core/backend/lib/monetarie_web/controllers/regulatory/sisbajud_controller.ex` + `core/backend/lib/monetarie_web/router.ex` (rotas `POST .../orders/:id/accept-transfer` e `.../reject-transfer`, gate admin + permissão `judicial:transfer:accept`)
- Modify: `core/backend/config/runtime.exs` (flag `JUDICIAL_TRANSFER_ACCEPT_ENABLED` default false; `JUDICIAL_ACCEPT_ESCALATION_MINUTES` default 60; `JUDICIAL_ACCEPT_CUTOFF_MINUTES`)
- Modify: `core/apps/admin/src/views/regulatory/SisbajudView.vue` (botões Aceitar/Recusar com justificativa)
- Tests: `core/backend/test/monetarie/judicial/`, `core/backend/test/monetarie_web/controllers/regulatory/`

**Steps (TDD, RED primeiro):**
1. Teste RED: com flag ON, `process_order(TRANSFER)` deixa a ordem em `awaiting_acceptance` SEM tocar TB e SEM responder 01 ao BCB; com flag OFF, comportamento atual byte-idêntico.
2. Implementar o gate em `process_transfer` (antes de `settle_blocks_and_respond/3`), snapshot dos blocos.
3. Teste RED: `POST accept-transfer` (permissão ok) liquida pelo trilho EXISTENTE `settle_blocks_and_respond/3` inalterado, grava auditoria, idempotente (segundo accept = no-op 200). `POST reject-transfer` exige justificativa, responde ao BCB não cumprida (`not_fulfilled_by_operator`).
4. Implementar endpoints + permissão.
5. Teste RED: escalação nível 1 (worker notifica após N min) e nível 2 (cutoff responde `not_fulfilled_timeout`, NUNCA auto-executa).
6. Implementar worker + cutoff.
7. UI: botões na SisbajudView (spec Vue no padrão do atendimento F3, `SisbajudView.atendimento.spec.ts` como referência).
8. Suítes: `cd core/backend && mix test test/monetarie/judicial test/monetarie/regulatory/sisbajud test/monetarie_web/controllers/regulatory`; vitest do admin.
9. Commit.

**Guardas:** dinheiro só se move no aceite; crash entre aceite e liquidação reprocessa pelo estado; flag OFF = zero mudança de comportamento (provar por teste).

### Task A2: grade nominal de e-mails CCS + transporte SES (desenho P6-2)

**Design:** `docs/plans/2026-07-19-grade-nominal-emails-ccs-design.md`. Correções de âncora: `:accs003_received`/`:accs009_received` vivem em `core/backend/lib/monetarie/use_cases/ccs/sta_submission.ex:674/:692` (não em sta_inbound.ex); Logger adapter referenciado em `notifications.ex:25`.

**Files:**
- Modify: `core/backend/lib/monetarie/use_cases/ccs/notifications.ex` (3 eventos novos: `:ccs_system_window`, `:cc_imported`, `:consolidation`; e-mail nominal com "sem movimento" explícito)
- Create: `core/backend/lib/monetarie/workers/cadoc/ccs_schedule_notifier.ex` (worker único, arg = slot)
- Create: migration `create_ccs_schedule_notifications` (slot, date, sent_at; unique (slot, date))
- Modify: `core/backend/config/runtime.exs` (crons dos slots da grade: 09:00 ACCS003, 09:21 ACCS009, 10:00 janela, 10:20 CC, 10:40 consolidação, 11:00 geração, 20:10 envio, 20:42 baixa; horários BRT convertidos a UTC; envs `CCS_SCHEDULE_*`; e o branch SES: `EMAIL_TRANSPORT=ses` -> `Swoosh.Adapters.AmazonSES`, mantendo `SMTP_HOST` -> SMTP e default Logger, em `runtime.exs:930-958`)
- Tests: `core/backend/test/monetarie/ccs/notifications_test.exs`, novo `ccs_schedule_notifier_test.exs`

**Steps:** TDD por slot (RED: slot dispara 1 e-mail nominal idempotente por (slot, date); estado real consultado; sem movimento = e-mail dizendo isso). Depois o branch SES: teste de config resolvendo adapter por `EMAIL_TRANSPORT` (Logger default, smtp com SMTP_HOST, ses com EMAIL_TRANSPORT=ses). Cron parity test se existir padrão no repo (existe `cron parity` em core, seguir). Commit.

### Task A3: webhook test entrega SÓ ao webhook alvo

**Fatos:** `webhooks_controller.ex:269-281` (partner), `v2/webhook_controller.ex:154-179`, `admin/coreproviders_parity_controller.ex:1054-1060`, `webhook_controller.ex:74` (legacy): todos chamam `Webhooks.dispatch_event("webhook.test", ...)` que broadcasta (system event, tenant nil, `webhooks.ex:157-241`). Entrega single-target não existe; primitivas: `insert_and_deliver/4` privada (`webhooks.ex:243`), `DeliveryJob.deliver_now/2` (`delivery_job.ex:84-88`).

**Files:**
- Modify: `core/backend/lib/monetarie/use_cases/webhooks.ex` (nova função pública `dispatch_test/1` ou `dispatch_event_to(webhook, event_type, payload)`: monta o evento e usa o MESMO trilho `insert_and_deliver` restrito ao webhook alvo; dedup e HMAC preservados)
- Modify: os 4 call sites para usar a função nova
- Tests: `core/backend/test/monetarie_web/controllers/partner_v1/webhooks_controller_test.exs` (RED: criar 2 webhooks de partners distintos inscritos em webhook.test; POST test no primeiro; asserir que SÓ o primeiro recebe Delivery), `test/monetarie/use_cases/webhooks_dispatch_test.exs`

**Steps:** RED do fan-out -> implementar -> os 4 call sites -> suítes webhooks + partner -> atualizar doc do portal se ela descrever o comportamento (grep `webhooks/{id}/test` em docs-site) -> commit.

### Task A4: natureza da ação judicial (tabela oficial, se houver fonte)

**Fatos:** `wire_enums.ex:52-86` (mapa vazio, D4), parser posição 366-367 (`parser.ex:102`), serializer fallback honesto (`sisbajud_controller.ex:457-475`), tela `SisbajudView.vue:1076-1078`.

**Steps:**
1. WebSearch pela tabela oficial de "tipo natureza ação" do leiaute SISBAJUD (manual do arquivo de remessa 5301, CNJ/BCB). Aceitar SOMENTE fonte autoritativa (CNJ, BCB, manual oficial); registrar URL e data de captura no moduledoc.
2. Se encontrada: teste RED de `natureza_acao_label/1` para os códigos oficiais; popular `@natureza_acao_map`; suíte sisbajud.
3. Se NÃO encontrada em fonte autoritativa: NÃO inventar; escrever no dossiê final o insumo exato que falta (nome do documento e onde obter) e manter o fallback.
4. Commit.

### Task A5: Cadoc1201, suíte própria + parâmetros do operador

**Fatos:** gerador sem NENHUM teste dedicado; defaults em `aggregator.ex:147-190` (disponibilidade fixa 10_000 bp linha 184, devoluções/bloqueios/autorizações zero por default do schema); fontes: `transactions` (pix/tef), `dict_lookup_events`, `entities`; competência = `reference_date` 1º dia do mês; painel gera via `POST /admin/cadoc/generate` `{"tipo":"1201","year":Y,"month":M}` (`cadoc_controller.ex:114-145`).

**Files:**
- Create: `core/backend/test/monetarie/use_cases/regulatory/cadoc1201/aggregator_test.exs` + `xml_serializer_test.exs` (caracterização + novos comportamentos)
- Modify: `core/backend/lib/monetarie/use_cases/regulatory/cadoc1201/aggregator.ex` + `generator.ex` + `core/backend/lib/monetarie_web/controllers/admin/cadoc_controller.ex`

**Steps (TDD):**
1. Caracterização RED->GREEN: agregação de transactions pix/tef no mês, consultas DICT, receita fonte 1, XML válido com baldes certos (5=SPI, 6=fora-SPI), TipoEnvio.
2. Parâmetros do operador no generate (overrides opcionais e VALIDADOS: `disponibilidade_basis_points`, `devolucoes`, `bloqueios_cautelares`, `autorizacoes`, `receitas` extras, `tipo_envio` I/S): fluem do controller ao snapshot em vez dos defaults; ausentes = comportamento atual. Isso fecha as lacunas de forma honesta (dado do operador, não inventado) até existir fonte viva.
3. Suíte + commit.

### Task A6: remuneração SPI, lado CORE (consumidor do sweep)

**Design:** `docs/plans/2026-07-19-wave2-ordem-e-remuneracao-spi-design.md`. Contrato do evento (fixado neste plano, a cabine publica na Task B8): subject `monetarie.pix.remuneration.sweep`, payload `{"sweep_date":"YYYY-MM-DD","amount_cents":int,"reference":"REMN-<message_id>[,...]","source":"pix_cabin"}`. Idempotência no core por unique (sweep_date, reference).

**Files:**
- Create: `core/backend/lib/monetarie/infra/nats/handlers/pix_remuneration_handler.ex` (padrão do `spb_inbound_credit_handler.ex`)
- Create: migration + schema de espelho `pix_remuneration_sweeps` (sweep_date, amount_cents, reference unique, credited_at, transaction refs)
- Modify: wiring do consumer (onde os handlers NATS do core são registrados; seguir o padrão do subject `monetarie.spb.credits.inbound`)
- Tests: RED de idempotência (2 entregas = 1 crédito), crédito via funil institucional (candidato `Spb.InboundCredits.post_treasury_credit/4` `inbound_credits.ex:536` ou análogo dedicado com TB + extrato + COSIF fail-soft; decidir NO teste qual reusa com menos acoplamento)

**Guardas:** dinheiro-primeiro TB, COSIF espelho NUNCA bloqueia, dedup por reference. Commit.

### Task A7: merchant-ui delete-key (espelho do fix do banking)

**Fatos:** `core/apps/merchant/src/views/pix/PixKeysView.vue:237` manda `.id`; `core/apps/merchant/src/composables/usePix.ts:301` + `core/apps/merchant/src/http/api.ts:143` sem encode. Fix = `.key || .id` + `encodeURIComponent` (mesmo diff do banking em `19570dd5`).

**Steps:** vitest RED se houver spec da tela; aplicar as 2 linhas; build verde; commit.

---

## TRILHA B (pix/backend): serial

### Task B1: NettingResult.net_amount (:decimal + normalização)

**Fatos:** schema `netting_result.ex:44` declara `:integer`; coluna legada é numeric; único full-row load em `scheduler.ex:264-269` (`reconcile_session`); serialização `core_event_adapter.ex:74`.

**Steps (TDD):**
1. RED: inserir linha com `net_amount` fracionário via SQL cru (simula acervo legado) e provar que `reconcile_session`/load via schema NÃO crasha e normaliza para centavos inteiros (round half up documentado).
2. Field vira `:decimal`; accessor `NettingResult.net_amount_cents/1` normaliza; `scheduler.ex` e `core_event_adapter.ex` usam o accessor; changeset continua aceitando inteiro.
3. Suíte settlement + commit.

### Task B2: MED sem details = 4xx local (antes de efeito externo)

**Fatos:** validação de `report_details` só existe dentro do request builder (`request_builder.ex:428-470`), DEPOIS do `DictExternalOperations.start` (`funds_recovery.ex:1112-1113`); resultado vira 503 `bacen_external_failed` (`funds_recovery.ex:1760-1762`, controller `funds_recovery_controller.ex:80-84`).

**Steps (TDD):**
1. RED: `create_recovery` sem `report_details` retorna `{:error, {:missing_field, :report_details}}` ANTES de registrar operação externa (asserir zero linha em DictExternalOperations) e o controller devolve 422 com erro legível.
2. Validação local em `create_recovery/1` (junto de `validate_tracking_graph_limits`, `funds_recovery.ex:84-85`); caminho da infração (`infractions.ex:200-217`) coberto.
3. Suíte dict_service + commit.

### Task B3: retry do create de infração = sucesso idempotente

**Fatos:** unique `uq_infraction_report_tx` estoura em `insert_infraction_report_and_publish` (`infractions.ex:263-285`), controller devolve 422 `inspect(changeset.errors)` (`infraction_report_controller.ex:80-83`); teste atual do retry em `infractions_recovery_reroute_test.exs:202-220`.

**Steps (TDD):**
1. RED novo: retry do MESMO create retorna `{:ok, report_existente, :already_reported}` (ou shape equivalente), controller 200 com `already_reported: true`, ZERO nova chamada BACEN, count continua 1.
2. Implementar: capturar a violação do índice (changeset error em `:funds_recovery_id`), recarregar por (funds_recovery_id, end_to_end_id), retornar o existente.
3. Atualizar o teste antigo (que asseria 422 cru) para o contrato novo. Suíte + commit.

### Task B4: FraudMarkerEnumMapper: COERCION e UNKNOWN

**Fatos:** `fraud_marker_enum_mapper.ex:60-79` (COERCION/UNKNOWN fora da tabela, fail-closed `unknown_fraud_type`, moduledoc :44-46).

**Steps:** RED: `to_bacen("COERCION") == {:ok, "OTHER"}`, `to_bacen("UNKNOWN") == {:ok, "UNKNOWN"}`; round-trip documentado (from_bacen("OTHER") continua "OTHER": mapeamento é lossy e isso fica no moduledoc). Atualizar moduledoc (decisão de produto tomada 19/07). Suíte shared + commit.

### Task B5: sweep put_env(nil)

**Fatos:** 2 restos: `operation_query_test.exs:156-158` e `operations_query_controller_test.exs:77-79` (env `:spi_service, :camt060_spi_client`; padrão correto em `cid_entry_ingestor_db_test.exs:123-138`).

**Steps:** aplicar nil-guard (delete_env quando prev nil) nos 2; rodar os 2 arquivos + 1 seed alternativo; commit.

### Task B6: pacs.004 no 4xx-terminal (flag OFF)

**Fatos:** decisão vive em `rejected_outcome/2` (`outbound_sender.ex:704-711`); trilho terminal já existe (`:526-540` + `fail_outbound` -> `return_not_sent` barulhento `:998-1037` + `mark_return_failed` RJCT `:1039-1053`).

**Steps (TDD):**
1. RED: com `PIX_RETURN_4XX_TERMINAL_ENABLED=true`, 4xx síncrono em pacs.004 terminaliza JÁ na primeira recusa (claim settled rejected, `return_not_sent` logado, RJCT, telemetria); com flag OFF (default), comportamento atual `:retry_regulatory` byte-idêntico.
2. Flag em `runtime.exs` (spi_service) + `rejected_outcome/2` consulta a flag SÓ para pacs.004.
3. Runbook do flip anotado no pacote. Suíte spi_service + commit.

### Task B7: PixInOrphanRecon resolve devolução concluída + higiene de timeout

**Fatos:** worker não conhece pacs.004 (`pix_in_orphan_reconciliation.ex`, classify `:230-248`, resolve só `:confirmed` `:335-349`); caso Wise E2E `E5958811120260717205916346PG2TJD` re-alerta a cada ciclo; queries com `timeout: 30_000` (`:189-198`) acima do `db_timeout` 15s do pool (`runtime.exs:257-279`), candidato forte dos Postgrex disconnects (cron 17,47 = 2x/h).

**Steps (TDD):**
1. RED: órfão cujo E2E tem pacs.004 OUTBOUND concluída (status settled/accepted na `messages`/`transaction_returns`) re-classifica como `:returned` e é `resolved` (razão gravada), SEM re-alertar.
2. Implementar a classificação (consulta por `message_code == "pacs.004"` vinculada ao E2E original; usar a fonte que o ReturnProcessor grava, verificar `transaction_returns`).
3. Higiene de timeout: por-query `timeout:` alinhado ao teto do pool (15s) + chunking do EXISTS de oban_jobs se necessário; teste de regressão do lookback.
4. Suíte spi_service + commit. Validação viva PRD (sonda read-only do órfão da Wise) vai no pacote.

### Task B8: remuneração SPI, lado CABINE (relatório + sweep, flag OFF)

**Design:** `docs/plans/2026-07-19-wave2-ordem-e-remuneracao-spi-design.md`. Fato: crédito de remuneração já existe (`inbound_processor.ex:2692-2737`, camt.053 Bal[REMN], idempotente por `REMN-<message_id>`; correlação CRE `:2734`).

**Files:**
- Create: agregador/endpoint de relatório (admin da cabine): remuneração por dia/mês a partir de `BalanceHistory` `reference_type == "spi_remuneration"`, com CRE correlacionado; export CSV
- Create: `SpiService.Workers.RemunerationSweepWorker` (cron diário pós-fechamento, flag `SPI_REMUNERATION_SWEEP_ENABLED` default OFF): apura o acumulado ainda não varrido, grava linha local de sweep (idempotência), publica `monetarie.pix.remuneration.sweep` (contrato da Task A6) e registra o débito equivalente no espelho da PI
- Create: migration da tabela de sweeps (cabine) + sonda de reconciliação (soma movimentos - repasses = remanescente)
- Tests: RED de idempotência do sweep (2 execuções no mesmo dia = 1 evento), flag OFF = no-op, reconciliação fecha

**Guardas:** NUNCA varrer valor não creditado; evento publicado via outbox roteado (ObanRouting, `publish_async` dentro da transação do repo certo). Suíte + commit.

---

## TRILHA C (scripts, validação, higiene): paralela a A e B

### Task C1: APIX de abril com números corretos (projeção + geração + dossiê)

**Fatos:** restore `monetarie-bak-mssql` UP; abril real = 243 externas aprovadas (244 pacs.008 enviadas), 5 internas R$804.000,00, 189 recebidas, 604 consultas DICT (596 ok); receita 586,03 não derivável; leitura do gerador: `transactions` + `dict_lookup_events` + `entities` no mon_core.

**Steps:**
1. Script versionado `scripts/apix_abril/project_restore_to_core.py` (ou .sh+SQL): extrai do restore (tabelas do fact pack: `METRICAS.PAGAMENTO_FINAL`, `PACS008_REGISTRO_ENVIO`, `METRICAS.RECEBIMENTO_FINAL`, `METRICAS.DICT_CONSULTA`, `EXTRATO.EXTRATO_MOVIMENTO_GI`) e INSERE NO MON_CORE LOCAL (nunca HML/PRD): `transactions` type=pix settled (externas) e type=tef outbound (5 internas), `dict_lookup_events` (604 com occurred_at real), entity da Monetarie. Idempotente (delete+insert por marcador `apix_abril_projecao` em metadata).
2. Gerar o XML de abril local: `GenerateReportJob` com reference_date 2026-04-01, deliver=false, overrides do operador (Task A5): disponibilidade do legado 98.45 (fato do arquivo original), receita fonte 1 = 586.03 SE o dono confirmar a origem, senão a receita derivada do restore com a divergência documentada.
3. Batimento: tabela arquivo-legado vs arquivo-correto vs restore, ao centavo, no relatório.
4. Dossiê de retificação: `docs/reports/2026-07-19-apix-abril-numeros-corretos-e-dossie-retificacao.md` (números certos, defeito do legado provado, arquivo corrigido pronto, TipoEnvio S, passos de envio via painel CADOC quando o dono der OK).

### Task C2: AMES-SIMBA validação viva local + correção do desenho

**Fatos:** elo completo (backend `ames_controller.ex:72-76`, UI `AmesView.vue:100-346`, `useAmes.ts:117-119`).

**Steps:** corrigir `docs/plans/2026-07-19-elo-ames-simba-design.md` (drift: nada de endpoint novo; o gap real é validação); conferir cobertura de teste do attach type=simba (`ames_controller_test.exs`), completar se faltar (RED: attach simba adota regulatory_file, response_type simba, 422 legível sem acervo); validação viva local (subir core-api local + admin, exercitar a tela com caso SIMBA; screenshots em docs/reports/screenshots/). Se o ambiente local impedir (dados), registrar a receita e marcar para a janela HML no pacote.

### Task C3: mover `diversos/` para fora do repo

**Steps:** `grep -r "diversos/"` no repo (fora de docs) para provar zero referência; `mv /Users/luizpenha/monetarie/diversos ~/monetarie-diversos-sensivel/`; nota no pacote: chaves ficam tratadas como expostas a tooling local, rotação é decisão do dono.

---

## TRILHA D (fecho): depois de A+B+C

### Task D1: revisão adversarial final + suítes completas
Code review geral das mudanças (spec + qualidade), suítes completas core e cabine (com os gotchas: lsof 15432 antes do core, seccomp p/ TB se integração), vitest admin/banking/merchant, builds.

### Task D2: pacote único de ações PRD/externas para OK do dono
Documento `docs/operator/2026-07-19-pacote-acoes-prd-ok-unico.md` com comando pronto + rollback para cada item:
1. Deploy core-api + pix-api (código novo desta sessão) + banking-ui (delete-key já commitado) + merchant-ui (A7). Migrations ANTES do swap via rpc (listar todas as novas).
2. Flips recomendados: `SPB_AUTO_RETURN_ENABLED=true` (código pronto, paridade legado), `EMAIL_TRANSPORT=ses` + destinatários CCS, `PIX_RETURN_4XX_TERMINAL_ENABLED` (recomendação: ligar depois de 1 semana de observação), `JUDICIAL_TRANSFER_ACCEPT_ENABLED`, `SPI_REMUNERATION_SWEEP_ENABLED` (ligar só depois de validação viva do relatório).
3. G3 do lote PIX (janela HML com rajada, roteiro do runbook F5).
4. Purge DLQ PRD (25 triadas; seq 41/42 nunca redespachar; comando nats-box).
5. Portal: build da imagem limpa + deploy (opção A, executa takedown do /raw/ de brinde).
6. Retificação APIX ao BACEN (dossiê C1).
7. ECR lifecycle policy (JSON conservador: nunca tagueada, untagged > 30 dias) + nota de risco de rollback por digest.
8. Runbook de reconciliação do drift Terraform HML (NUNCA apply; passos de state reconcile por recurso).
9. Rotação das chaves de `diversos/` (agora fora do repo).

### Task D3: atualizar CLAUDE.md (estado canônico), memórias persistentes e Serena; commit final de docs.

---

## Regras de execução (invioláveis)
TDD com RED provado antes do GREEN em toda task de código; revisão de spec + revisão de qualidade por task; commit local por task (mensagens pt-br, sem push); zero deploy; zero terraform; zero mudança em HML/PRD; validação viva local somente; suítes multi-seed onde o padrão do app pedir; nunca LIKE full-scan em banco vivo; docs pt-br sem travessão de IA.
