# Dossie de paridade profunda: trck.001 / trck.002 (MED tracking / grafo cautelar)

Auditor: revisao senior PIX. Metodo: leitura dos DOIS lados com prova arquivo:linha
ou tabela.coluna. READ-ONLY. Sem inferencia: onde falta prova, verdict INCONCLUSIVO.

## 0. Escopo e primeira constatacao (trck.001 nao existe)

O pedido cita "trck.001 / trck.002". Empiricamente:

- Catalogo oficial SPI v5.12.1 tem SOMENTE `trck.002` (arquivo
  `/Users/luizpenha/cecresa/md/spi.5.12.1/v5.12.1/xsd/trck.002.spi.1.1.xsd` +
  exemplo `.../exemplos/trck002/trck.002_PSP_msg.xml`). Nao existe `trck.001` em
  `/Users/luizpenha/cecresa/md` nem em `apps/shared/priv/xsd`.
- Legado: so ha `TRCK002` (busca por `trck001|TRCK001|MED20TRCK001` = 0 ocorrencias
  no decompilado). Enum `enumTipoMsg` so tem `TRCK002` (SPI.Core.General.decompiled.cs:8137).
- Nosso: so `trck.002` (spi_version.ex:168 `"trck.002" => "1.1"`; message_parser.ex:117).

**Verdict trck.001: INCONCLUSIVO/NAO APLICAVEL** — mensagem inexistente no catalogo
BACEN e ausente nos dois sistemas. O dossie trata trck.002 (PmtStsTrckrRpt =
Payment Status Tracker Report), a peca do "grafo cautelar" do MED 2.0.

O tema tem DUAS pecas distintas que a pista agrupou:

1. **Relatorio trck.002** (legado: `TB_TRCK002` + `WorkerMED20TRCK002` + `addTrck002`;
   nosso: `CoreEventProcessor.handle_internal_settlement`). Reporta ao SPI as
   transacoes PIX liquidadas nos sistemas PROPRIOS do participante (book transfer,
   nao passou pelo SPI) para alimentar o grafo de rastreamento de fraude.
2. **Grafo de rastreamento / Recuperacao de Valores** (legado: `TB_RECUPERACAOVALOR`
   + `TB_GRAFO_PESSOA/CONTA/TRANSACAO`; nosso: `dict FundsRecovery` +
   `tracking_graphs` + `tracking_graph_persons/accounts/transactions`). O grafo
   propriamente dito, consultado via DICT/MED 2.0.

---

## 1. Peca 1 — Relatorio trck.002 (PmtStsTrckrRpt)

### 1.1 LEGADO

**Persistencia dedicada.** Tabela `TB_TRCK002` (GID DB) — schema em
`GID.Core.General.decompiled.cs:4241-4285` (TRCK002Configuration) e no script
`LegadoPIX/Pix/Med_gid/scripts/01.Inicial.sql:55-93`. Colunas: `UniqueId` (PK),
`EndToEndId char(32)`, `InstructionReturnId char(32)`, `InitiationForm char(4)`,
`Amount decimal(18,2)`, `TransactionDateTime`, `ISPBDebtor/BranchDebtor/AccountDebtor/
AccountTypeDebtor/CpfCnpjDebtor`, idem Creditor, `TransactionalAccountid varchar(77)`,
`MessageId`, `ProtocoloSPI varchar(max)`, `RetornoBACEN varchar(max)`, `Status int`.
DB vivo confirma a tabela existe com 0 linhas (gid.TB_TRCK002 = 0 rows;
colunas conferidas via sys.columns).

**Historico/auditoria.** `TB_TRCK002_HIST` (GID.Core.General.decompiled.cs:4286-4304;
DB gid.TB_TRCK002_HIST 0 rows). Toda criacao E atualizacao gravam uma linha de
historico: `TRCK002Repository.CriarTRCK002` chama `CriaTRCK002Hist`, e
`AtualizaTRCK002` idem (GID.Core.Application.decompiled.cs:1120-1144).

**Ciclo de status** (enum, decodificado em SQL na
GID.Core.Application.decompiled.cs:1090,1099): `0=''`, `1=Registrado`, `2=Enviado`,
`3=ErroEnvio`, `4=Efetivado`, `5=Rejeitado`. Nasce `Registrado`
(TRCK002ApiDTO.ToTRCK002 seta `Status = enumStatus.Registrado`,
GID.Core.General.decompiled.cs:5369).

**API de entrada com validacao.** `MED20Controller.addTrck002`
(SPI.Web.Api.decompiled.cs:983-997) recebe `TRCK002ApiDTO` e delega a
`InserePgtoComConversao`. Validacao em `ValidaTRCK002UseCase.Valida`
(SPI.Core.Application.decompiled.cs:4808-4839): checa DTO nao nulo, resolve/valida
sistema de origem, valida UniqueId, resolve `MsgDefIdr` por VIGENCIA
(`FindVigencia(enumTipoMsg.TRCK002, DtHrOperacao)`) e exige `Amount > 0` (senao
`enumValidationError.ValorNaoInformado`). Validacoes de campo no DTO
(GID.Core.General.decompiled.cs:5288-5344): EndToEndId 32 chars, InitiationForm 4,
ISPB regex `[a-zA-Z0-9]{8}`, Branch 0..9999, CpfCnpj 11..14, AccountType via
`enumTipoConta`.

**Worker de envio.** `WorkerMED20TRCK002 : WorkerBase`
(SPI.Core.Worker.FilaEntrada.decompiled.cs:368-374), finalidade de fila
`enumFinalidadeFila.MED20TRCK002 = 31` (SPI.Core.General.decompiled.cs:8420). Consome
a fila, monta o XML e envia. Recepcao/processamento em
`UnitOfWorkRecepcaoTRCK002DTO.Processamento` (SPI.Core.Infrastructure.decompiled.cs:
1602-1639): valida -> ProcessaMsg -> grava marca de processado.

**Montagem ISO 20022** — `SPI.Core.Mensageria.Application.Book.v111 ... TRCK002.v10.ToXml`
(SPI.Core.Mensageria.Application.Book.v111.decompiled.cs:192-224). Envelope
`PmtStsTrckrRpt` com `GrpHdr(MsgId,CreDtTm)` + `TrckrStsAndTx` + `TxSts/Sts=ACCC`
(hardcode) + `Tx` com `PmtId` (InstrId quando InstructionReturnId presente +
EndToEndId), `PmtTpInf/LclInstrm/Prtry = InitiationForm`, `PmtScnro/Prtry =
(ISPBDebtor==ISPBCreditor ? "BOK1" : "BOK2")`, `IntrBkSttlmAmt`, `ReqdExctnDt/DtTm`,
`Dbtr/Pty/Id/PrvtId/Othr/Id = CpfCnpjDebtor` (SEMPRE PrvtId), DbtrAcct (Id + opcional
Issr + Tp/Cd), DbtrAgt/CdtrAgt (MmbId=ISPB), `Cdtr/.../PrvtId/Othr/Id` (SEMPRE
PrvtId), CdtrAcct com Prxy opcional (TransactionalAccountId).

**Correlacao do retorno BACEN.** `TRCK002Repository.AtualizaTRCK002(MessageId,
Status, RetornoBacen)` faz UPDATE de Status + RetornoBACEN por MessageId
(GID.Core.Application.decompiled.cs:1146-1149). `getStatusOperacao`
(GID.Core.Application.decompiled.cs:1071-1092) DECODIFICA o `RetornoBACEN` XML
(`RctDtls/ReqHdlg/StsRsn/Rsn/Prtry` + `AddtlInf`) e o JSON `ProtocoloSPI/$.Erros`
para exibir o MOTIVO da rejeicao.

**Monitor/consulta.** `monitorList` paginado com filtros InitiationForm/ISPB/CpfCnpj/
periodo (GID.Core.Application.decompiled.cs:1040-1068); `ListStatus` (distinct por
periodo, :1094-1101); `ListHist` por UniqueId (:1103-1109). Endpoints em
`GID.Api` (Med_gid/api/GID.Api.xml: AddTRCK002, monitorList, ListHist).

**Recepcao inbound (correlacao).** `ConversorEnvioAPI.Impl.TRCK002.v10.ConverteMsg`
(SPI.Core.Application.decompiled.cs:8620-8674) faz PARSE de um `PmtStsTrckrRpt`
recebido (origem `RetornoAPIBacen`) de volta para `TRCK002DTO` (extrai EndToEndId,
InitiationForm, Amount, Dbtr/Cdtr, ISPBs, TransactionalAccountId do Prxy).

### 1.2 NOSSO

**Gatilho** — evento NATS `internal_settlement` (Core -> PIX), publicado pelo Core
em `core/backend/.../partner_v1/pix_controller.ex:1516-1534`
(`publish_internal_settlement`), quando o PIX e para chave da PROPRIA instituicao
(book transfer). Consumido em
`settlement_service/.../workers/core_event_processor.ex:80-81`
(`process_message(%{"event" => "internal_settlement"})` -> `handle_internal_settlement`).

**Montagem + envio** — `handle_internal_settlement`
(core_event_processor.ex:1833-1890): monta params (status `"ACCC"`,
payment_scenario `"BOK1"` HARDCODE, local_instrument `"DICT"`, E2E preferindo o da
consulta DICT cacheada), chama `Shared.Bacen.Iso20022.MessageBuilder.build("trck.002",
params)` e envia via `internal_settlement_send_fun` (default
`Shared.Bacen.SpiClient.send_signed_message/2`, core_event_processor.ex:1948-1954).
Builder `build_trck002` em
`shared/lib/shared/bacen/iso20022/message_builder.ex:1510-1547` (envelope identico ao
legado: PmtStsTrckrRpt/GrpHdr/TrckrStsAndTx/TxSts/Tx...).

**Persistencia** — `record_internal_settlement_message`
(core_event_processor.ex:1902-1944): grava UMA linha em `monetarie_spi.messages`
(`create_transaction`) com `message_code: "trck.002"`, `direction: "OUTBOUND"`,
`debit_credit: "DEBIT"`, `status_id: StatusCodes.id("ACSC")` HARDCODE. Best-effort;
falha so loga CRITICO. NAO ha tabela dedicada, NAO ha historico dedicado.

**Catalogo/manual** — `message_form_catalog.ex:671-702` define `trck.002`
(direction OUTBOUND, sendable) para o "Construir Mensagem"; required_fields
end_to_end_id/amount/execution_datetime/debtor_ispb/creditor_ispb.

**Inbound/monitor** — NAO ha handler que processe um trck.002 recebido. O
`message_parser.ex:117` sabe CLASSIFICAR `PmtStsTrckrRpt` como `trck.002`, mas nenhum
worker (inbound_processor, status_updater, return_processor) roteia trck. O monitor
generico (`admin/monitor_controller.ex:493,798`) apenas lista `trck.%` como mensagem
qualquer; sem filtro por InitiationForm/CpfCnpj nem decode de rejeicao.

### 1.3 Amount / unidade — sem risco 100x (info)

Core envia `res.amount` (reais, pix_controller.ex:1522); nosso
`to_decimal` (core_event_processor.ex:2093-2119) + `fmt_amount`
(message_builder.ex:1853-1857) produzem 2 casas. Legado `Amount decimal(18,2)`.
Coerente, sem multiplicador. (Nao ha o padrao de bug de centavos visto em outras
frentes.)

---

## 2. Peca 2 — Grafo de rastreamento / Recuperacao de Valores

### 2.1 LEGADO

**Persistencia do grafo COMPLETO** (GID DB, confirmado vivo, 0 rows mas schema
presente):
- `TB_RECUPERACAOVALOR` (cols: Id, DataHoraCriacao, DataHoraUltimaModificacao,
  IdStatus, IdTransacaoRaiz, IdTipoSituacao, ParticipanteReportador, TempoRequisicao,
  ContatoEmail, ContatoTelefone, Detalhes, GrafoValorMinimo, GrafoMaximoTransacoes,
  GrafoJanelaHoras, GrafoProfundidade).
- `TB_RECUPERACAOVALOR_STATUS` (7 rows): 1 CREATED, 2 TRACKED, 3 AWAITING_ANALYSIS,
  4 ANALYSED, 5 REFUNDING, 6 COMPLETED, 7 CANCELLED.
- `TB_GRAFO_PESSOA` (IdRecuperacaoValor, Id, IdTipoPessoa, DataCriacao).
- `TB_GRAFO_CONTA` (IdRecuperacaoValor, Id, IdPessoa, Participante, DataAbertura).
- `TB_GRAFO_TRANSACAO` (IdRecuperacaoValor, Id, IdContaDebito, IdContaCredito, Valor,
  ValorReembolsavel, Data).

**DTOs/retorno completos.** `GrafoRastreamentoDTO` com listas `Persons/Accounts/
Transactions` (GID.Core.General.decompiled.cs:4586-4615); `DetalharRecuperacaoValorReturnValue`
retorna `List<DetalheGrafo>` com POR-TRANSACAO: DataTransacao, Valor, ValorReembolsavel,
IdContaDebito/Credito, ParticipanteDebito/Credito, IdPessoa e TipoPessoa dos dois lados,
datas de abertura de conta e de criacao de entidade
(GID.Core.General.decompiled.cs:2491-2554). Criacao envia `TrackingGraphParameters`
(MinTransactionAmount, MaxTransactions, HopWindow `PT{H}H`, MaxHops) ao BACEN
(CriarRecuperacaoValorRequestDTO.ToXML, GID.Core.General.decompiled.cs:4554-4562).
Endpoint `ConsultarGrafoRastreamento` (GID.Api.xml:149-156).

### 2.2 NOSSO

**Schemas presentes** (2 conjuntos, ver gap g7):
- `Shared.Schemas.Dict.TrackingGraph` + `TrackingGraphPerson/Account/Transaction`
  (shared/lib/shared/schemas/dict/tracking_graph.ex) — modelo rico, com child tables e
  associacoes has_many.
- `DictService.FundsRecovery.TrackingGraph`
  (dict_service/.../funds_recovery/tracking_graph.ex) — modelo raso; persons_count/
  accounts_count/transactions_count/total_amount_traced sao VIRTUAL (nao persistidos).
- `funds_recoveries` + status via `Shared.Schemas.Dict.FundsRecovery`
  (@statuses 7 identicos ao legado; matriz de transicao em funds_recovery.ex:85-91).

**Fetch real do BACEN** — `DictService.FundsRecovery.refresh_tracking_graph/1`
(funds_recovery.ex:270-284) faz `BacenAdapter.get_tracking_graph` (GET; o POST BACEN
esta 410/deprecated) e upserta. Porem `tracking_graph_attrs_from_bacen`
(funds_recovery.ex:1348-1384) extrai SO agregados (totalHops, totalAmountTraced,
personsCount, accountsCount, transactionsCount) — NUNCA parseia as listas de
Persons/Accounts/Transactions. As child tables `tracking_graph_persons/accounts/
transactions` NAO sao escritas em NENHUM ponto do codigo (grep de uso das changesets
= so o arquivo de schema). `default_tracking_graph_attrs` (funds_recovery.ex:1322-1342)
cria grafo GENERATED com contadores ZERO.

**Gateway usa STUB** — a rota que o front chama
(`/api/v2/funds-recoveries/:id/tracking-graph`, settlement router.ex:398-404) cai em
`dict_proxy_controller.get/generate_funds_recovery_tracking_graph`
(dict_proxy_controller.ex:347-370). `insert_tracking_graph`
(dict_proxy_controller.ex:874-893) FABRICA um grafo por SQL cru a partir de
`funds_recoveries` (`hop_count=1, max_hops=5, status='COMPLETED', total_amount=
fr.amount`), sem chamar dict_service nem BACEN. `tracking_graph_row_to_json`
(:895-915) devolve `persons_count: nil, accounts_count: nil,
transactions_count: hop_count`.

**Front** — `FundsRecoveryDetailView.vue` aba "tracking" renderiza SO agregados
(total_hops, total_amount_traced, transactions_count, persons_count, accounts_count,
hop_window, max_hops; linhas 217-291). Nao ha lista/visualizacao de nos e arestas do
grafo. Nao ha view/monitor dedicado de trck.002 (grep trck no front = so o label
`useIso20022Labels.ts:67`).

---

## 3. Tabela de GAPS (resumo)

| id | titulo | tipo | risco |
|----|--------|------|-------|
| g1 | Party CNPJ emite `<OrgId>` (invalido no XSD trck.002) | divergencia | alto |
| g2 | Status trck.002 hardcode ACSC, sem correlacao com retorno BACEN | divergencia | medio |
| g3 | Sem persistencia/historico/monitor dedicado de trck.002 | ausente | medio |
| g4 | Grafo detalhado (pessoas/contas/transacoes) nunca persistido nem exibido | parcial | medio |
| g5 | Gateway do tracking-graph usa STUB que FABRICA grafo | divergencia | alto |
| g6 | Sem addTrck002 com validacao (amount>0, participante, vigencia) | parcial | medio |
| g7 | Dois schemas divergentes p/ tracking_graphs (UUID vs int PK) | divergencia | baixo |
| g8 | PmtScnro fixo BOK1 (legado calcula BOK1/BOK2) | parcial | baixo |
| g9 | InstrId (InstructionReturnId) nao suportado no builder | parcial | baixo |
| g10 | Builder aceita status != ACCC (XSD so permite ACCC) | divergencia | baixo |
| g11 | trck.001 inexistente nos dois lados e no catalogo | coberto | info |
| g12 | Envelope/estrutura trck.002 fiel ao XSD e ao legado | coberto | info |
| g13 | Ciclo de status da Recuperacao de Valores identico | coberto | info |
| g14 | Amount/unidade trck.002 coerente (sem 100x) | coberto | info |

Detalhamento dos gaps abaixo (prova nos itens 1 e 2).

### g1 (ALTO) Party CNPJ -> `<OrgId>` invalido
`handle_internal_settlement` seta `debtor_id_type: party_id_type(doc)` /
`creditor_id_type: party_id_type(doc)` (core_event_processor.ex:1858,1862);
`party_id_type/1` retorna `"OrgId"` p/ documento de 14 digitos
(core_event_processor.ex:1892-1896). `build_trck_party` embrulha em
`<OrgId>` (message_builder.ex:1553-1555). MAS o XSD trck.002.spi.1.1
`Party38Choice` so permite `PrvtId` (PersonIdentification13/Othr/Id, tipo PICpfCnpj
que ja aceita CNPJ 14) — trck.002.spi.1.1.xsd:193-197,230-239. Logo trck.002 de book
transfer com pagador/recebedor PJ emite `<OrgId>` = XSD-invalido -> BACEN rejeita o
reporte. Legado SEMPRE emite PrvtId (Book.v111 ToXml, linha 222). Money-path de
reporte quebra para PJ.

### g2 (MEDIO) Status hardcode / sem correlacao de aceite/rejeicao
Nosso: `{:ok, _response} -> record_internal_settlement_message` grava
`status_id: StatusCodes.id("ACSC")` FIXO (core_event_processor.ex:1873,1902-1924),
independentemente de o BACEN ter aceitado/rejeitado; o `_response` nao e inspecionado;
nenhum inbound handler atualiza. Legado: worker atualiza `TB_TRCK002.Status`
(Efetivado/Rejeitado) via `AtualizaTRCK002(MessageId,Status,RetornoBACEN)` e
`getStatusOperacao` decodifica o motivo da rejeicao
(GID.Core.Application.decompiled.cs:1090,1146-1149).

### g3 (MEDIO) Sem persistencia/historico/monitor dedicado
Nosso: so 1 linha em `monetarie_spi.messages`; sem TB_TRCK002/HIST equivalente, sem
`monitorList`/`ListStatus`/`ListHist`, sem filtro InitiationForm/CpfCnpj. Legado:
`TB_TRCK002` + `TB_TRCK002_HIST` (historico em toda escrita) +
monitor/consulta (GID.Core.Application.decompiled.cs:1040-1109,1120-1144).

### g4 (MEDIO) Grafo detalhado nunca persistido/exibido
Nosso: child tables `tracking_graph_persons/accounts/transactions` existem (schema
tracking_graph.ex:85-226) mas NUNCA sao escritas;
`tracking_graph_attrs_from_bacen` (funds_recovery.ex:1348-1384) extrai so contadores;
front mostra so agregados (FundsRecoveryDetailView.vue:217-291). Legado persiste
`TB_GRAFO_PESSOA/CONTA/TRANSACAO` e retorna `List<DetalheGrafo>` por transacao
(GID.Core.General.decompiled.cs:2491-2554,4586-4615).

### g5 (ALTO) Gateway usa STUB fabricado
`/api/v2/funds-recoveries/:id/tracking-graph` (settlement router.ex:398-404) ->
`dict_proxy_controller` que FABRICA o grafo por SQL cru sobre `funds_recoveries`
(`hop_count=1, max_hops=5, status='COMPLETED'`, dict_proxy_controller.ex:874-893) e
NAO chama o caminho real do dict_service (`FundsRecovery.refresh_tracking_graph`).
O front recebe dados sinteticos. Legado consulta o grafo REAL do BACEN
(ConsultarGrafoRastreamento).

### g6 (MEDIO) Sem addTrck002 validado
Nosso trck.002 so nasce do evento `internal_settlement` (sem validacao amount>0,
existencia de participante, resolucao de vigencia/MsgDefIdr) ou do "Construir Mensagem"
generico. Legado: `MED20Controller.addTrck002` + `ValidaTRCK002UseCase`
(amount>0, unique id, participante, `FindVigencia(TRCK002,...)`; SPI.Web.Api:983-997;
SPI.Core.Application:4808-4839).

### g7 (BAIXO) Dois schemas divergentes p/ mesma tabela
`Shared.Schemas.Dict.TrackingGraph` (UUID PK, child tables, colunas
min_transaction_amount/max_transactions/hop_window/max_hops/total_*) vs
`DictService.FundsRecovery.TrackingGraph` (integer PK, graph_id string, min_amount
source total_amount, virtuais) — ambos `monetarie_dict.tracking_graphs`. Mapeamentos
de coluna conflitantes (ex.: `total_amount` = min_amount num, = total_amount_traced
noutro). Risco de leitura inconsistente.

### g8 (BAIXO) PmtScnro fixo BOK1
Nosso hardcode `"BOK1"` (core_event_processor.ex:1850; default builder 1531). Legado
calcula `ISPBDebtor==ISPBCreditor ? BOK1 : BOK2` (Book.v111 ToXml:222). Como o gatilho
nosso e sempre mesma instituicao, BOK1 e correto hoje; latente se reusado p/ reporte
cross-ISPB de sistema proprio (XSD permite BOK1 e BOK2).

### g9 (BAIXO) InstrId nao suportado
`build_trck002` so emite `<EndToEndId>` em PmtId; nunca `<InstrId>`
(message_builder.ex:1525-1527). XSD PaymentIdentification10 tem InstrId opcional
(RtrIdType, trck.002.spi.1.1.xsd:208-213). Legado emite InstrId quando
InstructionReturnId presente (Book.v111:222). Book transfer BOK1 nao tem RtrId, entao
sem impacto hoje; builder incompleto p/ reuso.

### g10 (BAIXO) Builder aceita status != ACCC
`build_trck002` usa `p[:status] || "ACCC"` e o moduledoc cita "ACCC/RJCT/PDNG/STLD"
(message_builder.ex:1508,1522). XSD `ExternalPaymentTransactionStatus1Code_Trck002` so
permite `ACCC` (trck.002.spi.1.1.xsd:156-160). internal_settlement usa ACCC (ok), mas
o "Construir Mensagem" pode gerar invalido. Legado sempre ACCC (hardcode).

### g11 (COBERTO/info) trck.001 inexistente
Nao ha trck.001 no catalogo v5.12.1 nem nos dois sistemas. Ambos corretamente so
tratam trck.002.

### g12 (COBERTO/info) Envelope trck.002 fiel
`build_trck002` (message_builder.ex:1510-1566) reproduz o PmtStsTrckrRpt do XSD e do
legado (GrpHdr, TrckrStsAndTx, TxSts/Sts, Tx com PmtId/PmtTpInf/PmtScnro/
IntrBkSttlmAmt/ReqdExctnDt/Dbtr/DbtrAcct/DbtrAgt/CdtrAgt/Cdtr/CdtrAcct incl. Prxy no
CdtrAcct). Versao 1.1 correta (spi_version.ex:168).

### g13 (COBERTO/info) Ciclo de status da Recuperacao de Valores identico
`TB_RECUPERACAOVALOR_STATUS` (7: CREATED/TRACKED/AWAITING_ANALYSIS/ANALYSED/
REFUNDING/COMPLETED/CANCELLED) == nosso `@statuses` (funds_recovery.ex:23) + matriz de
transicao coerente (funds_recovery.ex:85-91).

### g14 (COBERTO/info) Amount/unidade coerente
Reais em ambos; sem multiplicador de centavos (ver 1.3).

---

## 4. Conclusao

- trck.002 de RELATORIO existe nos dois lados. Nosso e AUTOMATICO (evento
  internal_settlement) — cobertura de gatilho arguivelmente melhor que a API manual do
  legado — mas RASO: g1 (bug XSD p/ PJ, ALTO), g2/g3 (sem lifecycle/historico/monitor
  nem correlacao de rejeicao), g6 (sem validacao), g8/g9/g10 (builder incompleto).
- O GRAFO de rastreamento tem schema rico no nosso lado, mas o DETALHE
  (pessoas/contas/transacoes) nunca e persistido nem exibido (g4) e o caminho que o
  front usa e um STUB fabricado (g5). O legado persiste e retorna o grafo completo.
- Prioridade de correcao: g1 (reporte PJ quebra no BACEN) e g5 (dado fabricado
  enganoso), depois g2/g3/g4.
