from __future__ import annotations import json import zipfile from pathlib import Path from typing import Any from .safe_archive import inspect_zip, verify_checksum_ledger REQUIRED_PACKET_MEMBERS = { '00_READ_ME_FIRST.md', 'creator_trace_capsule.json', 'evidence_asset_manifest.json', 'temporal_chain.json', 'causal_arc_packet.json', 'dpio_procedural_read.json', 'dpio_execution_order_receipt.json', 'minimum_cut_candidates.json', 'consent_receipt.json', 'run_manifest.json', 'validation_receipt.txt', 'SHA256SUMS.txt', } def audit_packet(path: str | Path) -> dict[str, Any]: archive = inspect_zip(path) if archive['findings']: return { 'state': 'MUST_STOP', 'archive': archive, 'missing_members': [], 'checksum_receipt': {'state': 'NOT_RUN'}, 'continuity_findings': ['Archive safety boundary failed.'], 'repair_plan': ['Rebuild the packet without unsafe paths, duplicate members, symlinks, or excessive expansion.'], } with zipfile.ZipFile(path) as zf: names = set(zf.namelist()) missing = sorted(REQUIRED_PACKET_MEMBERS - names) capsule = json.loads(zf.read('creator_trace_capsule.json')) if 'creator_trace_capsule.json' in names else {} execution = json.loads(zf.read('dpio_execution_order_receipt.json')) if 'dpio_execution_order_receipt.json' in names else [] ledger = verify_checksum_ledger(path) findings: list[str] = [] repairs: list[str] = [] if missing: findings.append('Required packet surfaces are missing.') repairs.append('Regenerate the packet from the source-bound compiler; do not hand-fill missing surfaces.') stages = [row.get('stage') for row in execution if isinstance(row, dict)] required_order = ['SOURCE_REGISTERED','EVENTS_REGISTERED','CHRONOLOGY_MAPPED','CAUSAL_FAMILIES_COLLAPSED','PREDICTIONS_FROZEN','HYPOTHESES_FROZEN','PRESSURE_TESTED'] if stages != required_order: findings.append('DPIO causal execution order is missing or drifted.') repairs.append('Restore the frozen DPIO execution order before pressure testing hypotheses.') if ledger['state'] != 'PASS': findings.append('Packet checksum continuity failed.') repairs.append('Return to original source bytes and rebuild the checksum ledger; do not mutate evidence in place.') consent = capsule.get('consent', {}) if consent.get('publication_requires_additional_review') is not True: findings.append('Publication review lock is absent.') repairs.append('Require separate publication review and preserve creator-controlled consent scope.') state = 'GREEN' if not findings else ('MUST_STOP' if ledger['state'] != 'PASS' or archive['findings'] else 'REPAIRING') return { 'state': state, 'archive': archive, 'missing_members': missing, 'checksum_receipt': ledger, 'capsule_id': capsule.get('capsule_id'), 'loop_state': capsule.get('loop_state'), 'continuity_findings': findings, 'repair_plan': repairs, 'boundary': 'Audit prepares repair deltas but never mutates the submitted packet.', }