AnasSarkiz/NEMA14_RP2040
A NEMA stepper motor assembly concept with a controller board, proposed M3 screws and spacers, four motor leads with insulated splices, and a JST 4-pin connector harness.
- Version
- 1.12.2
- License
- ISC
- Stars
- 0
scripts/verify-publish-readiness.py
"""Prevent publication of an unqualified or stale saved board revision."""
import hashlib,json,pathlib,re,sys
from placement_advisories import orientation_advisories_only
root=pathlib.Path(__file__).resolve().parents[1];board=root/'artifacts/board.circuit.json';sha=hashlib.sha256(board.read_bytes()).hexdigest();errors=[];prototype="--prototype" in sys.argv
receipt_path=root/'artifacts/resume-validation.json'
if not receipt_path.exists():errors.append('No complete current qualification receipt.')
else:
r=json.loads(receipt_path.read_text())
if r.get('board_sha256')!=sha:errors.append('Qualification receipt belongs to a different board revision.')
if not r.get('native_STEP_mechanical_pass'):errors.append('Current native STEP mechanical check has not passed.')
for e in r.get('checks',[]):
if not e['exit_code']:continue
if prototype and e['check']=='native_placement':
log=(root/e['log']).read_text()
if orientation_advisories_only(log):continue
errors.append('Check failed: '+e['check'])
required={'native_circular_keepout_regression','actual_via_drills_and_JLCPCB_clearances','oscillator_layout','all_resistor_edge_clearances','schematic_geometry_ERC','typescript','drc','connectivity','fitted_JST_and_actual_drills','exact_mounts_and_actual_drills','native_json_checks','native_netlist','native_pin_specification','native_source','native_schematic-placement','native_placement','every_trace_review','reference_feedback','gerber_shorts','copper_widths','full_independent_CAM','strict_Circuit_JSON_schema','USB_coupled_copper_and_ground_reference'}
if required-{e['check'] for e in r.get('checks',[])}:errors.append('Qualification receipt is missing required checks.')
cam=json.loads((root/'artifacts/manufacturing/audit.json').read_text())
if cam.get('source_sha256')!=sha:errors.append('Independent CAM receipt is stale.')
if r.get('full_CAM_status')!='PASS' or cam.get('status')!='PASS' or cam.get('issues'):errors.append('Independent manufacturing audit has not passed.')
if json.loads((root/'index.circuit.json').read_text())!=json.loads(board.read_text()):errors.append('Delivered preview differs from the saved board.')
print(json.dumps({'publication_allowed':not errors,'board_sha256':sha,'publication_scope':'hardware prototype; supplier approval and bench qualification remain incomplete' if prototype else 'all recorded checks passed','blockers':errors},indent=2))
raise SystemExit(bool(errors))