fix: product_role never infers OWN_PRODUCTION from a single COMPOSICAO occurrence

Missão 4 / Bloco A.1 (prioridade máxima): central.app.field_contract.infer_role
treated ANY C000032.TIPO=COMPOSICAO row for a product as proof of own
production, with no ratio check - a beer sold 19 times and used once as a
recipe component (Agent 2, real data) was classified OWN_PRODUCTION from
that single occurrence, proposing to change its CFOP and IPPT.

New deterministic threshold in field_contract.py: COMPOSICAO must be a
majority (>=70%) of that product's own C000032 movement history, with at
least 5 total events, to count as own-production evidence. Below 30% the
evidence is discarded entirely (falls through to other role evidence,
e.g. TIPO=VENDA -> RESALE). Between 30% and 70% (with enough events to be
meaningful) is genuinely conflicting evidence -> UNKNOWN, never guessed
either way. RECEITA_INGREDIENTES/PROD_COZINHA-based evidence (a direct
recipe-table linkage, not a statistical ratio) is untouched.

agent/src/gti_fiscal_agent/firebird_reader.py now counts COMPOSICAO vs other
C000032 rows per product (read_product_evidence: single indexed query;
read_evidence: one grouped query for the whole catalog) into a new
ev["composed_ratio"] key, alongside the existing "composed" set (kept for
other, non-role consumers like coverage.py). central/app/enrichment/api.py's
sanitize_product_evidence and fiscal_completion.py's empty-ev fallback both
carry the new key through.

New tests (central/tests/test_field_contract.py) cover the 5 real cases named
in the mission: the beer (1 vs 19, 5% - discarded), a second beer (3 vs 4,
42.9% - MIXED/UNKNOWN), the liqueur (34 vs 22, 60.7% - still MIXED/UNKNOWN,
below the 70% bar), the juice with PROD_COZINHA=1+RECEITA_INGREDIENTES
(unaffected, stays OWN_PRODUCTION), and the tilapia/corvina fish (no
composed evidence at all, stays RESALE) - plus a strong 90% majority case
and an insufficient-sample (<5 events) case. A new end-to-end test in
agent/tests/test_cfop_ippt_auto_apply.py (committed separately, see the
feature/cfop-ippt-write branch) proves the weak-evidence beer never reaches
select_candidates as a write candidate, independent of any write flag.

Re-running the dry-run over Agent 2's real database (GTI.FDB, 527 products)
after this fix: AUTO_FILL_SAFE CFOP/IPPT cells drop from 12 to 3 (the two
fish CFOP fills + the juice's IPPT, all with strong, non-statistical
evidence) - docs/runs/GTI_dryrun_universe_summary_after_A1.json. This
corrects the Missão 3 report's 12/9(downgraded)/4(sustained) manual
judgment call with a deterministic, tested engine rule.

No schema/migration change. Zero Firebird writes (read-only analysis only).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
gti
2026-09-28 10:53:10 -03:00
co-authored by Claude Sonnet 5
parent a3ced77fc5
commit 1abb7e516e
8 changed files with 379 additions and 13 deletions
@@ -0,0 +1,275 @@
{
"name": "GTI",
"total_products": 527,
"company": {
"uf": "BA",
"crt": "1",
"contribuinte_ipi": "N",
"company_code": "000001",
"company_key": "9b1d6541",
"pis_cofins_emission_items": 34946,
"pis_cofins_emission_nonblank": 3336,
"pis_cofins_unused_by_emission": false
},
"context_entries": 0,
"fields": {
"CLASSIFICACAO_FISCAL": {
"ALREADY_CORRECT": 500,
"MANUAL_INPUT_REQUIRED": 27
},
"IPI": {
"NOT_APPLICABLE": 317,
"MANUAL_INPUT_REQUIRED": 210
},
"EX_TIPI": {
"NOT_APPLICABLE": 500,
"MANUAL_INPUT_REQUIRED": 27
},
"CEST": {
"NOT_APPLICABLE": 482,
"MANUAL_INPUT_REQUIRED": 41,
"ALREADY_CORRECT": 4
},
"SITUACAO_TRIBUTARIA": {
"ALREADY_CORRECT": 499,
"MANUAL_INPUT_REQUIRED": 28
},
"CFOP": {
"ALREADY_CORRECT": 490,
"MANUAL_INPUT_REQUIRED": 28,
"NOT_APPLICABLE": 7,
"CHANGE_REQUIRED": 2
},
"CFOP_ENTRADA": {
"MANUAL_INPUT_REQUIRED": 527
},
"CST": {
"NOT_APPLICABLE": 527
},
"CST_ENTRADA": {
"NOT_APPLICABLE": 527
},
"CSOSN": {
"ALREADY_CORRECT": 489,
"MANUAL_INPUT_REQUIRED": 38
},
"ALIQUOTA": {
"NOT_APPLICABLE": 493,
"ALREADY_CORRECT": 34
},
"COD_ORIGEM_MERCADORIA": {
"MANUAL_INPUT_REQUIRED": 526,
"ALREADY_CORRECT": 1
},
"CST_IPI": {
"NOT_APPLICABLE": 527
},
"COD_ENTRADA_PIS": {
"MANUAL_INPUT_REQUIRED": 526,
"ALREADY_CORRECT": 1
},
"COD_SAIDA_PIS": {
"MANUAL_INPUT_REQUIRED": 525,
"ALREADY_CORRECT": 2
},
"ALIQ_PIS": {
"MANUAL_INPUT_REQUIRED": 525,
"ALREADY_CORRECT": 2
},
"COD_ENTRADA_COFINS": {
"MANUAL_INPUT_REQUIRED": 526,
"ALREADY_CORRECT": 1
},
"COD_SAIDA_COFINS": {
"MANUAL_INPUT_REQUIRED": 525,
"ALREADY_CORRECT": 2
},
"ALIQ_COFINS": {
"MANUAL_INPUT_REQUIRED": 525,
"ALREADY_CORRECT": 2
},
"INCIDENCIA_PISCOFINS": {
"ALREADY_CORRECT": 527
},
"PISCOFINS": {
"ALREADY_CORRECT": 527
},
"IAT": {
"ALREADY_CORRECT": 527
},
"IPPT": {
"ALREADY_CORRECT": 519,
"CHANGE_REQUIRED": 1,
"NOT_APPLICABLE": 7
}
},
"reasons": {
"CLASSIFICACAO_FISCAL": {
"ALREADY_CORRECT|NCM_VALID_IN_DATASET": 500,
"MANUAL_INPUT_REQUIRED|NCM_INVALID": 24,
"MANUAL_INPUT_REQUIRED|NCM_LEGACY_NO_UNAMBIGUOUS_SUCCESSOR": 3
},
"IPI": {
"NOT_APPLICABLE|TIPI_RATE_BLANK_NEVER_ZERO": 297,
"MANUAL_INPUT_REQUIRED|STORE_IPI_PROFILE_NOT_DECIDED": 107,
"MANUAL_INPUT_REQUIRED|SEVERAL_TIPI_ROWS_FOR_NCM": 76,
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 27,
"NOT_APPLICABLE|TIPI_NT_OR_NON_NUMERIC_NEVER_WRITTEN_TO_NUMERIC_FIELD": 20
},
"EX_TIPI": {
"NOT_APPLICABLE|NO_EX_ROW_FOR_NCM": 424,
"NOT_APPLICABLE|DESCRIPTION_EVIDENCES_NO_EX_BASE_RATE_APPLIES": 76,
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 27
},
"CEST": {
"NOT_APPLICABLE|DESCRIPTION_MATCHES_NO_OFFICIAL_CEST_ITEM": 449,
"NOT_APPLICABLE|NCM_NOT_IN_CEST_LIST": 33,
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 27,
"MANUAL_INPUT_REQUIRED|SEVERAL_OFFICIAL_CEST_FOR_NCM": 13,
"ALREADY_CORRECT|ERP_CEST_IS_OFFICIAL_FOR_NCM": 4,
"MANUAL_INPUT_REQUIRED|ERP_CEST_NOT_OFFICIAL_FOR_NCM": 1
},
"SITUACAO_TRIBUTARIA": {
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 499,
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 27,
"MANUAL_INPUT_REQUIRED|BLANK_OR_INVALID": 1
},
"CFOP": {
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 471,
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 21,
"ALREADY_CORRECT|RULE_PROVEN_EQUALS_DECLARED": 19,
"NOT_APPLICABLE|INPUT_IS_NOT_A_SALE_ITEM": 7,
"MANUAL_INPUT_REQUIRED|CFOP_NEEDS_ST_STATUS": 7,
"CHANGE_REQUIRED|DERIVED_FROM_ROLE_AND_ST_FILLING_BLANK": 2
},
"CFOP_ENTRADA": {
"MANUAL_INPUT_REQUIRED|CFOP_ENTRADA_NEEDS_PRODUCT_ROLE": 254,
"MANUAL_INPUT_REQUIRED|CFOP_ENTRADA_NEEDS_ENTRY_SCOPE": 246,
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 27
},
"CST": {
"NOT_APPLICABLE|CRT1_SIMPLES_EMISSION_USES_CSOSN": 527
},
"CST_ENTRADA": {
"NOT_APPLICABLE|CRT1_SIMPLES_EMISSION_USES_CSOSN": 527
},
"CSOSN": {
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 489,
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 27,
"MANUAL_INPUT_REQUIRED|CSOSN_NEEDS_ICMS_TREATMENT": 11
},
"ALIQUOTA": {
"NOT_APPLICABLE|SIMPLES_CSOSN_HIGHLIGHTS_NO_ICMS_RATE": 493,
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 34
},
"COD_ORIGEM_MERCADORIA": {
"MANUAL_INPUT_REQUIRED|ORIGIN_NO_EVIDENCE": 526,
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 1
},
"CST_IPI": {
"NOT_APPLICABLE|COMPANY_IS_NOT_AN_IPI_TAXPAYER_C000004.CONTRIBUINTE_IPI": 527
},
"COD_ENTRADA_PIS": {
"MANUAL_INPUT_REQUIRED|NO_OFFICIAL_RULE_SOURCE_IN_CORE_DATASETS": 525,
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 1,
"MANUAL_INPUT_REQUIRED|DECLARED_CST_NOT_IN_OFFICIAL_TABLE": 1
},
"COD_SAIDA_PIS": {
"MANUAL_INPUT_REQUIRED|NO_OFFICIAL_RULE_SOURCE_IN_CORE_DATASETS": 524,
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 2,
"MANUAL_INPUT_REQUIRED|DECLARED_CST_NOT_IN_OFFICIAL_TABLE": 1
},
"ALIQ_PIS": {
"MANUAL_INPUT_REQUIRED|NO_OFFICIAL_RULE_SOURCE_IN_CORE_DATASETS": 525,
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 2
},
"COD_ENTRADA_COFINS": {
"MANUAL_INPUT_REQUIRED|NO_OFFICIAL_RULE_SOURCE_IN_CORE_DATASETS": 525,
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 1,
"MANUAL_INPUT_REQUIRED|DECLARED_CST_NOT_IN_OFFICIAL_TABLE": 1
},
"COD_SAIDA_COFINS": {
"MANUAL_INPUT_REQUIRED|NO_OFFICIAL_RULE_SOURCE_IN_CORE_DATASETS": 524,
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 2,
"MANUAL_INPUT_REQUIRED|DECLARED_CST_NOT_IN_OFFICIAL_TABLE": 1
},
"ALIQ_COFINS": {
"MANUAL_INPUT_REQUIRED|NO_OFFICIAL_RULE_SOURCE_IN_CORE_DATASETS": 525,
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 2
},
"INCIDENCIA_PISCOFINS": {
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 527
},
"PISCOFINS": {
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 527
},
"IAT": {
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 527
},
"IPPT": {
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 265,
"ALREADY_CORRECT|DERIVED_FROM_PRODUCT_ROLE:C000025.TIPO=VENDA,STOCK_ENTRIES(C000100.ENTRADAS>0)": 234,
"ALREADY_CORRECT|DERIVED_FROM_PRODUCT_ROLE:C000025.TIPO=VENDA,PURCHASE_DOCUMENT": 20,
"NOT_APPLICABLE|INPUT_OR_SERVICE_HAS_NO_PRODUCTION_INDICATOR": 7,
"CHANGE_REQUIRED|DERIVED_FROM_PRODUCT_ROLE:PROD_COZINHA=1,RECEITA_INGREDIENTES": 1
}
},
"manual_inputs": {
"COD_ORIGEM_MERCADORIA|origin": 526,
"COD_ENTRADA_PIS|pis_cofins_profile": 526,
"COD_ENTRADA_COFINS|pis_cofins_profile": 526,
"COD_SAIDA_PIS|pis_cofins_profile": 525,
"ALIQ_PIS|pis_cofins_profile": 525,
"COD_SAIDA_COFINS|pis_cofins_profile": 525,
"ALIQ_COFINS|pis_cofins_profile": 525,
"CFOP_ENTRADA|product_role": 254,
"CFOP_ENTRADA|entry_scope": 246,
"IPI|store_ipi_profile": 107,
"IPI|ex_tipi": 76,
"CLASSIFICACAO_FISCAL|ncm": 27,
"IPI|ncm": 27,
"EX_TIPI|ncm": 27,
"CEST|ncm": 27,
"SITUACAO_TRIBUTARIA|ncm": 27,
"CFOP_ENTRADA|ncm": 27,
"CSOSN|ncm": 27,
"CFOP|ncm": 21,
"CEST|cest": 14,
"CSOSN|icms_treatment": 11,
"CFOP|st_status": 7,
"SITUACAO_TRIBUTARIA|icms_treatment": 1
},
"roles": {
"RESALE": 254,
"UNKNOWN": 265,
"OWN_PRODUCTION": 1,
"INPUT": 7
},
"change_required_cells": 3,
"write_eligible_cells": 3,
"manual_inputs_by_scope": {
"COD_ORIGEM_MERCADORIA|origin|GROUP": 526,
"COD_ENTRADA_PIS|pis_cofins_profile|COMPANY": 526,
"COD_ENTRADA_COFINS|pis_cofins_profile|COMPANY": 526,
"COD_SAIDA_PIS|pis_cofins_profile|COMPANY": 525,
"ALIQ_PIS|pis_cofins_profile|COMPANY": 525,
"COD_SAIDA_COFINS|pis_cofins_profile|COMPANY": 525,
"ALIQ_COFINS|pis_cofins_profile|COMPANY": 525,
"CFOP_ENTRADA|product_role|GROUP": 254,
"CFOP_ENTRADA|entry_scope|COMPANY": 246,
"IPI|store_ipi_profile|COMPANY": 107,
"IPI|ex_tipi|PRODUCT": 76,
"CLASSIFICACAO_FISCAL|ncm|PRODUCT": 27,
"IPI|ncm|PRODUCT": 27,
"EX_TIPI|ncm|PRODUCT": 27,
"CEST|ncm|PRODUCT": 27,
"SITUACAO_TRIBUTARIA|ncm|PRODUCT": 27,
"CFOP_ENTRADA|ncm|PRODUCT": 27,
"CSOSN|ncm|PRODUCT": 27,
"CFOP|ncm|PRODUCT": 21,
"CEST|cest|PRODUCT": 14,
"CSOSN|icms_treatment|GROUP": 11,
"CFOP|st_status|GROUP": 7,
"SITUACAO_TRIBUTARIA|icms_treatment|GROUP": 1
}
}