"""Reconcile the approved 0.5% three-day trial with its zero-rate reference. Run from the project root after both test reports exist. Evidence only; does not set game balancing values or claim long-term/Windows acceptance. """ import json from pathlib import Path root = Path('artifacts/upkeep-2026-09-29') reference = json.loads((root / 'zero-rate-reference-report.json').read_text()) trial = json.loads((root / 'rate-0-5-percent/normal-play-report.json').read_text()) checks = [] def check(label, condition): checks.append({'condition': label, 'passed': bool(condition)}) check('both gameplay trials passed', reference['failures'] == trial['failures'] == 0) check('three closes in each trial', len(reference['closes']) == len(trial['closes']) == 3) for key in ('meal_sales', 'lodging_sales', 'raw_deliveries', 'meal_deliveries'): check(f'{key} unchanged', reference[key] == trial[key]) receipts = trial['upkeep']['receipts'] expense = sum(row['new_expense'] for receipt in receipts for row in receipt['rows']) paid = sum(row['paid'] for receipt in receipts for row in receipt['rows']) check('positive upkeep charged', expense > 0) check('maintenance ledger matches receipts', expense == trial['maintenance_expense']) check('maintenance ledger matches daily P&L', expense == sum(c['category_totals']['maintenance'] for c in trial['closes'])) check('expense minus payments matches arrears', expense - paid == trial['upkeep']['arrears_total']) check('trial cash change exactly equals upkeep payments', reference['cash'] - trial['cash'] == paid) check('no unpaid upkeep', trial['upkeep']['arrears_total'] == 0) fractions, debt = {}, {} for receipt in receipts: rows = receipt['rows'] end = receipt['period']['period_end'] for row in rows: fid = row['facility_id'] units = receipt['period']['facility_units'].get(fid, 0) + fractions.get(fid, 0) check(f'{end}/{fid} exact proration and fractional carry', divmod(units, 1440) == (row['new_expense'], row['fraction_units'])) check(f'{end}/{fid} debt carries and payment reconciles', debt.get(fid, 0) + row['new_expense'] - row['paid'] == row['arrears']) fractions[fid], debt[fid] = row['fraction_units'], row['arrears'] for old, new in zip(reference['closes'], trial['closes']): day = new['day'] check(f'day {day} balanced', new['balanced'] and new['reconciliation_difference'] == 0) check(f'day {day} no total arrears', new['arrears_total'] == 0) check(f'day {day} P&L difference equals upkeep', old['net_profit'] - new['net_profit'] == new['category_totals']['maintenance']) check(f'day {day} other expense/revenue categories unchanged', all(new['category_totals'][k] == v for k,v in old['category_totals'].items() if k != 'maintenance')) result = { 'approved_rate_percent': 0.5, 'passed': all(c['passed'] for c in checks), 'checks': checks, 'cash_reference': reference['cash'], 'cash_trial': trial['cash'], 'maintenance_expense': expense, 'maintenance_paid': paid, 'upkeep_arrears': trial['upkeep']['arrears_total'], 'days': [{k:c[k] for k in ('day','category_totals','net_profit','arrears_total','balanced')} for c in trial['closes']], 'scope': 'Three simulated days, one normal inn layout and fixed seed; not long-term balancing or Windows acceptance.' } (root / 'rate-0-5-percent-reconciliation.json').write_text(json.dumps(result, ensure_ascii=False, indent=2)+'\n') print(json.dumps({k:v for k,v in result.items() if k not in ('checks','days')},ensure_ascii=False)) raise SystemExit(0 if result['passed'] else 1)