from pathlib import Path
import json,sys
ROOT=Path(__file__).resolve().parent.parent
checks=[]
def ck(i,c,d=''): checks.append({'id':i,'pass':bool(c),'detail':d if not c else ''})
required=['learner/README.en-US.md','learner/README.fa-IR.md','learner/package.json','learner/starter/index.html','learner/starter/vite.config.ts','learner/starter/src/main.tsx','learner/starter/src/App.tsx','learner/starter/src/products.ts','learner/transfer/index.html','learner/transfer/vite.config.ts','learner/transfer/src/main.tsx','learner/transfer/src/orders.ts','learner/transfer/src/README_TASK.ts','learner/evidence/Server_State_Typed_Route_Contract_Record_v1.template.json','learner/evidence/learner_evidence.json']
for f in required: ck('file:'+f,(ROOT/f).is_file(),'required public lab file')
starter=(ROOT/'learner/starter/src/App.tsx').read_text('utf-8')
ck('starter.unsolved.cast','as ProductSearch' in starter)
ck('starter.unsolved.incomplete_key',"queryKey:['products']" in starter.replace(' ',''))
ck('starter.unsolved.remote_copy','useState<Product[]>(query.data ?? [])' in starter)
ck('starter.unsolved.wrong_invalidation',"queryKey:['product']" in starter.replace(' ',''))
transfer=(ROOT/'learner/transfer/src/README_TASK.ts').read_text('utf-8')
ck('transfer.unsolved.explicit','Intentionally unsolved transfer surface' in transfer)
ck('transfer.unsolved.no_app',not (ROOT/'learner/transfer/src/App.tsx').exists())
ev=json.loads((ROOT/'learner/evidence/learner_evidence.json').read_text('utf-8'))
for k in ['runtime_context','contract','query_identity','runtime_validation','observations','mutation','repair','transfer','residual_limitation','attestation']: ck('evidence.schema:'+k,k in ev)
obs=ev.get('observations',[]); ck('evidence.observation_template',isinstance(obs,list) and len(obs)>=1 and all(k in obs[0] for k in ['action','observation','inference']))
ck('evidence.no_fabricated_attestation',ev.get('attestation',{}).get('browser_dom_claims_are_observed_not_invented') is False)
result={'schema':'WEB012_LAB_PUBLIC_PREFLIGHT_v1','checks':checks,'passed':sum(c['pass'] for c in checks),'total':len(checks),'runtime_execution_claimed':False,'verdict':'PASS' if all(c['pass'] for c in checks) else 'FAIL'}
print(json.dumps(result,indent=2)); raise SystemExit(0 if result['verdict']=='PASS' else 1)
