# sowai-fiscal Núcleo fiscal puro da SowAI: motor de regras tributário (imposto-como-dado), chave de acesso de NF-e (módulo 11) e builder do XML NF-e 55 (leiaute NT 2025.002 v1.40, bindings `nfelib` 2.5.x). Extraído do produto `sowai-auto` (F1 do plano `sowai-fiscal-svc`) como lib versionada — zero I/O, zero SQLAlchemy, zero FastAPI, zero acoplamento a nenhum produto: a interface com o ORM do consumidor é o `Protocol` estrutural `sowai_fiscal.types.TaxRuleLike`. ## Módulos - `domains` — catálogo `TaxDomain`/`DOMAIN_FIELDS`/`MATCHER_WEIGHTS` + transposição de CFOP intra→interestadual. - `chave_acesso` — DV módulo 11, sorteio de `cNF`, montagem da chave de 44 dígitos. - `tpag` — tabela de códigos `tPag` (MOC, grupo YA02). - `presets` — presets fiscais seed-editáveis (perfis reais extraídos do iCode da Thiago Auto Center). - `resolver` — `resolve_fiscal`: `FiscalOperation` × regras (`TaxRuleLike`) → `FiscalResult`. Puro, determinístico, fail-closed. - `xml_builder` — `build_nfe`: `DadosEmissao` (já resolvido) → objeto `Nfe` (bindings `nfelib`). - `types` — `TaxRuleLike`, o `Protocol` que desacopla o resolver do ORM do produto. - `golden_helpers` — `dados_from_json`/`serialize_infnfe`, usados pelo corpus golden (`goldens/`) e pelo teste de paridade do produto consumidor. ## Corpus golden `src/sowai_fiscal/goldens/caso_.{input.json,expected.xml}` — pares determinísticos (`dh_emi`/`cnf`/`chave_acesso` pinados no input) que travam o leiaute XML pré-assinatura gerado a partir de um `DadosEmissao`. São dados de pacote (lidos via `importlib.resources`), para que o produto consumidor compare byte a byte contra os MESMOS arquivos da lib instalada — nenhuma cópia que possa divergir. Regenerar com `uv run python scripts/gen_goldens.py` apenas quando uma NT mudar o leiaute DE PROPÓSITO. ## Testes ```bash uv sync uv run pytest ``` 100% local — sem Postgres, sem k8s.