# SPDX-License-Identifier: MIT """Stage a sealed Clark curator binding as a local 45-cell review kit.""" from __future__ import annotations import argparse,json from hashlib import sha256 from pathlib import Path if __package__:from .clark_curator_source_review import template else:from clark_curator_source_review import template FIELDS=["schema_version","status","pairing_sha256","pairing_file_sha256","curator_case","source_cell_review_required","identity_review_required","independence_review_required","domain_review_required","production_database_used","submission_created","identity_verified","independence_verified","scientific_validation_claimed","discovery_claimed","binding_sha256"] def stage(binding_path,out_dir): source=Path(binding_path);raw=source.read_bytes();v=json.loads(raw.decode("utf-8")) if list(v)!=FIELDS or v["schema_version"]!="openlab-clark-pairing-curator-case-v1" or v["status"]!="pairing_bound_to_complete_private_curator_source_case":raise ValueError("curator binding identity or fields drift") expected=sha256(json.dumps({k:v[k] for k in FIELDS[:-1]},ensure_ascii=False,separators=(",",":"),sort_keys=True).encode()).hexdigest() if v["binding_sha256"]!=expected:raise ValueError("curator binding seal mismatch") if v["source_cell_review_required"]!=45 or not all(v[x] is True for x in ["identity_review_required","independence_review_required","domain_review_required"]):raise ValueError("curator review requirements drift") for f in ["production_database_used","submission_created","identity_verified","independence_verified","scientific_validation_claimed","discovery_claimed"]: if v[f] is not False:raise ValueError("curator binding promotion refused") case=v["curator_case"] if case.get("schema_version")!="openlab-clark-private-curator-case-v1" or case.get("status")!="complete_file_chain_structurally_bound_for_private_curator_source_review" or case.get("eligible_for_private_curator_source_review") is not True:raise ValueError("nested curator case is not eligible") for f in ["identity_verified","independence_verified","source_truth_verified","scientific_validation_claimed","discovery_claimed","submission_created","contact_triggered"]: if case.get(f) is not False:raise ValueError("nested curator case promotion refused") out=Path(out_dir) if out.exists():raise FileExistsError("review kit output must not already exist") out.mkdir(parents=True);case_path=out/"curator-case.json";case_path.write_text(json.dumps(case,ensure_ascii=False,indent=2)+"\n",encoding="utf-8") review=template(case_path);review_path=out/"source-review-template.json";review_path.write_text(json.dumps(review,ensure_ascii=False,indent=2)+"\n",encoding="utf-8") files=[] for p in [case_path,review_path]:d=p.read_bytes();files.append({"name":p.name,"bytes":len(d),"sha256":sha256(d).hexdigest()}) body={"schema_version":"openlab-clark-bound-review-kit-v1","status":"local_private_curator_review_kit_staged_not_reviewed","binding_sha256":v["binding_sha256"],"pairing_sha256":v["pairing_sha256"],"files":files,"source_cells":45,"all_cells_checked":False,"production_database_used":False,"submission_created":False,"identity_verified":False,"independence_verified":False,"scientific_validation_claimed":False,"discovery_claimed":False} body["kit_sha256"]=sha256(json.dumps(body,ensure_ascii=False,separators=(",",":"),sort_keys=True).encode()).hexdigest();(out/"review-kit-manifest.json").write_text(json.dumps(body,ensure_ascii=False,indent=2)+"\n",encoding="utf-8");return body def main(): p=argparse.ArgumentParser();p.add_argument("binding");p.add_argument("--out-dir",required=True);a=p.parse_args();print(json.dumps(stage(a.binding,a.out_dir),ensure_ascii=False)) if __name__=="__main__":main()