feat: add autonomous fiscal completion v1

This commit is contained in:
gti
2026-09-22 13:08:38 -03:00
parent eada0df37e
commit e3ac68c70e
28 changed files with 44630 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
from central.app.ai.budget_ledger import BudgetLedger, BudgetLimits
def test_budget_rejects_before_provider_when_daily_limit_is_exceeded():
ledger = BudgetLedger(BudgetLimits(max_run_cost_usd=2.0, max_daily_cost_usd=1.0))
assert ledger.check_and_reserve("r1", "t1", 0.75, 1, 0).allowed is True
decision = ledger.check_and_reserve("r2", "t1", 0.30, 1, 0)
assert decision.allowed is False
assert decision.reason == "AI_BUDGET_EXHAUSTED"
def test_budget_allows_exact_limit_and_counts_new_products():
ledger = BudgetLedger(BudgetLimits(max_run_cost_usd=1.0, max_new_products_per_run=2))
assert ledger.check_and_reserve("r1", "t1", 1.0, 1, 2).allowed is True
assert ledger.check_and_reserve("r1", "t1", 0.0, 0, 1).allowed is False
+15
View File
@@ -0,0 +1,15 @@
from central.app.product_data_provider import result_cache_key
def test_same_classification_inputs_have_same_cache_key():
first = result_cache_key({"gtin": "789", "description": "X"}, ["12345678"], {"ncm": "v1"}, "prompt-v1", "model-v1")
second = result_cache_key({"description": "X", "gtin": "789"}, ["12345678"], {"ncm": "v1"}, "prompt-v1", "model-v1")
assert first == second
def test_changed_dataset_changes_cache_key():
first = result_cache_key({"gtin": "789"}, ["12345678"], {"ncm": "v1"}, "prompt-v1", "model-v1")
second = result_cache_key({"gtin": "789"}, ["12345678"], {"ncm": "v2"}, "prompt-v1", "model-v1")
assert first != second
@@ -0,0 +1,16 @@
from central.app.deterministic_resolution import resolve_entry_scope, resolve_product_role, resolve_st_status
def test_product_role_requires_two_independent_strong_signals():
assert resolve_product_role({"recipe": True, "production": True})["value"] == "OWN_PRODUCTION"
assert resolve_product_role({"single_flag": True})["value"] is None
def test_st_distinguishes_subject_from_withheld():
assert resolve_st_status({"official_cest": True, "purchase_retained": True})["value"] == "ST_ALREADY_WITHHELD_IN_PURCHASE"
assert resolve_st_status({"official_cest": True, "purchase_retained": None})["status"] == "PENDING_ST_WITHHELD"
def test_entry_scope_is_dynamic_when_both_ufs_are_observed():
assert resolve_entry_scope(["BA", "SP"], "BA")["value"] == "MIXED_OR_DYNAMIC"
assert resolve_entry_scope(["BA"], "BA")["value"] == "INTRA"
@@ -0,0 +1,38 @@
from central.app.evidence_aggregation import Observation, aggregate_observations
from scripts.analyze_inbound_observations import summarize_rows
def test_two_suppliers_agree_without_conflict():
rows = [
Observation("P1", "origin", "0", "S1", "D1", "2026-01-01"),
Observation("P1", "origin", "0", "S2", "D2", "2026-02-01"),
]
result = aggregate_observations(rows)[("P1", "origin")]
assert result["observation_count"] == 2
assert result["supplier_count"] == 2
assert result["agreement_rate"] == 1.0
assert result["strong_evidence"] is True
assert result["conflict_count"] == 0
def test_supplier_disagreement_is_conflict_not_majority():
rows = [
Observation("P1", "origin", "0", "S1", "D1", "2026-01-01"),
Observation("P1", "origin", "0", "S2", "D2", "2026-02-01"),
Observation("P1", "origin", "1", "S3", "D3", "2026-03-01"),
]
result = aggregate_observations(rows)[("P1", "origin")]
assert result["conflict_count"] == 1
assert result["strong_evidence"] is False
assert result["value"] is None
def test_inbound_rows_become_supplier_observations_without_raw_identity():
result = summarize_rows([("P1", "S1", "2026-01-01", "12345678", "1102", "060")])
assert result["observation_count"] == 3
assert result["sources"] == ["SUPPLIER_OBSERVATION"]
+49
View File
@@ -0,0 +1,49 @@
import json
from pathlib import Path
from central.app.fiscal_completeness import evaluate_field, evaluate_product, load_requiredness_matrix
ROOT = Path(__file__).resolve().parents[2]
def test_requiredness_matrix_covers_contract_fields_once():
contract = json.loads((ROOT / "docs/FISCAL_FIELD_CONTRACT_V1.json").read_text(encoding="utf-8"))
matrix = load_requiredness_matrix(ROOT / "docs/FISCAL_REQUIREDNESS_MATRIX_V1.json")
assert set(matrix["fields"]) == set(contract["fields"])
assert len(matrix["fields"]) == 23
assert set(matrix["classifications"]) == {
"REQUIRED", "CONDITIONAL", "OPTIONAL_REFERENCE", "NOT_APPLICABLE", "ERP_NOT_USED"
}
def test_conditional_empty_when_not_triggered_is_not_missing():
matrix = load_requiredness_matrix(ROOT / "docs/FISCAL_REQUIREDNESS_MATRIX_V1.json")
result = evaluate_field("IPI", None, {"contribuinte_ipi": "N", "has_numeric_tipi": False}, matrix)
assert result["status"] == "CONDITIONAL_NOT_TRIGGERED"
assert result["valid"] is True
def test_required_missing_makes_product_incomplete():
matrix = load_requiredness_matrix(ROOT / "docs/FISCAL_REQUIREDNESS_MATRIX_V1.json")
result = evaluate_product(
{"CLASSIFICACAO_FISCAL": None, "CFOP": "5102"},
{"product_role": "RESALE", "operation": "SALE"},
matrix,
)
assert result["FISCALLY_COMPLETE"] is False
assert result["fields"]["CLASSIFICACAO_FISCAL"]["status"] == "REQUIRED_MISSING"
def test_erp_not_used_is_not_missing():
matrix = load_requiredness_matrix(ROOT / "docs/FISCAL_REQUIREDNESS_MATRIX_V1.json")
result = evaluate_field("IAT", None, {"erp_uses_iat": False}, matrix)
assert result["status"] == "ERP_NOT_SUPPORTED"
assert result["valid"] is True
+21
View File
@@ -0,0 +1,21 @@
from central.app.origin_resolution import resolve_origin
def test_origin_requires_strong_supplier_evidence():
result = resolve_origin("P1", {"value": "0", "strong_evidence": True, "conflict_count": 0}, {})
assert result["status"] == "ORIGIN_CONFIRMED"
assert result["value"] == "0"
def test_origin_conflict_stays_pending():
result = resolve_origin("P1", {"value": None, "strong_evidence": False, "conflict_count": 1}, {})
assert result["status"] == "ORIGIN_CONFLICT"
assert result["value"] is None
def test_origin_does_not_use_cst_digit():
result = resolve_origin("P1", {}, {"cst": "040"})
assert result["status"] == "ORIGIN_NEEDS_EVIDENCE"
@@ -0,0 +1,16 @@
from central.app.product_data_provider import ProviderRecord, cache_key, normalize_record
def test_provider_record_has_stable_gtin_cache_key_and_hash():
record = normalize_record("GS1", "v1", "789", {"brand": "Acme", "description": "Produto"})
assert isinstance(record, ProviderRecord)
assert record.raw_hash
assert cache_key(record.gtin, record.provider, record.provider_record_version).startswith("789:")
def test_provider_normalization_does_not_claim_fiscal_authority():
record = normalize_record("COMMERCIAL", "v1", "789", {"ncm": "12345678"})
assert record.normalized_data["ncm"] == "12345678"
assert record.fiscal_authority == "OBSERVATION_ONLY"