fix: RTC observed live with provenance, non-circular PIS/COFINS applicability, canonical CST normalization (1.1.8)

- RTC: Agent reads ALL PARAMETROS rows every sync (conflict => off), reports rtc_source/rtc_observed_at/rtc_param_rows; legal_effective_context is informational only
- PIS/COFINS: applicability from CRT + PISCOFINS flag + incidence only (never from empty fields); Simples w/o special treatment NOT_APPLICABLE, taxed regime with explicit N OPTIONAL, unreadable declaration NEEDS_REVIEW
- CST: one digit with an official zero-padded form is VALID_AFTER_NORMALIZATION (non-blocking warning), nothing is written to the ERP
- tests: RTC toggle 0->1->0 across syncs (Agent + Hub stale closing), non-circularity, normalization, panel provenance

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
gti
2026-09-24 17:46:45 -03:00
co-authored by Claude Sonnet 5
parent 1430042322
commit 88f4318072
18 changed files with 679 additions and 814 deletions
+23
View File
@@ -185,3 +185,26 @@ def test_partial_reprocess_does_not_claim_a_full_fiscal_evaluation(env_setup, mo
hub, state = env_setup
result, _ = run_job("REPROCESS_PRODUCTS", [product("1")], state, monkeypatch)
assert result["fiscal_context"] is None and result["operational"] is None
def test_rtc_toggle_between_two_syncs_is_followed_by_the_next_job(env_setup, monkeypatch):
"""The Agent asks the database EVERY sync: 0 -> 1 makes the next job report RTC blockers, 1 -> 0 makes the following job report none (Hub then closes the old ones)."""
from gti_fiscal_agent import unified_fiscal
switch = {"on": False}
def assess(conn, company, **kw):
found = _findings(**{"1": [("CCLASSTRIB_MISSING", "RTC")]}) if switch["on"] else {}
return {"context": {"rtc_enabled": switch["on"], "rtc_supported": True, "rtc_catalog_valid": True, "rtc_source": "PARAMETROS.USAR_REFORMA_TRIBUTARIA", "rtc_observed_at": "2026-09-24T20:00:00+00:00"}, "findings": found}
monkeypatch.setattr(unified_fiscal, "assess_from_connection", assess)
hub, state = env_setup
products = [product("1"), product("2")]
off1, _ = run_job("INITIAL_SYNC", products, state, monkeypatch)
switch["on"] = True
on, _ = run_job("SYNC_INCREMENTAL", products, state, monkeypatch) # nothing changed in C000025: the delta cache must not hide the RTC change
switch["on"] = False
off2, _ = run_job("SYNC_INCREMENTAL", products, state, monkeypatch)
assert off1["blocked_products"] == [] and off1["fiscal_context"]["rtc_enabled"] is False
assert [b["field"] for b in on["blocked_products"]] == ["RTC"] and on["fiscal_context"]["rtc_enabled"] is True and on["operational"]["BLOCKED_FISCAL_DATA"] == 1
assert on["fiscal_context"]["rtc_observed_at"] and on["fiscal_context"]["rtc_source"] == "PARAMETROS.USAR_REFORMA_TRIBUTARIA"
assert off2["blocked_products"] == [] and off2["fiscal_context"]["rtc_enabled"] is False and off2["fiscal_context"]["evaluated_all"] is True
assert off2["operational"]["COMPLETE_PRODUCTS"] == 2