Files
GTI_GERENCIADOR_FISCAL/docs/superpowers/plans/2026-09-25-cclasstrib-applicability.md
T

12 KiB

cClassTrib Applicability Implementation Plan

For agentic workers: Execute this plan inline task-by-task with test checkpoints. Do not delegate or publish an Agent without following the release gate in Task 5.

Goal: Gate cClassTrib validation, blockers, and completeness by live company CRT and its official effective date, instead of treating global RTC enablement as universal requiredness.

Architecture: Keep PARAMETROS.USAR_REFORMA_TRIBUTARIA as the ERP-level RTC switch, then calculate a separate company-level cClassTrib applicability state from the already-read C000004.CRT and the current date. The shared pure evaluator owns the date/regime rule; the Agent carries the state into per-product findings and fingerprints; existing Hub presentation surfaces show a concise non-applicable label without adding another coverage panel.

Tech Stack: Python, pytest, SQLAlchemy-backed Hub presentation, Jinja templates, existing read-only Firebird Agent connection.

Global Constraints

  • Do not change architecture or add a new SGV flag, schema, API, or second coverage panel.
  • Do not change NCM, PIS, COFINS, or other fiscal rules.
  • Do not write to Firebird; reads use the existing READ COMMITTED READ ONLY Agent connection.
  • Preserve Agent 2's current rtc_write_mode=DRY_RUN; REAL_WRITES=0 and CCLASSTRIB_WRITES=0.
  • PARAMETROS.USAR_REFORMA_TRIBUTARIA remains the RTC feature switch, not proof that every product requires cClassTrib.
  • cClassTrib applicability uses live company CRT: CRT 3 from 2026-08-03; CRT 1/2/4 from 2027-01-01; unresolved/unsupported CRT is not applicable until resolved.
  • Agent 2 baseline: total 521, complete 0, safe-blocked 521, failed 0, unclassified 0, coverage 0%; RTC 521 blockers; PIS 1, COFINS 1, NCM 26 distinct products/29 open rows.
  • Current code uses Agent-side assessment; do not claim the live Agent 2 result changed until the updated Agent code is running and a new job completes.

Task 1: Add failing pure applicability tests

Files:

  • Modify: central/tests/test_unified_fiscal_coverage.py
  • Test: central/app/unified_fiscal_coverage.py

Interfaces:

  • Existing input is evaluate_product(product, company, rtc, today); use company["crt"], rtc["enabled"], and the supplied date.

  • Applicability states remain in result["applicability"]["RTC"]; basis is exposed in result["basis"]["RTC"].

  • Step 1: Add the business-rule tests

Add tests equivalent to:

def test_cclasstrib_is_not_applicable_for_simples_before_2027_even_when_rtc_is_on():
    result = evaluate_product({**EMPTY, "CCLASSTRIB": None}, SIMPLES, ON, date(2026, 9, 25))
    assert result["applicability"]["RTC"] == "NOT_APPLICABLE"
    assert "CCLASSTRIB" not in result["mandatory_fields"]
    assert not [b for b in result["blockers"] if b["category"] == "RTC"]


def test_cclasstrib_effective_date_is_inclusive_by_crt():
    for crt in ("1", "2", "4"):
        before = evaluate_product({**EMPTY, "CCLASSTRIB": None}, {"crt": crt}, ON, date(2026, 12, 31))
        on_date = evaluate_product({**EMPTY, "CCLASSTRIB": None}, {"crt": crt}, ON, date(2027, 1, 1))
        assert before["applicability"]["RTC"] == "NOT_APPLICABLE"
        assert "CCLASSTRIB_MISSING" in kinds(on_date)

    before = evaluate_product({**EMPTY, "CCLASSTRIB": None}, NORMAL, ON, date(2026, 8, 2))
    on_date = evaluate_product({**EMPTY, "CCLASSTRIB": None}, NORMAL, ON, date(2026, 8, 3))
    assert before["applicability"]["RTC"] == "NOT_APPLICABLE"
    assert "CCLASSTRIB_MISSING" in kinds(on_date)


def test_non_applicable_cclasstrib_does_not_mask_pis_cofins_blockers():
    product = {**EMPTY, "CCLASSTRIB": None, "PISCOFINS": "S", "INCIDENCIA_PISCOFINS": "MONOFÁSICA"}
    result = evaluate_product(product, SIMPLES, ON, date(2026, 9, 25))
    assert kinds(result) == {"PIS_CST_MISSING", "COFINS_CST_MISSING"}

Also cover RTC off, missing/unsupported CRT, and applicable CRT 3 with empty cClassTrib.

  • Step 2: Run the tests and confirm the current code fails

Run: python -m pytest central/tests/test_unified_fiscal_coverage.py -q

Expected: new applicability assertions fail because RTC enabled currently makes the empty field required for CRT 1/2/4 and before the effective dates.


Task 2: Implement one shared applicability gate and carry it through Agent findings

Files:

  • Modify: central/app/unified_fiscal_coverage.py
  • Modify: agent/src/gti_fiscal_agent/unified_fiscal.py
  • Test: central/tests/test_unified_fiscal_coverage.py
  • Test: agent/tests/test_unified_fiscal.py

Interfaces:

  • Add a pure helper with the stable signature cclasstrib_applicability(crt, rtc_enabled, today) -> dict returning state, basis, and effective_from as an ISO-8601 string or None so the summary is JSON serializable.

  • Pass the result through the existing rtc context to evaluate_rtc; do not add a Firebird setting or database write.

  • Add the applicability inputs to each product input fingerprint so changes in company CRT/effective state invalidate stale decisions.

  • Include the company-level applicability result and source (C000004.CRT plus effective-date rule) in the Agent's fiscal_context summary.

  • Step 1: Implement the helper and make evaluate_rtc return no cClassTrib blocker when the gate is false

Use these effective dates and exact CRT sets:

CCLASSTRIB_EFFECTIVE_FROM = {
    "3": date(2026, 8, 3),
    "1": date(2027, 1, 1),
    "2": date(2027, 1, 1),
    "4": date(2027, 1, 1),
}

RTC disabled, CRT absent/unsupported, and dates before the CRT effective date must return NOT_APPLICABLE. For an applicable company, retain the existing catalog validation and missing-value blocker.

  • Step 2: Update the Agent evaluation context and input fingerprint

Calculate the company gate once per assessment using the live company["crt"] and today; pass it to each evaluate_product. Extend fingerprint input with the resulting applicability state (not a cached Hub value). Continue to issue only SELECT statements to Firebird.

  • Step 3: Extend the Agent fake-cursor regression tests

Cover RTC param on + CRT 1 before 2027 (no RTC finding), RTC param on + CRT 3 on/after 2026-08-03 (empty value blocked), separate PIS/COFINS findings preserved, the observed applicability source/state in fiscal_context, and a SELECT-only statement list.

  • Step 4: Run pure and Agent evaluator tests

Run: python -m pytest central/tests/test_unified_fiscal_coverage.py agent/tests/test_unified_fiscal.py -q

Expected: PASS; all cursor statements in Agent discovery tests are SELECT-only.


Task 3: Prove no candidates or writes while cClassTrib is not applicable

Files:

  • Modify: agent/tests/test_rtc_auto_apply.py only if an existing case does not cover the no-finding path.
  • Test: agent/src/gti_fiscal_agent/rtc_auto_apply.py and the assessment output from Task 2.

Interfaces:

  • Candidate creation continues to consume the existing RTC findings; a non-applicable product must have no RTC missing finding and therefore no R3 candidate.

  • Auto-apply authorization and allowed field remain unchanged.

  • Step 1: Add a focused candidate/write regression if needed

Use RTC enabled, CRT 1, empty CCLASSTRIB, and the existing fake read-only Firebird connection. Assert zero CCLASSTRIB_MISSING* findings, zero preview candidates, zero write attempts, zero write successes, and no SQL other than SELECT on the assessment path.

  • Step 2: Run RTC auto-apply tests

Run: python -m pytest agent/tests/test_rtc_auto_apply.py agent/tests/test_unified_fiscal.py -q

Expected: PASS; existing applicable CRT 3 safe-write unit tests remain valid and the non-applicable case has no candidate/write.


Task 4: Present non-applicability on existing Hub views

Files:

  • Modify: central/app/panel_presentation.py
  • Modify: central/templates/rtc_control.html
  • Modify: central/templates/agent_detail.html
  • Test: central/tests/test_control_panel_pages.py
  • Test: central/tests/test_operational_view_models.py

Interfaces:

  • Preserve the existing ops.rtc.enabled value for the global RTC status.

  • Add a presentation state for cClassTrib applicability; when false, do not render the current “cClassTrib pendente em N produtos” summary or RTC blocker empty-state warning for that field.

  • Render one concise label in the existing RTC status areas: cClassTrib: Não utilizado neste cliente.

  • Step 1: Add a presentation test using Agent 2-like data

Supply rtc_enabled=true, CRT 1, 521 resolution rows, 521 prior cClassTrib blocker products, and the derived non-applicable state. Assert the displayed label and assert that “cClassTrib pendente em 521 produtos” is absent on the Agent detail and RTC pages. Keep the single existing fiscal coverage metrics unchanged.

  • Step 2: Implement the smallest existing-view changes

Have rtc_status_view use the Agent-reported applicability state. Show the concise label in the existing summary areas and suppress cClassTrib-pending metrics when not applicable. Do not add a new panel or alter the current RTC write mode.

  • Step 3: Run presentation tests

Run: python -m pytest central/tests/test_control_panel_pages.py central/tests/test_operational_view_models.py -q

Expected: PASS; applicable CRT 3 views continue showing the existing candidate/coverage information.


Task 5: Run the full suite, then gate Agent release and live reprocess

Files:

  • Version/release files only after the user confirms the release action: release/VERSION, central/app/version.py, release/RELEASE_MANIFEST.json, and the installer metadata generated by scripts/build_windows_installer.ps1.
  • No Firebird tables or records are modified.

Interfaces:

  • The updated Agent must be running for Agent 2's live REPROCESS_ALL to exercise the new gate; the current production Agent is version 1.2.4.

  • Official Hub deployment entry point is scripts/deploy_hub.ps1; a new Agent release uses -PublishAgent and the installer build script.

  • Step 1: Run all offline tests before any version bump

Run: python -m pytest tests -q

Also run the relevant Agent and Hub tests together: python -m pytest central/tests/test_unified_fiscal_coverage.py central/tests/test_control_panel_pages.py central/tests/test_operational_view_models.py central/tests/test_zero_touch_hub.py agent/tests/test_unified_fiscal.py agent/tests/test_rtc_auto_apply.py agent/tests/test_zero_touch_agent.py -q

Expected: PASS with no Firebird writes.

  • Step 2: Pause at the Agent release gate

Reported that the rule change is in Agent-executed logic, listed the Agent files/tests, and stated the current deployed version 1.2.4. The operator explicitly authorized bumping to 1.2.5, building/publishing, and upgrading Agent 2 in place.

  • Step 3: After release approval, build and publish through official scripts

Run the repository's supported installer build script, then:

powershell -ExecutionPolicy Bypass -File .\scripts\deploy_hub.ps1 -PublishAgent -Version 1.2.5

Do not use ad-hoc SSH/Docker deployment. Confirm the deployed Hub health/version and that Agent 2 is running the new Agent version before queuing its full reprocess.

  • Step 4: Reprocess Agent 2 and compare read-only ERP results

Queue REPROCESS_ALL only after the updated Agent is confirmed running. Keep rtc_write_mode=DRY_RUN. Compare the new snapshot/job against the recorded baseline for total, complete, safe-blocked, failed, unclassified, coverage, cClassTrib blockers, and distinct NCM/PIS/COFINS blockers. Confirm PARAMETROS.USAR_REFORMA_TRIBUTARIA was observed live, C000004.CRT=1 led to cClassTrib non-applicability as of 2026-09-25, and Firebird WRITE_ATTEMPTS=0, WRITE_SUCCESSES=0, CCLASSTRIB_WRITES=0.

Expected for this CRT 1 client before 2027-01-01: RTC cClassTrib blockers fall from 521 to 0; other fiscal field findings remain evaluated; RTC mode is unchanged; no candidates or writes are produced.