"""Launch gate-w3.sh detached under a PROVEN scrubbed environment — launch-gate.py with the W3 freeze list.

Same mechanism as launch-gate.py (W1's launcher): explicit env without the endpoint identity trio +
perch companions + the pool hatch + SPT_HOME, child env read back with psutil, refused unless clean.
FREEZE covers every script the W3 driver calls (bash reads by byte offset; an edit under a running shell
resumes mid-line as vacuous greens). TIP / SKIP / OUT_SUFFIX / MUT_FLOOR_GB pass through the environment.
"""
import hashlib, os, pathlib, shutil, subprocess, sys, time
from pathlib import Path
import psutil

root = Path(__file__).resolve().parents[1]
outdir = root / ".spt" / "gate-doyle"
TRIO = ("OWL_SESSION_ID", "SPT_AGENT_ID", "SPT_ENDPOINT_ID")
COMPANIONS = ("SPT_SESSION_NAME", "SPT_ADAPTER", "SPT_HOST_PID", "SPT_INJECT_VERIFY_ECHO", "SPT_POOL_UNCHECKED", "SPT_HOME", "CARGO_TARGET_DIR")
env = dict(os.environ)
dropped = [k for k in TRIO + COMPANIONS if env.pop(k, None) is not None]
if "TIP" not in env:
    print("TIP=<sha> required in the environment", file=sys.stderr); sys.exit(2)
outdir.mkdir(parents=True, exist_ok=True)
log = open(outdir / f"launcher-w3-{env['TIP'][:8]}.log", "wb")
flags = subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.DETACHED_PROCESS
bash = r"C:\Program Files\Git\bin\bash.exe"
script = ".spt/gate-w3.sh"
frozen_names = ["gate-w3.sh", "mutate-w3.py", "twohost-web-local.sh", "twohost-ladder-local.sh", "twohost-ladder-xbox.sh", "twohost-web-xbox.sh"]
frozen_src = {"twohost-web-local.sh": "rig/twohost-web-local.sh", "twohost-ladder-local.sh": "rig/twohost-ladder-local.sh", "twohost-ladder-xbox.sh": "rig/twohost-ladder-xbox.sh"}
h = hashlib.sha256()
for n in frozen_names:
    h.update((root / ".spt" / frozen_src.get(n, n)).read_bytes())
frozen = root / ".spt" / "frozen" / h.hexdigest()[:12]
frozen.mkdir(parents=True, exist_ok=True)
for n in frozen_names:
    shutil.copyfile(root / ".spt" / frozen_src.get(n, n), frozen / n)
env["FROZEN"] = str(frozen).replace("\\", "/")
script = str(frozen / "gate-w3.sh").replace("\\", "/")
print(f"frozen scripts -> {frozen} ({', '.join(frozen_names)})")
child = subprocess.Popen(
    [bash, "-lc", f"bash {script}"],
    cwd=str(root), env=env, stdout=log, stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL,
    creationflags=flags, close_fds=True,
)
time.sleep(2)
try:
    proc = psutil.Process(child.pid)
    seen = proc.environ()
except psutil.NoSuchProcess:
    log.close()
    print(f"driver pid={child.pid} EXITED within the settle window; launcher log tail:")
    print((outdir / f"launcher-w3-{env['TIP'][:8]}.log").read_text(errors="replace")[-600:])
    sys.exit(3)
leaked = [k for k in TRIO + COMPANIONS if k in seen]
print(f"driver pid={child.pid} TIP={env['TIP'][:8]} SKIP={env.get('SKIP','')} dropped-at-launch={' '.join(dropped) or 'none'}")
print(f"read-back: scrubbed vars in the driver's environment = {leaked or 'NONE'}")
if leaked:
    proc.kill()
    sys.exit(4)
