feat: deterministic cClassTrib resolver + gated CCLASSTRIB auto-apply (default OFF), RTC panel summary; 1.1.9
- resolver (rules RTC-R0..R4/A1..A3/G1..G2) over the official cClassTrib table 2026-06-22 and LC 214/2025 annexes; local vs official catalog comparison - ONE root-cause RTC blocker per product (missing/unresolved/ambiguous/conflict/official mismatch/catalog outdated/evidence missing) - auto-apply: C000025.CCLASSTRIB only, three switches (FIREBIRD_WRITES + RTC_AUTO_APPLY_ENABLED + Hub authorization), per-product re-read and re-decision, never overwrites, rowcount 1, audit table rtc_write_audits (migration 0027) - copy-only write E2E (280/280 applied, only CCLASSTRIB changed, 2nd run 0 writes, stale decision 0 writes); real databases untouched - docs: cclasstrib_resolution, rtc_auto_apply, unified_fiscal_completeness Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
# Determinação segura do cClassTrib (resolver determinístico)
|
||||
|
||||
`central/app/cclasstrib_resolver.py` (puro, sem Firebird, sem rede, sem probabilidade) + `central/app/rtc_reference_data.py` (gerado por `scripts/build_rtc_reference_data.py`, com hash).
|
||||
`ACCESSED_AT`: **2026-09-24/25**. Nada aqui é chute: uma classe só é proposta quando uma regra **explícita**, ancorada nos textos oficiais, a prova.
|
||||
|
||||
## Fontes oficiais (SOURCE / DOCUMENT / VERSION / PUBLICATION / SHA256)
|
||||
| Fonte | Documento | Versão / publicação | SHA256 |
|
||||
|---|---|---|---|
|
||||
| Portal Nacional NF-e (ENCAT) | Tabela **cClassTrib** (164 classes, 18 CST) — `cClassTrib 2026-06-22.xlsx` | publicada 22/06/2026; no repo em `sources/raw/bootstrap_v1/` e no Hub (dataset `RTC_CCLASSTRIB` ACTIVE) | `1448cb63a41bdb67…` |
|
||||
| Planalto (cópia do Internet Archive; planalto.gov.br recusa conexão direta) | **LC 214/2025 compilada** (com LC 227/2026: Anexo XIV revogado) — arts. 125–152 (reduções), 172 (combustíveis), 348 (2026); Anexos I–XV | acessado 2026-09-24 | `5c7d59b3c49e5b7c…` |
|
||||
| Portal Nacional NF-e | **NT 2025.002-RTC v1.51** (04/08/2026) — para CRT 1/2/4 as orientações de IBS/CBS "serão publicadas em NT futura"; tributação a partir de 2027 (LC 214 art. 348) | `https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=AKD/muSmiIY=` | ver `docs/sources/SOURCES_MANIFEST_UNIFIED_FISCAL_V1.json` |
|
||||
| SGV 5.1.0.4 (executável) | tela de produto: `cClassTrib` = `TRzDBButtonEdit` `DataField=CCLASSTRIB`; consulta `select * from RTC_CCLASSTRIB where … (IND_NFE=1 or IND_NFCE=1 or IND_CTE=1)`; junção do documento `C000025.CCLASSTRIB → RTC_CCLASSTRIB → RTC_CST` | binário local | — |
|
||||
|
||||
O portal NF-e foi rastreado (Documentos, Diversos, Atos): não expõe tabela cClassTrib mais nova que 22/06/2026. Não há endpoint oficial NCM→cClassTrib: o vínculo vem dos **Anexos da LC 214** (listas de NCM) + tabela oficial.
|
||||
|
||||
## O que o SGV faz (item 5) — DOCUMENT_CCLASSTRIB_SOURCE
|
||||
O SGV **não tem** regra produto→cClassTrib: o operador escolhe a classe pelo botão de busca (filtrada por `IND_NFE/IND_NFCE/IND_CTE=1`) e o documento usa `C000025.CCLASSTRIB` diretamente, juntando ao catálogo local e ao CST. Nenhuma trigger/procedure referencia RTC; `USAR_REFORMA_TRIBUTARIA` só liga/desliga. Consequência: qualquer resolução automática é regra **nossa**, portanto tem de ser provada e auditável. A classe proposta tem de passar no mesmo filtro do SGV (usável em NF-e/NFC-e).
|
||||
|
||||
## Catálogo local × oficial (item 4) — RTC_LOCAL_OFFICIAL_COMPATIBILITY
|
||||
Comparação por código (CST, reduções IBS/CBS, indicadores NF-e/NFC-e, vigência): `MATCH | LOCAL_ONLY | OFFICIAL_ONLY | MISMATCH | EXPIRED`. Nada é escrito no catálogo local.
|
||||
|
||||
| | TESTESOFICIAIS (= todos os bancos com RTC, mesmo catálogo) |
|
||||
|---|---|
|
||||
| MATCH | 131 |
|
||||
| OFFICIAL_ONLY (local desatualizado) | 19 (`000005, 200053, 200054, 221002-4, 400002, 410032-7, 550022-5, 620007, 820009`) |
|
||||
| MISMATCH | 11 — só `DOCUMENT_FLAGS` (IND_NFE/IND_NFCE): `200001, 200044, 410027, 410028, 410031, 550002, 620001-5` |
|
||||
| EXPIRED presentes no local | 3 (`220001-3`, fim 01/01/2026) |
|
||||
| LOCAL_ONLY | 0 |
|
||||
|
||||
Conclusão: **LOCAL_CATALOG_HAS_ENOUGH_METADATA_TO_RESOLVE = false**. O catálogo local (33 colunas: CST, tipo de alíquota, reduções, indicadores de documento, monofasia, `ANEXO`, `LINK`) descreve *a classe*, não contém NCM nem critério de produto: só o `ANEXO` liga classe a anexo. A determinação usa o catálogo local **para validar** e os Anexos da LC 214 **para decidir**. Incompatibilidade material ⇒ só a classe afetada é bloqueada (`RTC_LOCAL_CATALOG_OUTDATED` / `CCLASSTRIB_OFFICIAL_MISMATCH`); as classes que as regras usam (`000001, 200003, 200014, 200034, 200035`) são `MATCH`.
|
||||
|
||||
## Modelo de resolução e regras
|
||||
Premissa documentada: **venda ordinária no mercado interno** (default de produto). Classes que dependem do adquirente/operação (órgão público, exportação, ZFM/ALC, crédito presumido, diferimento…) não cabem num default de produto ⇒ `AMBIGUOUS`.
|
||||
|
||||
| Regra | Condição | Status |
|
||||
|---|---|---|
|
||||
| RTC-R0 | RTC desligada no ERP | `NOT_APPLICABLE` |
|
||||
| RTC-G1 | catálogo RTC local com falha de integridade | `INSUFFICIENT_EVIDENCE` |
|
||||
| RTC-R1 | Simples (CRT 1/2/4) ou regime desconhecido | `INSUFFICIENT_EVIDENCE` (NT 2025.002: orientação pendente) |
|
||||
| RTC-R2 | NCM sem confirmação de 8 dígitos válidos | `INSUFFICIENT_EVIDENCE` |
|
||||
| RTC-A1 | NCM em anexo revogado, em anexo sem classe-padrão única (IV, V, VI, IX, X, XI, XII, XIII…) ou sob texto condicional ("exceto", "em conformidade com…", "ressalvados…") | `AMBIGUOUS` |
|
||||
| RTC-A2 | NCM listado em mais de um anexo | `AMBIGUOUS` |
|
||||
| RTC-A3 | capítulos 01–14, 27, 30, 49, 71, 87, 88, 89, 90 e posições 9619, 2207, 3826, 8703: regime definido pela natureza/operação do bem | `AMBIGUOUS` |
|
||||
| RTC-R3 | NCM em **exatamente um** anexo com classe-padrão única (I→`200003`, VII→`200034`, VIII→`200035`, XV→`200014`) e item sem condição | `RESOLVED_WITH_EXPLICIT_RULE` |
|
||||
| RTC-R4 | NCM em **nenhum** anexo e fora dos capítulos acima ⇒ tributação integral (regra geral, LC 214 art. 4) | `RESOLVED_WITH_EXPLICIT_RULE` → `000001` |
|
||||
| RTC-G2 | classe proposta ausente/diferente no catálogo local, fora de vigência ou inutilizável em NF-e/NFC-e | `INSUFFICIENT_EVIDENCE` |
|
||||
|
||||
`RESOLVED_DETERMINISTIC` (regra sem premissa de operação) não é usado: toda resolução carrega a premissa "venda ordinária" e por isso é `RESOLVED_WITH_EXPLICIT_RULE`.
|
||||
Saída auditável: `status, resolved_cclasstrib, resolved_cst_ibscbs, reason, rule_id, confidence_type` (`ANNEX_TEXT_MATCH` | `EXCLUSION_OF_ALL_SPECIAL_REGIMES`; sem score), `inputs_used`, `evidence` (item do anexo, prefixo, texto), `source_references` (sha256).
|
||||
O anexo é lido do texto oficial por `scripts/build_rtc_reference_data.py` (item a item; `clean=False` quando há condição). `verify_annex_class_map()` prova contra a tabela oficial que cada classe-padrão existe, é a única classe do anexo usável em NF-e/NFC-e e tem o `ANEXO` esperado (o Anexo IX ficou de fora: a classe `515001` é irmã).
|
||||
|
||||
## Blockers RTC (uma causa raiz, um blocker por produto)
|
||||
`CCLASSTRIB_MISSING` (com `READY_TO_APPLY:<classe>:<regra>` quando a regra prova a classe) · `CCLASSTRIB_MISSING_UNRESOLVED` (cClassTrib não determinado) · `CCLASSTRIB_AMBIGUOUS` (cClassTrib ambíguo) · `RTC_RULE_EVIDENCE_MISSING` (evidência fiscal insuficiente) · `RTC_LOCAL_CATALOG_OUTDATED` (catálogo RTC local incompatível) · `CCLASSTRIB_OFFICIAL_MISMATCH` (classe existente diverge do oficial) · `CCLASSTRIB_CONFLICT` (valor existente ≠ regra determinística) + os de validação (`INVALID_FORMAT`, `NOT_IN_CATALOG`, `RTC_CST_MISSING`, `RTC_CATALOG_INVALID`). Todos vão para a mesma fila (categoria `RTC`).
|
||||
|
||||
## Dry-run real (somente leitura; `scripts/rtc_resolution_dryrun.py` → `docs/runs/rtc_resolution_dryrun.json`, amostra de 100 em `docs/runs/rtc_resolution_audit_sample.csv`)
|
||||
Estado como está hoje: TESTESOFICIAIS e CONSTRUCAO têm RTC ligada e regime Simples ⇒ **0 candidatos** (RTC-R1). Simulação "regime normal + RTC ligada" (o que as regras resolveriam quando existir orientação oficial para Simples):
|
||||
|
||||
| Banco | Produtos | Prontos (R3+R4) | Ambíguos | Insuficientes (NCM inválido) |
|
||||
|---|---|---|---|---|
|
||||
| TESTESOFICIAIS | 521 | 280 | 215 | 26 |
|
||||
| CONSTRUCAO | 3.712 | 2.725 | 973 | 14 |
|
||||
| MMMODAS | 20.996 | 20.831 | 49 | 116 |
|
||||
| RINCAO (CRT 3, RTC off no banco) | 894 | 530 | 364 | 0 |
|
||||
| UNIAO | 8.942 | 7.419 | 1.432 | 91 |
|
||||
|
||||
## Limitações
|
||||
Simples fica bloqueado até haver orientação oficial (ou decisão explícita de empresa, não implementada); operações especiais não são cobertas pelo default de produto; a extração dos anexos é textual (itens condicionais viram ambíguos de propósito); o catálogo oficial usado é o de 22/06/2026; sem autorização, nada é escrito (ver `docs/rtc_auto_apply.md`).
|
||||
Reference in New Issue
Block a user