#!/usr/bin/env python3
from pathlib import Path
import argparse, subprocess, sys, os, hashlib, json
BASE=Path(__file__).resolve().parent
CASES={'baseline':('workspace_baseline',{'root','alternate'}),'transfer':('workspace_transfer',{'north','south'})}
def h(p):
    if not p.exists(): return None
    return hashlib.sha256(p.read_bytes()).hexdigest()
def _bounded_child_env(mode):
    # Deliberately do not inherit the parent environment. DEMO_MODE is the
    # only instructional variable. On Windows, preserve only OS bootstrap
    # keys that may be required to launch an absolute interpreter.
    env={'DEMO_MODE':mode}
    inherited_platform_keys=[]
    if os.name=='nt':
        for key in ('SystemRoot','WINDIR'):
            if key in os.environ:
                env[key]=os.environ[key]
                inherited_platform_keys.append(key)
    return env,inherited_platform_keys
def probe(case,cwd_label,mode):
    work_name,allowed=CASES[case]
    if cwd_label not in allowed: raise ValueError('REFUSE_CWD: cwd label is not part of selected fixture')
    work=BASE/work_name
    if not (work/'.maknow_fnd008_workspace').exists(): raise RuntimeError('Run setup_fixture.py for this case first')
    cwd=(work/cwd_label).resolve(); out=cwd/'output.txt'; sibling=next(x for x in allowed if x!=cwd_label); sibling_out=(work/sibling/'output.txt').resolve()
    before=h(out); sibling_before=h(sibling_out)
    env,inherited_platform_keys=_bounded_child_env(mode)
    cmd=[sys.executable,str((BASE/'child_process.py').resolve()),'input.txt','output.txt']
    cp=subprocess.run(cmd,cwd=cwd,env=env,capture_output=True,text=True,timeout=10)
    return {'case':case,'shell_boundary':'Python subprocess runner; Bash-specific probes are separate','cwd':str(cwd),'resolved_executable':str(Path(sys.executable).resolve()),'argv':cmd[1:],'child_env_policy':'SANITIZED_MINIMAL_EXPLICIT','relevant_env':{'DEMO_MODE':mode},'inherited_platform_env_keys':inherited_platform_keys,'stdin':'NONE','stdout':cp.stdout.rstrip('\n'),'stderr':cp.stderr.rstrip('\n'),'exit_status':cp.returncode,'resolved_file_effect':str(out),'before_hash':before,'after_hash':h(out),'sibling_output':str(sibling_out),'sibling_before_hash':sibling_before,'sibling_after_hash':h(sibling_out),'output_changed':before!=h(out),'sibling_changed':sibling_before!=h(sibling_out)}
def main():
    p=argparse.ArgumentParser();p.add_argument('--case',choices=sorted(CASES),default='baseline');p.add_argument('--cwd',required=True);p.add_argument('--mode',choices=['safe','alternate','audit'],required=True);a=p.parse_args()
    try: print(json.dumps(probe(a.case,a.cwd,a.mode),ensure_ascii=False,sort_keys=True))
    except (ValueError,RuntimeError) as e: raise SystemExit(str(e))
if __name__=='__main__': main()
