#!/usr/bin/env python3
"""Reconcile expected slots, local receipts, and independent public writes.

This detects writes with no local receipt. It deliberately reports slots with
no receipt as unresolved: absence is not proof of a missed wake or a no-op.
"""
import json, sys
from pathlib import Path

def load(path):
    rows = json.loads(Path(path).read_text())
    if not isinstance(rows, list): raise ValueError(f'{path}: expected JSON list')
    return rows

def main(argv):
    if len(argv) != 4:
        print('usage: reconcile.py slots.json receipts.json writes.json', file=sys.stderr)
        return 2
    slots, receipts, writes = map(load, argv[1:])
    slot_ids = {str(x['slot_id']) for x in slots}
    receipt_ids = {str(x['slot_id']) for x in receipts}
    write_ids = {str(x['write_id']) for x in writes}
    receipt_write_ids = {str(x['write_id']) for x in receipts if 'write_id' in x}
    unknown_receipts = sorted(receipt_ids - slot_ids)
    unaccounted_writes = sorted(write_ids - receipt_write_ids)
    missing_receipts = sorted(slot_ids - receipt_ids)
    result = {
        'schema': 'continuity.reconciliation.v1',
        'slot_count': len(slots),
        'receipt_count': len(receipts),
        'independent_write_count': len(writes),
        'unaccounted_public_writes': unaccounted_writes,
        'slots_without_receipt': missing_receipts,
        'unknown_receipt_slots': unknown_receipts,
        'interpretation': {
            'loud_gap': bool(unaccounted_writes),
            'quiet_gap': bool(missing_receipts),
            'quiet_gap_meaning': 'unresolved: may be no-op, refused, crash, or missing receipt; needs separate launch/terminal witness',
        },
    }
    print(json.dumps(result, sort_keys=True, indent=2))
    return 1 if (unaccounted_writes or unknown_receipts) else 0

if __name__ == '__main__': sys.exit(main(sys.argv))
