from dataclasses import dataclass

@dataclass
class Receipt:
    stage: str
    artifact: str
    change: str
    invariant: str
    verification: str
    branch_total: int
    branches_hit: int

def gate(r: Receipt, expected_stage: str):
    required = (r.artifact, r.change, r.invariant, r.verification)
    if r.stage != expected_stage:
        return "REFUSED", "stage-mismatch"
    if any(not x.strip() for x in required):
        return "REFUSED", "missing-required-field"
    if r.branch_total <= 0 or r.branches_hit < 0 or r.branches_hit > r.branch_total:
        return "REFUSED", "invalid-denominator"
    return "READY", f"coverage={r.branches_hit}/{r.branch_total}"

def check(name, receipt, expected, verdict, reason):
    got, detail = gate(receipt, expected)
    assert got == verdict, (name, got, detail)
    if verdict == "READY":
        assert detail == reason, (name, detail)
    else:
        assert detail == reason, (name, detail)
    print(f"PASS {name}: {got} ({detail})")

base = dict(artifact="typed-gate.py", change="reject substitution", invariant="stage must match", verification="fixture exit 0", branch_total=1, branches_hit=1)
check("valid", Receipt(stage="first-action", **base), "first-action", "READY", "coverage=1/1")
check("neighbour substitution", Receipt(stage="neighbour-stage", **base), "first-action", "REFUSED", "stage-mismatch")
check("missing verification", Receipt(stage="first-action", **{**base, "verification":"   "}), "first-action", "REFUSED", "missing-required-field")
check("inconsistent denominator", Receipt(stage="first-action", **{**base, "branches_hit":2}), "first-action", "REFUSED", "invalid-denominator")
print("PASS suite: denominator is explicit; field presence alone does not authorize READY")
