feat: unified fiscal coverage - PIS/COFINS applicability + conditional RTC in one definition, one queue, one panel

- central/app/unified_fiscal_coverage.py: pure rules (PIS/COFINS NOT_APPLICABLE/REQUIRED/OPTIONAL/NEEDS_REVIEW, RTC only when the ERP switch is on)
- agent: read-only loader (unified_fiscal.py) replaces the legacy/expanded module; findings feed the single operational state, coverage and blocker queue
- hub: BLOCKED_FISCAL_DATA blockers (PIS/COFINS/RTC) share the queue; stale ones close on the next full pass; dashboard breakdown gains CEST/PIS/COFINS/RTC
- panel: legacy/expanded coverage block removed; discreet 'Reforma Tributaria: Ativa/Desativada'
- docs: unified_fiscal_completeness, pis_cofins_applicability, rtc_pis_cofins_model + official source manifests; read-only E2E script

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
gti
2026-09-24 16:39:53 -03:00
co-authored by Claude Sonnet 5
parent d897cceebb
commit b15dbea213
32 changed files with 3979 additions and 517 deletions
+30 -48
View File
@@ -1,60 +1,42 @@
# Modelo RTC + PIS/COFINS no SGV (evidência: TESTESOFICIAIS.FDB)
# Reforma Tributária (RTC) no cadastro de produto — modelo condicional
Tudo abaixo é observação read-only. Nenhum valor é preenchido, nenhum write é habilitado (`FIREBIRD_WRITES=0`).
Código: `agent/src/gti_fiscal_agent/rtc_pis_cofins.py` (capabilities, validadores, aplicabilidade, cobertura ampliada),
integrado ao job de sync do Agent (`expanded_scope` no `result_summary`) e exibido no detalhe do Agent.
Substitui o modelo anterior de "escopo ampliado". Não existe segundo escopo, segundo painel ou segunda fila: RTC é **uma condição** da definição única de completude (`docs/unified_fiscal_completeness.md`).
## 1. Modelo real do RTC
## Regra definitiva
`RTC_ENABLED = PARAMETROS.USAR_REFORMA_TRIBUTARIA truthy (1/S/T/TRUE) E o schema comporta RTC`
(`C000025.CCLASSTRIB`, `RTC_CCLASSTRIB(CCLASSTRIB, CSTIBSCBS)`, `RTC_CST(CSTIBSCBS)`).
`C000025.CCLASSTRIB` (VARCHAR(6)) → `RTC_CCLASSTRIB.CCLASSTRIB` (CHAR(6), PK) → `RTC_CCLASSTRIB.CSTIBSCBS` (CHAR(3)) → `RTC_CST.CSTIBSCBS` (CHAR(3), PK).
- `RTC_ENABLED=false` (parâmetro 0, nulo, ausente ou schema antigo): `CCLASSTRIB` e CST IBS/CBS **não entram** na completude; nenhum blocker RTC; o painel só mostra "Reforma Tributária: Desativada".
- `RTC_ENABLED=true`: RTC passa a ser obrigatório para todo produto.
- **Há FK física** nos dois elos: `FK_C000025_CCLASSTRIB` (RESTRICT/RESTRICT) e `FK_RTC_CCLASSTRIB_CST`.
- Catálogo local: 145 cClassTrib (6 dígitos, únicos, 0 duplicados, 0 órfãos) para 18 CST IBS/CBS (3 dígitos); nenhum registro com `FIM_VIGENCIA`; `INICIO_VIGENCIA` de 2025-05-05 a 2025-11-19. Cada CST tem ao menos um cClassTrib.
- Atributos do catálogo (não são valores do produto): `TIPO_ALIQUOTA`, `PRED_IBS`/`PRED_CBS` (redução), `IND_TRIB_REGULAR`, `IND_CREDPRES_OPER`, `IND_ESTORNO_CRED`, monofasia, `IND_NFE/NFCE/...` (documentos aplicáveis), `ANEXO`, `LINK`. `RTC_CST` descreve o CST (`IND_IBSCBS`, `IND_REDBC`, `IND_REDALIQ`, `IND_DIF`, `IND_CREDPRES_IBSZFM`...).
- **Não existem no produto**: CST IBS/CBS, alíquotas IBS/CBS, cCredPres. O CST IBS/CBS só se obtém **do catálogo, a partir do cClassTrib informado**.
- `PARAMETROS.USAR_REFORMA_TRIBUTARIA = 0`: o ERP não usa RTC neste banco. Documentos (`C000062`, `C000032`, `C000088`, `NFCE_ITENS`) não têm campos RTC.
- `LOCAL_CATALOG_ONLY=true`: comparamos apenas com o catálogo do próprio banco. Não há dataset oficial integrado; o ponto de extensão é `catalog` em `expanded_scope_summary`/`validate_cclasstrib`.
Não há estado "desconhecido": um parâmetro ilegível conta como não habilitado pelo ERP (fail-closed para *escopo*, sem inflar cobertura porque o campo não é exigido).
## 2. PIS/COFINS no produto (`C000025`)
## Validação com RTC ativa
`C000025.CCLASSTRIB → RTC_CCLASSTRIB.CSTIBSCBS → RTC_CST` (o CST IBS/CBS **não** é coluna do produto; é derivado pela relação).
| Campo | Tipo | Semântica observada |
|---|---|---|
| `COD_ENTRADA_PIS` / `COD_ENTRADA_COFINS` | VARCHAR(3) | CST de entrada (ex.: `73`); 2/521 preenchidos |
| `COD_SAIDA_PIS` / `COD_SAIDA_COFINS` | VARCHAR(3) | CST de saída (ex.: `01`, `04`); 3/521 |
| `ALIQ_PIS` / `ALIQ_COFINS` | VARCHAR(8) | percentual **textual** com vírgula (`0,65`, `3`); 2 não vazios |
| `PISCOFINS` | VARCHAR(1) | flag S/N (N=519, S=2) |
| `INCIDENCIA_PISCOFINS` | VARCHAR(30) | regime adicional: NENHUMA=519, MONOFÁSICA=1, SUBST.TRIBUTÁRIA=1 (coerente com o flag) |
| Blocker (PT-BR) | Condição |
|---|---|
| `CCLASSTRIB_MISSING` cClassTrib ausente | vazio |
| `CCLASSTRIB_INVALID_FORMAT` cClassTrib com formato inválido | não tem exatamente 6 dígitos |
| `CCLASSTRIB_NOT_IN_CATALOG` cClassTrib fora do catálogo local | inexistente em `RTC_CCLASSTRIB`, ou fora da vigência (`INICIO_VIGENCIA` futura / `FIM_VIGENCIA` passada — colunas do próprio catálogo) |
| `RTC_CST_MISSING` CST IBS/CBS ausente no catálogo | a classe não aponta CST ou o CST não existe em `RTC_CST` |
| `RTC_CATALOG_INVALID` Catálogo RTC local inválido | catálogo com órfãos, duplicatas ou formatos inválidos (todo produto, enquanto RTC ativa) |
- CST oficial PIS/COFINS tem 2 dígitos; um produto traz `2` em todos os campos (formato inválido, aparenta dado de teste) e é o único com flag inconsistente (`N` com códigos).
- Não existe catálogo PIS/COFINS no SGV (nenhuma tabela com PIS/COFINS/CST no nome além de `RTC_CST`). Os códigos são texto livre.
- **Produto × documento.** `C000062` (itens de saída) grava `COD_*_PIS/COFINS` e alíquotas por item (7 de 693 com `20`/`41`/`12`); `NFCE_ITENS.CST_PIS_COFINS` tem `01` em 3.336 itens, inclusive de produtos com `INCIDENCIA=NENHUMA` e sem código no produto. Conclusão: o documento **não** depende do cadastro do produto para o CST. `PRODUCT_DEFAULT_MODEL` = campos esparsos em `C000025` (2–3 produtos); `DOCUMENT_ITEM_MODEL` = campos por item; `CANONICAL_SOURCE_FOR_PRODUCT_DEFAULT` = `C000025` somente onde preenchido, sem fonte canônica para os demais.
Integridade do catálogo: sem órfãos (classe → CST inexistente), sem duplicatas, classes com 6 dígitos, CST com 3 dígitos. TESTESOFICIAIS: 145 classes, 18 CSTs, 0 órfãos, 0 duplicatas.
## 3. Aplicabilidade (conservadora)
## O que NÃO é validado
O schema do produto não modela alíquota IBS/CBS, valor IBS/CBS nem `cCredPres`. Não existem blockers desses campos e nenhum write target foi inventado. A validação do produto reflete só o que o SGV guarda como default: `CCLASSTRIB`.
Quatro coisas separadas: SCHEMA_SUPPORT, DATA_PRESENT, APPLICABILITY, MANDATORYNESS. Só a última bloqueia, e só com aplicabilidade provada por dado local.
## Fontes (ACCESSED_AT 2026-09-24)
- NT 2025.002-RTC v1.51, Portal Nacional da NF-e (publicada 04/08/2026): campos IBS/CBS (grupo UB) obrigatórios em 2026; para emitentes CRT 1/2/4 as orientações "serão publicadas em NT futura" porque a tributação IBS/CBS/IS desses contribuintes ocorre a partir de 2027 (art. 348 da LC 214/2025).
- LC 214/2025 (Planalto, compilada): art. 348 (2026: IBS/CBS compensados com PIS/Cofins; alíquotas de teste).
- Catálogo local do ERP (`RTC_CCLASSTRIB`/`RTC_CST`, `PUBLICACAO`/`INICIO_VIGENCIA`) e cClassTrib oficial no Hub (`cClassTrib 2026-06-22.xlsx`).
- `PARAMETROS.USAR_REFORMA_TRIBUTARIA`: parâmetro do próprio SGV (executável 5.1.0.4 o lê; o 5.0.6.124 não tem RTC).
- **RTC**: `NOT_SUPPORTED` (schema sem o modelo) · `NOT_ENABLED_BY_ERP` (parâmetro do ERP = 0; não bloqueia nem conta como desconhecido) · `UNKNOWN_APPLICABILITY` (parâmetro ilegível) · `APPLICABLE` (parâmetro = 1 e modelo existe → cClassTrib passa a ser exigido/validado).
- **PIS/COFINS**: `APPLICABLE` só quando o próprio produto traz evidência (algum código/alíquota, `PISCOFINS='S'` ou incidência especial). Produto vazio com `N`/`NENHUMA` é `UNKNOWN_APPLICABILITY`: não é completo nem bloqueado.
Nota fiscal vs. regra do produto: para CRT 1 a legislação só exige IBS/CBS no documento a partir de 2027; a regra deste motor segue o **interruptor do ERP** — quando o cliente liga a reforma no SGV, o cadastro passa a ser cobrado.
## 4. Validadores (determinísticos, sem preenchimento)
## Achado de corpus (somente leitura)
A cópia local `TESTESOFICIAIS.FDB` tem `USAR_REFORMA_TRIBUTARIA=1` e 0 produtos com `CCLASSTRIB`, enquanto o piloto confirmado pelo operador tem `0`. Nada foi alterado no arquivo; o resultado do piloto é reproduzido por simulação pura (`RTC_ENABLED=false`, `scripts/unified_coverage_e2e.py`).
- cClassTrib: `EMPTY`, `INVALID_FORMAT` (≠ 6 dígitos), `NOT_IN_LOCAL_CATALOG`, `VALID_LOCAL`, `CST_MISSING`, `VALID_WITH_CST`.
- CST PIS/COFINS: `EMPTY`, `VALID`, `INVALID_FORMAT` (fora do conjunto oficial 01–09, 49, 50–56, 60–67, 70–75, 98, 99). Alíquota: `EMPTY`, `VALID` (0–100, vírgula ou ponto), `INVALID_RATE`. Flag: `CONSISTENT`/`INCONSISTENT`/`EMPTY`.
- Blockers específicos (rótulos PT-BR no painel): `CCLASSTRIB_MISSING/INVALID/NOT_IN_CATALOG`, `RTC_CST_INVALID`, `PIS|COFINS_CST_MISSING/INVALID`, `PIS|COFINS_RATE_INVALID`, `PIS_COFINS_FLAG_INCONSISTENT`. Eles ficam em `expanded_scope.blockers_by_type`, **separados** dos blockers legados (não alteram o invariante 495+26+0=521 do escopo anterior).
## 5. Cobertura: legado × ampliada
`legacy_scope` (LEGACY_SCOPE_COVERAGE) é preservado sem alteração. `expanded_scope` (EXPANDED_FISCAL_SCOPE_COVERAGE) só **acrescenta** condições: bloqueado/falha legado continua assim; completo legado vira completo ampliado, bloqueado (blocker específico) ou `unknown_applicability`. Invariante: soma = total.
Resultado no TESTESOFICIAIS (521 produtos): legado 495 completos / 26 bloqueados / 0 falhas; ampliado 2 completos / 27 bloqueados / 0 falhas / 492 com aplicabilidade desconhecida; blockers novos: `PIS_CST_INVALID` 2, `COFINS_CST_INVALID` 2, `PIS_COFINS_FLAG_INCONSISTENT` 1 (mesmo produto). Os 492 desconhecidos **não** são defeitos: faltam evidências para dizer se o cadastro do produto deve trazer CST de PIS/COFINS.
## 6. Limitações
- Sem catálogo oficial RTC nem regra tributária: nenhuma correspondência é inventada.
- A aplicabilidade de PIS/COFINS por regime (CRT 1 aqui) não está determinada por dado local confiável.
- Vigência do cClassTrib não é usada como bloqueio (o catálogo local não tem `FIM_VIGENCIA`).
## 7. Campos candidatos a write futuro (NÃO autorizado)
`CANDIDATE`, sem write habilitado e sem autorização: `C000025.CCLASSTRIB`, `COD_ENTRADA_PIS`, `COD_SAIDA_PIS`, `ALIQ_PIS`, `COD_ENTRADA_COFINS`, `COD_SAIDA_COFINS`, `ALIQ_COFINS`.
Não devem ser escritos: `RTC_CCLASSTRIB`, `RTC_CST` (catálogos), `PARAMETROS.USAR_REFORMA_TRIBUTARIA`, `PISCOFINS`/`INCIDENCIA_PISCOFINS` sem evidência de regime, campos de documentos fiscais, e qualquer CST IBS/CBS "inventado" no produto.
## Testes
RTC off/on, `CCLASSTRIB` vazio/válido/inválido/órfão/expirado, catálogo inválido: `central/tests/test_unified_fiscal_coverage.py`, `agent/tests/test_unified_fiscal.py`.