from pathlib import Path
import json,sys
ROOT=Path(__file__).resolve().parents[1]; checks=[]
def ck(n,c): checks.append((n,bool(c)))
def load(r): return json.loads((ROOT/r).read_text())
cfg=load('fixture/service-contract.json'); cases=load('fixture/probe-cases.json'); req=load('requirements.json'); pol=load('toolchain-policy.json'); gold=load('fixture/golden-policy.json'); ev=load('evidence/validation-status.json'); dt=load('submission/decision.template.json'); runner=(ROOT/'src/run_local_lab.py').read_text(); runtime=(ROOT/'src/runtime_fixture.py').read_text()
expected_ids=['baseline_fast_receiver','short_deadline_active_work','slow_receiver_flow_probe','write_heavy_no_read_guard']; expected_classes={'baseline_fast_receiver':'COMPLETE_OR_BOUNDED_LOCAL_SUCCESS','short_deadline_active_work':'DEADLINE_OR_BOUNDED_TERMINATION','slow_receiver_flow_probe':'OBSERVE_WRITE_PROGRESS_TIMING','write_heavy_no_read_guard':'DEADLOCK_RISK_SIMULATION_ONLY'}
ck('service name',cfg.get('service')=='InventoryFeed'); ck('four rpc shapes',cfg.get('rpc_shapes')=={'GetSnapshot':'unary','WatchUpdates':'server_streaming','UploadAdjustments':'client_streaming','CommandStream':'bidirectional_streaming'}); ck('owned baseline',cfg.get('owned_baseline')=='WatchUpdates'); ck('message count 12',cfg.get('message_count')==12); ck('payload 512k',cfg.get('payload_bytes')==524288); ck('deadline exact',cfg.get('default_deadline_ms')==900 and cfg.get('short_deadline_ms')==160); ck('slow exact',cfg.get('slow_receiver_ms')==70); ck('work delay exact',cfg.get('server_work_delay_ms')==40); ck('queue exact',cfg.get('application_queue_bound')==4); ck('watchdog exact',cfg.get('deadlock_watchdog_ms')==180)
ck('case ids exact',[c['id'] for c in cases.get('cases',[])]==expected_ids); ck('case classes exact',{c['id']:c['expected_class'] for c in cases['cases']}==expected_classes); ck('deadline case binds cfg',cases['cases'][1]['deadline_ms']==cfg['short_deadline_ms']); ck('slow case binds cfg',cases['cases'][2]['receiver_delay_ms']==cfg['slow_receiver_ms']); ck('deadlock watchdog binds cfg',cases['cases'][3]['watchdog_ms']==cfg['deadlock_watchdog_ms'])
ck('five dims exact',set(req.get('critical_dimensions',[]))=={'rpc_shapes','deadline','cancellation','flow_control','deadlock_boundary'}); ck('runtime scope exact','External network, external services, and production behavior are out of scope.' in req.get('runtime_rule','')); ck('prediction rule present','All four required case predictions' in req.get('prediction_completeness_rule','')); ck('provenance rule present','SHA-256' in req.get('provenance_rule','')); ck('flow boundary present','does not prove network delivery' in req.get('flow_control_boundary_rule',''))
ck('loopback exact',pol.get('loopback_host')=='127.0.0.1'); ck('external forbidden',pol.get('external_network_forbidden') is True and pol.get('external_service_forbidden') is True); ck('scope local',pol.get('fixture_scope')=='DISPOSABLE_LOOPBACK_ONLY' and pol.get('evidence_scope')=='BOUNDED_LOCAL_FIXTURE_ONLY'); ck('policy case ids',pol.get('expected_case_ids')==expected_ids); ck('policy prediction ids',pol.get('required_prediction_ids')==expected_ids); ck('provenance keys eight',len(pol.get('runtime_input_hashes_required',[]))==8)
ck('forbidden conclusions exact',gold.get('forbidden_conclusions')==['streaming always faster','one deadline fits every system','DEADLINE_EXCEEDED proves worker cleanup','transport flow control equals business admission control']); ck('gold probe semantics',gold.get('required_probe_semantics')==expected_classes)
ck('status untouched',ev.get('status')=='NOT_RUN_AUTHORING_BOUNDARY' and ev.get('runtime_observations_claimed') is False and ev.get('production_runtime_claimed') is False); ck('decision incomplete',dt.get('status')=='LEARNER_INCOMPLETE' and set(dt.get('predictions',{}))==set(expected_ids) and all(v is None for v in dt['predictions'].values()))
ck('runner exact loop','for c in cases:' in runner and 'cases[:1]' not in runner); ck('runner exact predictions',"set(preds)==set(expected)" in runner); ck('runner confirm','if not args.confirm_local:' in runner); ck('runner full provenance',all(k in runner for k in pol['runtime_input_hashes_required'])); ck('runtime deadlock saturated','queue.Queue(maxsize=1); q_ba=queue.Queue(maxsize=1)' in runtime); ck('publisher asserts no progress',"c['progress']==[]" in runtime)
for n,v in checks: print(('PASS' if v else 'FAIL'),n)
print(f'{sum(v for _,v in checks)}/{len(checks)} PASS'); sys.exit(0 if all(v for _,v in checks) else 1)
