Files
GTI_GERENCIADOR_FISCAL/docs/unified_fiscal_completeness.md
T
gtiandClaude Sonnet 5 9f08998800 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>
2026-09-24 21:18:34 -03:00

61 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Completude fiscal unificada (UNIFIED_FISCAL_COVERAGE)
Uma definição de "completo", um painel, uma fila de blockers, uma cobertura.
## Definição
```
campos obrigatórios(produto, empresa) =
campos fiscais base aplicáveis (NCM, CEST, CFOP, ICMS/CST/CSOSN, IPI ... — decididos pelo motor de decisão do Hub)
+ PIS/COFINS aplicáveis (docs/pis_cofins_applicability.md)
+ RTC (cClassTrib → CST IBS/CBS) SOMENTE quando o ERP tem a Reforma Tributária ligada (docs/rtc_pis_cofins_model.md)
```
Campos `NOT_APPLICABLE` não contam contra a completude. Nenhum campo é exigido só porque a coluna existe.
## Onde vive (nenhuma cópia paralela)
| Peça | Arquivo |
|---|---|
| regras puras (PIS/COFINS, RTC, `evaluate_product`) | `central/app/unified_fiscal_coverage.py` |
| estado do produto (`COMPLETE`/`CORRECTED`/`BLOCKED_*`/`BLOCKED_FISCAL_DATA`/`FAILED_TECHNICAL`/`NEEDS_REVIEW`) | `central/app/operational_state.py` (`classify_product_state(..., fiscal=)`) |
| leitura do ERP (somente SELECT) | `agent/src/gti_fiscal_agent/unified_fiscal.py` |
| integração no job do Agent | `agent/scripts/run_agent_service.py` (`_unified_fiscal`, `_fiscal_blocked_products`) |
| snapshot / cobertura no Hub | `central/app/api.py` (`_apply_job_outcome` — inalterado: usa o mesmo `operational`) |
| fila única + fechamento automático | `central/app/blocked_products.py` (`resolve_stale_fiscal_blockers`) |
| painel | `central/app/panel_presentation.py`, `central/templates/{dashboard,blockers,agent_detail}.html` |
## Estados finais do produto
`COMPLETE` (+`CORRECTED`) · `SAFE_BLOCKED` (`BLOCKED_*`, incluindo `BLOCKED_FISCAL_DATA` para PIS/COFINS/RTC) · `FAILED_TECHNICAL` · `NEEDS_REVIEW` (não classificado; só incidência PIS/COFINS fora do vocabulário do SGV).
Invariante: `TOTAL = COMPLETE + SAFE_BLOCKED + FAILED + UNCLASSIFIED` (o Hub calcula "não classificados" como `total − completos − bloqueados − falhas`, então a igualdade fecha por construção e é reverificada em `coverage_invariant_pass`).
Precedência: um blocker de decisão (NCM, conflito, contexto) permanece o estado principal; blockers fiscais só rebaixam produto que seria completo. Um blocker real vale mais que `NEEDS_REVIEW`.
## Fila única e fechamento
Cada blocker fiscal é um blocker comum: `blocker_type=BLOCKED_FISCAL_DATA`, `field ∈ {PIS, COFINS, RTC}`, `reason_code` = tipo (ex.: `PIS_CST_INVALID`). A cada job de varredura completa (`fiscal_context.evaluated_all=true`) o Agent reenvia todos os blockers vigentes e o Hub fecha (`AUTO_REEVALUATION`) os blockers PIS/COFINS/RTC da instalação não reenviados (dado corrigido, ou RTC desligada). Reprocesso parcial não fecha nada de outros produtos. O fingerprint do blocker inclui os valores fiscais lidos.
## Painel
- Dashboard: um único bloco "Cobertura dos produtos" (Produtos, Completos, Bloqueados com segurança, Falhas técnicas, Não classificados, Cobertura fiscal). Breakdown de blockers: `NCM, CEST, CFOP, ST, ICMS, CSOSN, PIS, COFINS, RTC, OTHER` (categoria com 0 fica esmaecida).
- Detalhe do Agent: a mesma cobertura + uma linha discreta "Reforma Tributária: Ativa/Desativada" (do último job). RTC desativada nunca aparece como problema. O bloco "Escopo anterior/ampliado" foi removido.
- Removidos do código: `expanded_scope_summary`, `expanded_scope_view`, `LEGACY_SCOPE_COVERAGE`, `EXPANDED_SCOPE_COVERAGE`, `UNKNOWN_APPLICABILITY` (como estado em massa).
## Segurança
Somente leitura. `FIREBIRD_WRITES=0`: a avaliação abre uma conexão `READ COMMITTED READ ONLY`, executa apenas SELECT e nunca preenche `CCLASSTRIB`, PIS ou COFINS. Testes provam que só SELECT é emitido.
## Validação nos bancos reais (somente leitura, cinco bancos)
`scripts/unified_coverage_e2e.py` → `docs/runs/unified_coverage_e2e*.json`. RTC lida **do banco como está hoje**; "RTC desligada" é simulação pura do avaliador (o parâmetro nunca é tocado).
| Banco | CRT | RTC no banco | Produtos | Completos | Bloqueados | Não class. | Cobertura (como está) | Cobertura com RTC off |
|---|---|---|---|---|---|---|---|---|
| CONSTRUCAO | 1 | **ligada** | 3.712 | 0 | 3.712 (RTC) | 0 | 0% | 100% |
| MMMODAS | 1 | desligada | 20.997 | 20.997 | 0 | 0 | 100% | 100% |
| RINCAO | 3 | desligada | 894 | 893 | 1 | 0 | 99,89% (antes da normalização: 91,16%) | 99,89% |
| UNIAO | 1 | desligada | 8.942 | 8.942 | 0 | 0 | 100% | 100% |
| TESTESOFICIAIS | 1 | **ligada** | 521 | 0 | 521 (RTC) | 0 | 0% | 94,82% (494/521) |
Bancos além do piloto: medida só da parte fiscal (`--fiscal-only`, sem decisão do Hub). TESTESOFICIAIS: com a decisão do Hub (antes 495/521 = 95,01%). Bloqueios PIS/COFINS: TESTESOFICIAIS 1 produto (incidência SUBST.TRIBUTÁRIA com CST 01), RINCAO 1 produto (`049`/`000`), demais 0. Produtos com warning (não bloqueante): RINCAO 78 (`4`→`04`, não canônico), UNIAO 2 (CST `000`/`060` inválido, ignorado por ser Simples), TESTESOFICIAIS 1 (não canônico). Aplicabilidade: Simples ⇒ `NOT_APPLICABLE`; RINCAO ⇒ `OPTIONAL` (894); TESTESOFICIAIS 519 `NOT_APPLICABLE` + 2 `REQUIRED`.
## RTC no motor único (cClassTrib) — atualização
- **RTC ligada** ⇒ o Agent avalia cada produto com o resolver determinístico (`docs/cclasstrib_resolution.md`) e transforma o resultado em UM blocker de causa raiz por produto (mesma fila, categoria `RTC`): `CCLASSTRIB_MISSING` (pronto para preencher), `CCLASSTRIB_MISSING_UNRESOLVED`, `CCLASSTRIB_AMBIGUOUS`, `RTC_RULE_EVIDENCE_MISSING`, `RTC_LOCAL_CATALOG_OUTDATED`, `CCLASSTRIB_OFFICIAL_MISMATCH`, `CCLASSTRIB_CONFLICT`. **RTC desligada** ⇒ nenhuma avaliação, nenhum blocker, nada no painel além de "Desativada".
- Cobertura continua UMA: produto só é completo quando o `CCLASSTRIB` é válido (ou seja, depois de preenchido pelo operador ou pelo auto-apply autorizado). Produtos "prontos para preenchimento" contam como bloqueados até a escrita.
- O painel explica o 0%: "Reforma Tributária ativa — cClassTrib pendente em N produtos" + resumo Total / válidos / prontos / ambíguos-bloqueados.
- Preenchimento automático: `docs/rtc_auto_apply.md` (desligado por padrão; três chaves; somente `CCLASSTRIB`; auditado).