# Trilha 06: TigerBeetle e tb-gateway Go, todas as otimizacoes de eficiencia do TB (AVIV vs Monetarie)

Data: 2026-07-09. Trilha READ-ONLY do mandato de mapeamento exaustivo AVIV/coreproviders vs cabine Monetarie.
Fontes: `/Users/luizpenha/coreproviders` (branch aviv-hml) e `/Users/luizpenha/monetarie`. Nenhuma chamada AWS foi feita; toda afirmacao vem de arquivo:linha ou e marcada como afirmacao de documento (doc) ou NAO VERIFICADO.

Convencao de rotulo usada abaixo:
- [codigo] = o codigo faz X (arquivo:linha lido nesta trilha).
- [doc] = um documento interno do repo afirma X (pode refletir estado de runtime que nao da para provar sem AWS).
- [NAO VERIFICADO] = nao encontrei prova em codigo nem doc.

---

## 1. Sumario executivo

A AVIV atacou o TigerBeetle como um problema de CLIENTE, nao de servidor: o cluster TB deles esta ocioso (CPU 1-2%) e o gargalo provado e a sessao unica 1-request-in-flight do driver NIF tigerbeetlex somado ao teto HARD de 64 sessoes (`clients_max=64`) do TB (`docs/plans/2026-07-07-tb-gateway-grpc-design.md` secao 1; `docs/audits/2026-07-07-tb-capacidade-pixin-pixout-analise.md:22,224`). A resposta deles veio em camadas: (1) retry idempotente de leitura + circuit breakers lock-free; (2) split de sessao leitura pesada vs money path (`:tb_bulk`); (3) coalescer manual de depositos PIX-IN (chains linked concorrentes fundidas num unico `create_transfers`, p99 do TB caiu de 1561ms para 219ms em prod, [doc]); (4) self-heal de sessao pos-eviccao no driver (ClientOwner, PR #18); e (5) o `tb-gateway`, um servico gRPC em Go com o client oficial do TB, que desacopla o numero de sessoes TB do numero de nos backend e entrega o batching NATIVO do client oficial. A bancada de 4 gates provou: hop gRPC de software e gratis (delta p50 +0,31ms), sob rajada o gateway corta a cauda pela raiz (p99 862ms para 246ms, zero requests acima de 600ms), e a escrita via gateway e segura no dinheiro (atomicidade de chain, zero duplicata, resubmit byte-identico converge). A Fase 1 (leitura) esta no ar nos 4 ambientes deles, incluindo Aviv PRD [doc].

A Monetarie hoje esta aproximadamente onde a AVIV estava antes de 03/07: caminho vivo de credito PIX-in cria UM transfer sincrono por evento via `Wallet.deposit` (sem batch, sem coalescer), pool de conexoes NIF pequeno, sem telemetry por operacao TB, sem self-heal de eviccao no vendored, e com um defeito da mesma classe que a AVIV documentou como LAUDO-TIGERBEETLE-2026-05-19: erro transiente de infra do TB achatado em `:account_not_found`. A Monetarie ja portou BalanceCheckpoint, caches e PromEx (04/07) e ja tem um `TbFirst.Deposit` (batch linked COSIF) e um `BatchAccumulator` (30k+ TPS por desenho) escritos, mas o primeiro esta atras da flag PROIBIDA `TWO_PHASE_PIX_IN` e o segundo e codigo morto (nao supervisionado, sem callers). O tb-gateway da AVIV e portavel quase inteiro: o proto espelha o TB 0.17.3 puro, sem nada especifico de AVIV.

---

## 2. Como a AVIV faz (fluxo e otimizacoes, com evidencia)

### 2.1 Driver e pool

- Driver: `tigerbeetlex` vendored (fork FluxiqBR), path dep [codigo: `coreproviders/backend/mix.exs:55-60`]. O vendored INCLUI `client_owner.ex` (self-heal de sessao, PR #18): apos eviccao o tb_client se dealoca e todo submit falha `:client_closed` para sempre; o ClientOwner publica o client atual em `:persistent_term` com geracao e recria exatamente 1 vez por morte, com cooldown de 1s [codigo: `coreproviders/backend/vendor/tigerbeetlex/lib/tigerbeetlex/client_owner.ex:1-36`].
- Pool round-robin lock-free com `:atomics` em `:persistent_term` [codigo: `coreproviders/backend/lib/fluxiq/infra/tigerbeetle.ex:15-16,46-79`]. `TB_POOL_SIZE` default 1 [codigo: `coreproviders/backend/config/runtime.exs:381`]. O default 1 e INTENCIONAL: a doc do TB manda escalar com batching, nao com mais clientes; pool=6 estourou o `clients_max=64` no deploy (overlap dobra as sessoes) e causou o incidente de eviccao de 2026-07-07; teto seguro empirico: `2 x (pool+1) x 6 nos < 64`, logo pool <= 4 [doc: `docs/audits/2026-07-07-tb-capacidade-pixin-pixout-analise.md:216-238`]. Em Aviv PRD rodou `TB_POOL=3` + coalescer a partir de 04/07 [doc: `docs/audits/2026-07-03-aviv-prd-pixin-tb-transient-gateway-timeout.md` secao 7].
- Timeout por chamada: `@tb_timeout 3_000` ms via `CallOptions`; comentado que timeout NAO cancela a request no TB (sem abort), por isso idempotencia por id no call site [codigo: `tigerbeetle.ex:18-24`].

### 2.2 Split de sessao: leitura pesada vs money path (`:tb_bulk`)

- Leituras analiticas pesadas (bulk `lookup_accounts` ate 8000 ids, history/balance scans, sondas de reconciliacao) roteiam para um client dedicado `:tb_bulk`, para nao fazer head-of-line blocking nas ESCRITAS do money path no client primario `:tb`. TB e linearizavel entre clients, entao leitura no `:tb_bulk` observa escrita no `:tb` [codigo: `tigerbeetle.ex:81-104,344-349,896-901,986-991`; child spec sob a mesma flag em `application.ex:540-557`]. Flag `TB_BULK_READ_ENABLED` default true [codigo: `runtime.exs:391`].
- Pacing das leituras bulk: lookups de milhares de IDs fatiados em chunks de 500 (`TB_BULK_LOOKUP_CHUNK`) com sleep de 100ms entre chunks (`TB_BULK_LOOKUP_SLEEP_MS`), porque um request gigante ocupa a pipeline VSR do servidor e atrasa os batches de escrita atras dele (picos de cauda 1-2,6s correlacionados ao OrphanRecon) [codigo: `tigerbeetle.ex:767-804`; `runtime.exs:393-402`]. O TbStuckPendingMonitor tem pacing proprio (lookback 72h, paginas 1000, sleep 200ms) [codigo: `runtime.exs:404-418`].

### 2.3 Retry idempotente de leitura + circuit breakers

- `lookup_account` re-tenta SO erro transiente de infra (gateway_timeout/service_unavailable), ate 3 tentativas com backoff exponencial 50ms..1s + jitter; resposta POSITIVA (conta achada OU results vazio) nunca re-tenta; NUNCA aplicado a create (nao idempotente no mesmo sentido) [codigo: `tigerbeetle.ex:26-39,371-424`].
- Regra de ouro (LAUDO-TIGERBEETLE-2026-05-19): o UNICO `:not_found` legitimo e o TB responder positivamente com results vazio; qualquer erro de transporte vira `{:gateway_timeout,_}` ou `{:service_unavailable,_}` DISTINTOS, nunca not_found (o bug original fazia burst de timeout virar `account_not_found` para contas validas de PIX-OUT) [codigo: `tigerbeetle.ex:440-457`].
- Circuit breaker lock-free (`:atomics` em `:persistent_term`), abre apos 5 falhas transientes consecutivas, cooldown 5s, half-open por tempo; `open?/0` e leitura lock-free no hot path. Sao DOIS breakers independentes: primario (money path `:tb`) e bulk (`:tb_bulk`), para lentidao de scan de 8000 ids nao abrir o breaker que bloqueia o lookup pequeno do money path [codigo: `coreproviders/backend/lib/fluxiq/infra/tigerbeetle/circuit_breaker.ex:1-56,124-128`].

### 2.4 DepositCoalescer (batching manual do PIX-IN)

- Motivacao medida: sob rajada de ACCCs, ~40 depositos concorrentes enfileiravam atras da sessao unica do client TB (1 request in-flight por sessao VSR), formando comboios de 0,8-3,5s; os `gateway_timeout` de 3s eram a cauda desses comboios [codigo: comentario `deposit_coalescer.ex:13-16`; medicao em `docs/audits/2026-07-03-aviv-prd-pixin-tb-transient-gateway-timeout.md` secao 6.3].
- Mecanica: GenServer acumula chains linked independentes (ultima transfer com linked=false) numa janela de 5ms (`TB_COALESCE_WINDOW_MS`) ate teto de 2000 transfers (`TB_COALESCE_MAX_TRANSFERS`, bem abaixo do limite ~8190 do TB); flush roda em processo separado (batches pipelineiam, o GenServer nunca bloqueia em TB); resultados voltam 1:1 posicionais e cada caller recebe exatamente a fatia da sua chain, com o MESMO contrato do caminho direto; mismatch de contagem falha todos os callers explicitamente (retry idempotente cobre) [codigo: `deposit_coalescer.ex:1-181`].
- Entrada: `Tigerbeetle.create_transfers_for_deposit/1` roteia pro coalescer quando `TB_DEPOSIT_COALESCE_ENABLED` (default false em codigo) e o processo esta vivo [codigo: `tigerbeetle.ex:600-618`; `runtime.exs:420-435`]. Em Aviv PRD foi ligado em 04/07 com TB_POOL=3: tb p99 1561ms para 219ms; validacao HML: 60 chains viraram 1 request com batch_size=180 [doc: audit 2026-07-03 secao 7].
- Resultado por evento e denso e `:exists`/`:linked_event_failed` propagam para o ErrorClassifier detectar replay idempotente ("exists + linked_event_failed = continue") [codigo: `tigerbeetle.ex:659-667`; `deposit_coalescer.ex:160-171`].

### 2.5 Chains linked, two-phase pending/post/void e codigos de transfer

- PIX-IN e uma chain LINKED de 3-4 transfers diretos com IDs DETERMINISTICOS (BatchChain root + legs; replay NATS produz os mesmos IDs, TB devolve `:exists`, no-op): T1 moeda eletronica -> SPI (lastro primeiro, senao `:exceeds_credits`), T2 SPI -> transit, T3 transit -> wallet, T4 opcional wallet -> fee (clamped), mais legs de fee split e espelho Caixa, tudo `mark_linked` [codigo: `coreproviders/backend/lib/fluxiq/use_cases/pix/tb_first/deposit.ex:1-136`].
- PIX-OUT/TED/TEF sao TWO-PHASE: `build_pending` reserva com `flags.pending: true` (cliente -> transit + cliente -> fee), `build_post` confirma com `post_pending_transfer` + `amount_max()` e adiciona as pernas diretas transit -> SPI -> reserva, `build_void` cancela com `void_pending_transfer`; tudo linked (all-or-nothing) [codigo: `coreproviders/backend/lib/fluxiq/use_cases/payments/pending_transfers.ex:32-221`]. `void_with_retry` tem guard contra void pos-liquidacao BACEN (incidente de R$105k, 2026-04-20): se o BACEN ja liquidou, RECUSA o void [codigo: `pending_transfers.ex:223-270`].
- Catalogo de codigos: `Fluxiq.Util.Codes.TransferCode` com structs gerados em compile time, `sharp_code` unico por perna (PIX-IN 1001/1018/1016, fee 5050; PIX-OUT 1002/1019/1017, fee 5051; MED 1022-1032; splits 5060-5065; TED 2001+; catalogo 1001..90007), com checagem de unicidade em compile time [codigo: `coreproviders/backend/lib/fluxiq/util/codes/transfer_code.ex:123-499`].
- Codigo 9116 (compensacao): a regra deles e NUNCA resetar o TB em nenhum ambiente; equalizacao so via transfers compensatorios code 9116 [doc: `coreproviders/docs/2026-05-24-codex-comprehensive-system-audit.md:397`]. Transacoes sinteticas reconstituidas via 9116 sao pintadas `metadata.kind=system_reconstitution` e excluidas das views operacionais [codigo: `coreproviders/backend/lib/fluxiq/use_cases/admin/dashboard/queries.ex:42-51`]. O replay TB<-PG usa conta sink `99999116` para ajustes [codigo: `coreproviders/backend/lib/mix/tasks/fluxiq.tb.replay_from_pg.ex:17`]. A prova G-write da Fase 2 usa transfer code 9116 de 1 unidade [doc: `docs/plans/2026-07-08-tb-gateway-fase2-rollout-runbook.md` secao 3].

### 2.6 BalanceGuard: saldo seguro = min(TB, PG)

- Razao de existir: creditos fantasma (depositos sem confirmacao BACEN) inflaram o TB em R$2,1M e um bot drenou R$538k explorando isso; o TB sozinho nao e confiavel como verdade de saldo disponivel [codigo: `coreproviders/backend/lib/fluxiq/use_cases/payments/pix_out/balance_guard.ex:6-24`].
- `safe_balance = min(tb_available, pg_net_available)` onde tb_available = credits_posted - debits_posted - debits_pending (menos obrigacao MED nao fundeada) e pg_net vem das rows settled canonicas de `transactions` + `outbound_requests` in-flight; divergencia e logada e emitida em telemetry; saldo negativo bloqueia PIX-OUT (corrompido) exceto quando explicado por hold MED [codigo: `balance_guard.ex:46-197`].
- `pg_net_available` roteia para `BalanceCheckpoint` (checkpoint por hora + delta <= 1h, partition-pruned, bit-identico ao full scan) quando `BALANCE_CHECKPOINT_ENABLED` [codigo: `balance_guard.ex:325-350`]. Cache de saldo APENAS para display, nunca no verify (Safety #7) [codigo: `balance_guard.ex:212-241`].

### 2.7 Infra do TB na AVIV

- Cluster TB: 3 replicas `m6g.xlarge` rodando o container oficial `ghcr.io/tigerbeetle/tigerbeetle:0.17.3`, enderecos fixos `192.168.{130,134,138}.10:3001` [doc: `docs/plans/2026-07-07-tb-gateway-grpc-design.md` secoes 1 e 3.4]. As replicas sao geridas como unit files (systemd) em EC2, inspecionadas/corrigidas via SSM (ex.: remocao do `--development` das 3 replicas da MK PRD com restart rolante) [doc: `docs/audits/2026-07-08-handoff-tb-gateway-fase1.md` secoes 1 e "Estado final"]. Metricas de infra dos nos TB vem de `AWS/EC2` [doc: audit 2026-07-07:351]. A formulacao exata "service ECS a 0" citada no mandato NAO foi encontrada em codigo nem doc [NAO VERIFICADO]; o que os docs mostram e TB fora do ECS de aplicacao, em EC2 dedicada com systemd.
- Servidor atestado saudavel sob o volume deles: CPU avg ~1% max <13%, EBS write latency 1,7-1,9ms constante, IOPS a 2-4% do provisionado; a latencia de cauda NAO e servidor nem storage, e fila client-side [doc: audit 2026-07-03 secao 6.2-6.3].

### 2.8 Subcentavo

- 1 unidade interna = R$ 0,0001 (scale 100 sobre centavos; 1 BRL = 10.000 unidades). Todas as colunas de DB em base units; conversao SO nas bordas (OnZ em BRL) [codigo: `coreproviders/backend/lib/fluxiq/util/money_unit.ex:1-59,88`]. O plano antigo de milesimos (x1000) [doc: `docs/plans/2026-03-27-tb-milesimos-migration.md`] NAO e o vivo: o vivo e x100.

---

## 3. tb-gateway Go, o mapa completo

### 3.1 Por que existe

Decisao registrada no design [doc: `coreproviders/docs/plans/2026-07-07-tb-gateway-grpc-design.md` secao 1]:
- `clients_max=64` e teto HARD compilado na imagem oficial; escalar backend multiplica sessoes NIF e estoura o teto (incidente de eviccao 2026-07-07).
- O NIF e 1-request-in-flight por conexao e o coalescer manual quase nao dispara em regime (batch ~1 a ~5 ACCC/s por no).
- A doc oficial do TB manda: menos clientes, requests maiores; o client oficial (Go) faz batching automatico de submissoes concorrentes.
- Solucao: servico gRPC central em Go com UM client TB oficial compartilhado por instancia (2-3 instancias ECS = 2-3 sessoes TB no total, independente do numero de nos backend). Stateless. Migracao incremental por flag, leitura primeiro, NIF vivo como fallback.

### 3.2 Arquitetura de diretorios

- `cmd/tb-gateway/main.go`: boot, env (`TB_ADDRESSES`, `TB_CLUSTER_ID`, `GRPC_ADDR` :50051, `METRICS_ADDR` :9464, `TB_GATEWAY_MAX_INFLIGHT` 256, `WRITE_DEADLINE_MS` 10000), smoke lookup no boot (falhou = boot falha), health gRPC padrao, shutdown gracioso (drena e fecha o client), keepalive EnforcementPolicy MinTime 10s (sem isso o grpc-go derruba o canal do grpc-elixir com GOAWAY ENHANCE_YOUR_CALM a cada ~1min) [codigo: `tb-gateway/cmd/tb-gateway/main.go:70-185`].
- `cmd/tb-bench/main.go`: gerador de carga Go (A/B NIF vs go-direct vs go-grpc, ids deterministicos por run-id).
- `internal/ledger/shared_client.go`: `SharedClient`, client TB unico + geracao atras de RWMutex, espelho Go do ClientOwner do PR #18. `ReportDead(gen)` recria SOMENTE se gen == atual (1 recriacao por morte), cooldown 1s anti-storm, factory falhou mantem morto e re-tenta no proximo report; `IsClientDead` reconhece `ErrClientEvicted/Closed/ReleaseTooLow/High` (client evictado NUNCA se recupera sozinho, design upstream) [codigo: `shared_client.go:36-172`].
- `internal/ledger/write.go`: o coracao da seguranca de escrita. Retry bounded IDEMPOTENTE: reenvia SEMPRE o MESMO batch (mesmos ids, mesma ordem); `created` e `exists` significam ambos "esta no ledger"; ctx expirado = `OutcomeUnknown` em TODOS os itens (nunca sucesso nem falha limpa; reconcilia fora). Classificacao POR CHAIN do resultado denso do 0.17.3: tudo created = Created; >=1 exists e resto em {exists, linked_event_failed} = chain JA APLICADA (Exists, code 46, o padrao do ErrorClassifier); qualquer outro codigo = Failed com o primeiro codigo real; anomalias (created+exists na mesma chain) logadas, nunca mascaradas [codigo: `write.go:29-270`].
- `internal/server/server.go`: handlers gRPC. Backpressure por semaforo (cap = max inflight, default 256): sem slot livre devolve `RESOURCE_EXHAUSTED` imediato (o analogo controlado e observavel do comboio de hoje); leitura falha apos retry = `UNAVAILABLE`; escrita NUNCA vira erro gRPC por desfecho de item (o desfecho, incluindo UNKNOWN, viaja posicional em `TransferResult`). Resposta de lookup e 1:1 POSICIONAL com o request (conta ausente vira placeholder `found=false` com id ecoado) [codigo: `server.go:1-225`].
- `internal/server/codec.go` + `metrics.go`: validacao de request (u128 = 16 bytes little-endian; rejeita flags two-phase no v0) e decorator `InstrumentedTB` (retries, batch estimate soh na escrita com sucesso) [codigo: `server/metrics.go:1-25`].
- `internal/metrics/`: instrumentos Prometheus: `tbgw_rpc_duration_ms` (por RPC), `tbgw_tb_roundtrip_ms` (por op, retry incluso), `tbgw_queue_wait_ms`, `tbgw_batch_size_estimate`, `tbgw_client_recreations_total`, `tbgw_retries_total`, `tbgw_unknown_total`, `tbgw_inflight`. Buckets de latencia com bordas explicitas em 600 e 3000 ms (as bandas de retransmissao do vsr.Client) [codigo: `metrics/metrics.go:13-105`]. `BatchEstimator`: conclusoes de chamadas TB a < 200us uma da outra quase certamente vieram da mesma reply de fio; a soma dos itens do grupo estima o batch nativo (o contador exato exigiria patch no client Zig) [codigo: `metrics/batch_estimator.go:1-82`].
- `proto/tbgateway/v1/tbgateway.proto` + `gen/` (buf: `buf.yaml`, `buf.gen.yaml`): superficie v0 minima, `LookupAccounts` e `CreateTransfers`. `Uint128` = 16 bytes little-endian nativos do TB. `Account` espelho COMPLETO do tb.Account (4 saldos u128 + user_data + timestamp). `Transfer` SEM pending_id/timeout/timestamp (two-phase fora do v0). `TransferResult` denso posicional com `STATUS_CREATED/EXISTS/FAILED/UNKNOWN_OUTCOME` + `tb_result_code` cru [codigo: `tbgateway.proto:1-110`].
- `internal/bench/` + `bench/`: harness de bancada (loadgen, classify, ids deterministicos, resubmit, audit do ledger, report JSON canonico), docker-compose com toxiproxy, scripts de matriz de falha (blackhole, +200ms, reset TCP, view-change, cpu hog), resultados em `bench/results/`.
- `Dockerfile` e `bin/tb-gateway`: build do binario unico.

### 3.3 Lado Elixir do gateway

- `Fluxiq.Infra.TbGateway` (cliente gRPC): Fase 1 leitura atras de `TB_GATEWAY_LOOKUP_ENABLED`, Fase 2 escrita atras de `TB_GATEWAY_WRITE_ENABLED` (ambas default OFF em codigo; com flags OFF o modulo e dormente, nenhum canal gRPC sobe) [codigo: `coreproviders/backend/lib/fluxiq/infra/tb_gateway.ex:1-56`; `runtime.exs:437-484`; supervision gated em `application.ex:602-612`].
- Leitura: mesmo shape do NIF (`%LookupAccountsResultBatch{}`); guard de contrato posicional (contagem diferente do pedido = erro de contrato, nunca `results: []`, para jamais fabricar not_found); deadline apertado 1500ms porque em erro do gateway o roteamento ainda paga o NIF por cima (custo aditivo, pior caso ~4,5s por tentativa) [codigo: `tb_gateway.ex:107-144`; `tigerbeetle.ex:466-506`]. Fallback pro NIF em QUALQUER erro de transporte, contado em telemetry `[:fluxiq,:tb,:gateway,:fallback]` com razao de baixa cardinalidade [codigo: `tigerbeetle.ex:482-514`].
- Escrita: elegibilidade espelha o codec do servidor (sem pending/post/void/imported, pending_id/timeout/timestamp zerados; PIX-OUT pending chains e rebuild ficam no NIF) [codigo: `tb_gateway.ex:162-185`]. Contrato de falha: `{:not_sent,_}` (canal inexistente/encode falhou, provadamente nao saiu do processo) e a UNICA classe com fallback NIF; QUALQUER erro pos-envio vira `{:error,:timeout}` transiente (sem fallback na mesma chamada; a retry machinery re-submete byte-identico e a idempotencia por id converge, Gate 4); `UNKNOWN_OUTCOME` degrada a chamada inteira para timeout ("incerto, reconciliar") [codigo: `tb_gateway.ex:146-302`; `tigerbeetle.ex:685-734`].
- `Fluxiq.Infra.TbGateway.Channel`: dono do canal gRPC persistente. Checkout NAO-BLOQUEANTE lock-free via `:persistent_term` (gateway caido = lookup cai no NIF instantaneo, sem esperar handshake); connect em background com owner de conexao monitorado (a conexao do grpc-elixir morre com o processo que conectou, provado em HML); DEBOUNCE de reconnect (max 1 drop de canal por 10s) contra o churn observado em Aviv PRD (71 connect-failures/h no pico); sem `GRPC.Stub.disconnect` (bug do grpc-elixir 0.11.5 que crasheia) [codigo: `coreproviders/backend/lib/fluxiq/infra/tb_gateway/channel.ex:1-219`; `runtime.exs:457-468`].
- Quem chama de verdade: o roteamento vive DENTRO de `Fluxiq.Infra.Tigerbeetle` (`lookup_accounts_source/1` para leitura, `create_transfers_transport/2` para escrita), entao TODOS os callers de `lookup_account`/`create_transfers` passam pelo gateway quando a flag liga, sem mudanca nos call sites [codigo: `tigerbeetle.ex:482-506,701-740`]. NAO e experimento: a Fase 1 esta deployada e ligada nos 4 ambientes (Aviv PRD `tb-gateway:1` 2/2 + backend `:208` com flag lookup ON, 7.351+ lookups reais na 1a hora, tb_transient=0, 503=0) [doc: `docs/audits/2026-07-08-handoff-tb-gateway-fase1.md` secao 1]. A Fase 2 (escrita) esta implementada e o gateway ja serve `CreateTransfers`; a flag de escrita e dormente por default e o flip em PRD exigia ok final do dono [doc: `docs/plans/2026-07-08-tb-gateway-fase2-rollout-runbook.md` secoes 1-2]; estado atual do flip [NAO VERIFICADO].

### 3.4 Resultados de bench (bancada local, numeros RELATIVOS, 30 ops/s salvo indicacao)

Gate 1, matriz de stall NIF vs go-direct vs go-grpc [doc: `tb-gateway/bench/results/gate1-stall.md`]:
- Baseline sem falha: NIF p99 122ms (unico driver com requests >600ms no caminho limpo); go-direct 40ms; go-grpc 56ms.
- Blackhole (f1): os TRES colapsam para p99 1,9-2,6s. Conclusao central: o stall de rede e do core VSR do TB, NAO do driver; o gateway nao elimina, mas amansa o tail extremo (over3000 = 0 vs 23 do NIF e 32 do go-direct).
- Reset TCP (f3): NIF foi o unico a escalar para hang de 10s com 377 timeouts duros; caminhos Go capam ~650ms.
- Starvation de CPU (f5): NIF degrada (p99 657ms, 271 reqs >600ms); go-grpc fica liso (p99 106ms, zero >600ms). Ressalva de mecanismo registrada (hog no BEAM vs hog no host).
- View-change (f4, cluster 3 replicas): nao-evento nos dois caminhos Go; go-grpc p99 44ms, zero >600ms.
- Gate 1b: eviccao REAL de sessao (flood de 70 sessoes) com self-heal provado (recriacao gen 2, sem zumbi).

Gate 2, custo do hop gRPC [doc: `gate2-hop.md`]: mediana das reps delta p50 +0,306ms e delta p99 -1,223ms. O hop de software e essencialmente gratis. O hop de rede in-VPC ficou para a fase HML.

Gate 3, batching real [doc: `gate3-batching.md`]:
- Regime estavel: batch ~1 (esperado, sem contencao nao ha o que fundir).
- Rajada 100 requests em 100ms: fusao clara (direct mean 8,25; estimador do gateway mean 46,8) e o resultado que importa para a meta de latencia: p99 do request individual cai de 862ms (direct, 99 reqs >600ms) para 246ms (gateway, ZERO reqs >600ms); paga p50 um pouco maior (30,5 vs 19,2ms) e corta a cauda pela raiz.
- Sob stall F1 com um unico gerador o gateway NAO resgata o request individual (leitura honesta registrada: o ganho arquitetural e consolidar N sessoes em 1, nao salvar o request preso).

Gate 4, semantica de escrita sob morte do TB [doc: `gate4-write-semantics.md`]:
- 20 mortes do TB durante 10min de escrita: 17.908 chains, PARTIAL=0 (atomicidade), sum_ok=true (zero escrita dupla), 983 ausentes = exatamente as chamadas com erro de transporte (falha LIMPA, nada aplicado).
- Resubmit byte-identico da faixa inteira: created=983 (so o que faltava), exists=16.925 (nada reaplicado), failed=0. Convergencia idempotente provada ponta a ponta.
- View-change durante escrita: errors={}, ledger integro sem reenvio. Este gate e o que autorizou a Fase 2.

Checagem de CPU em PRD [doc: `prd-cpu-check.md`]: nas janelas de rajada de `:tb_transient`, CPU max de qualquer instancia backend nunca passou de 16,8%; janela de controle com MAIS volume teve CPU igual/maior e ZERO timeouts. Starvation de host descartada como causa; reforca a tese de fila client-side.

Harness reutilizavel: `tb-gateway/bench/` (compose com toxiproxy, scripts de matriz e kill-cycle, auditoria de ledger) + espelho Elixir `coreproviders/backend/bench/tb_nif_bench.exs` (mesmo contrato JSON, profiles steady/burst, `--beam-hog` para F5) [codigo: cabecalho do proprio arquivo].

---

## 4. Como a Monetarie faz hoje

### 4.1 Wrapper e pool

- Wrapper `Monetarie.Infra.Tigerbeetle` (herdado do port Owem/AVIV antigo): timeout por chamada `@tb_timeout 1_500` ms, deliberadamente menor que os 3s da AVIV por causa do SLA ANS do BACEN de 1,6s ponta a ponta [codigo: `monetarie/core/backend/lib/monetarie/infra/tigerbeetle.ex:343-354`]. Sem NENHUM `:telemetry.span` nas operacoes TB (a AVIV instrumenta todas).
- Pool round-robin lock-free identico em desenho ao da AVIV [codigo: `monetarie/core/backend/lib/monetarie/infra/tigerbeetle/pool.ex:35-113`]. `TB_POOL_SIZE`: default 3 no runtime [codigo: `monetarie/core/backend/config/runtime.exs:270`]; o Terraform baseline injeta `TB_POOL_SIZE=1` na task def [codigo: `monetarie/infra/aws/greenfield/ecs.tf:52`]; o CLAUDE.md raiz afirma HML vivo com `TB_POOL_SIZE=4` desde a task def core-api:83 [doc]. Ou seja: tres fontes com tres valores; o vivo precisa ser conferido na task def (fora do escopo desta trilha).
- Circuit breaker: GenServer + ETS/atomics com estados closed/open/half_open (threshold 5, reset 30s, half-open max 2), UM breaker global para todas as operacoes [codigo: `monetarie/core/backend/lib/monetarie/infra/tigerbeetle/circuit_breaker.ex:1-140`; supervision em `application.ex:138-141`]. Nao ha split money path vs bulk (a AVIV tem 2 breakers e 2 clients).

### 4.2 DEFEITO da classe LAUDO-TIGERBEETLE-2026-05-19 presente na Monetarie

`do_lookup_account/1` achata QUALQUER erro nao-circuit em `:account_not_found`:

```
{:ok, {:ok, account}} -> {:ok, account}
{:ok, :not_found}     -> {:error, :account_not_found}
{:error, :circuit_open} -> {:error, :circuit_open}
{:error, _}           -> {:error, :account_not_found}   <- timeout/infra vira "conta nao existe"
```

[codigo: `monetarie/core/backend/lib/monetarie/infra/tigerbeetle.ex:120-125`]. Um `{:error, :timeout}` do CallOptions (TB saturado, exatamente o cenario de rajada) sai do `CircuitBreaker.call` como `{:error, :timeout}` [codigo: `circuit_breaker.ex:66-77`, "if it returns {:error,_} ... counts as a failure"] e cai no ramo final. E precisamente o bug que a AVIV corrigiu (burst de timeout virava `account_not_found` para contas validas de PIX-OUT) e que la e tratado como regra de ouro: erro de transporte NUNCA vira not_found [codigo AVIV: `fluxiq/infra/tigerbeetle.ex:440-457`]. Classificacao: PLAUSIBLE por leitura de codigo (nao reproduzi em runtime nesta trilha read-only).

### 4.3 Caminho vivo de credito PIX-in (canonico, flag OFF)

- Cabine publica evento -> `PixHandler` -> com `TWO_PHASE_PIX_IN` OFF (default false [codigo: `runtime.exs` do core, `two_phase_pix_in_enabled: System.get_env("TWO_PHASE_PIX_IN","false")=="true"`, linha 13 do bloco]; PROIBIDO ligar por decisao canonica de 09/07) o fluxo e `handle_transaction_ledger` -> journal COSIF PG + `create_tigerbeetle_transfer` -> `Wallet.deposit/withdraw` [codigo: `monetarie/core/backend/lib/monetarie/infra/nats/handlers/pix_handler.ex:108-118,349-432,783-826`].
- `Wallet.deposit` cria UM UNICO transfer direto (cash_asset -> client_liability), id deterministico `<<transaction_id::128>>`, e executa SINCRONO via `Tigerbeetle.create_transfer` (batch de 1); `:exists` e tratado como sucesso (retry idempotente ok) [codigo: `monetarie/core/backend/lib/monetarie/use_cases/wallet.ex:156-233,438-485`].
- Consequencia de desenho: throughput do money path = pool_size sessoes x 1 transfer por request. E o mesmo desenho que na AVIV formava comboios de 0,8-3,5s sob rajada de ACCC (secao 2.4). A Monetarie ainda nao viu isso porque o volume e minimo (1 pacs.008 recebida em prod ate 09/07), mas a meta do dono e superar 1,53M tx/dia, e nesse regime o desenho atual colapsa em fila exatamente como o da AVIV colapsava.

### 4.4 O que ja existe portado ou escrito mas NAO esta no caminho vivo

- `Monetarie.UseCases.Pix.TbFirst.Deposit`: port do batch linked COSIF (3-4 transfers, IDs deterministicos SHA-256, fee clamped) [codigo: `monetarie/core/backend/lib/monetarie/use_cases/pix/tb_first/deposit.ex:1-40`], usado por `TbFirst.Handler.handle_settled` SOMENTE quando `two_phase_pix_in_enabled` [codigo: `pix_handler.ex:112-116`]. Como a flag e PROIBIDA (gatilho settled so existe no simulador; canonico 09/07), esse batch nao roda em producao.
- `Monetarie.Infra.Tigerbeetle.BatchAccumulator` (+ `BatchTransfer`, `LinkedTransfer`): acumulador hibrido tempo+contagem desenhado para 30.000+ TPS, batch ate 8.189 (limite do protocolo TB), flush a cada 10ms, N shards com conexao exclusiva por shard, single-flight por shard [codigo: `monetarie/core/backend/lib/monetarie/infra/tigerbeetle/batch_accumulator.ex:1-40`]. CODIGO MORTO: nao esta na supervision tree [codigo: `application.ex:138-160,362-395`, so CircuitBreaker + conexoes do pool] e nao tem nenhum caller fora dos proprios modulos [verificado por grep: unicas referencias sao comentarios em `tigerbeetle.ex:394` e `pool.ex:24,82`].
- `BalanceGuard` com `min(tb, pg)` (mesma semantica da AVIV) e `BalanceCheckpoint` portado em 04/07 (adaptado para `account_daily_summaries`, com anti-retro-datacao), atras de `BALANCE_CHECKPOINT_ENABLED` [codigo: `monetarie/core/backend/lib/monetarie/use_cases/payments/balance_guard.ex:16,73,121`; `balance_checkpoint.ex:1-60`]. CLAUDE.md afirma checkpoint LIGADO em HML e paridade validada ao centavo [doc].
- Escrow/holds two-phase: `Wallet.hold` com `flags.pending: true` [codigo: `wallet.ex:235-283`] e `use_cases/payments/pending_transfers.ex` existem; nao auditei o wiring completo nesta trilha.

### 4.5 Vendored tigerbeetlex SEM self-heal

O vendored da Monetarie NAO tem `client_owner.ex` (o da AVIV tem) [verificado por listagem: `monetarie/core/backend/vendor/tigerbeetlex/lib/tigerbeetlex/` nao contem client_owner.ex; `coreproviders/backend/vendor/tigerbeetlex/lib/tigerbeetlex/client_owner.ex` existe]. Consequencia (mecanismo documentado pela AVIV): uma eviccao de sessao no TB deixa a `TigerBeetlex.Connection` zumbi com `:client_closed` para sempre ate o container reiniciar; foi o mecanismo fino do outage de 27min deles em 2026-07-07 [doc: design doc secao 2; codigo AVIV: `client_owner.ex:1-18`]. A Monetarie em prod tem TB de 3 replicas e vai escalar o core; este buraco esta aberto.

### 4.6 Subcentavo e a fronteira monetaria

- Mesma escala da AVIV: 1 unidade = R$ 0,0001 [codigo: `monetarie/core/backend/lib/monetarie/util/money_unit.ex:5`]. Cabine PIX permanece em centavos/Decimal; TODA travessia core<->cabine converte no `MoneyBoundary` (ADR-005) [codigo: `monetarie/core/backend/lib/monetarie/infra/nats/money_boundary.ex:1-60`]. O bug 100x do credito SPB->TB (depositou centavos onde o TB e subcentavo) foi corrigido em 06/07 com ajuste vivo idempotente [doc: CLAUDE.md raiz, estado 2026-07-06; commit `a7db5a66`].

### 4.7 Infra do TB na Monetarie

- HML: 1 no TB (default `tigerbeetle_node_azs = ["a"]`), instancia default `t4g.large` (t4g.small sofreu OOM-kill do tigerbeetle ~1,5GB RSS em 2026-06-24) [codigo: `monetarie/infra/aws/greenfield/variables.tf:157-161,472-476`].
- PROD: 3 replicas, 1 por AZ, `10.50.{1,2,3}.20`, EBS dedicado por no [codigo: `monetarie/infra/aws/greenfield/envs/prod.tfvars:141`].
- Core roda em ECS EC2 (nao Fargate) PORQUE o client TB usa io_uring, indisponivel no Fargate [codigo: `variables.tf:478-482`]. Versao pinada 0.17.3 (regra absoluta no CLAUDE.md raiz [doc]; mesma versao da AVIV).
- `clients_max=64` vale igual para o cluster da Monetarie (limite do servidor TB 0.17.3, nao da AVIV): a conta de sessoes deles (2 x (pool+1) x nos no overlap de deploy) precisa entrar no planejamento de escala do core.

---

## 5. Diferencas estruturais e por que existem

| Dimensao | AVIV | Monetarie | Por que difere |
|---|---|---|---|
| Batching do money path | Coalescer manual (flag; ON em PRD [doc]) + batching NATIVO via tb-gateway (Fase 2 pronta) | 1 transfer sincrono por evento (`Wallet.deposit`) | AVIV foi forcada pelos comboios a 400k+ dep/dia; Monetarie ainda sem volume |
| Modelo PIX-in | Two-phase ACSP->ACCC com deposito so em ACCC (chain linked TbFirst) | Legado flag-OFF: credito no evento da cabine (BACEN ja liquidou ANTES da pacs.008; canonico 09/07) | Indireto (OnZ entrega eventos two-phase) vs direto (BACEN liquida antes de entregar) |
| Sessoes TB | Pool 1-3 + `:tb_bulk` dedicado + gateway central (2-3 sessoes p/ toda a frota) | Pool 1/3/4 (fontes divergem), sem split bulk, sem gateway | Gateway nasceu do incidente clients_max=64 deles |
| Self-heal de eviccao | ClientOwner no vendored + SharedClient no gateway | Ausente | PR #18 deles e posterior ao fork vendored da Monetarie |
| not_found vs transiente | Distintos por contrato, retry so em transiente | Achatado em `:account_not_found` | Monetarie herdou o wrapper PRE-laudo de 2026-05-19 |
| Circuit breaker | 2 breakers lock-free (money vs bulk) | 1 breaker GenServer global | Evolucao pos-storm deles |
| Observabilidade TB | telemetry span em toda op + metricas tbgw_* + estimador de batch | Nenhum span nas ops TB (PromEx existe no app) | Port de 04/07 trouxe PromEx mas nao os spans TB |
| Timeout TB | 3000ms (sem SLA externo apertado; OnZ absorve) | 1500ms (ANS BACEN 1,6s) | Participante direto tem SLA regulatorio no proprio caminho |
| Verdade de saldo | min(TB, PG) + checkpoint | min(TB, PG) + checkpoint (portado) | Paridade ja feita em 04/07 |
| Reset do TB | Proibido; compensacao code 9116 | TB 0.17.3 pinado; regra "nunca resetar" nao formalizada em codigo | Cultura operacional deles pos-incidentes |

---

## 6. O que a AVIV tem de melhor (candidatos a port) e esforco estimado

1. **tb-gateway completo (servico Go + cliente Elixir)**. O servico e agnostico de plataforma: proto espelha o TB 0.17.3 puro, zero dependencia de schema AVIV. Reuso quase direto do diretorio `tb-gateway/`. O trabalho real e: (a) cliente Elixir (`tb_gateway.ex` ~450 linhas + `channel.ex` ~220 + roteamento em `Monetarie.Infra.Tigerbeetle` + stubs gerados + testes; a AVIV ja tem tudo isso escrito para copiar/adaptar namespace); (b) infra (servico ECS/EC2, SG liberando 3001 do TB para o gateway e 50051 do backend para o gateway, ECR; gotchas ja documentados no handoff fase1 [doc]); (c) adaptar deadlines ao budget ANS 1,6s da Monetarie (leitura 1500ms da AVIV NAO cabe: o custo e aditivo com o fallback NIF; algo como 300-500ms de deadline de leitura + NIF 1500ms atras). Esforco: dias, nao semanas, porque design, codigo, runbooks de rollout (fase1 e fase2) e bancada ja existem prontos no repo deles. Ganho esperado (medido la): cauda de rajada colapsa (p99 862->246ms, over600 99->0), sessoes TB param de escalar com nos do core, eviccao vira nao-evento, instrumentacao total.
2. **DepositCoalescer** (ou, alternativamente, dar vida ao BatchAccumulator ja escrito na Monetarie). O coalescer e ~180 linhas + config + testes, contrato identico ao caminho direto, provado em producao (tb p99 1561->219ms [doc]). Encaixa no caminho vivo da Monetarie com uma mudanca minima: rotear o `create_transfer` do `Wallet.deposit`/`withdraw` por um `create_transfers_for_deposit` equivalente. Observacao: se o tb-gateway Fase 2 for adotado, o coalescer fica redundante (o batching nativo do client Go o aposenta, como no plano deles); como passo intermediario de baixo risco, ainda vale.
3. **ClientOwner (PR #18) no vendored tigerbeetlex**. Fecha o zumbi pos-eviccao. Port de 1 arquivo + wiring no Connection + testes (a AVIV tem bancada de eviccao real reutilizavel). Esforco: pequeno. Urgencia alta: prod da Monetarie ja roda 3 replicas e o core vai escalar.
4. **Contrato not_found vs transiente + retry idempotente de leitura + breakers separados**. Port das linhas 26-39 e 371-514 do `fluxiq/infra/tigerbeetle.ex` + `circuit_breaker.ex` lock-free com 2 ref_keys. Corrige o defeito da secao 4.2 de quebra. Esforco: pequeno/medio (muda shapes de retorno; callers como BalanceGuard precisam propagar como a AVIV fez).
5. **Split `:tb_bulk` + chunk/pacing de leituras pesadas**. A Monetarie ja tem reconcilers (orphan_hold_reconciler, pix_in_orphan_reconciliation, enhanced reconciliation a cada 5min) que hoje disputam a MESMA sessao do money path. Port direto do padrao (child extra + roteamento + chunk 500 + sleep 100ms). Esforco: pequeno.
6. **Telemetry spans nas ops TB + metricas do gateway**. `:telemetry.span` em lookup/create/query/history + (se gateway) dashboards tbgw_*. Sem isso a Monetarie nao vai enxergar comboios quando o volume chegar. Esforco: pequeno.
7. **Bancada A/B reutilizavel** (`tb-gateway/bench` + `tb_nif_bench.exs`): permite provar na infra da Monetarie os mesmos gates antes de ligar qualquer flag. Esforco: pequeno (ajustar enderecos/perfis).
8. **Disciplina 9116**: formalizar a regra "nunca resetar TB; equalizar so por transfer compensatorio com code dedicado e metadata de reconstituicao excluida das views operacionais" (a Monetarie ja tem catalogo de codes em `util/codes/transfer_code.ex` para abrigar isso).

## 7. O que a Monetarie tem de melhor (nao regredir)

1. **Timeout de 1500ms alinhado ao ANS BACEN 1,6s** [codigo: `monetarie .../tigerbeetle.ex:343-347`]. A AVIV pode esperar 3s porque o OnZ absorve; a Monetarie nao pode. Qualquer port de deadline da AVIV tem que ser recalibrado para caber no budget.
2. **Modelo PIX-in canonico correto para participante DIRETO**: credito pelo caminho legado flag-OFF, provado empiricamente em prod 09/07 (BACEN liquida ANTES de entregar a pacs.008; recebedor nao recebe pacs.002). O two-phase da AVIV e correto PARA ELES (indireto via OnZ) e errado para a Monetarie; `TWO_PHASE_PIX_IN` segue PROIBIDO. Portar batching NAO pode significar portar o gatilho settled.
3. **BalanceGuard min(TB,PG) + BalanceCheckpoint ja portados e validados ao centavo em HML** [codigo: `balance_guard.ex`; doc: CLAUDE.md raiz 2026-07-04]. Paridade ja conquistada; manter.
4. **Infra TB como codigo**: replicas, AZs, EBS dedicado e instance types em Terraform versionado [codigo: `variables.tf`, `prod.tfvars:141`], contra unit files geridos a mao via SSM na AVIV [doc]. Inclui a licao operacional do OOM (t4g.small -> t4g.large) codificada na descricao da variavel.
5. **MoneyBoundary como ponto UNICO de conversao monetaria core<->cabine (ADR-005)** [codigo: `money_boundary.ex`], mais explicito que o espalhamento from_provider/to_provider da AVIV.
6. **Latencia de plataforma**: cabine ICOM 24-28ms por GET vs long-poll OnZ p50 471ms [doc: comparativo 2026-07-04]. O ponto de partida da Monetarie para a meta de latencia e estruturalmente melhor; o gargalo a atacar e o ledger-path, nao o transporte BACEN.

---

## 8. Recomendacoes priorizadas (meta: mais volume, menos latencia)

**P0 (defeitos e riscos de dinheiro, fazer antes de qualquer volume):**
- P0-1: Corrigir o achatamento `{:error,_} -> :account_not_found` no `Monetarie.Infra.Tigerbeetle.do_lookup_account` (secao 4.2), adotando o contrato da AVIV (not_found so em resposta positiva vazia; transiente distinto; retry so em transiente). Sob rajada, o codigo atual pode responder "conta nao existe" para conta valida, exatamente o modo de falha do laudo deles.
- P0-2: Portar o ClientOwner (self-heal pos-eviccao) para o vendored tigerbeetlex da Monetarie. Sem ele, 1 eviccao = conexao zumbi ate restart (outage de 27min na AVIV). Reusar a bancada de eviccao real deles como teste.
- P0-3: Adicionar telemetry spans nas operacoes TB do wrapper (paridade com a AVIV) para enxergar comboios ANTES que virem incidentes.

**P1 (capacidade e cauda, o coracao da meta):**
- P1-1: Adotar o tb-gateway em fases identicas as da AVIV (Fase 1 leitura com fallback NIF, Fase 2 escrita com contrato not_sent/ambiguo), reusando servico Go, cliente Elixir, runbooks e gates de bancada; recalibrar deadlines para o budget ANS 1,6s. E a resposta estrutural ao clients_max=64 e o unico caminho provado (Gate 3/4) de cortar a cauda de rajada sem multiplicar sessoes.
- P1-2: Enquanto o gateway nao entra, batching do money path: portar o DepositCoalescer (ou promover o BatchAccumulator morto a vivo, com os testes e o contrato posicional do coalescer da AVIV) e rotear `Wallet.deposit`/`withdraw` por ele atras de flag OFF. Decisao recomendada: portar o coalescer (provado em prod, contrato mais simples) e tratar o BatchAccumulator como codigo a remover ou substituir.
- P1-3: Split `:tb_bulk` + chunk/pacing para reconcilers e dashboards (secao 6 item 5), com breaker separado.
- P1-4: Rodar a bancada A/B (NIF vs gateway) na infra da Monetarie (HML 1 no e depois prod-like 3 replicas) e fixar baselines proprios de p50/p99/over600/over3000 antes e depois de cada flag.

**P2 (higiene e paridade):**
- P2-1: Unificar as tres fontes divergentes de `TB_POOL_SIZE` (runtime default 3, Terraform 1, CLAUDE.md HML 4) e documentar o teto seguro em funcao de `clients_max=64` e do numero de nos do core (formula da AVIV: 2 x (pool+1) x nos < 64 no overlap de deploy).
- P2-2: Formalizar a regra 9116 (nunca resetar TB; compensacao com code dedicado + metadata de reconstituicao excluida de views operacionais) no catalogo de codes da Monetarie.
- P2-3: Breaker lock-free (atomics) substituindo o GenServer no hot path, com os 2 ref_keys.
- P2-4: Ao adotar o gateway, planejar o proto v1 com two-phase pending/post/void (a Monetarie usa `Wallet.hold` pending para escrow; no v0 esses batches ficam no NIF, como na AVIV).

---

## 9. Perguntas abertas / NAO VERIFICADO

1. `TB_GATEWAY_WRITE_ENABLED` chegou a ser ligado em Aviv PRD? O runbook exige ok final do dono para o flip; o estado do flip nao esta registrado no repo ate onde li [NAO VERIFICADO].
2. A formulacao "TB em EC2 dedicada com service ECS a 0" na AVIV: os docs mostram TB em EC2 com systemd/unit files via SSM; nao achei referencia a um service ECS zerado para TB [NAO VERIFICADO].
3. Valor VIVO de `TB_POOL_SIZE` nas task defs da Monetarie (HML e prod): tres fontes divergem (1/3/4); exige describe-task-definition, fora do escopo sem AWS [NAO VERIFICADO nesta trilha].
4. Estado atual do coalescer em Aviv PRD pos-Fase 1/2 (o desfecho de 04/07 diz ligado; o plano da Fase 2 preve aposenta-lo) [NAO VERIFICADO].
5. Recorde de 1,53M tx/dia em 08/07: contexto do mandato (medicao de outra trilha), nao verificavel neste repo [NAO VERIFICADO aqui].
6. Wiring completo do `use_cases/payments/pending_transfers.ex` da Monetarie (two-phase de PIX-out/TED): nao auditei nesta trilha; o caminho de debito PIX-out da Monetarie merece a mesma analise de comboio do PIX-in.
7. O `@max_batch_size 8_189` do BatchAccumulator da Monetarie vs o teto ~8190 citado pela AVIV: os limites exatos por operacao no 0.17.3 devem ser conferidos contra o vendored antes de qualquer batching agressivo.
