Capture current source, content data, tests, asset licenses, and original-specification traceability. Original implementation remains incomplete. The accepted matching UI generation passed 154 suites and 12,253 checks, with eight rendered staff-contract screens reviewed. Latest native Windows and full-original acceptance remain outstanding.
57 lines
3.5 KiB
Python
57 lines
3.5 KiB
Python
"""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)
|