#!/usr/bin/env python3
import json, sys

ALLOWED = {"1f916.inbox.since_last_visit.v4", "1f916.inbox.since_last_visit.v5"}
REQUIRED = {"contract", "provenance", "evidence_ids", "current_line", "expected_head"}

def refuse(code, detail):
    print(f"REFUSE {code}: {detail}")
    return 1

def validate(doc, external_head=None):
    if not isinstance(doc, dict): return refuse("malformed", "document is not an object")
    missing = sorted(REQUIRED - set(doc))
    if missing: return refuse("missing_keys", ",".join(missing))
    if doc["contract"] not in ALLOWED: return refuse("contract_mismatch", doc["contract"])
    if not isinstance(doc["provenance"], str) or doc["provenance"] in ("", "INHERITED"):
        return refuse("bad_provenance", "provenance must be observed")
    ids = doc["evidence_ids"]
    if not isinstance(ids, list) or not ids or any(not isinstance(x, int) for x in ids):
        return refuse("bad_evidence_ids", "non-empty integer list required")
    if ids != list(range(ids[0], ids[-1] + 1)):
        return refuse("non_contiguous", "evidence ids have a gap")
    if not isinstance(doc["current_line"], str) or not doc["current_line"].strip():
        return refuse("bad_current_line", "current_line required")
    if external_head is not None and doc["expected_head"] != external_head:
        return refuse("head_mismatch", f"expected {doc['expected_head']}, got {external_head}")
    print("PASS continuity carrier accepted")
    return 0

def main():
    if len(sys.argv) == 2:
        with open(sys.argv[1], encoding="utf-8") as f: doc=json.load(f)
        return validate(doc)
    base={"contract":"1f916.inbox.since_last_visit.v5","provenance":"OBSERVED:2026-09-19T17:00Z","evidence_ids":[10,11,12],"current_line":"portable continuity gate","expected_head":"h2"}
    cases=[
      ("valid",base, "h2", 0),
      ("unknown contract",{**base,"contract":"v99"},"h2",1),
      ("missing provenance",{k:v for k,v in base.items() if k!="provenance"},"h2",1),
      ("inherited",{**base,"provenance":"INHERITED"},"h2",1),
      ("empty evidence",{**base,"evidence_ids":[]},"h2",1),
      ("evidence gap",{**base,"evidence_ids":[10,12]},"h2",1),
      ("stale external head",base,"h3",1),
    ]
    failed=0
    for name,doc,head,want in cases:
        import io, contextlib
        buf=io.StringIO()
        with contextlib.redirect_stdout(buf): got=validate(doc,head)
        first=buf.getvalue().strip().splitlines()[0]
        ok=got==want
        print(f"{name}: {'PASS' if ok else 'FAIL'} | {first} | exit={got}")
        failed += not ok
    print(f"MATRIX {'PASS' if not failed else 'FAIL'} cases={len(cases)} failures={failed}")
    return 1 if failed else 0

if __name__ == "__main__": sys.exit(main())
