PT EN
Voltar ao site

Base Negativa Pública

Bases negativas brasileiras e internacionais carregadas para o grafo de referência pelo Datta Extract: sanções do Portal da Transparência (CEIS/CNEP/CEPIM), pessoas expostas politicamente (PEP), instituições autorizadas pelo Banco Central e a lista consolidada do Conselho de Segurança da ONU (CSNU). A checagem contra essas bases é parte inseparável do KYB — e a verificação da lista da ONU é obrigação legal (Lei 13.810/2019, Circular BCB 3.978).

Como toda integração de dados abertos da plataforma, cada fonte é um fluxo do DATTA Extract (origin=DESIGNER, arquivos em scripts/pipelines/base-negativa/), executado pelo motor da própria plataforma, dentro do pipeline-designer-service, no agendamento cron do próprio fluxo. Não existe serviço, tela ou classe Java dedicada por fonte.

Antes, a execução era submetida ao Spark, num container próprio. Não é mais: o motor é o do serviço, e o Spark saiu do caminho de ETL.

A operação começa em Extract › Pacotes, a galeria que lista todos os pipelines de extração: buscar o fluxo pelo nome (ex.: "CEIS", "CSNU"), executar, pausar, duplicar ou arquivar direto do cartão, e abrir para editar — no modo Avançado, porque estes fluxos não são as cadeias lineares simples que o Assistente monta (a galeria informa o motivo no cartão). Ver Fontes Externas de Dados Abertos para a anatomia geral e para a tabela de permissões.

Os sete fluxos

FluxoCadênciaOrigemEscreve
CEIS Empresas Inidôneas e Suspensasdiária 04h30zip+CSV, URL datadaSancao (com cnpjBasico p/ PJ) + screening + base_negativa.ceis
CNEP Empresas Punidasdiária 04h40zip+CSV, URL datadaSancao (com valorMulta, cnpjBasico) + screening + base_negativa.cnep
CEPIM Entidades Impedidasdiária 04h50zip+CSV, URL datadaSancao por convênio + screening + base_negativa.cepim
CSNU Indivíduosdiária 05h00XML únicoEntidadeSancionadaInternacional + screening + base_negativa.csnu_individuos
CSNU Entidadesdiária 05h10XML únicoEntidadeSancionadaInternacional + screening + base_negativa.csnu_entidades
PEP Pessoas Expostas Politicamentemensal (dia 3, 05h20)zip+CSV, URL datadaPessoaExpostaPoliticamente + screening + base_negativa.pep
Instituições Autorizadas BCBmensal (dia 3, 05h30)4 CSVs via Olinda (Instituicoes_em_funcionamento)InstituicaoAutorizadaBcb (chave CNPJ básico) + screening (datta_bcb) + bcb.instituicoes

Destinos por ORIGEM: cada origem tem o SEU banco Neo4j — declarado como dataSource NEO4J do contexto FEBRABAN com role=base-negativa (CEIS, CNEP, CEPIM, PEP, CSNU) ou role=bcb (instituições) —, o SEU índice de screening (datta_base-negativa / datta_bcb) e o SEU schema Trino/Iceberg (base_negativa.* / bcb.*, modo overwrite: as fontes são snapshot completo). Todos os nós carregam versaoCarga (data da execução) e a recarga no grafo é MERGE por chave.

A aresta para a (:Empresa) da Receita não existe mais: a Receita vive no banco cnpj e aresta entre bancos não existe no Neo4j. O vínculo é por CHAVE — Sancao.cnpjBasico de um lado, Empresa.empresaCnpj do outro — e quem faz o join é o cruzamento KYB (sancoesDaEmpresa), nunca o pacote (Diretrizes do Projeto §22).

Capacidades do componente de origem por URL

Os fluxos usam capacidades do UrlSource pensadas para dados abertos brasileiros — todas configuráveis no canvas, sem código:

  • URL datada com tolerância a defasagem — a URL aceita o placeholder {data:padrão} (ex.: .../ceis/{data:yyyyMMdd}, @dataBase='{data:MM-yyyy}'). Na execução, o runner tenta a data corrente e recua até N períodos (campo Tolerância de defasagem): dias quando o padrão tem componente de dia, meses caso contrário. A publicação dos portais atrasa e o CEPIM publica em dias irregulares — a tolerância absorve isso.
  • Tamanho mínimo (bytes) — o Olinda do BCB responde HTTP 200 com um CSV só de cabeçalho para competência ainda não publicada; resposta menor que o mínimo conta como "não publicado" e recua a data. Status HTTP sozinho não discrimina. No pacote do BCB o piso não tem efeito hoje: as origens gravam a chave minBytes, enquanto o componente lê minimoBytes — sem a chave esperada vale o default de 1 byte, que qualquer resposta de cabeçalho ultrapassa. Nos pacotes do Portal da Transparência (CEIS/CNEP/CEPIM/PEP), que gravam minimoBytes, o piso vale.
  • Compressão zip — o Portal da Transparência publica zip com um CSV dentro; o campo Arquivo dentro do zip escolhe a entrada quando houver mais de uma.
  • Formato XML — a lista da ONU é XML. O runner converte para registros tabulares pelo Elemento de registro (INDIVIDUAL/ENTITY); grupos repetidos (apelidos) viram arrays acessíveis nas fórmulas do designer (transform(INDIVIDUAL_ALIAS, x -> x.ALIAS_NAME)).
  • Inferência de tipos desligável — cadastros chaveados por CPF/CNPJ de dígitos puros desligam Inferir tipos automaticamente: a inferência transformaria "07935099120" em número e destruiria o zero à esquerda.
  • Citação desligável (quote vazio) — dado aberto brasileiro nem sempre é CSV válido. Os datasets de sancionadores e de fundos da CVM trazem aspa tipográfica solta dentro de campo citado (alínea c"), e o parser RFC 4180 aborta a carga inteira, não só a linha. Desligar a citação resolve — mas só é seguro quando nenhum campo citado contém o delimitador, e essa condição não vale para todas as fontes. Medição de 2026-08-05, contando campos por linha com e sem citação:
FonteCitaçãoDesligar?
CVM sancionadores, CVM fundosdecorativasim — já aplicado
CVM companhias abertas, CEPIM, PEPdecorativaseguro, desnecessário hoje
CEIS, CNEPestrutural (texto livre com ;)não — 24 colunas viram 24/25/26
BCB Olindaestruturalnão — 15 colunas viram 15/16/17

Aplicar a válvula em bloco corromperia CEIS, CNEP e BCB sem levantar erro — só colunas trocadas. Meça a fonte antes, com este teste: se o número de campos por linha mudar ao desligar a citação, ela é estrutural e a válvula está proibida ali.

  • Índice na chave é garantido pela plataforma — o MERGE de cada lote usa a propriedade-chave do destino. Sem índice nela, cada lote varre o label inteiro e o custo da carga cresce com o quadrado do número de linhas. O sintoma não é lentidão, é falha: em 2026-08-05 a carga da PEP (133.905 linhas) gravou cerca de 90 mil nós no banco febraban — que não tinha nenhum índice de chave — e estourou o timeout de 60s de um lote, terminando com o label pela metade. Hoje o graph-data-service emite CREATE INDEX ... IF NOT EXISTS na primeira gravação de cada combinação banco/label/chave, e também nos dois lados da ligação por chave. Não é preciso criar índice à mão para um pacote novo; se o usuário do Neo4j não tiver privilégio de schema, a carga continua e o log registra o aviso.

Fontes que mudaram do lado do órgão (2026-08)

Duas fontes pararam de servir dado e foram substituídas. As duas falhavam do mesmo jeito — HTTP 200 com corpo vazio, que não se distingue de "ainda não publicado" pelo status:

  • BCB: o serviço BcBase/EntidadesSupervisionadas passou a devolver só o cabeçalho em toda competência testada (01/2025 a 08/2026), assim como a função irmã Cooperativas — enquanto os entity sets estáticos do mesmo serviço continuam com dado. Substituído pelo serviço Instituicoes_em_funcionamento, que traz 4 conjuntos (bancos e múltiplos, cooperativas, sociedades, consórcios) com ~1.750 instituições. Ganho colateral: a fonte nova publica CNPJ básico, que é exatamente a chave de junção com :Empresa da Receita.
  • CVM sancionadores: PAS/DADOS/pas.csv virou 404 — o diretório saiu do ar. Substituído por PROCESSO/SANCIONADOR/DADOS/processo_sancionador.zip, com dois CSVs e esquema novo.

O campo Tamanho mínimo (bytes) do componente de origem existe por causa dessa classe de falha: ele transforma "200 com corpo vazio" em "não publicado", em vez de deixar a carga gravar zero linha e terminar como sucesso — com a ressalva acima de que, no pacote do BCB, a chave gravada não é a que o componente lê.

Casamento probabilístico — nunca reprovação automática

Duas características da fonte condicionam o produto, e não são defeito:

  • O CPF vem mascarado no cadastro PEP (só os 6 dígitos centrais), no mesmo formato dos sócios da Receita. O nó guarda cpfParcial + nomeNormalizado; o casamento com uma Pessoa do dossiê é probabilístico, feito pelo cruzamento KYB com score exposto — nunca por esta carga.
  • A lista da ONU não traz documento nenhum. O screening é exclusivamente por nome e apelidos, no índice textual (abaixo). Homonímia internacional é esperada: o resultado é insumo com score para decisão humana, jamais aresta direta de sanção nem reprovação automática.

Índice de screening por nome

TODOS os fluxos gravam documento de screening no índice da sua origem: CEIS/CNEP/CEPIM/PEP/CSNU em datta_base-negativa e instituições BCB em datta_bcb (nomes configuráveis por BASE_NEGATIVA_INDEX e BCB_INDEX no seed). O documento é unificado entre os produtores — nome, nomeNormalizado, tipoRegistro (ENTIDADE/INDIVIDUO/INSTITUICAO), fonte e as chaves da origem em keyword — para que a busca não dependa do produtor que gravou (Diretrizes do Projeto §20). O próprio fluxo cria o índice com mappings explícitos (keyword para campos de filtro, text para nome/apelidos) antes do primeiro indexing — mapping criado depois do dado indexado produziria filtro com resultado parcial sem erro.

Este índice é textual (BM25/fuzzy por nome), sem vetor de embedding por decisão: screening de sanção casa grafias de nomes próprios, não semântica de texto corrido — não é busca semântica e não entra no fluxo de embeddings da plataforma (Diretrizes do Projeto §22 trata de corpo textual).

Registro dos fluxos (seed)

O mesmo seed das demais integrações — e, como elas, já roda no instalador: o setup-datta.sh registra estes sete fluxos na Fase 7B, pulando com aviso quando o contexto da Receita ainda não existe. Detalhes e os dois modos de execução manual em Fontes externas.

Para rodar avulso depois:

bash
DATTA_API_URL=http://<ip-do-gateway>:7070 \
DATTA_JWT=<accessToken> \
NEO4J_PASSWORD=<senha> \
./scripts/seed-extract-pipelines.sh

Idempotente por nome — edições feitas no designer nunca são sobrescritas, e rodar o instalador de novo não duplica fluxo. BASE_NEGATIVA_INDEX é opcional (default datta_base-negativa).

Instalação sem internet (air-gapped)

Igual às demais fontes: baixe o arquivo da origem numa máquina conectada, disponibilize no storage da plataforma e, em Extract › Pacotes, duplique o fluxo e abra a cópia no designer trocando o nó de origem de URL para Arquivo (FileSource) — para os zips do Portal, extraia o CSV antes (o FileSource não descompacta). Pause o fluxo original com URL.

Certidões do dossiê

A vigência das certidões extraídas do dossiê é avaliada offline, sem depender de internet: a data de validade é comparada com a data da análise e a certidão recebe uma situação — VALIDA, A_VENCER (dentro da janela de alerta), VENCIDA (com os dias de atraso) ou NAO_VERIFICAVEL. A situação chega pronta ao console, ao resumo de compliance e ao bloco de dados da triagem; o modelo não compara datas.

Certidão sem data legível é NAO_VERIFICAVEL, nunca vigente — a lacuna vira critério insuficiente, que é o comportamento correto.

A data da análise é o dia em America/Sao_Paulo, não o do relógio do servidor. Os contêineres da plataforma rodam em UTC; usar o relógio deles faria o dia virar às 21h de Brasília e uma certidão que vence hoje sair como vencida.

ConfiguraçãoVariávelPadrãoPara que serve
datta.kyb.certidoes.dias-alertaDATTA_KYB_CERTIDOES_DIAS_ALERTA30Janela em dias para marcar A_VENCER
datta.kyb.certidoes.online.enabledDATTA_KYB_CERTIDOES_ONLINE_ENABLEDfalseLiga a consulta ao órgão emissor
datta.kyb.certidoes.online.timeout-secondsDATTA_KYB_CERTIDOES_ONLINE_TIMEOUT30Tempo limite da consulta
datta.kyb.certidoes.online.verificadores.<tipo>URL do verificador por tipo de certidão, com {cnpj} e {numero}

A janela de alerta é de plataforma, não de serviço. A mesma janela é usada para montar o selo que o analista vê e o laudo que a triagem produz — janelas diferentes fariam a tela dizer "a vencer" e o laudo dizer "válida" para a mesma certidão. Por isso ela é definida uma única vez, em datta.kyb.certidoes.diasAlerta nos values do chart, que a publica para todos os serviços. Não configure a variável em um serviço só.

Os valores substituídos em {cnpj} e {numero} são codificados antes de compor a URL: o número da certidão vem do documento que o próprio requerente enviou, e sem a codificação ele poderia acrescentar parâmetros à consulta que a instituição faz.

A consulta online é opcional e vem desligada. Cada verificador é cadastrado como fonte do tipo web em Sistema › Conexões (com catalogação automática) e apontado aqui pelo tipo de certidão; a URL passa pela guarda anti-SSRF a cada chamada. Com a consulta desligada, sem verificador cadastrado, com URL recusada pela guarda ou com o órgão fora do ar, a certidão volta com a avaliação offline e um aviso acionável em português — nunca um erro técnico, e a triagem nunca cai por causa disso. Resposta do emissor sem situação reconhecida preserva a avaliação offline.

Limitações conhecidas (por decisão)

  • Certidão de débitos federais: a consulta pública tem captcha; o resultado no dossiê é "não verificável" — decisão final, não pendência técnica. Contornar captcha está fora de cogitação. O tipo debitos_federais não consulta o emissor nem quando há verificador configurado.
  • Junta Comercial: não há dado aberto nacional unificado; a validação é documental (chancela e número de registro na ata).
  • Nenhum verificador público acompanha a plataforma: a lista de verificadores nasce vazia por decisão — cada instituição aponta o serviço que tem contrato para consultar.

Solução de problemas

SintomaCausa provávelAção
Os sete fluxos não aparecem em Extract › PacotesFase 7B do setup-datta.sh não rodou ou perfil sem PIPELINE_VIEWRodar scripts/seed-extract-pipelines.sh; conferir a permissão em RBAC
"nenhuma publicacao encontrada nas datas tentadas"Portal fora do ar ou defasagem maior que a tolerânciaAumentar Tolerância de defasagem no nó de origem; conferir o portal
Sanção não aparece no cruzamento KYB de um CNPJSancao.cnpjBasico vazio (sancionado PF) ou dossiê consultando o banco erradoEsperado para PF; para PJ, conferir os dataSources por role do contexto FEBRABAN
"o zip contem varias entradas candidatas"Layout do pacote mudou na origemRefinar o campo Arquivo dentro do zip no nó de origem
"nenhum elemento <...> encontrado no XML"Estrutura do XML da ONU mudouAjustar o Elemento de registro no nó de origem
Índice de screening com busca parcialÍndice criado sem mappings (fora do fluxo)Apagar o índice vazio e reexecutar o fluxo (ele cria com mappings)