"""Final read-only verification of sealed artifacts and audit preservation.""" from pathlib import Path from datetime import datetime,timezone import json,csv,hashlib,zipfile,collections csv.field_size_limit(20000000) root=Path(__file__).resolve().parent.parent;private=root/'storage/app/private/investmoz-v2/portal-audit';doc=root/'docs/investmoz/v2/auditoria-portal';out=root/'outputs/investmoz-opportunity-workflow-candidate-20261011' sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() receipt=json.loads((out/'pacote.json').read_text());manifest=json.loads((out/'manifesto.json').read_text());plan=json.loads((private/'portal-stability-latest.json').read_text());source=Path(plan['source']) assert sha(out/receipt['archive'])==receipt['sha256'] and sha(out/'manifesto.json')==receipt['manifest_sha256'] core={k:v for k,v in manifest.items()if k not in ['revision','sealed_at']} assert hashlib.sha256(json.dumps(core,sort_keys=True,separators=(',',':'),ensure_ascii=False).encode()).hexdigest()==receipt['revision'] with zipfile.ZipFile(out/receipt['archive'])as z: assert z.testzip() is None for n,h in manifest['payload'].items(): assert sha(out/'payload'/n)==h and sha(source/n)==h assert hashlib.sha256(z.read('payload/'+n)).hexdigest()==h for n in ['manifesto.json','relatorio.md','procedimento.md','evidencias-por-criterio.json']:assert z.read(n)==(out/n).read_bytes() for n,h in manifest['unchanged_dependencies'].items():assert sha(root/n)==h for n,h in json.loads((private/'functional-active-files-before-20261011.json').read_text()).items():assert sha(root/n)==h for n,h in manifest['QA_evidence'].items():assert sha(private/n)==h original=json.loads((private/'functional-finalize-20261011/csv-edits.json').read_text()) packets=[json.loads((private/folder/'csv-edits.json').read_text())for folder in ['functional-finalize-20261011','functional-candidate-finalize-20261011','functional-fixed-finalize-20261011']] changed_ids=set() for file in original['files']: with (doc/file['filename']).open(encoding='utf-8-sig',newline='')as stream:rows=list(csv.reader(stream)) before=file['rows'];assert len(rows)==len(before) and rows[0]==before[0];headers=rows[0];allowed={} for packet in packets: for entry in packet['files']: if entry['filename']!=file['filename']:continue for patch in entry['patches']:allowed.setdefault(patch['row'],set()).update(patch['values']) for number,(a,b)in enumerate(zip(before[1:],rows[1:]),1): assert len(a)==len(b) for column,(old,new)in enumerate(zip(a,b)): if old!=new: assert headers[column]in allowed.get(number,set()),(file['filename'],number,headers[column]);changed_ids.add(b[headers.index('ID')]) if file['filename']=='matriz-requisitos.csv': states=dict(collections.Counter(row[headers.index('Estado')]for row in rows[1:]));assert states==dict(collections.Counter(row[headers.index('Estado')]for row in before[1:]));assert len(rows)-1==3393 occurrences=sum(int(row[headers.index('Quantidade de linhas de origem')])for row in rows[1:]);assert occurrences==6845 assert len(changed_ids)==25 snapshot=json.loads((private/'functional-final-persistence-qa-20261011.json').read_text()) assert len(snapshot['categories'])==6 for row in snapshot['categories']:assert row['state']=='published'and row['approval_actor']==24 and row['publication_actor']==25 and row['current_hash']==row['approval_hash']==row['publication_hash'] backup=json.loads((private/'functional-backup-restoration-qa-20261011.json').read_text()) assert backup['result']=='passed'and sha(Path(backup['dump_path']))==backup['dump_sha256']and sha(Path(backup['files_path']))==backup['files_sha256'] result={'result':'passed','at':datetime.now(timezone.utc).isoformat(),'candidate':receipt['revision'],'code_revision':receipt['code_revision'],'package_sha256':receipt['sha256'],'source_payload_bundle_and_proof_hashes_verified':True,'requirements':3393,'source_occurrences':6845,'states':states,'updated_requirements':25,'unmodified_IDs_sources_acceptance_and_closed_states':True,'six_current_approval_publication_hashes_match':True,'active_baseline_preserved':True,'activation_ready':False,'active_writes':0} (out/'verificacao-final.json').write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n',encoding='utf-8');print(json.dumps(result,ensure_ascii=False))