#!/usr/bin/env python3 """Source-bound Action 1 verifier. No candidate imports, execution, or source writes. A successful mechanical run does NOT assert semantic equivalence. Unless an externally approved, hash-pinned model adjudication is supplied, exit 3 and keep semantic statuses UNRESOLVED. Exit 2 is malformed/untrusted input. Exit 0 is only bounded specification equivalence under that declared approval, never runtime. """ from __future__ import annotations import argparse import hashlib import io import json import re import stat import sys import zipfile from pathlib import Path, PurePosixPath from typing import Any CANDIDATE_SHA = 'c3bd53d775752494d982183cc71b551af6b4bf2c879416d6866a859e64fd28ac' CANDIDATE_TREE = 'ddc0e4fd644b59a29d1bb7a7f647cb89f2556f4d' ROOT_NAME = 'VPL_V5_R08_HF03_T01_R01' V4_NAME = 'VPL_V4_SEMANTIC_LOAD_BUNDLE_REV006.md' V4_SHA = 'd4e75170b791b4458d60ea39f35fa165a81b89fce236c12f15f40af038a95d62' V5_NAME = 'VPL_V5_SEMANTIC_LOAD_BUNDLE_R08.md' MAP = 'controls/V4_PRESERVATION_MAP_HF02.json' MATRIX = 'controls/MANUAL_LIGHT_PRESERVATION_MATRIX_R02.md' AUTH_PINS = { V4_NAME: V4_SHA, 'VPL_V4_EQUAL_LOAD_MANIFEST_REV006.json': '1e7ce7be27906b1f3251735a1f38c3c14b7d34e5ded7d4679938c5e68d242aea', 'PERSISTENCE_CHALLENGE_MATRIX_REV006.json': 'f3e224d4c18a5aa6f2efe3708a9d62607660965d3db446078e7c02a3f10e7ae9', 'REV006_SHA256SUMS.txt': 'ccf8bce20b37c6f6613abc4c855734332ea7f37edff6f3ced57e590b08e32c98', } REGISTRIES = ( ('AGENT_REGISTRY.json', 'controls/VPL_V5_06_AGENT_REGISTRY_R02.json', 'agents'), ('V4_MODULE_REGISTRY_FINAL.json', 'controls/VPL_V5_06_MODULE_REGISTRY_R02.json', 'modules'), ('V4_LOCKED_GUIDELINES.json', 'controls/VPL_V5_06_GUIDELINE_REGISTRY_R02.json', 'rules'), ) MODEL_RULE = 'SOURCE_BOUND_VERBATIM_INHERITANCE_WITH_EXPLICIT_OVERLAY_REVIEW_R01' class InvalidInput(ValueError): pass def require(condition: bool, message: str) -> None: if not condition: raise InvalidInput(message) def sha(b: bytes) -> str: return hashlib.sha256(b).hexdigest() def canonical(x: Any) -> bytes: return (json.dumps(x, sort_keys=True, ensure_ascii=False, allow_nan=False, separators=(',', ':')) + '\n').encode('utf-8') def load_json(b: bytes) -> Any: def pairs(items): out = {} for k, v in items: require(k not in out, 'duplicate JSON key: ' + k) out[k] = v return out def bad_constant(value): raise InvalidInput('non-finite JSON value: ' + value) try: return json.loads(b.decode('utf-8'), object_pairs_hook=pairs, parse_constant=bad_constant) except (UnicodeError, json.JSONDecodeError) as e: raise InvalidInput('invalid UTF-8 JSON') from e def same(a: Any, b: Any) -> bool: return canonical(a) == canonical(b) def valid_path(name: str) -> str: p = PurePosixPath(name) require(bool(name) and not name.startswith('/') and '\\' not in name and ':' not in name and '\x00' not in name and all(x not in ('', '.', '..') for x in name.split('/')), 'unsafe path: ' + repr(name)) require(p.as_posix() == name, 'noncanonical path') return name def read_archive(raw: bytes) -> dict[str, bytes]: """In-memory reads only; reject duplicates, traversal and nonregular members.""" require(len(raw) <= 25_000_000, 'archive exceeds bounded input size') try: with zipfile.ZipFile(io.BytesIO(raw)) as z: require(len(z.infolist()) <= 2000, 'too many archive members') seen, data, total = set(), {}, 0 for item in z.infolist(): name = item.filename.rstrip('/') if item.is_dir() else item.filename valid_path(name) require(item.filename not in seen, 'duplicate archive member') seen.add(item.filename) mode = item.external_attr >> 16 require(not stat.S_ISLNK(mode), 'archive symlink forbidden') require(not mode or stat.S_IFMT(mode) in (0, stat.S_IFREG, stat.S_IFDIR), 'nonregular archive member') require(not (item.flag_bits & 1), 'encrypted archive forbidden') if item.is_dir(): continue require(name.startswith(ROOT_NAME + '/'), 'wrong candidate root') total += item.file_size require(total <= 75_000_000 and item.file_size <= 10_000_000, 'uncompressed size exceeds bound') rel = name[len(ROOT_NAME) + 1:] data[valid_path(rel)] = z.read(item) return data except (zipfile.BadZipFile, RuntimeError, EOFError) as e: raise InvalidInput('invalid candidate archive') from e def git_tree(data: dict[str, bytes]) -> str: tree: dict[str, Any] = {} for name, b in data.items(): parts = valid_path(name).split('/') here = tree for part in parts[:-1]: require(not isinstance(here.get(part), bytes), 'path/file collision') here = here.setdefault(part, {}) require(parts[-1] not in here, 'duplicate tree leaf') here[parts[-1]] = b def obj(kind: str, b: bytes) -> bytes: return hashlib.sha1(kind.encode() + b' ' + str(len(b)).encode() + b'\0' + b).digest() def digest(node) -> bytes: out = b'' for name in sorted(node, key=lambda n: (n + ('/' if isinstance(node[n], dict) else '')).encode()): v = node[name] out += (b'40000' if isinstance(v, dict) else b'100644') + b' ' + name.encode() + b'\0' out += digest(v) if isinstance(v, dict) else obj('blob', v) return obj('tree', out) return digest(tree).hex() def source_blocks(v4: bytes, manifest: dict) -> tuple[dict[str, bytes], list[dict]]: """Recover exact original files from named byte-counted V4 transport blocks.""" require(manifest.get('canonical_source_count') == 29, 'authority must bind 29 sources') require(manifest.get('semantic_bundle_sha256') == sha(v4), 'manifest/V4 hash mismatch') require(manifest.get('semantic_bundle_bytes') == len(v4), 'manifest/V4 length mismatch') declared = manifest.get('canonical_sources') require(isinstance(declared, list) and len(declared) == 29, 'incomplete canonical source list') blocks, observations = {}, [] begins = re.findall(rb'^# BEGIN CANONICAL SOURCE: (.+)$', v4, re.M) require(len(begins) == 29 and len(set(begins)) == 29, 'missing/duplicate source blocks') require([x.decode() for x in begins] == [d['name'] for d in declared], 'source order differs') manifest_lines = re.findall(rb'^- `([^`]+)` \xe2\x80\x94 ([\d,]+) bytes \xe2\x80\x94 `([a-f0-9]{64})`$', v4, re.M) observed_manifest = [{'name': n.decode(), 'bytes': int(s.replace(b',', b'')), 'sha256': h.decode()} for n, s, h in manifest_lines] require(same(observed_manifest, declared), 'embedded and recovered manifest differ') for row in declared: name = valid_path(row['name']) require(name not in blocks and type(row['bytes']) is int and row['bytes'] > 0, 'invalid canonical source row') marker = b'# BEGIN CANONICAL SOURCE: ' + name.encode() + b'\n\n' require(v4.count(marker) == 1, 'ambiguous canonical source marker') start = v4.index(marker) + len(marker) raw = v4[start:start + row['bytes']] endmarker = b'\n\n# END CANONICAL SOURCE: ' + name.encode() + b'\n' require(v4[start + len(raw):].startswith(endmarker), 'canonical source terminator differs') require(sha(raw) == row['sha256'], 'canonical source bytes differ: ' + name) blocks[name] = raw observations.append({**row, 'bundle_start_byte': start, 'hash_verified': True}) return blocks, observations def derive_spans(v4: bytes) -> list[dict]: """Re-derive the frozen inventory's heading spans, including its preambles. The original inventory treats hash-prefixed headings inside fenced examples as section boundaries. Preserve that exact scope; do not relabel these as 328 clauses. """ lines = v4.decode('utf-8').splitlines(keepends=True) result, src, start, heading = [], None, None, None for pos, line in enumerate(lines): if line.startswith('# BEGIN CANONICAL SOURCE: '): require(src is None, 'nested canonical block') src, start, heading = line.strip().split(': ', 1)[1], pos + 1, 'SOURCE_PREAMBLE' elif src is not None and (line.startswith('# END CANONICAL SOURCE: ') or re.match(r'^#{1,6} ', line)): if any(x.strip() for x in lines[start:pos]): raw = ''.join(lines[start:pos]).encode() entry = {'source': src, 'heading': heading, 'start_line': start + 1, 'end_line': pos, 'span_sha256': sha(raw)} entry['span_id'] = 'S-' + sha(canonical(entry))[:24] result.append(entry) if line.startswith('# END CANONICAL SOURCE: '): require(line.strip().split(': ', 1)[1] == src, 'wrong source end marker') src, start, heading = None, None, None else: start, heading = pos, line.strip() require(src is None and len(result) == 328, 'expected complete 328-span inventory') require(len({r['span_id'] for r in result}) == 328, 'duplicate derived span identity') return result def verify_source_map(mapping: dict, spans: list[dict], v4: bytes) -> None: require(mapping.get('source_sha256') == sha(v4), 'preservation map V4 pin differs') rows = mapping.get('source_sections') require(isinstance(rows, list) and len(rows) == 328, 'source map incomplete') keys = ('source', 'heading', 'start_line', 'end_line', 'span_sha256') for row, derived in zip(rows, spans): require(same({k: row.get(k) for k in keys}, {k: derived[k] for k in keys}), 'map coverage/range/identity differs') require(row.get('destination') == V5_NAME and row.get('disposition') == 'RETAIN', 'map destination/disposition differs') # semantic_equivalence/status/resolved metadata is deliberately NOT consulted. def verify_v5_bundle(data: dict[str, bytes], v4: bytes) -> tuple[int, list[dict]]: idx = load_json(data['SEMANTIC_INPUTS_R08.json']) entries = idx.get('files') require(isinstance(entries, list) and len(entries) == 35, 'V5 input inventory incomplete') expected = ['frozen-source/' + V4_NAME, 'VPL_V5_EXECUTION_BIBLE_R10.md', 'VPL_V5_REMEDIATION_BIBLE_R05.md', 'O1_ADOPTED_AMENDMENTS.md'] expected += sorted(n for n in data if n.startswith('controls/') and n.count('/') == 1 and PurePosixPath(n).suffix in ('.json', '.md')) expected += ['templates/BUILD_RECAP_STRUCTURE_R02.html'] require([e['path'] for e in entries] == expected, 'V5 source set/order differs') require(idx.get('no_selective_pruning') is True and idx.get('runtime_ingestion_certified') is False, 'invalid semantic source scope') require(idx.get('module_ids') == [f'M{i:02}' for i in range(1, 27)], 'module scope differs') bundle = data[V5_NAME] first = b'\n\n## Source 1: ' require(bundle.count(first) == 1, 'ambiguous first V5 source') header = bundle.split(first, 1)[0] require(b'Published authority remains V4 FINAL / REV006.' in header and b'On an unresolved conflict: STOP for source/owner resolution.' in header, 'V5 authority/conflict boundary missing') rebuilt = header for i, e in enumerate(entries, 1): path = valid_path(e['path']) require(path in data and sha(data[path]) == e['sha256'] and len(data[path]) == e['size_bytes'], 'V5 semantic entry hash/size differs: ' + path) rebuilt += (f'\n\n## Source {i}: {path}\n\nSHA-256: {e["sha256"]}\n\n' '\n').encode() + data[path] + b'\n\n' require(rebuilt == bundle, 'V5 bundle cannot be reconstructed from complete source list') require(data['frozen-source/' + V4_NAME] == v4 and bundle.count(v4) == 1, 'recovered V4 authority not uniquely verbatim in V5') return bundle[:bundle.index(v4)].count(b'\n'), entries def field_diffs(old: dict, new: dict) -> list[dict]: """Keep missing and JSON null distinct, and preserve complete values.""" return [{'field': k, 'source_present': k in old, 'destination_present': k in new, 'source_value': old.get(k), 'destination_value': new.get(k)} for k in sorted(set(old) | set(new)) if k not in old or k not in new or not same(old[k], new[k])] def registry_comparison(blocks: dict, data: dict) -> dict: rows, wrappers = [], [] for source, dest, array in REGISTRIES: a, b = load_json(blocks[source]), load_json(data[dest]) def keyed(x): require(isinstance(x.get(array), list) and len(x[array]) > 0, 'missing registry rows') out = {} for r in x[array]: require(isinstance(r, dict) and isinstance(r.get('id'), str), 'invalid registry row') require(r['id'] not in out, 'duplicate registry ID') out[r['id']] = r return out aa, bb = keyed(a), keyed(b) require(set(aa) == set(bb), 'registry IDs added/removed without mapping') for rid in sorted(aa): diffs = field_diffs(aa[rid], bb[rid]) rows.append({'id': rid, 'source_file': source, 'destination_file': dest, 'array': array, 'source_value': aa[rid], 'destination_value': bb[rid], 'source_payload_sha256': sha(canonical(aa[rid])), 'destination_payload_sha256': sha(canonical(bb[rid])), 'comparison': 'NONIDENTICAL_REQUIRES_RULE' if diffs else 'IDENTICAL_ROW_VALUE', 'field_differences': diffs}) wrappers.append({'source_file': source, 'destination_file': dest, 'field_differences': field_diffs({k: v for k, v in a.items() if k != array}, {k: v for k, v in b.items() if k != array}), 'interpretation': 'V4 wrapper remains inherited; V5 wrapper is not an identical replacement. Model approval required.'}) return {'rows': rows, 'wrapper_context_differences': wrappers, 'total_registry_rows': len(rows), 'identical_row_values': sum(r['comparison'] == 'IDENTICAL_ROW_VALUE' for r in rows), 'changed_row_values': sum(r['comparison'] != 'IDENTICAL_ROW_VALUE' for r in rows)} def bounded_translation_checks(reg: dict, data: dict) -> dict: """Execute explicit PROPOSED source-to-destination predicate mappings. These predicates are not approved semantic rules merely because they pass. M01/M25 are exact transformations, not similarity tests. Persistence pairs make the human interpretation assumption visible with exact source anchors. Scheduler replacement is reported as a change, never an identity proof. """ by_id = {r['id']: r for r in reg['rows']} checks = [] m01 = by_id['M01'] old, new = m01['source_value']['contract'], m01['destination_value']['contract'] a = 'REV 006 retains' b = 'V4 FINAL / REV006 authority also requires' suffix = ' Candidate mutable position is read only from VPL_V5_CURRENT_STATE.json.' checks.append({'id': 'TR-M01', 'operator': 'EXACT_NAMED_SUBSTITUTION_AND_APPEND', 'source_id': 'M01', 'source_phrase': a, 'destination_phrase': b, 'append': suffix, 'predicate_pass': old.count(a) == 1 and new == old.replace(a,b) + suffix, 'semantic_adjudication': 'REQUIRED_NOT_INFERRED'}) m25 = by_id['M25'] suffix = ' A trigger while this module remains proposed must return UNCERTAIN_ESCALATE and STOP; owner activation is separate.' checks.append({'id': 'TR-M25', 'operator': 'EXACT_APPEND_WITH_ORIGINAL_CONTRACT_UNCHANGED', 'source_id': 'M25', 'append': suffix, 'predicate_pass': m25['destination_value']['contract'] == m25['source_value']['contract'] + suffix, 'semantic_adjudication': 'REQUIRED_NOT_INFERRED'}) current = data['controls/PERSISTENCE_STATE_R02.md'].decode('utf-8') pairs = [ ('M26', 'contract', 'Load all canonical V4 module semantics equally', 'loaded the full equal-priority semantic set', 'equal-priority full load'), ('M26', 'contract', 'balanced anti-parroting challenge plus behavioral proof', 'required balanced behavioral challenge', 'balanced challenge'), ('M26', 'contract', 'save complete receipt', 'banked a matching durable receipt with readback', 'durable source-bound receipt'), ('VPL-GL-15', 'requirement', 'Load every canonical V4 operating control with equal persistence priority', 'loaded the full equal-priority semantic set', 'equal-priority full load'), ('VPL-GL-15', 'requirement', 'balanced challenge coverage and immediate behavioral test', 'required balanced behavioral challenge', 'balanced challenge plus action-bound contract'), ('VPL-GL-15', 'requirement', 'Self-report, recap or selective retrieval is not evidence', 'a verbal recap, or a contract-test PASS alone cannot establish CURRENT', 'recap/test PASS insufficient'), ] for i, (rid, field, left, right, concept) in enumerate(pairs, 1): checks.append({'id': f'PR-{i:02}', 'operator': 'PROPOSED_LITERAL_ANCHORED_PROPOSITION_PAIR', 'concept': concept, 'source_id': rid, 'source_field': field, 'source_anchor': left, 'destination_file': 'controls/PERSISTENCE_STATE_R02.md', 'destination_anchor': right, 'predicate_pass': left in by_id[rid]['source_value'][field] and right in current, 'semantic_adjudication': 'PAIR_MEANING_REQUIRES_APPROVAL; matching anchors is not a general entailment proof'}) a01, m26 = by_id['VPL-A01'], by_id['M26'] scheduler_change = (a01['source_value'].get('schedule') != a01['destination_value'].get('schedule')) module_change = ('Hostinger 15-minute full-bundle producer' in m26['source_value']['contract'] and 'optional freshness/watchdog producer' in m26['destination_value']['contract']) return {'checks': checks, 'predicates_passed': sum(x['predicate_pass'] for x in checks), 'predicates_total': len(checks), 'cron_policy_difference_detected': scheduler_change and module_change, 'cron_policy_classification': 'NONIDENTICAL_DESIGN_REQUIRES_EXPLICIT_OWNER_DISPOSITION', 'rule_status': 'PROPOSED_FOR_SEMANTIC_ADJUDICATION_NOT_SELF_APPROVED'} def verify_rules(rules: dict, spans: list[dict], offset: int, reg: dict, matrix: bytes, entries: list[dict]) -> list[dict]: require(isinstance(rules, dict), 'rule model must be an object') require(rules.get('kind') == 'ACTION1_SOURCE_BOUND_RULE_MODEL_R01' and rules.get('rule_id') == MODEL_RULE, 'unknown rule model') require(rules.get('proof_scope') == 'BOUNDED_SPECIFICATION_MODEL_NOT_RUNTIME', 'scope overclaim') require(rules.get('v4_sha256') == V4_SHA and rules.get('candidate_sha256') == CANDIDATE_SHA, 'rule source binding differs') require(rules.get('matrix_sha256') == sha(matrix), 'rule matrix binding differs') require(same(rules.get('v5_source_inventory'), entries), 'rule overlay inventory differs') require(same(rules.get('registry_comparison'), reg), 'rule registry values/context differ') maps = rules.get('span_mappings') require(isinstance(maps, list) and len(maps) == len(spans), 'rule mappings incomplete') out = [] for expected, row in zip(spans, maps): require(isinstance(row, dict), 'span mapping must be an object') require(same(row.get('source_span'), expected), 'mapping source span altered or reordered') require(row.get('operator') == 'EXACT_SPAN_IN_COMPLETE_SOURCE_CONTEXT', 'unknown span operator') destination = {'file': V5_NAME, 'start_line': expected['start_line'] + offset, 'end_line': expected['end_line'] + offset, 'span_sha256': expected['span_sha256']} require(same(row.get('destination_span'), destination), 'mapping destination wrong') require(row.get('manual') == 'LOAD_ALL_PRESERVE_SOURCE_DEFINED_TRIGGERS' and row.get('light') == 'LOAD_ALL_PRESERVE_SOURCE_DEFINED_TRIGGERS', 'route/activation assumption changed') require(row.get('approval_requirement') == 'EXTERNAL_MODEL_ADJUDICATION', 'missing approval boundary') out.append({'span_id': expected['span_id'], 'source': expected, 'destination': destination, 'operator': row['operator'], 'manual': row['manual'], 'light': row['light'], 'mechanical_result': 'PASS_VERBATIM_SPECIFICATION_MAPPING', 'semantic_status': 'UNRESOLVED', 'reason': 'Exact-span/context predicate passes; this does not approve the inheritance/overlay semantic model.'}) return out def check_adjudication(raw: bytes | None, trusted_sha: str | None, rules_sha: str, reg: dict) -> tuple[bool, dict]: """External trust input, not a signature, reviewer identity, or self-approval. A future operator must supply BOTH an approval record and its independently trusted SHA. This wave supplies no such record. Synthetic fixtures are tests only. """ if raw is None: require(trusted_sha is None, 'approval hash without record') return False, {'state': 'NOT_SUPPLIED', 'identity_attested': False} require(trusted_sha is not None and bool(re.fullmatch('[0-9a-f]{64}', trusted_sha)) and sha(raw) == trusted_sha, 'untrusted approval record') a = load_json(raw) require(isinstance(a, dict), 'approval must be an object') require(a.get('kind') == 'ACTION1_EXTERNAL_SPECIFICATION_MODEL_ADJUDICATION_R01', 'wrong approval kind') require(a.get('rules_sha256') == rules_sha and a.get('candidate_sha256') == CANDIDATE_SHA and a.get('v4_sha256') == V4_SHA, 'approval binds different source/model') require(a.get('decision') == 'APPROVE_BOUNDED_SPECIFICATION_MODEL' and a.get('rule_id') == MODEL_RULE, 'no explicit semantic model approval') require(a.get('all_328_span_mappings_reviewed') is True and a.get('all_35_source_overlay_effects_reviewed') is True and a.get('wrapper_context_differences_reviewed') is True, 'incomplete interpretation review') for key in ('owner_decision_reference', 'independent_review_reference'): require(isinstance(a.get(key), str) and bool(a[key].strip()), 'missing approval provenance') ids = sorted(r['id'] for r in reg['rows'] if r['field_differences']) require(a.get('approved_changed_registry_ids') == ids, 'changed registry decisions incomplete') return True, {'state': 'SUPPLIED_HASH_PINNED_DECLARATION', 'sha256': sha(raw), 'owner_decision_reference': a['owner_decision_reference'], 'independent_review_reference': a['independent_review_reference'], 'identity_attested': False, 'trust_boundary': 'Supplied trusted hash and documentary declarations; authenticity/semantic judgment are external, not proved by this program.'} def evaluate(candidate: bytes, authority: dict[str, bytes], rules_raw: bytes, adjudication: bytes | None = None, adjudication_sha: str | None = None) -> dict: require(sha(candidate) == CANDIDATE_SHA, 'candidate archive pin mismatch') data = read_archive(candidate) require(len(data) == 451 and git_tree(data) == CANDIDATE_TREE, 'candidate count/tree differs') for name, pin in AUTH_PINS.items(): require(name in authority and sha(authority[name]) == pin, 'recovered authority pin mismatch: ' + name) v4 = authority[V4_NAME] manifest = load_json(authority['VPL_V4_EQUAL_LOAD_MANIFEST_REV006.json']) challenge = load_json(authority['PERSISTENCE_CHALLENGE_MATRIX_REV006.json']) sums = {line.split(' ', 1)[1]: line.split(' ', 1)[0] for line in authority['REV006_SHA256SUMS.txt'].decode().splitlines()} for name in (V4_NAME, 'VPL_V4_EQUAL_LOAD_MANIFEST_REV006.json', 'PERSISTENCE_CHALLENGE_MATRIX_REV006.json'): require(sums.get(name) == sha(authority[name]), 'recovered file fails original checksum record') blocks, block_proofs = source_blocks(v4, manifest) spans = derive_spans(v4) mapping = load_json(data[MAP]) verify_source_map(mapping, spans, v4) offset, entries = verify_v5_bundle(data, v4) matrix = data[MATRIX] require(mapping.get('matrix_sha256') == sha(matrix), 'matrix/map hash mismatch') base_ids = re.findall(rb'^\| ((?:P|M|L|C)\d{2}) \|', matrix, re.M) h_ids = re.findall(rb'^\| (H\d{2}) \|', matrix, re.M) require(len(base_ids) == len(set(base_ids)) == 41 and h_ids == [f'H{i:02}'.encode() for i in range(1,8)], 'matrix rows missing/duplicated') reg = registry_comparison(blocks, data) rules = load_json(rules_raw) results = verify_rules(rules, spans, offset, reg, matrix, entries) translation = bounded_translation_checks(reg, data) require(same(rules.get('bounded_translation_checks'), translation), 'translation predicate mapping differs') require(translation['predicates_passed'] == translation['predicates_total'], 'bounded translation predicate failed') v4_lines = v4.splitlines(keepends=True) v5_lines = data[V5_NAME].splitlines(keepends=True) for result in results: a, b = result['source'], result['destination'] aa = b''.join(v4_lines[a['start_line']-1:a['end_line']]) bb = b''.join(v5_lines[b['start_line']-1:b['end_line']]) require(aa == bb and sha(aa) == a['span_sha256'], 'actual mapped span differs') # Evaluate authoritative machine-readable persistence predicates, without # pretending a schema/challenge definition is an executed behavioral proof. require(manifest.get('no_priority_weighting') is True, 'equal-priority invariant missing') require(challenge.get('mutation_requirement') == 'PERSISTENCE_STATE=CURRENT', 'mutation invariant missing') require(challenge.get('proofs') == ['semantic_completeness', 'cross_reference_understanding', 'false_premise_rejection', 'behavioral_follow_through'], 'proof requirement differs') approved, approval = check_adjudication(adjudication, adjudication_sha, sha(rules_raw), reg) if approved: for result in results: result['semantic_status'] = 'EQUIVALENT_UNDER_EXTERNALLY_APPROVED_BOUNDED_MODEL' result['reason'] = 'Derived exact-span/context predicate passed under the hash-pinned external model adjudication; no runtime claim.' missing = [name for name in ('VPL_V4_EQUAL_LOAD_MANIFEST_REV006.json', 'PERSISTENCE_CHALLENGE_MATRIX_REV006.json') if not any(PurePosixPath(p).name == name for p in data)] return {'kind': 'SEMANTIC_EQUIVALENCE_RECEIPT_R08_ACTION1_R01', 'result': 'PASS_UNDER_EXTERNALLY_APPROVED_BOUNDED_MODEL' if approved else 'MECHANICAL_PASS_SEMANTIC_APPROVAL_PENDING', 'exit_code': 0 if approved else 3, 'total_spans': len(results), 'mechanically_verified_spans': len(results), 'resolved': len(results) if approved else 0, 'unresolved': 0 if approved else len(results), 'r2_m01_closed': False, 'closure_note': 'Independent coordinator/owner closure is external; this tool never promotes the finding.', 'proof_scope': 'BOUNDED_SPECIFICATION_MODEL_NOT_RUNTIME', 'verifier_sha256': sha(Path(__file__).read_bytes()), 'source_binding': {'candidate_archive_sha256': sha(candidate), 'candidate_git_tree': git_tree(data), 'candidate_files': len(data), 'v4_bundle_sha256': sha(v4), 'v5_bundle_sha256': sha(data[V5_NAME]), 'matrix_sha256': sha(matrix), 'rule_model_sha256': sha(rules_raw)}, 'source_blocks': block_proofs, 'v5_source_inventory': entries, 'matrix_base_rows_verified': 41, 'matrix_h_rows_verified': 7, 'registry_comparison': reg, 'bounded_translation_checks': translation, 'external_model_adjudication': approval, 'recovered_authority_files': [{'file': n, 'sha256': sha(authority[n]), 'original_checksum_matches': True} for n in AUTH_PINS if n != 'REV006_SHA256SUMS.txt'], 'supplemented_original_candidate_omissions': missing, 'supplement_note': 'Recovered V4 authority accompanies the sidecar; missing originals were NOT inserted into or backdated into frozen candidate.', 'persistence_definition_checks': {'equal_priority': True, 'complete_29_sources': True, 'balanced_four_proofs_required': True, 'runtime_proofs_executed': False}, 'results': results, 'zero_manual_decisions_during_execution': True, 'rule_authorship_and_semantic_adjudication_are_not_automated': True, 'arbitrary_natural_language_conflicts_exhaustively_detected': False, 'runtime_or_model_persistence_certified': False, 'candidate_code_executed': False, 'source_written': False, 'score_change_established': False} def main(argv=None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--candidate', type=Path, required=True) parser.add_argument('--v4-authority', type=Path, required=True) parser.add_argument('--rules', type=Path, required=True) parser.add_argument('--output', type=Path, required=True) parser.add_argument('--adjudication', type=Path) parser.add_argument('--adjudication-sha256') args = parser.parse_args(argv) try: require(not args.output.exists(), 'refusing to overwrite existing output') require(args.output.parent.is_dir(), 'output directory must already exist') authority = {n: (args.v4_authority/n).read_bytes() for n in AUTH_PINS} receipt = evaluate(args.candidate.read_bytes(), authority, args.rules.read_bytes(), args.adjudication.read_bytes() if args.adjudication else None, args.adjudication_sha256) with args.output.open('xb') as f: f.write(canonical(receipt)) print(json.dumps({'result': receipt['result'], 'total_spans': receipt['total_spans'], 'mechanically_verified_spans': receipt['mechanically_verified_spans'], 'resolved': receipt['resolved'], 'unresolved': receipt['unresolved'], 'receipt_sha256': sha(args.output.read_bytes())}, sort_keys=True)) return receipt['exit_code'] except (InvalidInput, OSError, KeyError, TypeError, IndexError) as e: print(json.dumps({'result': 'INPUT_REJECTED', 'error': str(e)}, sort_keys=True), file=sys.stderr) return 2 if __name__ == '__main__': sys.exit(main())