feat: close pre-zai local blockers
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
"""Evidence reconstruction for historical KB conflicts.
|
||||
|
||||
The seed payload contains the current 90 observable conflicts but not the
|
||||
identity/evidence rows for the remaining 73 historical conflict records. This
|
||||
module makes that limitation explicit instead of fabricating identities.
|
||||
"""
|
||||
|
||||
from collections import Counter
|
||||
|
||||
RESOLVED_EQUIVALENT_PRODUCT = "RESOLVED_EQUIVALENT_PRODUCT"
|
||||
FALSE_MATCH = "FALSE_MATCH"
|
||||
VALID_NCM_CONFLICT = "VALID_NCM_CONFLICT"
|
||||
STALE_OBSERVATION = "STALE_OBSERVATION"
|
||||
INSUFFICIENT_EVIDENCE = "INSUFFICIENT_EVIDENCE"
|
||||
|
||||
|
||||
def reconstruct_historical_conflicts(payload: dict, historical_count: int = 73) -> dict:
|
||||
products = payload.get("products", [])
|
||||
gtin_count = sum(1 for product in products if product.get("gtin"))
|
||||
fingerprint_count = sum(1 for product in products if product.get("fingerprint"))
|
||||
evidence_summary = {
|
||||
"payload_products": len(products),
|
||||
"payload_gtin_products": gtin_count,
|
||||
"payload_fingerprint_products": fingerprint_count,
|
||||
"fields_available": ["gtin", "fingerprint", "normalized_description", "unit", "ncm", "observations"],
|
||||
"historical_identity_records_found": 0,
|
||||
}
|
||||
rows = []
|
||||
for index in range(1, historical_count + 1):
|
||||
rows.append({
|
||||
"historical_conflict_id": f"HISTORICAL-{index:03d}",
|
||||
"classification": INSUFFICIENT_EVIDENCE,
|
||||
"evidence_search": evidence_summary,
|
||||
"resolution": "PRESERVE_CONFLICT",
|
||||
"reason": "original conflict identity/evidence row is absent from available artifacts; no NCM selected",
|
||||
})
|
||||
return {
|
||||
"artifact": "KB_HISTORICAL_CONFLICT_AUDIT_V1",
|
||||
"historical_conflicts_before": historical_count,
|
||||
"historical_conflicts_resolved": 0,
|
||||
"historical_conflicts_remaining": historical_count,
|
||||
"classification_counts": dict(Counter(row["classification"] for row in rows)),
|
||||
"conflicts": rows,
|
||||
"current_observable_conflicts_preserved": 90,
|
||||
"current_conflict_policy": "NCM_CONFLICT rows remain blocked; no majority resolution",
|
||||
"evidence_complete": False,
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
"""Audit the historical KB conflicts without inventing missing evidence."""
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from central.app.ai.historical_conflicts import reconstruct_historical_conflicts
|
||||
|
||||
|
||||
def main(payload_path="docs/runs/ai_kb_seed_payload.json", output="docs/KB_HISTORICAL_CONFLICT_AUDIT_V1.json"):
|
||||
payload = json.loads(Path(payload_path).read_text(encoding="utf-8"))
|
||||
report = reconstruct_historical_conflicts(payload)
|
||||
Path(output).write_text(json.dumps(report, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
return report
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--payload", default="docs/runs/ai_kb_seed_payload.json")
|
||||
parser.add_argument("--output", default="docs/KB_HISTORICAL_CONFLICT_AUDIT_V1.json")
|
||||
args = parser.parse_args()
|
||||
print(json.dumps(main(args.payload, args.output), indent=2, ensure_ascii=False))
|
||||
@@ -0,0 +1,13 @@
|
||||
def test_company_session_is_company_first_review_only_and_has_ipi_impact(tmp_path):
|
||||
from scripts.run_company_decision_session import build_session
|
||||
|
||||
session = build_session(tmp_path, "docs/LOCAL_FISCAL_CONTEXT_QUESTIONS_V2.json") if (tmp_path / "docs/LOCAL_FISCAL_CONTEXT_QUESTIONS_V2.json").exists() else None
|
||||
# Use a small local fixture because the production artifact is intentionally large.
|
||||
if session is None:
|
||||
(tmp_path / "docs/runs/multi_db").mkdir(parents=True)
|
||||
(tmp_path / "docs").mkdir(exist_ok=True)
|
||||
(tmp_path / "docs/LOCAL_FISCAL_CONTEXT_QUESTIONS_V2.json").write_text('{"questions":[{"QUESTION_ID":"Q1","DATABASE":"A","SCOPE":"COMPANY","KEY":"entry_scope","VALID_OPTIONS":["INTRA","INTER","MIXED_OR_DYNAMIC"],"QUESTION":"Escopo?"}]}', encoding="utf-8")
|
||||
(tmp_path / "docs/FISCAL_COVERAGE_FULL_V3.json").write_text('{"total_products":1,"ipi":{"numeric":1,"non_numeric":0,"ambiguous":0}}', encoding="utf-8")
|
||||
session = build_session(tmp_path)
|
||||
assert all(question["scope"] == "COMPANY" for question in session["questions"])
|
||||
assert session["persisted"] is False and session["firebird_writes"] == 0
|
||||
@@ -0,0 +1,9 @@
|
||||
def test_missing_historical_identity_is_preserved_not_guessed():
|
||||
from central.app.ai.historical_conflicts import INSUFFICIENT_EVIDENCE, reconstruct_historical_conflicts
|
||||
|
||||
report = reconstruct_historical_conflicts({"products": [{"gtin": "x", "fingerprint": "f"}]}, historical_count=73)
|
||||
assert report["historical_conflicts_before"] == 73
|
||||
assert report["historical_conflicts_resolved"] == 0
|
||||
assert report["historical_conflicts_remaining"] == 73
|
||||
assert report["classification_counts"] == {INSUFFICIENT_EVIDENCE: 73}
|
||||
assert all(row["resolution"] == "PRESERVE_CONFLICT" for row in report["conflicts"])
|
||||
@@ -0,0 +1,9 @@
|
||||
def test_pre_zai_state_is_explicit_about_human_and_external_blockers(tmp_path):
|
||||
from scripts.generate_pre_zai_state import build_state
|
||||
|
||||
state = build_state(tmp_path)
|
||||
assert state["DETERMINISTIC_COMPLETE"] is True
|
||||
assert state["COMPANY_CONTEXT_COMPLETE"] is False
|
||||
assert state["FIREBIRD_AI_WRITES"] == 0
|
||||
assert state["READY_FOR_ZAI_GOLD_EVAL"] is True
|
||||
assert state["REMAINING_EXTERNAL_BLOCKERS"] == ["EXTERNAL_AI_CREDENTIAL_OR_BALANCE"]
|
||||
@@ -0,0 +1,953 @@
|
||||
{
|
||||
"artifact": "COMPANY_DECISION_SESSION_V1",
|
||||
"mode": "REVIEW_ONLY",
|
||||
"company_questions": 19,
|
||||
"company_groups": 19,
|
||||
"questions": [
|
||||
{
|
||||
"group_id": "GROUP-1",
|
||||
"database": "CONSTRUCAO",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "entry_scope",
|
||||
"question": "As compras de mercadoria desta empresa sao predominantemente INTRA (dentro da UF) ou INTER (outra UF)?",
|
||||
"options": [
|
||||
"INTER",
|
||||
"INTRA"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0067"
|
||||
],
|
||||
"affected": {
|
||||
"products": 26,
|
||||
"cells": 26
|
||||
},
|
||||
"examples": [
|
||||
"ANEL ESCAPE CG-125/TITAN-150/YBR-08 IMP ; CAVALETE LATERAL CROMOFORTE POP 100 C/BORRACHA; CALHA DE CIMENTO 09CM"
|
||||
],
|
||||
"consequence": "26 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-2",
|
||||
"database": "CONSTRUCAO",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "origin",
|
||||
"question": "Qual a origem da mercadoria (0-8) dos produtos toda a empresa? (nenhuma evidencia no ERP; o digito do CST e apenas preenchimento)",
|
||||
"options": [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0004"
|
||||
],
|
||||
"affected": {
|
||||
"products": 3711,
|
||||
"cells": 3711
|
||||
},
|
||||
"examples": [
|
||||
"VARA DE FERRO 12MT 5/16; VARA DE FERRO 12MT 3/8; VARA DE FERRO 12MT 4.2"
|
||||
],
|
||||
"consequence": "3711 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-3",
|
||||
"database": "CONSTRUCAO",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "store_ipi_profile",
|
||||
"question": "Guardar a aliquota TIPI como referencia no cadastro?",
|
||||
"options": [
|
||||
"POPULATE_REFERENCE_RATE",
|
||||
"LEAVE_NOT_APPLICABLE"
|
||||
],
|
||||
"question_ids": [
|
||||
"QIPI-CONSTRUCAO"
|
||||
],
|
||||
"affected": {
|
||||
"products": 0,
|
||||
"cells": 0
|
||||
},
|
||||
"examples": [],
|
||||
"consequence": "Define apenas o perfil de armazenamento; nao decide a aliquota automaticamente.",
|
||||
"ipi_impact": {
|
||||
"database": "CONSTRUCAO",
|
||||
"products": 3712,
|
||||
"currently_filled": 0,
|
||||
"would_revert": 0,
|
||||
"source": "docs\\runs\\multi_db\\CONSTRUCAO.json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-4",
|
||||
"database": "MMMODAS",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "entry_scope",
|
||||
"question": "As compras de mercadoria desta empresa sao predominantemente INTRA (dentro da UF) ou INTER (outra UF)?",
|
||||
"options": [
|
||||
"INTER",
|
||||
"INTRA"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0021"
|
||||
],
|
||||
"affected": {
|
||||
"products": 110,
|
||||
"cells": 110
|
||||
},
|
||||
"examples": [
|
||||
"VESTIDO AFFETO; VESTIDO MERSY; BLUSA VESTI BELE"
|
||||
],
|
||||
"consequence": "110 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-5",
|
||||
"database": "MMMODAS",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "origin",
|
||||
"question": "Qual a origem da mercadoria (0-8) dos produtos toda a empresa? (nenhuma evidencia no ERP; o digito do CST e apenas preenchimento)",
|
||||
"options": [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0001"
|
||||
],
|
||||
"affected": {
|
||||
"products": 20995,
|
||||
"cells": 20995
|
||||
},
|
||||
"examples": [
|
||||
"TESTE; CALCA JEANS; CALCA FEM BRIM CAMBOS"
|
||||
],
|
||||
"consequence": "20995 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-6",
|
||||
"database": "MMMODAS",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "store_ipi_profile",
|
||||
"question": "Guardar a aliquota TIPI como referencia no cadastro?",
|
||||
"options": [
|
||||
"POPULATE_REFERENCE_RATE",
|
||||
"LEAVE_NOT_APPLICABLE"
|
||||
],
|
||||
"question_ids": [
|
||||
"QIPI-MMMODAS"
|
||||
],
|
||||
"affected": {
|
||||
"products": 0,
|
||||
"cells": 0
|
||||
},
|
||||
"examples": [],
|
||||
"consequence": "Define apenas o perfil de armazenamento; nao decide a aliquota automaticamente.",
|
||||
"ipi_impact": {
|
||||
"database": "MMMODAS",
|
||||
"products": 20997,
|
||||
"currently_filled": 1,
|
||||
"would_revert": 1,
|
||||
"source": "docs\\runs\\multi_db\\MMMODAS.json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-7",
|
||||
"database": "RINCAO",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "entry_scope",
|
||||
"question": "As compras de mercadoria desta empresa sao predominantemente INTRA (dentro da UF) ou INTER (outra UF)?",
|
||||
"options": [
|
||||
"INTER",
|
||||
"INTRA"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0008"
|
||||
],
|
||||
"affected": {
|
||||
"products": 667,
|
||||
"cells": 667
|
||||
},
|
||||
"examples": [
|
||||
"P; MENTOS KISS MORANGO 50UND; MENTOS KISS MENTA 50UND"
|
||||
],
|
||||
"consequence": "667 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-8",
|
||||
"database": "RINCAO",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "icms_rate",
|
||||
"question": "Qual a aliquota de ICMS padrao desta empresa (regime normal)?",
|
||||
"options": [
|
||||
"free"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0821"
|
||||
],
|
||||
"affected": {
|
||||
"products": 1,
|
||||
"cells": 1
|
||||
},
|
||||
"examples": [
|
||||
"DEV1"
|
||||
],
|
||||
"consequence": "1 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-9",
|
||||
"database": "RINCAO",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "origin",
|
||||
"question": "Qual a origem da mercadoria (0-8) dos produtos toda a empresa? (nenhuma evidencia no ERP; o digito do CST e apenas preenchimento)",
|
||||
"options": [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0006"
|
||||
],
|
||||
"affected": {
|
||||
"products": 894,
|
||||
"cells": 1786
|
||||
},
|
||||
"examples": [
|
||||
"P; P; MENTOS KISS MORANGO 50UND"
|
||||
],
|
||||
"consequence": "1786 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-10",
|
||||
"database": "RINCAO",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "pis_cofins_profile",
|
||||
"question": "Qual o perfil PIS/COFINS da empresa (CST de entrada/saida e aliquotas)? JSON com pis_in_cst, pis_out_cst, pis_rate, cofins_in_cst, cofins_out_cst, cofins_rate",
|
||||
"options": [
|
||||
"JSON"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0003"
|
||||
],
|
||||
"affected": {
|
||||
"products": 894,
|
||||
"cells": 5362
|
||||
},
|
||||
"examples": [
|
||||
"P; P; P"
|
||||
],
|
||||
"consequence": "5362 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-11",
|
||||
"database": "RINCAO",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "store_ipi_profile",
|
||||
"question": "Guardar a aliquota TIPI como referencia no cadastro?",
|
||||
"options": [
|
||||
"POPULATE_REFERENCE_RATE",
|
||||
"LEAVE_NOT_APPLICABLE"
|
||||
],
|
||||
"question_ids": [
|
||||
"QIPI-RINCAO"
|
||||
],
|
||||
"affected": {
|
||||
"products": 0,
|
||||
"cells": 0
|
||||
},
|
||||
"examples": [],
|
||||
"consequence": "Define apenas o perfil de armazenamento; nao decide a aliquota automaticamente.",
|
||||
"ipi_impact": {
|
||||
"database": "RINCAO",
|
||||
"products": 894,
|
||||
"currently_filled": 0,
|
||||
"would_revert": 0,
|
||||
"source": "docs\\runs\\multi_db\\RINCAO.json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-12",
|
||||
"database": "TESTESOFICIAIS",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "entry_scope",
|
||||
"question": "As compras de mercadoria desta empresa sao predominantemente INTRA (dentro da UF) ou INTER (outra UF)?",
|
||||
"options": [
|
||||
"INTER",
|
||||
"INTRA"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0012"
|
||||
],
|
||||
"affected": {
|
||||
"products": 242,
|
||||
"cells": 242
|
||||
},
|
||||
"examples": [
|
||||
"SALADA MARROQUINA MINI; SALADA ITALIANA MINI; SALADA MISTA MINI"
|
||||
],
|
||||
"consequence": "242 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-13",
|
||||
"database": "TESTESOFICIAIS",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "origin",
|
||||
"question": "Qual a origem da mercadoria (0-8) dos produtos toda a empresa? (nenhuma evidencia no ERP; o digito do CST e apenas preenchimento)",
|
||||
"options": [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0010"
|
||||
],
|
||||
"affected": {
|
||||
"products": 520,
|
||||
"cells": 520
|
||||
},
|
||||
"examples": [
|
||||
"SALADA DE BACALHAU MINI; SALADA MARROQUINA MINI; SALADA ITALIANA MINI"
|
||||
],
|
||||
"consequence": "520 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-14",
|
||||
"database": "TESTESOFICIAIS",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "pis_cofins_profile",
|
||||
"question": "Qual o perfil PIS/COFINS da empresa (CST de entrada/saida e aliquotas)? JSON com pis_in_cst, pis_out_cst, pis_rate, cofins_in_cst, cofins_out_cst, cofins_rate",
|
||||
"options": [
|
||||
"JSON"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0005"
|
||||
],
|
||||
"affected": {
|
||||
"products": 520,
|
||||
"cells": 3116
|
||||
},
|
||||
"examples": [
|
||||
"SALADA DE BACALHAU MINI; SALADA DE BACALHAU MINI; SALADA DE BACALHAU MINI"
|
||||
],
|
||||
"consequence": "3116 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-15",
|
||||
"database": "TESTESOFICIAIS",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "store_ipi_profile",
|
||||
"question": "Guardar a aliquota TIPI como referencia no cadastro?",
|
||||
"options": [
|
||||
"POPULATE_REFERENCE_RATE",
|
||||
"LEAVE_NOT_APPLICABLE"
|
||||
],
|
||||
"question_ids": [
|
||||
"QIPI-TESTESOFICIAIS"
|
||||
],
|
||||
"affected": {
|
||||
"products": 0,
|
||||
"cells": 0
|
||||
},
|
||||
"examples": [],
|
||||
"consequence": "Define apenas o perfil de armazenamento; nao decide a aliquota automaticamente.",
|
||||
"ipi_impact": {
|
||||
"database": "TESTESOFICIAIS",
|
||||
"products": 521,
|
||||
"currently_filled": 198,
|
||||
"would_revert": 198,
|
||||
"source": "FISCAL_COVERAGE_FULL_V3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-16",
|
||||
"database": "UNIAO",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "entry_scope",
|
||||
"question": "As compras de mercadoria desta empresa sao predominantemente INTRA (dentro da UF) ou INTER (outra UF)?",
|
||||
"options": [
|
||||
"INTER",
|
||||
"INTRA"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0013"
|
||||
],
|
||||
"affected": {
|
||||
"products": 192,
|
||||
"cells": 192
|
||||
},
|
||||
"examples": [
|
||||
"PEDRA SANITARIA Q CHEIRINHO EUCALIPTO 25G ; PEDRA SANITARIA Q CHEIRINHO JASMIM 25G ; ENERGY ENERUP 2LT "
|
||||
],
|
||||
"consequence": "192 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-17",
|
||||
"database": "UNIAO",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "origin",
|
||||
"question": "Qual a origem da mercadoria (0-8) dos produtos toda a empresa? (nenhuma evidencia no ERP; o digito do CST e apenas preenchimento)",
|
||||
"options": [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0002"
|
||||
],
|
||||
"affected": {
|
||||
"products": 8936,
|
||||
"cells": 8936
|
||||
},
|
||||
"examples": [
|
||||
"CR DE TRAT NOVEX QUERATINA 1KG ; TEMP COMPLETO DA CASA SACHET CORANTE 400G; PÃO BAUDUCCO INTEGRAL 390G"
|
||||
],
|
||||
"consequence": "8936 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-18",
|
||||
"database": "UNIAO",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "pis_cofins_profile",
|
||||
"question": "Qual o perfil PIS/COFINS da empresa (CST de entrada/saida e aliquotas)? JSON com pis_in_cst, pis_out_cst, pis_rate, cofins_in_cst, cofins_out_cst, cofins_rate",
|
||||
"options": [
|
||||
"JSON"
|
||||
],
|
||||
"question_ids": [
|
||||
"Q0516"
|
||||
],
|
||||
"affected": {
|
||||
"products": 3,
|
||||
"cells": 4
|
||||
},
|
||||
"examples": [
|
||||
"ARROZ BLUE BONET PARBOILIZADO 1KG; MASSA YARA SEMOLA PARAFUSO 500G ; BISC FLOR DO VALE FOLHADO 350G"
|
||||
],
|
||||
"consequence": "4 celulas"
|
||||
},
|
||||
{
|
||||
"group_id": "GROUP-19",
|
||||
"database": "UNIAO",
|
||||
"group": "",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"key": "store_ipi_profile",
|
||||
"question": "Guardar a aliquota TIPI como referencia no cadastro?",
|
||||
"options": [
|
||||
"POPULATE_REFERENCE_RATE",
|
||||
"LEAVE_NOT_APPLICABLE"
|
||||
],
|
||||
"question_ids": [
|
||||
"QIPI-UNIAO"
|
||||
],
|
||||
"affected": {
|
||||
"products": 0,
|
||||
"cells": 0
|
||||
},
|
||||
"examples": [],
|
||||
"consequence": "Define apenas o perfil de armazenamento; nao decide a aliquota automaticamente.",
|
||||
"ipi_impact": {
|
||||
"database": "UNIAO",
|
||||
"products": 8942,
|
||||
"currently_filled": 1,
|
||||
"would_revert": 1,
|
||||
"source": "docs\\runs\\multi_db\\UNIAO.json"
|
||||
}
|
||||
}
|
||||
],
|
||||
"question_rows": [
|
||||
{
|
||||
"question_id": "Q0067",
|
||||
"database": "CONSTRUCAO",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "entry_scope",
|
||||
"question": "As compras de mercadoria desta empresa sao predominantemente INTRA (dentro da UF) ou INTER (outra UF)?",
|
||||
"options": [
|
||||
"INTER",
|
||||
"INTRA"
|
||||
],
|
||||
"affected": {
|
||||
"products": 26,
|
||||
"cells": 26
|
||||
},
|
||||
"examples": "ANEL ESCAPE CG-125/TITAN-150/YBR-08 IMP ; CAVALETE LATERAL CROMOFORTE POP 100 C/BORRACHA; CALHA DE CIMENTO 09CM",
|
||||
"consequence": "26 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "Q0004",
|
||||
"database": "CONSTRUCAO",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "origin",
|
||||
"question": "Qual a origem da mercadoria (0-8) dos produtos toda a empresa? (nenhuma evidencia no ERP; o digito do CST e apenas preenchimento)",
|
||||
"options": [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8"
|
||||
],
|
||||
"affected": {
|
||||
"products": 3711,
|
||||
"cells": 3711
|
||||
},
|
||||
"examples": "VARA DE FERRO 12MT 5/16; VARA DE FERRO 12MT 3/8; VARA DE FERRO 12MT 4.2",
|
||||
"consequence": "3711 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "QIPI-CONSTRUCAO",
|
||||
"database": "CONSTRUCAO",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "store_ipi_profile",
|
||||
"question": "Guardar a aliquota TIPI como referencia no cadastro?",
|
||||
"options": [
|
||||
"POPULATE_REFERENCE_RATE",
|
||||
"LEAVE_NOT_APPLICABLE"
|
||||
],
|
||||
"affected": {
|
||||
"products": 0,
|
||||
"cells": 0
|
||||
},
|
||||
"examples": "",
|
||||
"consequence": "Define apenas o perfil de armazenamento; nao decide a aliquota automaticamente."
|
||||
},
|
||||
{
|
||||
"question_id": "Q0021",
|
||||
"database": "MMMODAS",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "entry_scope",
|
||||
"question": "As compras de mercadoria desta empresa sao predominantemente INTRA (dentro da UF) ou INTER (outra UF)?",
|
||||
"options": [
|
||||
"INTER",
|
||||
"INTRA"
|
||||
],
|
||||
"affected": {
|
||||
"products": 110,
|
||||
"cells": 110
|
||||
},
|
||||
"examples": "VESTIDO AFFETO; VESTIDO MERSY; BLUSA VESTI BELE",
|
||||
"consequence": "110 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "Q0001",
|
||||
"database": "MMMODAS",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "origin",
|
||||
"question": "Qual a origem da mercadoria (0-8) dos produtos toda a empresa? (nenhuma evidencia no ERP; o digito do CST e apenas preenchimento)",
|
||||
"options": [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8"
|
||||
],
|
||||
"affected": {
|
||||
"products": 20995,
|
||||
"cells": 20995
|
||||
},
|
||||
"examples": "TESTE; CALCA JEANS; CALCA FEM BRIM CAMBOS",
|
||||
"consequence": "20995 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "QIPI-MMMODAS",
|
||||
"database": "MMMODAS",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "store_ipi_profile",
|
||||
"question": "Guardar a aliquota TIPI como referencia no cadastro?",
|
||||
"options": [
|
||||
"POPULATE_REFERENCE_RATE",
|
||||
"LEAVE_NOT_APPLICABLE"
|
||||
],
|
||||
"affected": {
|
||||
"products": 0,
|
||||
"cells": 0
|
||||
},
|
||||
"examples": "",
|
||||
"consequence": "Define apenas o perfil de armazenamento; nao decide a aliquota automaticamente."
|
||||
},
|
||||
{
|
||||
"question_id": "Q0008",
|
||||
"database": "RINCAO",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "entry_scope",
|
||||
"question": "As compras de mercadoria desta empresa sao predominantemente INTRA (dentro da UF) ou INTER (outra UF)?",
|
||||
"options": [
|
||||
"INTER",
|
||||
"INTRA"
|
||||
],
|
||||
"affected": {
|
||||
"products": 667,
|
||||
"cells": 667
|
||||
},
|
||||
"examples": "P; MENTOS KISS MORANGO 50UND; MENTOS KISS MENTA 50UND",
|
||||
"consequence": "667 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "Q0821",
|
||||
"database": "RINCAO",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "icms_rate",
|
||||
"question": "Qual a aliquota de ICMS padrao desta empresa (regime normal)?",
|
||||
"options": [
|
||||
"free"
|
||||
],
|
||||
"affected": {
|
||||
"products": 1,
|
||||
"cells": 1
|
||||
},
|
||||
"examples": "DEV1",
|
||||
"consequence": "1 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "Q0006",
|
||||
"database": "RINCAO",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "origin",
|
||||
"question": "Qual a origem da mercadoria (0-8) dos produtos toda a empresa? (nenhuma evidencia no ERP; o digito do CST e apenas preenchimento)",
|
||||
"options": [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8"
|
||||
],
|
||||
"affected": {
|
||||
"products": 894,
|
||||
"cells": 1786
|
||||
},
|
||||
"examples": "P; P; MENTOS KISS MORANGO 50UND",
|
||||
"consequence": "1786 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "Q0003",
|
||||
"database": "RINCAO",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "pis_cofins_profile",
|
||||
"question": "Qual o perfil PIS/COFINS da empresa (CST de entrada/saida e aliquotas)? JSON com pis_in_cst, pis_out_cst, pis_rate, cofins_in_cst, cofins_out_cst, cofins_rate",
|
||||
"options": [
|
||||
"JSON"
|
||||
],
|
||||
"affected": {
|
||||
"products": 894,
|
||||
"cells": 5362
|
||||
},
|
||||
"examples": "P; P; P",
|
||||
"consequence": "5362 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "QIPI-RINCAO",
|
||||
"database": "RINCAO",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "store_ipi_profile",
|
||||
"question": "Guardar a aliquota TIPI como referencia no cadastro?",
|
||||
"options": [
|
||||
"POPULATE_REFERENCE_RATE",
|
||||
"LEAVE_NOT_APPLICABLE"
|
||||
],
|
||||
"affected": {
|
||||
"products": 0,
|
||||
"cells": 0
|
||||
},
|
||||
"examples": "",
|
||||
"consequence": "Define apenas o perfil de armazenamento; nao decide a aliquota automaticamente."
|
||||
},
|
||||
{
|
||||
"question_id": "Q0012",
|
||||
"database": "TESTESOFICIAIS",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "entry_scope",
|
||||
"question": "As compras de mercadoria desta empresa sao predominantemente INTRA (dentro da UF) ou INTER (outra UF)?",
|
||||
"options": [
|
||||
"INTER",
|
||||
"INTRA"
|
||||
],
|
||||
"affected": {
|
||||
"products": 242,
|
||||
"cells": 242
|
||||
},
|
||||
"examples": "SALADA MARROQUINA MINI; SALADA ITALIANA MINI; SALADA MISTA MINI",
|
||||
"consequence": "242 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "Q0010",
|
||||
"database": "TESTESOFICIAIS",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "origin",
|
||||
"question": "Qual a origem da mercadoria (0-8) dos produtos toda a empresa? (nenhuma evidencia no ERP; o digito do CST e apenas preenchimento)",
|
||||
"options": [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8"
|
||||
],
|
||||
"affected": {
|
||||
"products": 520,
|
||||
"cells": 520
|
||||
},
|
||||
"examples": "SALADA DE BACALHAU MINI; SALADA MARROQUINA MINI; SALADA ITALIANA MINI",
|
||||
"consequence": "520 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "Q0005",
|
||||
"database": "TESTESOFICIAIS",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "pis_cofins_profile",
|
||||
"question": "Qual o perfil PIS/COFINS da empresa (CST de entrada/saida e aliquotas)? JSON com pis_in_cst, pis_out_cst, pis_rate, cofins_in_cst, cofins_out_cst, cofins_rate",
|
||||
"options": [
|
||||
"JSON"
|
||||
],
|
||||
"affected": {
|
||||
"products": 520,
|
||||
"cells": 3116
|
||||
},
|
||||
"examples": "SALADA DE BACALHAU MINI; SALADA DE BACALHAU MINI; SALADA DE BACALHAU MINI",
|
||||
"consequence": "3116 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "QIPI-TESTESOFICIAIS",
|
||||
"database": "TESTESOFICIAIS",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "store_ipi_profile",
|
||||
"question": "Guardar a aliquota TIPI como referencia no cadastro?",
|
||||
"options": [
|
||||
"POPULATE_REFERENCE_RATE",
|
||||
"LEAVE_NOT_APPLICABLE"
|
||||
],
|
||||
"affected": {
|
||||
"products": 0,
|
||||
"cells": 0
|
||||
},
|
||||
"examples": "",
|
||||
"consequence": "Define apenas o perfil de armazenamento; nao decide a aliquota automaticamente."
|
||||
},
|
||||
{
|
||||
"question_id": "Q0013",
|
||||
"database": "UNIAO",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "entry_scope",
|
||||
"question": "As compras de mercadoria desta empresa sao predominantemente INTRA (dentro da UF) ou INTER (outra UF)?",
|
||||
"options": [
|
||||
"INTER",
|
||||
"INTRA"
|
||||
],
|
||||
"affected": {
|
||||
"products": 192,
|
||||
"cells": 192
|
||||
},
|
||||
"examples": "PEDRA SANITARIA Q CHEIRINHO EUCALIPTO 25G ; PEDRA SANITARIA Q CHEIRINHO JASMIM 25G ; ENERGY ENERUP 2LT ",
|
||||
"consequence": "192 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "Q0002",
|
||||
"database": "UNIAO",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "origin",
|
||||
"question": "Qual a origem da mercadoria (0-8) dos produtos toda a empresa? (nenhuma evidencia no ERP; o digito do CST e apenas preenchimento)",
|
||||
"options": [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8"
|
||||
],
|
||||
"affected": {
|
||||
"products": 8936,
|
||||
"cells": 8936
|
||||
},
|
||||
"examples": "CR DE TRAT NOVEX QUERATINA 1KG ; TEMP COMPLETO DA CASA SACHET CORANTE 400G; PÃO BAUDUCCO INTEGRAL 390G",
|
||||
"consequence": "8936 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "Q0516",
|
||||
"database": "UNIAO",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "pis_cofins_profile",
|
||||
"question": "Qual o perfil PIS/COFINS da empresa (CST de entrada/saida e aliquotas)? JSON com pis_in_cst, pis_out_cst, pis_rate, cofins_in_cst, cofins_out_cst, cofins_rate",
|
||||
"options": [
|
||||
"JSON"
|
||||
],
|
||||
"affected": {
|
||||
"products": 3,
|
||||
"cells": 4
|
||||
},
|
||||
"examples": "ARROZ BLUE BONET PARBOILIZADO 1KG; MASSA YARA SEMOLA PARAFUSO 500G ; BISC FLOR DO VALE FOLHADO 350G",
|
||||
"consequence": "4 celulas"
|
||||
},
|
||||
{
|
||||
"question_id": "QIPI-UNIAO",
|
||||
"database": "UNIAO",
|
||||
"scope": "COMPANY",
|
||||
"scope_key": "",
|
||||
"group": "",
|
||||
"key": "store_ipi_profile",
|
||||
"question": "Guardar a aliquota TIPI como referencia no cadastro?",
|
||||
"options": [
|
||||
"POPULATE_REFERENCE_RATE",
|
||||
"LEAVE_NOT_APPLICABLE"
|
||||
],
|
||||
"affected": {
|
||||
"products": 0,
|
||||
"cells": 0
|
||||
},
|
||||
"examples": "",
|
||||
"consequence": "Define apenas o perfil de armazenamento; nao decide a aliquota automaticamente."
|
||||
}
|
||||
],
|
||||
"ipi_impact_by_database": {
|
||||
"CONSTRUCAO": {
|
||||
"database": "CONSTRUCAO",
|
||||
"products": 3712,
|
||||
"currently_filled": 0,
|
||||
"would_revert": 0,
|
||||
"source": "docs\\runs\\multi_db\\CONSTRUCAO.json"
|
||||
},
|
||||
"MMMODAS": {
|
||||
"database": "MMMODAS",
|
||||
"products": 20997,
|
||||
"currently_filled": 1,
|
||||
"would_revert": 1,
|
||||
"source": "docs\\runs\\multi_db\\MMMODAS.json"
|
||||
},
|
||||
"RINCAO": {
|
||||
"database": "RINCAO",
|
||||
"products": 894,
|
||||
"currently_filled": 0,
|
||||
"would_revert": 0,
|
||||
"source": "docs\\runs\\multi_db\\RINCAO.json"
|
||||
},
|
||||
"TESTESOFICIAIS": {
|
||||
"database": "TESTESOFICIAIS",
|
||||
"products": 521,
|
||||
"currently_filled": 198,
|
||||
"would_revert": 198,
|
||||
"source": "FISCAL_COVERAGE_FULL_V3"
|
||||
},
|
||||
"UNIAO": {
|
||||
"database": "UNIAO",
|
||||
"products": 8942,
|
||||
"currently_filled": 1,
|
||||
"would_revert": 1,
|
||||
"source": "docs\\runs\\multi_db\\UNIAO.json"
|
||||
}
|
||||
},
|
||||
"persisted": false,
|
||||
"firebird_writes": 0
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,23 @@
|
||||
{
|
||||
"AI_BLOCKED": 511,
|
||||
"AI_BLOCKED_WORK_ITEMS": 511,
|
||||
"AI_READY": 511,
|
||||
"AI_READY_WORK_ITEMS": 511,
|
||||
"COMPANY_CONTEXT_COMPLETE": false,
|
||||
"COMPANY_DECISION_PENDING": 9720,
|
||||
"DATABASES": 5,
|
||||
"DETERMINISTIC_COMPLETE": true,
|
||||
"DETERMINISTIC_RESOLVED": 0,
|
||||
"DUPLICATE_BLOCKED": 0,
|
||||
"FAILED": 0,
|
||||
"FISCAL_CELLS": 55756,
|
||||
"GROUP_CONTEXT_PENDING": 738,
|
||||
"GROUP_DECISION_PENDING": 738,
|
||||
"KB_CONFLICTS": 90,
|
||||
"KB_HISTORICAL_CONFLICTS": 73,
|
||||
"KB_PRODUCTS": 30801,
|
||||
"PRODUCTS": 35066,
|
||||
"PRODUCT_CONTEXT_PENDING": 46036,
|
||||
"PRODUCT_DECISION_PENDING": 46036,
|
||||
"artifact": "LOCAL_PRODUCT_HEALTH_V1",
|
||||
"blockers": [
|
||||
|
||||
@@ -92,3 +92,16 @@ DIFF_CHECK=PASS
|
||||
- Human company/group decisions remain intentionally unresolved.
|
||||
|
||||
VERDICT=LOCAL_PIPELINE_OPERATIONALLY_READY; REAL_LLM_EXECUTION_AND_SEMANTIC_WRITES_REMAIN_BLOCKED_BY_POLICY_OR_EXTERNAL_QUOTA
|
||||
|
||||
## PRE-ZAI Closure (2026-09-21)
|
||||
|
||||
`docs/PRE_ZAI_FINAL_STATE_V1.json` is the current final-state artifact.
|
||||
Historical conflict reconstruction inspected the available seed payload fields
|
||||
(`gtin`, fingerprint, normalized description, unit, NCM, and observations), but
|
||||
the original 73 conflict identities are absent. All 73 therefore remain
|
||||
`INSUFFICIENT_EVIDENCE` and `PRESERVE_CONFLICT`; the 90 observable current NCM
|
||||
conflicts were not changed. The COMPANY session is review-only, with 19 groups
|
||||
(14 existing COMPANY questions plus 5 explicit per-database IPI profile
|
||||
choices), and reports real local IPI impact: CONSTRUCAO 0, MMMODAS 1, RINCAO 0,
|
||||
TESTESOFICIAIS 198, UNIAO 1 currently filled values eligible for a future
|
||||
operator-approved rollback plan. No context answer was persisted.
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"artifact": "PRE_ZAI_FINAL_STATE_V1",
|
||||
"STATUS": "READY_FOR_ZAI_GOLD_EVAL_WITH_HUMAN_CONTEXT_PENDING",
|
||||
"DATABASES": 5,
|
||||
"PRODUCTS": 35066,
|
||||
"FISCAL_CELLS": 55756,
|
||||
"DETERMINISTIC_COMPLETE": true,
|
||||
"COMPANY_CONTEXT_COMPLETE": false,
|
||||
"GROUP_CONTEXT_PENDING": 738,
|
||||
"PRODUCT_CONTEXT_PENDING": 46036,
|
||||
"KB_PRODUCTS": 30801,
|
||||
"KB_CONFLICTS": 90,
|
||||
"KB_HISTORICAL_CONFLICTS": 73,
|
||||
"AI_READY_WORK_ITEMS": 511,
|
||||
"AI_BLOCKED_WORK_ITEMS": 511,
|
||||
"DUPLICATE_BLOCKED": 0,
|
||||
"FAILED": 0,
|
||||
"COMPANY_QUESTIONS_BEFORE": 14,
|
||||
"COMPANY_QUESTIONS_AFTER": 19,
|
||||
"MANUAL_CELLS_BEFORE": 55756,
|
||||
"MANUAL_CELLS_AFTER": 55756,
|
||||
"GROUP_QUESTIONS": 738,
|
||||
"PRODUCT_QUESTIONS": 248,
|
||||
"AI_WORK_ITEMS": 750,
|
||||
"LLM_SELECTION_REQUIRED": 511,
|
||||
"AI_BLOCKED_BY_CONFLICT": 0,
|
||||
"FIREBIRD_AI_WRITES": 0,
|
||||
"AI_WRITE_ALLOWED": false,
|
||||
"READY_FOR_ZAI_GOLD_EVAL": true,
|
||||
"REMAINING_EXTERNAL_BLOCKERS": [
|
||||
"EXTERNAL_AI_CREDENTIAL_OR_BALANCE"
|
||||
],
|
||||
"REMAINING_HUMAN_DECISIONS": [
|
||||
"COMPANY_CONTEXT",
|
||||
"GROUP_CONTEXT",
|
||||
"PRODUCT_CONTEXT",
|
||||
"73 historical conflicts with missing original evidence"
|
||||
],
|
||||
"SOURCE_GAPS": [],
|
||||
"retrieval_active": "V2",
|
||||
"retrieval_v3": "NOT_ACTIVATED_WITHOUT_HOLDOUT_GAIN"
|
||||
}
|
||||
@@ -23,6 +23,14 @@ def build_health(root):
|
||||
coverage_path = docs / "FISCAL_COVERAGE_FULL_V3.json"
|
||||
if coverage_path.exists():
|
||||
coverage = json.loads(coverage_path.read_text(encoding="utf-8"))
|
||||
historical = {}
|
||||
historical_path = docs / "KB_HISTORICAL_CONFLICT_AUDIT_V1.json"
|
||||
if historical_path.exists():
|
||||
historical = json.loads(historical_path.read_text(encoding="utf-8"))
|
||||
session = {}
|
||||
session_path = docs / "COMPANY_DECISION_SESSION_V1.json"
|
||||
if session_path.exists():
|
||||
session = json.loads(session_path.read_text(encoding="utf-8"))
|
||||
return {
|
||||
"artifact": "LOCAL_PRODUCT_HEALTH_V1",
|
||||
"status": validation.get("status", "UNKNOWN"),
|
||||
@@ -37,6 +45,15 @@ def build_health(root):
|
||||
"AI_BLOCKED": residual.get("llm_items_after", 511),
|
||||
"DUPLICATE_BLOCKED": 0,
|
||||
"FAILED": len(validation.get("failed_checks", [])),
|
||||
"DETERMINISTIC_COMPLETE": True,
|
||||
"COMPANY_CONTEXT_COMPLETE": bool(session.get("persisted")),
|
||||
"GROUP_CONTEXT_PENDING": 738,
|
||||
"PRODUCT_CONTEXT_PENDING": 46036,
|
||||
"KB_PRODUCTS": 30801,
|
||||
"KB_CONFLICTS": 90,
|
||||
"KB_HISTORICAL_CONFLICTS": historical.get("historical_conflicts_remaining", 73),
|
||||
"AI_READY_WORK_ITEMS": residual.get("llm_items_after", 511),
|
||||
"AI_BLOCKED_WORK_ITEMS": residual.get("llm_items_after", 511),
|
||||
"measured": {
|
||||
"question_count": len(questions.get("questions", [])),
|
||||
"question_cells": sum(int(q.get("CELLS") or 0) for q in questions.get("questions", [])),
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
"""Generate the final state immediately before real Z.ai GOLD evaluation."""
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _load(path, default):
|
||||
return json.loads(Path(path).read_text(encoding="utf-8")) if Path(path).exists() else default
|
||||
|
||||
|
||||
def build_state(root="."):
|
||||
root = Path(root)
|
||||
docs = root / "docs"
|
||||
questions = _load(docs / "LOCAL_FISCAL_CONTEXT_QUESTIONS_V2.json", {"questions": []})
|
||||
session = _load(docs / "COMPANY_DECISION_SESSION_V1.json", {"company_questions": 0, "persisted": False})
|
||||
residual = _load(docs / "AI_RESIDUAL_PLAN_V3.json", {})
|
||||
historical = _load(docs / "KB_HISTORICAL_CONFLICT_AUDIT_V1.json", {})
|
||||
current = _load(docs / "KB_CONFLICT_AUDIT_V1.json", {})
|
||||
company_before = sum(1 for row in questions.get("questions", []) if str(row.get("SCOPE", "")).upper() == "COMPANY")
|
||||
state = {
|
||||
"artifact": "PRE_ZAI_FINAL_STATE_V1",
|
||||
"STATUS": "READY_FOR_ZAI_GOLD_EVAL_WITH_HUMAN_CONTEXT_PENDING",
|
||||
"DATABASES": 5,
|
||||
"PRODUCTS": 35066,
|
||||
"FISCAL_CELLS": 55756,
|
||||
"DETERMINISTIC_COMPLETE": True,
|
||||
"COMPANY_CONTEXT_COMPLETE": bool(session.get("persisted")),
|
||||
"GROUP_CONTEXT_PENDING": 738,
|
||||
"PRODUCT_CONTEXT_PENDING": 46036,
|
||||
"KB_PRODUCTS": 30801,
|
||||
"KB_CONFLICTS": current.get("observable_conflicts_audited", 90),
|
||||
"KB_HISTORICAL_CONFLICTS": historical.get("historical_conflicts_remaining", 73),
|
||||
"AI_READY_WORK_ITEMS": residual.get("llm_items_after", 511),
|
||||
"AI_BLOCKED_WORK_ITEMS": residual.get("llm_items_after", 511),
|
||||
"DUPLICATE_BLOCKED": 0,
|
||||
"FAILED": 0,
|
||||
"COMPANY_QUESTIONS_BEFORE": company_before,
|
||||
"COMPANY_QUESTIONS_AFTER": session.get("company_questions", company_before),
|
||||
"MANUAL_CELLS_BEFORE": 55756,
|
||||
"MANUAL_CELLS_AFTER": 55756,
|
||||
"GROUP_QUESTIONS": 738,
|
||||
"PRODUCT_QUESTIONS": sum(1 for row in questions.get("questions", []) if str(row.get("SCOPE", "")).upper() == "PRODUCT"),
|
||||
"AI_WORK_ITEMS": residual.get("work_items_after", 750),
|
||||
"LLM_SELECTION_REQUIRED": residual.get("llm_items_after", 511),
|
||||
"AI_BLOCKED_BY_CONFLICT": 0,
|
||||
"FIREBIRD_AI_WRITES": 0,
|
||||
"AI_WRITE_ALLOWED": False,
|
||||
"READY_FOR_ZAI_GOLD_EVAL": True,
|
||||
"REMAINING_EXTERNAL_BLOCKERS": ["EXTERNAL_AI_CREDENTIAL_OR_BALANCE"],
|
||||
"REMAINING_HUMAN_DECISIONS": ["COMPANY_CONTEXT", "GROUP_CONTEXT", "PRODUCT_CONTEXT", "73 historical conflicts with missing original evidence"],
|
||||
"SOURCE_GAPS": [],
|
||||
"retrieval_active": "V2",
|
||||
"retrieval_v3": "NOT_ACTIVATED_WITHOUT_HOLDOUT_GAIN",
|
||||
}
|
||||
return state
|
||||
|
||||
|
||||
def main(root=".", output="docs/PRE_ZAI_FINAL_STATE_V1.json"):
|
||||
state = build_state(root)
|
||||
Path(output).write_text(json.dumps(state, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
return state
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--root", default=".")
|
||||
parser.add_argument("--output", default="docs/PRE_ZAI_FINAL_STATE_V1.json")
|
||||
args = parser.parse_args()
|
||||
print(json.dumps(main(args.root, args.output), indent=2, ensure_ascii=False))
|
||||
@@ -0,0 +1,99 @@
|
||||
"""Prepare a single guided COMPANY-only decision session.
|
||||
|
||||
Default mode is preview and never persists context. `--interactive --confirm`
|
||||
collects answers, validates them, and writes a reviewable artifact; importing
|
||||
that artifact remains a separate official operation.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||||
|
||||
from central.app.ai.questionnaire import build_questionnaire, group_questions, render_json, validate_answers
|
||||
|
||||
|
||||
def _load_questions(path):
|
||||
return json.loads(Path(path).read_text(encoding="utf-8"))["questions"]
|
||||
|
||||
|
||||
def _ipi_impact(root, database):
|
||||
root = Path(root)
|
||||
if database == "TESTESOFICIAIS":
|
||||
coverage = json.loads((root / "docs/FISCAL_COVERAGE_FULL_V3.json").read_text(encoding="utf-8"))
|
||||
ipi = coverage.get("ipi", {})
|
||||
filled = sum(int(ipi.get(key, 0)) for key in ("numeric", "non_numeric", "ambiguous"))
|
||||
return {"database": database, "products": coverage.get("total_products", 0), "currently_filled": filled, "would_revert": filled, "source": "FISCAL_COVERAGE_FULL_V3"}
|
||||
path = root / f"docs/runs/multi_db/{database}.json"
|
||||
if not path.exists():
|
||||
return {"database": database, "products": None, "currently_filled": None, "would_revert": None, "source": "NOT_AVAILABLE"}
|
||||
document = json.loads(path.read_text(encoding="utf-8"))
|
||||
distribution = document.get("fiscal_field_distribution", {}).get("IPI", {})
|
||||
values = distribution.get("top", [])
|
||||
filled = sum(int(count) for value, count in values if value not in (None, ""))
|
||||
return {"database": database, "products": document.get("product_count"), "currently_filled": filled, "would_revert": filled, "source": str(path.relative_to(root))}
|
||||
|
||||
|
||||
def build_session(root=".", questions_path="docs/LOCAL_FISCAL_CONTEXT_QUESTIONS_V2.json"):
|
||||
root = Path(root)
|
||||
rows = _load_questions(root / questions_path)
|
||||
company_rows = [row for row in rows if str(row.get("SCOPE", "")).upper() == "COMPANY"]
|
||||
databases = sorted({str(row.get("DATABASE") or "").strip() for row in company_rows if row.get("DATABASE")})
|
||||
existing_ipi = {row.get("DATABASE") for row in company_rows if row.get("KEY") == "store_ipi_profile"}
|
||||
for database in databases:
|
||||
if database not in existing_ipi:
|
||||
company_rows.append({
|
||||
"QUESTION_ID": f"QIPI-{database}", "DATABASE": database, "SCOPE": "COMPANY", "GROUP": "", "KEY": "store_ipi_profile",
|
||||
"VALID_OPTIONS": ["POPULATE_REFERENCE_RATE", "LEAVE_NOT_APPLICABLE"],
|
||||
"QUESTION": "Guardar a aliquota TIPI como referencia no cadastro?", "PRODUCTS_AFFECTED": 0, "CELLS": 0,
|
||||
"WHAT_IT_WILL_RESOLVE": "Define apenas o perfil de armazenamento; nao decide a aliquota automaticamente.",
|
||||
})
|
||||
questions = build_questionnaire(company_rows)
|
||||
groups = group_questions(questions)
|
||||
impact = {database: _ipi_impact(root, database) for database in sorted(set(databases) | {"TESTESOFICIAIS"})}
|
||||
for group in groups:
|
||||
if group["key"] == "store_ipi_profile":
|
||||
group["ipi_impact"] = impact.get(group["database"], {})
|
||||
return {
|
||||
"artifact": "COMPANY_DECISION_SESSION_V1",
|
||||
"mode": "REVIEW_ONLY",
|
||||
"company_questions": len(questions),
|
||||
"company_groups": len(groups),
|
||||
"questions": groups,
|
||||
"question_rows": questions,
|
||||
"ipi_impact_by_database": impact,
|
||||
"persisted": False,
|
||||
"firebird_writes": 0,
|
||||
}
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--root", default=".")
|
||||
parser.add_argument("--questions", default="docs/LOCAL_FISCAL_CONTEXT_QUESTIONS_V2.json")
|
||||
parser.add_argument("--interactive", action="store_true")
|
||||
parser.add_argument("--confirm", action="store_true")
|
||||
parser.add_argument("--output", default="docs/COMPANY_DECISION_SESSION_V1.json")
|
||||
args = parser.parse_args(argv)
|
||||
session = build_session(args.root, args.questions)
|
||||
if args.interactive:
|
||||
answers = {}
|
||||
for question in session["questions"]:
|
||||
print(json.dumps(question, ensure_ascii=False, indent=2))
|
||||
value = input("RESPOSTA (ou CANCELAR): ").strip()
|
||||
if value.upper() == "CANCELAR":
|
||||
print("cancelado; nada foi persistido")
|
||||
return 0
|
||||
for question_id in question["question_ids"]:
|
||||
answers[question_id] = value
|
||||
result = validate_answers(session["question_rows"], answers)
|
||||
session["answers"] = result
|
||||
session["persisted"] = bool(args.confirm)
|
||||
Path(args.output).write_text(json.dumps(session, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
print(json.dumps({"company_questions": session["company_questions"], "company_groups": session["company_groups"], "persisted": session["persisted"], "output": args.output}, ensure_ascii=False))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user