"""Independent original-archive verifier: no application, database, HTTP, or rewrites."""
import collections, hashlib, json, pathlib, struct, sys, tarfile

ROOT = pathlib.Path(sys.argv[1])
EXPECTED = {
 'B':('6d856c2a962fcbdb24b379deca7b0cd1f112ad72808e86270450de4581afe129',52,106,94,8,0,232,93),
 'C':('4750eb3bc63a0d1de8f3f86cf326d7b01ef958621c3b336c59f84d8c47ff642b',55,94,66,20,4,178,97),
}
checks=0
def need(value,message):
 global checks
 assert value,message
 checks+=1
def sha(data):return hashlib.sha256(data).hexdigest()
def canonical(data):return json.dumps(data,ensure_ascii=False,separators=(',',':'),sort_keys=True).encode()
def indexed(value,index):
 return (value[index] if index<len(value) else {}) if isinstance(value,list) else value.get(str(index),{})

summary={}
need(ROOT.is_dir() and (ROOT.stat().st_mode&0o777)==0o700,'Canonical private directory700')
for side,(archive_sha,count,total,observer,auth,code,eid,fresh) in EXPECTED.items():
 file=ROOT/(side+'.tar')
 need((file.stat().st_mode&0o777)==0o600 and sha(file.read_bytes())==archive_sha,'Original complete archive bytes/mode '+side)
 with tarfile.open(file) as tar:
  members=tar.getmembers()
  need(len(members)==count and all(m.isfile() and not m.name.startswith('/') and '..' not in pathlib.PurePosixPath(m.name).parts for m in members),'Exact bounded original archive members')
  assets={m.name:tar.extractfile(m).read() for m in members}
 manifest=json.loads(assets['private/runtime-manifest.json'])
 need(set(assets)==set(manifest['files'])|{'private/runtime-manifest.json'},'No omitted or extra archived evidence')
 for name,entry in manifest['files'].items():need(len(assets[name])==entry['bytes'] and sha(assets[name])==entry['sha256'],'Original per-file SHA/bytes '+name)
 def get(name):return json.loads(assets['private/'+name])
 need(sha(assets['machine-plan.json'])=='2cbf71e15720fb654b963bbea7f2556b2711177cd573e714670248e11cc5f1e5','Frozen granted machine plan unchanged')
 machine=json.loads(assets['machine-plan.json']);before=get('before-protected.json');final=get('final-failed-code-protected.json')
 need(len(before)==len(final)==29,'All29 exact protected groups')
 for key in before:
  need(before[key]['rows']==final[key]['rows'],'Old original complete rows conserved '+key)
  need(before[key]['types']==final[key]['types'] and before[key]['float_bits']==final[key]['float_bits'],'Old original native dtype/float bits conserved '+key)
 events=[json.loads(line) for line in assets['private/events.jsonl'].splitlines()]
 obs_before=[e for e in events if e['event']=='observer-before'];obs_after=[e for e in events if e['event']=='observer-result']
 native_before=[e for e in events if e['event']=='native-before'];native_after=[e for e in events if e['event']=='native-result']
 need(len(obs_before)==len(obs_after)==observer,'All actual independent read attempts/results counted')
 need(len(native_before)==len(native_after)==total-observer,'All actual source native readonly attempts/results counted')
 need(all(e['kind']=='READ' and e['success'] is True and e['errorInfo'][0]=='00000' for e in native_after),'No code/scan source DML or native SQL error hidden')
 need(collections.Counter(e['phase'] for e in native_before)==({'warm':4,'auth':auth}|({'code':code} if code else {})),'Warm/Auth/code actual category counts')
 budget=get('budget.json');need(budget['total']==total and budget['observer']==observer and budget['auth']==auth and budget['warm']==4,'Actual unified budget exact')
 need(total<=350 and observer<=(139 if side=='B' else 110) and auth<=(16 if side=='B' else 32) and code<=(24 if side=='B' else 48),'All granted limits including B amendment')
 for event in obs_after:
  for i,row in enumerate(event['rows']):
   for key,bits in indexed(event['float_bits'],i).items():need(struct.pack('d',row[key]).hex()==bits,'Original float bit materialization')
   streams=indexed(event['streams'],i)
   for key,entry in streams.items():need(len(row[key].encode())==entry['bytes'] and sha(row[key].encode())==entry['sha256'],'Original full CLOB bytes/SHA')
 result=get('prepare-result.json');attempt=get('prepare-attempt.json');approved=machine['equipment'][side]
 need(result['success'] is True and result['rowCount']==1 and result['errorInfo'][0]=='00000' and result['generated_ID']==eid,'Only approved own prepare INSERT really committed')
 need(all(attempt[k]==approved[k] for k in ['SQL','binds','PHP_types','PDO_types']) and len(attempt['binds'])==14,'Actual prepare exact14 typed binds')
 need(approved['unknown_omitted_required']==[],'No guessed required equipment fields')
 checkpoint=get('failed-code-checkpoint.json');need(checkpoint['new_prePay_marker0']['rows']==[] and checkpoint['code_business_DML']==0 and checkpoint['scan_HTTP']==0,'Independent current new Prepay0, code source DML0, no scan')
 eq=checkpoint['owned_device_full31']['rows'];need(len(eq)==1 and len(eq[0])==31 and eq[0]['id']==eid,'Exact generated full31 own device retained')
 need(eq==get('equipment.json')['full']['rows'],'Full31 owned device unchanged after failed HTTP')
 need(get('auth-proven.json')['original_UserModel'] is True and get('auth-proven.json')['store_id']==2147001111,'Real original own UserModel token was verified')
 need(get('token.json')['TTL']==300 and get('token.json')['profile']['login_type']=='thirdparty','Single original FileCache profile TTL300')
 need(sum(name.endswith('/token.json') for name in assets)==1 and 'private/send-attempt-scan.json' not in assets,'Single token and no scan attempt')
 need('private/DISPATCH_1.json' in assets and 'private/send-attempt-code.json' in assets,'One consumed immutable signature and one code HTTP attempt')
 client=get('client-response-code.json')
 if side=='B':
  need(get('response-code.json')['body']=='' and get('response-code.json')['status']==200 and 'think_page_trace' in client['body'],'B original blank app response and original wire trace retained, not passed')
  need(get('worker-proof-code.json')['native_DML']==[] and get('worker-proof-code.json')['generated']==[],'B default homepage made no source business DML')
 else:
  payload=json.loads(client['body']);need(payload['code']=='2' and 'extend/vendor/autoload.php' in payload['message'] and client['headers'][0].startswith('HTTP/1.0 500'),'C original missing real dependency framework500 preserved')
  need(get('worker-attempt-code.json')['PATH_INFO']=='/api/prepayOrder/code' and get('worker-attempt-code.json')['REQUEST_URI']=='/api/prepayOrder/code','C actual source route fields correct')
  need('private/response-code.json' not in assets,'C no invented pre-send application response')
 cleanup=get('cleanup.json');need(len(cleanup['worker_SIGTERM'])==2 and len(cleanup['only_owned_cache_removed'])==3 and cleanup['business_DELETE']==0,'Only exact two own workers/three cache files cleaned')
 summary[side]={'status':'HARNESS_FAILED_NOT_BUSINESS_PASS','new_readonly':total,'fresh_original_readonly':fresh,'cumulative_readonly':fresh+total,'prepare_INSERT':1,'device_ID':eid,'code_HTTP_attempt':1,'code_business_DML':0,'scan_HTTP':0,'DDL_DELETE_payment':0,'archive_files':count,'archive_sha256':archive_sha}
print(json.dumps({'independent_checks':checks,'result':'ORIGINAL_FAILURE_AND_SAFE_CLOSURE_PROVEN','sides':summary,'SQL':0,'HTTP':0},ensure_ascii=False))
