From a2bad050f97b8209d4eab2017b9b1e623840a1a8 Mon Sep 17 00:00:00 2001 From: gti Date: Mon, 28 Sep 2026 10:53:20 -0300 Subject: [PATCH] test: A.3 end-to-end regression - weak evidence never becomes a write candidate Adds test_weak_composed_evidence_never_becomes_a_candidate_regardless_of_the_write_flag, proving from the real field_contract.resolve_product (not an isolated stub) that the beer misclassification fixed on master (see "fix: product_role never infers OWN_PRODUCTION from a single COMPOSICAO occurrence") can never reach select_candidates as an AUTO_FILL_SAFE candidate, independent of cfop_ippt_write_mode/write_gate. Co-Authored-By: Claude Sonnet 5 --- agent/tests/test_cfop_ippt_auto_apply.py | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/agent/tests/test_cfop_ippt_auto_apply.py b/agent/tests/test_cfop_ippt_auto_apply.py index 58b0875..e21c116 100644 --- a/agent/tests/test_cfop_ippt_auto_apply.py +++ b/agent/tests/test_cfop_ippt_auto_apply.py @@ -97,6 +97,32 @@ def test_select_candidates_only_change_and_write_eligible_cfop_or_ippt(): assert all(c["field"] in apply_mod.ALLOWED_FIELDS for c in cands) +def test_weak_composed_evidence_never_becomes_a_candidate_regardless_of_the_write_flag(): + """Missão 4 / Bloco A.3: a cell whose role evidence is weak (field_contract itself refuses to + classify it OWN_PRODUCTION/RESALE with confidence) must never reach select_candidates as + AUTO_FILL_SAFE - proven end-to-end from the real resolver, not just asserted in isolation. + This holds independently of cfop_ippt_write_mode/write_gate, which only gates whether + apply_candidates() is ever invoked - it never affects what counts as a candidate.""" + from central.app.field_contract import resolve_product, Context, WRITE_FIELDS + + def product(**kw): + p = {f: None for f in WRITE_FIELDS} + p.update({"CODIGO": "000321", "PRODUTO": "CERVEJA LONG NECK NOVA SCHIN", "CODGRUPO": "G1", "TIPO": "VENDA", "PROD_COZINHA": None, "PRODUTO_SERVICO": None, + "CLASSIFICACAO_FISCAL": "22030000", "CFOP": "5102", "CSOSN": "102", "CST": "000", "SITUACAO_TRIBUTARIA": "T", "IAT": "A", "IPPT": "T", + "INCIDENCIA_PISCOFINS": "NENHUMA", "PISCOFINS": "N"}) + p.update(kw) + return p + + decision = {"status": "EXACT_NCM", "cest_status": "NO_CEST_MAPPING_FOUND", "ipi_status": "IPI_RESOLVED", "ba_st_mva_status": "NO_MVA_MAPPING_FOUND", "dataset_versions": {}, + "classification": {"ncm": "22030000", "ipi": {"rate_kind": "NUMERIC", "rate_numeric": 3.9, "rate": "3.9"}, "ipi_candidates": [], "cest": None, "cest_candidates": [], "ba_st_mva": None, "ba_st_mva_candidates": []}} + refs = {"cfop_valid": {"5101", "5102"}, "csosn": {"102"}, "cst_icms": set(), "cst_pis": set(), "cst_cofins": set(), "origem": set("012345678"), "fcp_uf": {}, "cbs_rate_2026": None, "cclasstrib_count": 0} + co = {"uf": "BA", "crt": "1", "contribuinte_ipi": "N", "company_code": "000001"} + ev_weak = {"recipes": set(), "composed": set(), "composed_ratio": {"000321": {"composed": 1, "other": 19}}, "purchases": {}, "stock_entry": {"000321": True}, "stock_in": {"000321": True}} + result = resolve_product(product(), decision, co, refs, ev_weak, Context([])) + candidates, total = apply_mod.select_candidates({"000321": result}) + assert total == 0 and candidates == [] # the weak-evidence beer never becomes a write candidate + + def test_select_candidates_respects_limit(): results = {f"{i:06d}": {"CFOP": {"state": CHANGE, "current": None, "proposed": "5102", "write_eligible": True, "reason": "R"}} for i in range(5)} cands, total = apply_mod.select_candidates(results, limit=2)