Bloco C.1-C.4: searched every BLOB column and every XML/IMPOSTO/TRIBUT-named
table across all 5 databases - no authorized NFC-e/NF-e XML is stored
anywhere (XML_MES only holds a filesystem path on the original machine;
CARTA_CORRECAO/MDFES_XML are for correction letters and cargo manifests;
DEOLHONOIMPOSTO is the national IBPT reference table, not per-item data).
FONTE_ENCONTRADA = NFCE_ITENS's own PIS/COFINS columns (the same values used
to build the XML) - docs/PISCOFINS_TRANSMITTED_SOURCE_V1.md.
Bloco D.1-D.3: the 27 products blocked by NCM on Agent 2, categorized
(4 placeholder 00000000, 3 legacy/vencido, 5 valid-format-but-not-in-the-
active-table, 15 obvious test/garbage values) with a prioritized kb.attest
queue - real products first (Coca-Cola, chicken cuts, pâté, broths), test
cadastro last. All 27 lack a real GTIN, so none can be resolved by barcode
lookup - documented in docs/NCM_27_BLOCKED_PRODUCTS_V1.md.
dossie_contador.md (internal + anonymized) updated with the Bloco C finding.
No schema/migration change. Zero Firebird writes (read-only SQL only).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Missao 3 / Bloco C.1-C.2: new agent/src/gti_fiscal_agent/cfop_ippt_auto_apply.py
mirrors the existing rtc_auto_apply.py safety model for a new, narrower
capability (CFOP_IPPT_WRITE_V1): compare-before-write, stale-write guard
("human override sempre vence" - a value changed since the candidate was
selected is never overwritten), one transaction per cell, readback
verification, and rollback that only restores a value still equal to what
was written. Candidates come exclusively from field_contract.resolve_product's
own AUTO_FILL_SAFE classification for CFOP/IPPT - no new fiscal rule.
14 new tests (agent/tests/test_cfop_ippt_auto_apply.py) prove: flag OFF means
the caller never reaches a write; only CHANGE+write_eligible CFOP/IPPT cells
become candidates; a human edit between decision and write blocks the write;
a second run over an already-applied cell writes zero; a technical failure on
one cell never stops the batch; rollback refuses when the value changed again.
Deliberately NOT wired into agent/scripts/run_agent_service.py::execute_job,
and the Hub-side authorization/audit plumbing (Installation.cfop_ippt_write_mode,
audit table, job-delivered authorization - the same pattern as
central/app/rtc_audit.py) does not exist yet. No currently-published Agent
behavior (1.3.8) changes with this commit - nothing imports this new module.
See docs/CFOP_IPPT_WRITE_CAPABILITY_V1.md for the acceptance roteiro (test
products only, never real ones) and what remains before this can ever be
activated for a real installation - deliberately left for review before any
further step, per this mission's explicit instruction not to publish it active.
Also: dossie_contador.md (internal + anonymized) updated with the Bloco B
finding that the ~9.5% CST=01 anomaly is confined to a single calendar month
(not the whole year), with no fiscal-dimension (NCM/CFOP/CSOSN/ICMS group)
explaining which items got it - consistent with a one-off technical event,
not a deliberate rule.
REAL_PRODUCT_FISCAL_WRITES=0 (no write path exists in this commit).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Missao 2 (fechamento de lacunas fiscais, read-only + UI/engine gated):
- field_contract: pis_cofins_profile now also accepts the literal sentinels
NOT_APPLICABLE/OPERATION_TIME, resolving to NA only from an audited
FiscalContextEntry - never inferred from emission statistics. CFOP_ENTRADA
under an already-decided entry_scope=MIXED_OR_DYNAMIC now resolves to NA
instead of MANUAL, so it stops blocking product completeness and stops
re-asking an already-answered question. Regression tests prove: no ADMIN
decision => unchanged old behavior; decision present => gated bucket, no write.
- context_keys: validate_entry accepts the two sentinels for pis_cofins_profile.
- Contexto Fiscal UI: PIS/COFINS and CFOP_ENTRADA cards show the Bloco 2
cross-database evidence (5 installations, CRT 1 and 3: emission never reads
the PIS/COFINS cadastral fields anywhere) and a link to an ADMIN-facing,
anonymized dossie-for-the-accountant; entry_scope is now a dropdown.
- release/tests: decoupled the Hub's GTI_FISCAL_VERSION from the Agent's own
version (test_versions_are_coherent_across_hub_and_packages vs the new
test_agent_version_is_internally_coherent) - a Hub-only release must not
require touching, rebuilding or republishing the Agent.
- New read-only evidence: docs/runs/GTI_dryrun_universe_summary.json (527
products, Agent 2's real database), docs/runs/BLOCO2_PIS_COFINS_CROSS_DB_V1.json
(5 installations), docs/fiscal_completeness_matrix.md, docs/dossie_contador.md
(internal, real names) + central/static/docs/dossie_contador.md (public,
anonymized - no CNPJ/razao social/product names), docs/AGENT2_UPGRADE_RUNBOOK_V1.md.
- CLAUDE.md: recorded the permanent fiscal-mission rules (no AI/scraping, no
Firebird schema changes, deploy only via deploy_hub.ps1, never reenroll,
no remote access to client Agent hosts, no client data in unauthenticated
static routes).
No schema/migration change. Zero Firebird writes (new scripts never open a
write connection). Hub only - Agent code untouched.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Collaborators logged into GTI Gerenciador open GTI Fiscal without a
second password. The panel signs a 60 s JWT (Ed25519; the Hub holds only
the public key); the Hub checks signature, iss/aud/exp/nbf, maximum
lifetime, nonce against a one-time state cookie set when the flow starts
at GET /login (login-CSRF protection) and a single-use jti
(sso_used_assertions). Collaborators are provisioned in admin_users with
auth_source=GTI_GERENCIADOR and no password; a CHECK constraint makes a
passwordless local account or a federated account with a password
impossible (migration 0021). Sessions last FEDERATED_SESSION_SECONDS
(1 h) and are renewed silently through the panel.
The local admin stays as break-glass at /login/local, audited. Logout ends
only the Hub session. Every SSO success/rejection (stable reason code),
logout and local login is audited with the real client IP, never the
token. verify_password now fails closed on a missing hash instead of
raising.
Visual identity: gti-theme.css is a verbatim copy of the panel's
design system (tokens, sidebar, light/dark theme) plus its tema.js,
sidebar.js and logo; control-panel.css keeps only Hub components, all
colours from the panel tokens. Page structure and features unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>