#!/usr/bin/env python3
"""
Temperature/top-p invariance KAT.

Proves: With GLYPHSCOPE_DETERMINISTIC=1, scaffold+SAT make output invariant
to temperature and top_p settings. Stochasticity is only allowed in free body
(state=IN_BODY_EXPR), which we avoid via scaffold+macro.
"""
import os
import sys
import itertools

os.environ["VAULT_DISABLED"] = "1"

from helix_cdc.cdc_decode import CDCDecoder

def run_once(temp, top_p):
    """Generate with given temperature and top_p."""
    os.environ["GLYPHSCOPE_DETERMINISTIC"] = "1"
    dec = CDCDecoder(seed_path=None)
    txt, tr = dec.generate_from_anchor("", max_new_tokens=128, temperature=temp, seed=123)
    return txt, tr["raw_symbols"], tr["generated_tokens"]

def main():
    print("=== Temperature/top-p Invariance KAT ===")
    print("Testing grid: temp ∈ {0.0, 0.2, 0.7, 1.0} × top_p ∈ {0.8, 0.9, 1.0}")

    # Grid of (temperature, top_p) combinations
    grid = [(t, p) for t in [0.0, 0.2, 0.7, 1.0] for p in [0.8, 0.9, 1.0]]

    # Baseline run
    base_txt, base_syms, base_tokens = run_once(0.2, 0.9)
    print(f"\nBaseline: temp=0.2, top_p=0.9")
    print(f"  Tokens: {base_tokens}")
    print(f"  Symbols: {base_syms[:32]}...")
    print(f"  Text length: {len(base_txt)}")

    # Test all combinations
    ok = True
    for t, p in grid:
        txt, syms, tokens = run_once(t, p)
        if (txt != base_txt) or (syms != base_syms):
            print(f"❌ Invariance fail at temp={t}, top_p={p}")
            print(f"   Tokens: {tokens} (expected {base_tokens})")
            print(f"   Symbols: {syms[:32]}... (expected {base_syms[:32]}...)")
            ok = False

    if ok:
        print(f"\n✅ PASS: temp/top_p invariance ({len(grid)} combinations)")
        print(f"   All runs produced identical output (deterministic in SAT zone)")
        return 0
    else:
        print(f"\n❌ FAIL: temp/top_p invariance")
        return 1

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