#!/usr/bin/env python3 """C326 fixed four-endpoint geometry and exact-phase audit. python C326_Independent_Audit.py --sources DIR --out DIR Inputs: PREVIOUS_DATA.json (C325), C322_DATA.json, File_09.md. No endpoint search, E endpoint generation, fitted map, or C327 calculation. """ import argparse import hashlib import itertools import json from fractions import Fraction as F from pathlib import Path def geometry(points): a, b, c, d = points interval_ac = (min(a, c), max(a, c)) interval_bd = (min(b, d), max(b, d)) return { 'ordered_descending': a > b > c > d, 'adjacent_gaps': [a - b, b - c, c - d], 'interval_lengths': [a - c, b - d], 'overlap': max(F(0), min(interval_ac[1], interval_bd[1]) - max(interval_ac[0], interval_bd[0])), 'outer_width': max(points) - min(points), 'pairwise_distance_multiset': sorted(abs(x - y) for x, y in itertools.combinations(points, 2)), } def encode(value): if isinstance(value, F): return str(value) if isinstance(value, dict): return {k: encode(v) for k, v in value.items()} if isinstance(value, (list, tuple)): return [encode(v) for v in value] return value def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--sources', required=True, type=Path) parser.add_argument('--out', required=True, type=Path) args = parser.parse_args() raw = {name: (args.sources / name).read_bytes() for name in ['PREVIOUS_DATA.json', 'C322_DATA.json', 'File_09.md']} previous, biographies = json.loads(raw['PREVIOUS_DATA.json']), json.loads(raw['C322_DATA.json']) source_text = raw['File_09.md'].decode() hashes = {name: hashlib.sha256(value).hexdigest() for name, value in raw.items()} checks = [] def check(name, actual, expected): ok = actual == expected checks.append({'name': name, 'pass': ok, 'actual': encode(actual), 'expected': encode(expected)}) if not ok: raise AssertionError(name) check('predecessor step', previous['step'], 'C325') check('six held annual triples', len(previous['hits']), 6) declared = '14511 ─40→ 14471 ─460→ 14011 ─40→ 13971 BC' check('File09 exact named declaration present', declared in source_text, True) file_points = [F(x) for x in [14511, 14471, 14011, 13971]] file_geom = geometry(file_points) check('File09 ordered gaps', file_geom['adjacent_gaps'], [F(40), F(460), F(40)]) check('File09 two intervals', file_geom['interval_lengths'], [F(500), F(500)]) check('File09 overlap', file_geom['overlap'], F(460)) check('File09 outer width', file_geom['outer_width'], F(540)) phases = [F(-1, 4), F(1, 4)] quadruples, candidates, successful = [], [], [] for old in previous['hits']: gear, index = old['gear'], old['source_i'] anchor_role, terminal_role = old['anchor_role'], old['terminal_role'] label = f'G{gear}/{anchor_role}/{terminal_role}' matches = [r for r in biographies['biographies'] if r['gear'] == gear and r['i'] == index] check(label + '/unique biography', len(matches), 1) row = matches[0] records = {'A': row['SP_records'][anchor_role], 'B': row['MT_records'][anchor_role], 'C': row['SP_records'][terminal_role], 'D': row['MT_records'][terminal_role]} points = [F(records[key]['center']) for key in 'ABCD'] for key, old_key in [('A', 'A_SP'), ('B', 'B_MT'), ('C', 'C_SP')]: check(label + '/held coordinate/' + key, records[key]['center'], old[old_key]) check(label + '/held source record/' + key, records[key], old['records'][key]) check(label + '/D matching role', records['D']['role'], records['C']['role']) check(label + '/D matching Gear', records['D']['gear'], gear) check(label + '/D exact MT context', [records['D'][k] for k in ['tradition', 'Cainan', 'Terah60', 'full430']], ['MT', 1, 1, 1]) base_geom = geometry(points) check(label + '/ordered endpoints', base_geom['ordered_descending'], True) check(label + '/full gaps', base_geom['adjacent_gaps'], [F(460), F(40), F(460)]) check(label + '/two500 intervals', base_geom['interval_lengths'], [F(500), F(500)]) check(label + '/overlap', base_geom['overlap'], F(40)) check(label + '/outer width', base_geom['outer_width'], F(960)) check(label + '/pairwise distances', base_geom['pairwise_distance_multiset'], [F(x) for x in [40, 460, 460, 500, 500, 960]]) congruent = base_geom['pairwise_distance_multiset'] == file_geom['pairwise_distance_multiset'] g, h = base_geom['adjacent_gaps'], file_geom['adjacent_gaps'] # Ratios are invariants; no coordinate map or fitted scale is constructed. similar = any(all(g[k] * trial[0] == g[0] * trial[k] for k in range(1, 3)) for trial in [h, list(reversed(h))]) check(label + '/not full metric congruence', congruent, False) check(label + '/not uniform similarity up to reversal', similar, False) check(label + '/first triple gap pattern', g[:2], h[1:]) check(label + '/second triple gap pattern', g[1:], h[:2]) quad = {'gear': gear, 'source_i': index, 'anchor_role': anchor_role, 'terminal_role': terminal_role, 'records': records, 'centers': points, 'geometry': base_geom, 'full_metric_congruence_with_File09': congruent, 'uniform_similarity_up_to_reversal_with_File09': similar, 'inherited_C325_ancestry': old['inherited_ancestry']} quadruples.append(quad) exact = {} for comp in row['components']: p = F(comp['phase']) for key, tradition, role in [('A', 'SP', anchor_role), ('B', 'MT', anchor_role), ('C', 'SP', terminal_role), ('D', 'MT', terminal_role)]: exact[key, p] = F(comp[tradition][row['roles'].index(role)]) check(label + '/' + key + '/held phase/' + str(p), exact[key, p] - records[key]['center'], p) for phase_tuple in itertools.product(phases, repeat=4): values = [exact[key, p] for key, p in zip('ABCD', phase_tuple)] a, b, c, d = values durations = [a - b, c - d, a - c, b - d] residuals = [v - target for v, target in zip(durations, [460, 460, 500, 500])] passed = all(r == 0 for r in residuals) geom = geometry(values) check(label + '/phase order/' + str(phase_tuple), geom['ordered_descending'], True) entry = {'gear': gear, 'source_i': index, 'anchor_role': anchor_role, 'terminal_role': terminal_role, 'physical_phases_ABCD': phase_tuple, 'coordinates_ABCD': values, 'durations_AB_CD_AC_BD': durations, 'residuals_460_460_500_500': residuals, 'geometry': geom, 'all_exact': passed} candidates.append(entry) if passed: check(label + '/all four phases agree/' + str(phase_tuple), len(set(phase_tuple)), 1) check(label + '/exact full geometry/' + str(phase_tuple), geom, base_geom) ancestry = [r for r in old['inherited_ancestry'] if F(r['output_phase']) == phase_tuple[0]] check(label + '/one inherited ancestry binding/' + str(phase_tuple), len(ancestry), 1) entry['inherited_C325_ancestry'] = ancestry[0] successful.append(entry) counts = { 'annual_quadruples': len(quadruples), 'phase_quadruples': len(candidates), 'phase_successes': len(successful), 'phase_failures': len(candidates) - len(successful), 'individual_leg_passes_AB_CD_AC_BD': [sum(r['residuals_460_460_500_500'][k] == 0 for r in candidates) for k in range(4)], 'both_same_role_460_passes': sum(all(r['residuals_460_460_500_500'][k] == 0 for k in [0, 1]) for r in candidates), 'both_same_context_500_passes': sum(all(r['residuals_460_460_500_500'][k] == 0 for k in [2, 3]) for r in candidates), } check('96 phase candidates', counts['phase_quadruples'], 96) check('12 phase successes', counts['phase_successes'], 12) check('84 phase failures', counts['phase_failures'], 84) check('individual legs', counts['individual_leg_passes_AB_CD_AC_BD'], [48] * 4) check('both same-role legs', counts['both_same_role_460_passes'], 24) check('both same-context legs', counts['both_same_context_500_passes'], 24) result = {'step': 'C326', 'source_sha256': hashes, 'quadruples': quadruples, 'File09_named_field': {'declaration': declared, 'centers': file_points, 'geometry': file_geom, 'status': 'Existing locally prescribed cumulative completion field; not transported into SP/MT.'}, 'phase_candidates': candidates, 'phase_successes': successful, 'counts': counts, 'checks': checks, 'check_count': len(checks), 'all_checks_passed': all(c['pass'] for c in checks), 'conclusion': 'Two shared three-point500 subpatterns; the full ordered four-point metric shapes differ.', 'source_prescription_limit': 'Metric comparison neither imports the File09 endpoint rule nor proves source absence.', 'prohibitions_observed': ['No new endpoints', 'No E endpoint generation', 'No fitted map or anchor', 'No File09 phase generation', 'No C327 calculation']} args.out.mkdir(parents=True, exist_ok=True) target = args.out / 'C326_Independent_Audit_Results.json' target.write_text(json.dumps(encode(result), indent=2, sort_keys=True) + '\n') print(json.dumps({'result': str(target), 'counts': counts, 'checks': len(checks), 'all_checks_passed': result['all_checks_passed']}, sort_keys=True)) if __name__ == '__main__': main()