Pular para conteúdo

Investigação — períodos do Simples Nacional com até 30 dias

  • Data de consolidação: 2026-07-29
  • Status: concluída sem causa histórica comprovada
  • Escopo: PeriodoSN_Novo.qvdT_PeriodoSN_Novo.qvdT1_Simples_Nacional.qvd
  • Decisão atual: manter o filtro de duração maior que 30 dias

Resumo executivo

A investigação começou após a identificação de divergências grandes em casos observados em junho. Os casos examinados posteriormente estavam corrigidos, e não foi possível associar as divergências a uma execução, versão de script ou arquivo-fonte histórico específico.

O ETL atual está coerente com a lógica implementada:

  1. lê os arquivos mais recentes de MEI e Simples;
  2. grava o universo bruto em PeriodoSN_Novo.qvd;
  3. elimina cancelados e períodos com duração de até 30 dias;
  4. consolida períodos contínuos em T_PeriodoSN_Novo.qvd;
  5. restringe o resultado ao universo de empresas da NFSE ao criar T1_Simples_Nacional.qvd;
  6. expande os períodos para a granularidade mensal.

Foram encontrados períodos curtos que parecem representar eventos reais, além dos casos relacionados a cancelamentos ou exclusões. Portanto, “período curto” não é sinônimo de erro de origem. A manutenção do filtro é uma decisão de negócio compatível com o uso mensal atual, com a perda conhecida de eventos intramês.

A hipótese de uma task ou fonte gravada parcialmente continua plausível para explicar a anomalia histórica, mas não foi comprovada. Os controles atuais validam a gravação física do QVD, porém não demonstram que a fonte recebida estava completa.

Escopo e limitações

Esta investigação usou:

  • o lineage atual;
  • os scripts-espelho atuais de E_Simples_Nacional e T1_Simples_Nacional;
  • estatísticas agregadas e amostras pseudonimizadas disponibilizadas pelo Guardião;
  • comparação conceitual do resultado com e sem o filtro de 30 dias.

Não foram usados CNPJ, CPF, razão social ou outros identificadores diretos neste documento. Dez casos com duração entre 1 e 29 dias e datas inicial e final diferentes foram disponibilizados por tickets privados durante a investigação; as identidades não são preservadas aqui.

Não estavam disponíveis, de forma vinculada aos casos de junho:

  • identificador e horário da task;
  • versão exata do script executado;
  • nomes e tamanhos dos TXT consumidos;
  • contagens de entrada e saída daquela execução;
  • estado histórico dos QVDs antes e depois do reload.

Por isso, este documento não atribui causa raiz à ocorrência histórica.

Uma tentativa de recalcular as estatísticas agregadas em 2026-07-29 excedeu o limite operacional de 600 segundos do Guardião. Os percentuais observados durante a investigação não foram transcritos de memória. Eles devem ser reexecutados antes de qualquer citação quantitativa futura.

Encadeamento confirmado

PERSIMEI-*.txt ─┐
                ├─> PeriodoSN_Novo.qvd
PERSIMPLES-*.txt┘          │
                           ├─ remove Cancelado? <> 'N'
                           ├─ remove duração <= 30 dias
                           └─ consolida continuidade
                                      │
                                      ▼
                           T_PeriodoSN_Novo.qvd
                                      │
                                      ├─ filtra pelo universo de
                                      │  T2_Empresas_NFSE.qvd
                                      └─ expande para ano-mês
                                      │
                                      ▼
                           T1_Simples_Nacional.qvd

1. Seleção das fontes

E_Simples_Nacional.qvs percorre PERSIMEI-*.txt e PERSIMPLES-*.txt, escolhe o maior nome de arquivo com MaxString() e carrega o arquivo selecionado. Isso confirma a preferência pelo arquivo mais recente segundo o nome, mas não valida a completude interna do TXT.

Evidência: E_Simples_Nacional.qvs, linhas 120–178.

2. Primeiro QVD com os períodos completos

As duas fontes são concatenadas na tabela Dados por LOAD DISTINCT, com raiz do CNPJ, datas, indicador de cancelamento, opção e origem (Simei ou Sn). A tabela é gravada como PeriodoSN_Novo.qvd.

Não existe filtro pelo universo municipal ou pela base NFSE nessa etapa. DISTINCT elimina linhas exatamente repetidas; ele não restringe quais contribuintes pertencem ao universo final.

Evidência: E_Simples_Nacional.qvs, linhas 137–192.

O nome PeriodoSN.qvd, visto em um script isolado durante a investigação, não aparece no lineage nem nos scripts atuais do repositório. Seu papel histórico não pode ser determinado com o material atual. O QVD rastreável no fluxo vigente é PeriodoSN_Novo.qvd.

3. Filtros do transformador

O transformador relê PeriodoSN_Novo.qvd e:

  • converte as datas textuais;
  • representa Data_Fim = '00000000' como vigente até Today() para calcular a duração;
  • mantém apenas Cancelado? = 'N';
  • marca como Mantem = 1 somente quando a chave do período difere da linha anterior e Dat_Fim - Dat_Inicio > 30;
  • elimina os demais registros por INNER JOIN com o valor Mantem = 1.

Consequentemente, a regra exclui 30 dias ou menos, e não apenas períodos menores que 30 dias. A comparação com a linha anterior também elimina uma das ocorrências quando a mesma raiz, início e fim se repetem entre as origens.

Evidência: E_Simples_Nacional.qvs, linhas 210–247.

Depois do filtro, o script calcula intervalos por contribuinte e regime e consolida sequências contínuas antes de montar a tabela Fim.

Evidência: E_Simples_Nacional.qvs, linhas 249–303.

4. Filtro de universo e granularidade mensal

O universo de contribuintes é carregado de T2_Empresas_NFSE.qvd. A leitura de T_PeriodoSN_Novo.qvd usa Where Exists() com uma chave de raiz normalizada para oito dígitos. Somente então o fluxo é restringido ao universo NFSE.

Na mesma etapa, um While cria cada mês compreendido entre Dt_Inicio e Dt_Fim, produzindo T1_Simples_Nacional.qvd.

Evidência: T1_Simples_Nacional.qvs, linhas 27–76.

Achados sobre períodos curtos

As verificações agregadas e a amostra privada sustentaram os seguintes achados qualitativos:

  • há grande concentração de períodos curtos associada a cancelamentos ou exclusões;
  • também existem períodos não cancelados, encerrados entre 1 e 29 dias, com Data_Inicio <> Data_Fim;
  • alguns desses períodos parecem eventos reais, e não simples duplicidades;
  • períodos com Data_Inicio = Data_Fim formam um grupo diferente dos períodos curtos com datas distintas e não devem ser tratados como equivalentes;
  • o filtro atual descarta ambos quando a duração não supera 30 dias.

Os dez exemplos usados na avaliação foram deliberadamente mantidos fora do repositório. A documentação registra o padrão observado, não a identidade dos contribuintes.

Efeito de retirar o filtro

Na tabela intermediária, retirar Dat_Fim - Dat_Inicio > 30 necessariamente mantém mais registros não cancelados.

No resultado consolidado, o efeito sobre a quantidade de linhas não é necessariamente um aumento da mesma magnitude. Um período curto pode preencher o intervalo entre dois períodos e fazer com que a lógica de continuidade os consolide em uma única linha. Assim:

  • as linhas antes da consolidação aumentam;
  • contribuintes que só tinham períodos curtos podem reaparecer;
  • a quantidade final de contribuintes pode permanecer igual ou aumentar;
  • a quantidade final de períodos pode aumentar, permanecer igual ou até diminuir por causa das fusões de continuidade.

O impacto final também é reduzido posteriormente pelo Where Exists() do universo NFSE. Portanto, o crescimento de PeriodoSN_Novo.qvd não pode ser projetado diretamente sobre T1_Simples_Nacional.qvd.

Hipóteses avaliadas

Hipótese Situação Fundamentação
O primeiro QVD já aplica o universo de contribuintes Descartada PeriodoSN_Novo.qvd é gravado antes do Where Exists()
Todo período curto é erro Descartada A amostra encontrou períodos curtos não cancelados e com datas distintas
A regra elimina somente períodos menores que 30 dias Descartada A condição é > 30; logo, 30 dias também são eliminados
Retirar o filtro sempre aumenta as linhas finais Descartada A continuidade pode fundir períodos antes separados
A regra dos 30 dias explica sozinha as divergências grandes de junho Não demonstrada Ela explica exclusões específicas, mas os casos atuais estavam corrigidos
Uma task ou fonte foi gravada parcialmente Plausível, não comprovada Faltam metadados históricos da execução e dos arquivos consumidos
O QVD foi gravado fisicamente pela metade no fluxo atual Menos provável Store_T_Retry compara as linhas gravadas com a tabela em memória
A entrada já chegou incompleta à tabela em memória Continua possível A validação de gravação não mede a completude esperada da fonte
O filtro de universo descartou quase todo o dataset por diferença de formato Defeito histórico confirmado, hoje corrigido O próprio script registra a normalização implantada em 2026-04-01

Controles atuais relevantes

Desde o ajuste documentado no script em 2025-12-22, a gravação final usa Store_T_Retry. A SUB:

  • rejeita tabela em memória vazia;
  • tenta novamente em caso de falha;
  • verifica mudança de FileTime e FileSize;
  • exige que QvdNoOfRecords(QVD) seja igual a NoOfRows(tabela);
  • só descarta a tabela em memória depois da confirmação.

Evidências:

Esse controle protege a consistência da gravação. Ele não detecta uma fonte TXT que já tenha chegado incompleta, porque nesse caso o QVD pode ser uma cópia perfeita de uma tabela em memória incompleta.

Há também um defeito histórico confirmado no filtro de universo: T2_Empresas_NFSE.qvd fornecia a raiz formatada como texto com máscara, enquanto T_PeriodoSN_Novo.qvd usava oito dígitos sem máscara. O comentário do script informa que a comparação exata do Exists() descartava quase todo o dataset. A correção de 2026-04-01 normalizou as duas chaves como texto de oito dígitos.

Evidência: T1_Simples_Nacional.qvs, linhas 15–30 e 59–70.

Não há evidência suficiente para ligar esse defeito aos casos específicos de junho, mas ele deve permanecer no histórico porque produziu o mesmo tipo geral de sintoma: desaparecimento de grande parte do universo.

Decisão

Foi decidido manter a regra Dat_Fim - Dat_Inicio > 30.

Justificativa:

  • os sistemas consumidores trabalham em granularidade mínima mensal;
  • a regra reduz eventos muito curtos, em grande parte relacionados a cancelamentos ou exclusões;
  • os casos grandes examinados já se encontravam corrigidos;
  • retirar a regra alteraria a consolidação de continuidade e exigiria nova definição de negócio para meses com mudança intramês.

Trade-off aceito:

  • períodos legítimos de até 30 dias deixam de representar o contribuinte na dimensão mensal.

A decisão pressupõe que a dimensão representa um regime mensal estável. Se a pergunta de negócio passar a ser “o contribuinte esteve no Simples em qualquer dia do mês?”, a regra deverá ser reavaliada, porque nesse conceito um período legítimo de poucos dias precisa contar.

Lacuna de observabilidade

Para confirmar ou descartar uma gravação parcial em uma ocorrência futura, devem ser preservados, por execução:

  • identificador da task e horários de início e fim;
  • resultado final do reload;
  • commit ou versão do script;
  • nome, tamanho e data dos TXT selecionados;
  • linhas carregadas por origem;
  • linhas antes e depois de cada filtro;
  • FileTime, FileSize e QvdNoOfRecords antes e depois do STORE;
  • contagem de contribuintes e períodos nos QVDs críticos.

Esses metadados devem ser agregados e não conter identificadores de contribuintes. Sem essa trilha, uma carga parcial histórica continuará sendo uma hipótese, mesmo que o estado atual esteja correto.

Conclusão

O encadeamento e as regras atuais do ETL do Simples Nacional foram compreendidos e não apresentaram uma inconsistência capaz de explicar, por si só, os erros grandes observados em junho.

O filtro de duração possui impacto real e também elimina alguns períodos legítimos, mas sua manutenção foi aceita como convenção para a dimensão mensal. A causa histórica permanece indeterminada. As explicações mais plausíveis que restam são uma execução/fonte incompleta ou um defeito já corrigido, sem evidência preservada que permita escolher entre elas.