# Dossie de paridade PROFUNDO — Saldo previsto/confirmado + Reserva + Remuneracao

Auditoria PIX (LegadoPIX crk_spi .NET x cabine PIX Elixir). READ-ONLY, prova arquivo:linha / tabela.coluna.
Data: 2026-07-23. Escopo: SpiSaldo (previsto/confirmado), SpiSaldoCAMT, SpiSaldoSpb, ReqSaldo (aporte/credito/debito),
parametros de reserva, remuneracao. Regra: sem prova, veredito INCONCLUSIVO.

---

## 0. Sumario executivo

O legado modela o saldo como um LEDGER DIARIO DE DUPLA DIMENSAO (previsto vs confirmado) por
(instituicao, data de movimento), mantido por stored procedures no SQL Server, alimentado pelas transicoes
de status das mensagens, com propagacao para frente das confirmacoes; guarda o historico de fotos CAMT
(disponivel/bloqueado) do BACEN; e OWNA no proprio SPI o money-path de aporte/credito/debito da reserva
(LPI0001..LPI0004 = SpiReqSaldo, 4.084 linhas em producao). A remuneracao no legado e apenas uma CONSULTA
(CAMT.060 demonstrativoRemuneracao).

Nossa cabine modela o saldo como UMA POSICAO VIVA por ISPB (available/blocked/projected + um checkpoint
confirmado camt.053 CLBD com trava de monotonicidade), holds em balance_blocks (Debit-Then-Send), snapshot
diario de abertura/fechamento, e ADICIONA um sweep de remuneracao ao Core (novidade sem par no legado). O
money-path de aporte/credito/debito da reserva (ReqSaldo/LPI) esta AUSENTE do backend da cabine PIX: a tela
existe mas esta gated OFF e a rota POST /balance/requests da 404 no spi_service. A reserva bancaria (RB/STR)
vive na cabine SPB e e lida por NATS.

Vereditos-chave: dupla dimensao previsto/confirmado por dia = PARCIAL; ReqSaldo/LPI money-path = AUSENTE na
cabine PIX (relocado para SPB, cobertura plena INCONCLUSIVA no escopo PIX); teto de reserva (MaximoReservaSPI)
e versionamento de parametros = AUSENTE; remuneracao (consulta) = COBERTO; sweep de remuneracao = novidade nossa.

---

## 1. LEGADO — modelo de dados e regras (com prova)

### 1.1 SpiSaldo — ledger diario de dupla dimensao previsto/confirmado

Tabela `crk_spi.dbo.SpiSaldo` (180 linhas vivas). Colunas (tabela.coluna, tipo):
- `IdInstFinanc int`, `DtMovto date` (chave por instituicao-dia)
- `VlrPrevisto numeric(28,2)` — fluxo PREVISTO do dia
- `VlrConfirmado numeric(28,2)` — fluxo CONFIRMADO do dia
- `VlrSaldoAnterior numeric(28,2)` — saldo de abertura (fechamento confirmado do dia anterior)
- `VlrSaldoPrevisto numeric(28,2)` — saldo ACUMULADO previsto
- `VlrSaldoConfirmado numeric(28,2)` — saldo ACUMULADO confirmado

Dominio C#: `SPI.Core.Domain.decompiled.cs:1142` classe `SaldoSPI` com exatamente esses 6 campos
(VlrSaldoAnterior/VlrPrevisto/VlrConfirmado/VlrSaldoPrevisto/VlrSaldoConfirmado).

DTO de atualizacao: `SPI.Core.General.decompiled.cs:11391` `AtualizacaoSaldoDTO { IdInstFinanc, DtMovto,
DtContabil, Vlr, FlDc, FlDcConf }`. `FlDc` (linha 11401) = flag credito(+1)/debito(-1); `FlDcConf` (11403)
= flag de confirmacao (0 previsto, 1 confirmado, -1 rejeitado).

Motor de atualizacao (stored procs, prova por `sys.sql_modules`):
- `SPI_SPUPDSLDSPI(@IdInstFinanc,@DtMovto,@DtContabil,@Vlr,@fldc,@flconf)` — chamada por
  `SPI.Core.Saldo.Infrastructure.decompiled.cs:281`. Regras (definicao viva no banco):
  - `IF @VLR = 0 RETURN` (movimento zero nao mexe no saldo).
  - `@VLR = @VLR * @FLDC` (aplica sinal credito/debito).
  - `@FLCONF = 0` (previsto): soma em VlrPrevisto/VlrSaldoPrevisto.
  - `@FLCONF = 1` (confirmado): soma em VlrConfirmado/VlrSaldoConfirmado E, quando DtContabil = DtMovto,
    SUBTRAI o previsto ja lancado (transicao previsto->confirmado sem dupla contagem).
  - `@FLCONF = -1` (rejeitado): reverte o previsto.
  - Data contabil != data movto (confirmacao em D+n): trata previsto na data do movimento e confirmado
    na data contabil (comentarios da propria proc: "SE A RESPOSTA VEIO COM DATA CONTABIL DIFERENTE...").
  - `MERGE DBO.SPISALDO ... WHEN MATCHED THEN UPDATE ... WHEN NOT MATCHED THEN INSERT` (upsert por inst-dia).
  - `IF @FLCONF = 1 UPDATE SPISALDO ... WHERE DTMOVTO > @DTCONTABIL` — PROPAGA a confirmacao para os
    saldos acumulados de TODOS os dias futuros (VlrSaldoAnterior/Previsto/Confirmado).
- `SPI_SPUPDSLDSPI2(@TAB REGSALDO READONLY)` — versao em lote via TVP `REGSALDO`
  (`SPI.Core.Saldo.Infrastructure.decompiled.cs:311`; layout do TVP em linhas 208-219: IdInstFinanc, DtMovto,
  DtContabil, Vlr, fldc, flconf). Cursor + `BEGIN TRANSACTION` + mesma logica.
- `SPI_SPSELSALDO(@IdInstFinanc,@DtMovto)` — RECONSTRUCAO on-demand do saldo:
  - Base = ultima `SpiSaldoCAMT.VlrSaldoDisponivel` com `DtHrSaldoDisponivel <= fim-do-dia`.
  - `@VlrOper` = soma das operacoes CONFIRMADAS (`SpiStatusOperacao.Resultado = 2`) desde a foto CAMT,
    com sinal `CASE FlDebitoCredito WHEN 1 THEN -1 ELSE 1` e excluindo `FlDebitoCredito = 3` (nao financeiro).
  - `@saldoConfirmado = CAMT_disponivel + @VlrOper`; `@saldoAnterior = saldoConfirmado - vlrConfirmado`;
    `@saldoPrevisto = saldoAnterior + vlrPrevisto` (Resultado IN (0,2), 0=previsto/2=confirmado).
  - Devolve JSON `Parciais` (VlrPrevisto/VlrConfirmado POR CdMsg) + VlrSaldoAnterior + VlrPrevisto +
    VlrConfirmado + VlrSaldoPrevisto + VlrSaldoConfirmado.

Wiring status->saldo: a fila de status (`SPI.Core.Worker.FilaEntradaStatus`) chama
`SPI_SPUPDSTATUSMESSAGE2` -> `SPI_SPUPDSTATUSMESSAGE`, que computa por operacao `@FLDC`, `@FLCONF`,
`@FLATUSLDCONF` (CHAR(1) N/S; "N->S quando confirmado ou rejeitado", def. viva) e devolve as linhas
`RetAltStat` (`...Application.decompiled.cs:262`: FlAtuSldConf, Ehstatusfinal, Fldc, Flconf, DtContabil,
DtMovto, Vlr; coletadas em `...Infrastructure.decompiled.cs:1700-1713`). Essas linhas alimentam a fila de
saldo (`IntegracaoSaldoParaProcessamentoUseCase`, `SPI.Core.Saldo.Infrastructure.decompiled.cs:62-139`,
subject `EntradaFilaSaldo`) -> SPUPDSLDSPI2.

### 1.2 SpiSaldoCAMT — foto de saldo do BACEN (disponivel/bloqueado)

Tabela `crk_spi.dbo.SpiSaldoCAMT` (9.788 linhas — historico de fotos). Colunas: `IdInstFinanc int`,
`DtHrSaldoDisponivel datetime`, `DtHrSaldoBloqueado datetime`, `VlrSaldoDisponivel numeric(28,2)`,
`VlrSaldoBloqueado numeric(28,2)`. Dominio: `SPI.Core.Domain.decompiled.cs:1120` classe `SaldoCAMT`.
E a foto do camt.052/053 (SADP disponivel, SABK bloqueado). Consumida como BASE do SPSELSALDO (secao 1.1).
API: `SaldoCAMTController` (`SPI.Web.Angular.Saldos.Api.decompiled.cs:857`) com find/listDe/listRange por
inst-data (historico consultavel).

### 1.3 SpiSaldoSpb — reserva bancaria (STR) dentro do SPI

Tabela `crk_spi.dbo.SpiSaldoSpb` (1.016 linhas). Colunas: `IdInstFinanc int`, `DtMovto datetime`,
`VlrSaldo numeric(28,2)`, `DtAtualizacao datetime2`. Dominio: `SPI.Core.Domain.decompiled.cs:1132`
classe `SaldoSpb`. API: `SaldoSPBController` (`...Saldos.Api.decompiled.cs:911`) find/refresh
(`Refresh` retorna `SaldoReservaReturnValue`). O legado GUARDA a reserva STR dentro do proprio SPI.

### 1.4 SpiReqSaldo — money-path de aporte/credito/debito da reserva (LPI0001..0004)

Tabela `crk_spi.dbo.SpiReqSaldo` (4.084 linhas em producao). Colunas: `IdRequisicao bigint`,
`IdInstFinanc`, `IdFilialInst`, `Ispb char`, `IspbDestino char`, `DtMovto date`, `DtHrEntrada`,
`IdTipoMsg tinyint`, `IdStatus int`, `IdTipoRequisicao tinyint`, `Vlr decimal(28,2)`, `DtHrEnvio`,
`DtHrRetorno`, `IdUsuario`, `NumCtrlIF varchar`, `FinlddLPI tinyint`, `Protocolo varchar`, `IdOperacao bigint`.
Dominio: `SPI.Core.Domain.decompiled.cs:1082` classe `ReqSaldo`. Historico: `SpiHistReqSaldo`
(IdRequisicao, DtHrHistorico, FlSentido, IdStatus, DadosMsg).

Enums (prova `SPI.Core.General.decompiled.cs:7649-7675`):
- `enumMsgSaldo`: SolicitacaoCredito=1, SolicitacaoDebito=2, Aporte=3, MetaSaldo=4.
- `enumTipoMsgSaldo`: Propria=1, Liquidante=2, SME=3.
- `enumFinalidadeLPI` (`:7786`): MovimentacaoPropria=1, DevolucaoAporte=2.

Money-path (montagem XML, `SPI.Core.SPB.Application.decompiled.cs:44-66` `MontaMsg.ConverteXML`):
- Credito Propria/Liquidante -> **LPI0001** (NumCtrlIF, ISPBIF, ISPBPSPI, VlrLanc, DtMovto).
- Credito SME -> **LPI0002** (NumCtrlIEME, ISPBIEME, VlrLanc, DtMovto).
- Debito Propria/Liquidante -> **LPI0003** (NumCtrlPSPI, ISPBPSPI, ISPBIFCredtd, FinlddLPI, VlrLanc, DtMovto).
- Debito SME -> **LPI0004** (NumCtrlPSPI, ISPBPSPI, VlrLanc, DtMovto).
Interface: `IReqPagtoUseCase` (`SPB.Application.decompiled.cs:36`): EnviaReqSaldo, InsereReqSaldo(ParamReqSaldo),
UpdateReqSaldo. Repo: `ReqPagtoWriteRepository : IReqSaldoWriteRepository` com Sequencial(dtMovto),
AtualizaReqSaldo, FindByNumCtrlIF, ObtemPendentes/ObtemPendentesEnvio (`:525-538`). ParamReqSaldo em `:542`.

Distribuicao viva (prova SQL agregada):
- por IdTipoMsg: SolicitacaoDebito(2)=4075, SolicitacaoCredito(1)=8, Aporte(3)=1.
- por IdStatus: 7(STLD)=3688, 4=297, 10(RTRN)=90, 9(CANC)=2, 17=7.
- por IdTipoRequisicao: Propria(1)=4078, Liquidante(2)=5, SME(3)=1.
Ou seja: o legado usava intensamente LPI0003 (debito = devolucao/varredura do excedente da PI de volta ao STR).

UI: `SPI/angular/src/app/pages/spi/saldos/solicitacao_saldo/incluir_req_saldo/incluir_req_saldo.component.ts`
form com dtMovto (required), cboTipo (required), txtValor (required), cboFinalidade (required).
API: `ReqSaldoController` (`...Saldos.Api.decompiled.cs:752`) add / listReqSaldo / totalPorMsg / listPaginaReqSaldo.

### 1.5 Parametros de reserva e de requisicao

- `SpiCadParamValoresSaldo` (300 linhas): `IdInstFinanc`, `DtInicioVigencia datetime2`, `IdTipoValor int`,
  `Vlr numeric(28,2)`, `IdUsuario`. `enumTipoValor` (`General.decompiled.cs:7669`): MinimoReservaSPI=1,
  MaximoReservaSPI=2 (PISO e TETO da reserva SPI), VERSIONADOS por vigencia. Valor vivo: IdTipoValor=1
  (minimo) = R$ 11.000,00. API `ParamValoresPadraoSaldoSPIController` (`...Saldos.Api.decompiled.cs:643`).
- `SpiCadParamReqSaldo` (299 linhas): valor default da requisicao por (inst, IdTipoMsg), versionado por
  DtInicioVigencia. API `ParamReqSaldoSPIController` (`...Saldos.Api.decompiled.cs:534`).

### 1.6 Remuneracao (somente consulta)

`CAMT060ApiRemuneracaoNaDataDTO` (`General.decompiled.cs:8860`: IdSystem, UniqueId, DtHrOperacao,
IdInstFinanc, IdFilialInst, IspbDebtor, DtInicio). Controller
`SPI.Web.Api.decompiled.cs:513` `[HttpPost("demonstrativoRemuneracao")]` -> monta camt.060 e envia ao BACEN.
Nao ha calculo de remuneracao nem repasse contabil no legado — apenas a CONSULTA do demonstrativo.
`MetaSaldo` (enumMsgSaldo=4) existe como tipo de mensagem de saldo (meta/alvo).

### 1.7 Dashboard/relatorios de saldo

`DashboardController` (`...Saldos.Api.decompiled.cs:396`): montaDashboard, filtroOvernight (evolucao dia-a-dia,
`DataOvernight`), saldoTituloGarantia (`SaldoDTO` com VlrSaldo). `SaldoSPIController` (`:983`) find/listAll/
listDe/listRange devolve `SaldoSPIDTO` (a serie diaria previsto/confirmado).

---

## 2. NOSSO — modelo de dados e regras (com prova)

### 2.1 monetarie_spi.balances — posicao viva unica por ISPB

Schema `SpiService.Balances.Balance` (`apps/spi_service/lib/spi_service/balances/balance.ex:14`):
`ispb, available, blocked, projected, confirmed, confirmed_at, pending_credits, pending_debits, as_of,
source`. Contexto `SpiService.Balances` (`apps/spi_service/lib/spi_service/balances.ex`):
- `get_balance/1` (:41) — posicao corrente (zero se nova).
- `update_balance/2` (:103) — credito/debito atomico (Repo.transaction, FOR UPDATE, grava history + evento).
  Debito checa `insufficient_funds` (:119).
- `get_projected_balance/1` (:551) — `available + pending_credits - pending_debits` (PREVISTO nosso);
  pending vem de `CanonicalTransactions.pending_totals` (monetarie_spi.messages nao liquidadas).
- `update_confirmed_balance/3` (:972) — grava `confirmed`/`confirmed_at` do CLBD camt.053, com trava de
  MONOTONICIDADE por data da posicao (`confirmed_retrograde?`, :1029) e registro em daily_reconciliations
  (`record_position_check`).
- `apply_bacen_position/5` (:885) — aplica SADP/SABK de camt.053/052 em available/blocked RESPEITANDO o
  tempo: foto mais nova sobrescreve; foto VELHA (`stale_position?`) preserva o vivo e vira so confirmado.
- `get_intraday_movements/2` (:689) — via `CanonicalTransactions.intraday_settled_movements`.

Observacao: NAO ha ledger diario de dupla dimensao previsto/confirmado por (ispb, data); ha UMA posicao +
UM checkpoint confirmado. "previsto" = campo `projected` derivado; "confirmado" = campo `confirmed` (CLBD).

Tabela paralela `Shared.Schemas.Spi.Balance` -> `monetarie_spi.balance_cache`
(`apps/shared/lib/shared/schemas/spi/balance.ex:13`: available_amount/blocked_amount/projected_amount/
last_updated) — cache separado. E `Shared.Schemas.Spi.BalanceQuery` -> `monetarie_spi.balance_queries`
(:110: query_type CURRENT/PROJECTED/PREVIOUS_DAY/HISTORY/INTRADAY, balance_type CRE/CSA/REL/TRD/TRT).

### 2.2 monetarie_spi.balance_blocks — holds/reserva (Debit-Then-Send)

Schema `SpiService.Balances.BalanceBlock` (`.../balances/balance_block.ex:16`): ispb, amount, reason,
status (active/released/expired/cancelled/confirmed), reference_id, reference_type, expires_at, released_at,
release_reason. Ciclo em `balances.ex`:
- `create_block/2` (:219) — UNICO ponto de saida de `available` no PIX-OUT: available -X, blocked +X;
  guarda PI reserve minimo (`below_minimum_reserve`, :239, via `SpiValidator.get_pi_reserve_config`).
- `confirm_block/1` (:373) — na liquidacao STLD: blocked -X (debito ja aconteceu no create_block).
- `revert_block/2` (:445) — em rejeicao/timeout/cancelamento: devolve hold ou estorna debito, idempotente,
  FOR UPDATE.

### 2.3 monetarie_spi.balance_history — razao de movimentos

Schema `SpiService.Balances.BalanceHistory`: available_before/after, change_amount, direction (credit/debit),
blocked, reference_type, reference_id, description, recorded_at. Gravado por `record_balance_change/4`
(`balances.ex:803`).

### 2.4 monetarie_spi.daily_balance_snapshots — snapshot EOD por (ispb, data)

Schema `SpiService.DailyReconciliation.BalanceSnapshot` (`.../daily_reconciliation/balance_snapshot.ex:25`):
`ispb, snapshot_date, opening_balance, closing_balance, opening_source (previous_close/none),
closing_source (camt.053_clbd/aggregate)`. Abertura D = fechamento D-1; fechamento do CLBD do BACEN com
fallback ao agregado. UM saldo por dia (nao dupla dimensao previsto/confirmado nem parciais por CdMsg).

### 2.5 CAMT.060 — orquestracao de consulta (Conta PI)

`SpiService.Camt060` (`apps/spi_service/lib/spi_service/camt060.ex`): 7 acoes (`@actions`, :22) =
saldo-atual, saldo-na-data, lista-lanctos, detalha-lancto, demonstrativo-tir, total-tir,
demonstrativo-remuneracao. Mapa `@camt060_spec` (:41) por acao -> ReqdMsgNmId + Prtry {CSA,REL,CRE,TRD,TRT}
+ estrategia de data. Envio assincrono (ACK; relatorio camt.052/053 chega pelo stream e materializa
`monetarie_spi.balances`). Tracking em `monetarie_spi.camt060_requests` (record_sent/mark_send_failed).

### 2.6 Remuneracao — credito do BACEN + relatorio + SWEEP ao Core

- Credito: `InboundProcessor.maybe_credit_remuneration/2`
  (`apps/spi_service/lib/spi_service/workers/inbound_processor.ex:2692`) — quando a camt.053 NAO solicitada
  traz `Bal[REMN] > 0`, credita via `Balances.update_balance` com reference_type "spi_remuneration",
  reference_id "REMN-<message_id>" (idempotente) e correlaciona a CRE pendente (correlate_remuneration_response).
- Relatorio + sweep: `SpiService.Remuneration` (`apps/spi_service/lib/spi_service/remuneration.ex`):
  `monthly_report/1` (agrega movimentos spi_remuneration por dia, correlacao CRE), `report_csv/1`,
  `sweep_closed_days/1` (:155) grava `spi_remuneration_sweeps` (migration 20260719140000, UNIQUE por
  sweep_date) e publica `monetarie.pix.remuneration.sweep` NA MESMA transacao (notifica o Core para creditar
  a conta institucional), `reconcile/1` sonda. Worker `RemunerationSweepWorker`
  (`.../workers/remuneration_sweep_worker.ex`) cron 21:30 UTC atras da flag `SPI_REMUNERATION_SWEEP_ENABLED`
  (default OFF). O sweep NAO debita o espelho local da PI (decisao de honestidade, moduledoc).

### 2.7 Parametros de reserva

`SettlementServiceWeb.Gateway.BalanceParametersController`
(`apps/settlement_service/.../gateway/balance_parameters_controller.ex`): chaves em
`monetarie_settlement.system_configs` categoria "limits": `min_balance_rb`, `min_balance_pi`,
`critical_balance_rb`, `critical_balance_pi`, `auto_request_enabled/threshold/amount/target_account`,
`require_dual_approval`, `critical_amount_threshold`, `executive_approval_amount`. Defaults em centavos
(`@default_parameters`, :46; minBalanceRB 1.000.000,00). NAO versionado por vigencia; sem conceito de TETO
de reserva (usa "critical" em vez de MAX). Piso da PI aplicado de fato no `create_block` via
`SpiValidator.get_pi_reserve_config` (le monetarie_spi.system_configs; min_default 0).

### 2.8 Reserva bancaria (RB/STR) — lida da cabine SPB por NATS

`SettlementServiceWeb.Gateway.SpbBalanceController` (`.../gateway/spb_balance_controller.ex`):
GET /api/v1/balances/spb-reserve faz request/reply NATS `spb.balance.request` respondido pela cabine SPB
(ReserveSnapshot). Simetrico: `SpiService.Nats.BalanceResponder` (`.../nats/balance_responder.ex`) responde
`spi.balance.request` com a Conta PI. A reserva STR NAO e persistida na cabine PIX (vive no SPB).

### 2.9 Balance-request flow (credito/debito/aporte) — GATED OFF, sem backend

- Frontend: `pix/frontend/admin/src/views/balance/{CreditRequestView,DebitRequestView,LiquidityInjectionView,
  BalanceRequestsListView,BalanceRequestDetailView,BalanceParametersView,BalanceDashboardView}.vue` +
  `composables/useBalanceRequestFlow.ts` + `stores/balance.ts` + `services/balance.ts`.
- `useBalanceRequestFlow.ts:6-13`: "The backend endpoint (POST /api/v1/balance/requests) is not provisioned
  in every environment, so submitting can 404 ... gate is opt-in via env VITE_BALANCE_REQUEST_FLOW_ENABLED"
  (DEFAULT OFF).
- Gateway: `SpiProxyController.create_balance_request` (`.../gateway/spi_proxy_controller.ex:502`) faz
  proxy POST -> spi_service `/api/v1/balance/requests`. Mas o router do spi_service
  (`apps/spi_service/lib/spi_service_web/router.ex:100-127`) NAO tem POST /balance/requests (so
  GET /balance/requests/pending, :111) -> a submissao da 404. `list_balance_requests` (:456) tambem so le
  os pending blocks.
- Balance-operations gateway: `BalanceOperationController` (`.../balance_operation_controller.ex`):
  create_block, create_debit e create_injection sao AJUSTES ADMIN internos (proxy p/ /admin/balance/:ispb/
  adjust|inject), NAO mensagens LPI ao BACEN. list/show de debits/injections retornam not_implemented (:173).

---

## 3. GAPS (legado x nosso)

Ver objeto estruturado. Resumo:

- g1 Ledger diario dupla dimensao previsto/confirmado: PARCIAL (temos projected+confirmed+snapshot diario,
  nao a serie previsto/confirmado por dia com propagacao nem parciais por CdMsg).
- g2 ReqSaldo/LPI0001-0004 (aporte/credito/debito da reserva): AUSENTE na cabine PIX (tela gated, rota 404;
  relocado ao SPB — cobertura plena INCONCLUSIVA no escopo PIX). RISCO ALTO.
- g3 Historico de status da requisicao (SpiHistReqSaldo): AUSENTE (decorre de g2).
- g4 Teto de reserva (MaximoReservaSPI) e versionamento por vigencia dos parametros: AUSENTE/DIVERGENCIA
  (temos min + "critical" nao versionados).
- g5 Valores default de requisicao por (inst, tipoMsg) versionados (SpiCadParamReqSaldo): AUSENTE
  (so auto_request_amount unico, no fluxo gated).
- g6 MetaSaldo (saldo alvo): PARCIAL (auto_request_threshold/amount em config, sem worker executor).
- g7 SaldoSpb persistido no SPI: DIVERGENCIA arquitetural (lemos do SPB por NATS, nao persistimos).
- g8 SpiSaldoCAMT como SERIE historica de fotos: PARCIAL (guardamos posicao viva + confirmado + snapshot,
  nao a serie completa de fotos camt).
- g9 Reconstrucao SPSELSALDO com parciais por CdMsg (previsto/confirmado por tipo de mensagem): PARCIAL.
- g10 saldoTituloGarantia (saldo de titulos/garantia): AUSENTE.
- coberto: holds/reserva (balance_blocks) COBERTO (mais rico); CAMT.060 7 acoes COBERTO;
  consulta de remuneracao (demonstrativo-remuneracao/CRE) COBERTO; confirmado CLBD com monotonicidade
  COBERTO; sweep de remuneracao ao Core = ENHANCEMENT nosso sem par no legado.
