imrishabh18/corne-keyboard
The code defines and renders two surface-mount chip components with SMT pads, silkscreen outlines, and 3D CAD models (OBJ and STEP) for PCB assembly.
- Version
- 2.0.21
- License
- unset
- Stars
- 1
scripts/verify-board.py
"""Run installed DRC and independent physical connectivity checks; every diagnostic fails validation."""
import sys,json,subprocess,hashlib
from pathlib import Path
project=Path(__file__).resolve().parent.parent
inputs=sys.argv[1:] or ['dist/left/circuit.json','dist/right/circuit.json']
failed=False
for arg in inputs:
path=(project/arg).resolve();j=json.loads(path.read_text());folder=path.parent/'validation';folder.mkdir(exist_ok=True)
raw_path=folder/'routing-errors.json'
subprocess.run(['bun',str(project/'scripts/check-circuit.ts'),str(path),str(raw_path)],cwd=project,check=True,capture_output=True,text=True)
raw=json.loads(raw_path.read_text());reports=[]
keys=sorted({e['subcircuit_connectivity_map_key'] for e in j if e['type']=='source_trace'})
for number,key in enumerate(keys):
output=folder/f'net-{number}.json'
result=subprocess.run([sys.executable,str(project/'scripts/audit-copper.py'),str(path),str(output),key],capture_output=True,text=True)
if result.returncode:raise RuntimeError(result.stderr)
reports.append(json.loads(output.read_text()))
physical_errors=[{'type':'physical_net_disconnected','net':r['connectivity_key'],'groups':r['groups']} for r in reports if r['physical_ground_groups']!=1]
ground_key=next(e['subcircuit_connectivity_map_key'] for e in j if e['type']=='source_net' and e['name']=='GND')
ground=next(r for r in reports if r['connectivity_key']==ground_key)
clearance_path=folder/'pour-clearance.json'
subprocess.run([sys.executable,str(project/'scripts/audit-pour-clearance.py'),str(path),str(clearance_path)],capture_output=True,text=True,check=True)
clearance=json.loads(clearance_path.read_text())
physical_errors.extend({'type':'pour_clearance_error',**e} for e in clearance['violations'])
physical_errors.extend({'type':'net_metadata_conflict',**e} for e in clearance['metadata_conflicts'])
# The live checker understands pours. Never remove or reclassify diagnostics.
compiler_errors=[e for e in j if e['type'].endswith('_error')]
confirmed=[*raw,*compiler_errors,*physical_errors]
if not confirmed:
(path.parent/'circuit.validated.json').write_text(json.dumps(j,indent=2))
summary={'circuit':str(path),'sha256':hashlib.sha256(path.read_bytes()).hexdigest(),'trace_count':sum(e['type']=='pcb_trace' for e in j),'via_count':sum(e['type']=='pcb_via' for e in j),'checked_nets':len(reports),'ground_ports':ground['ground_port_count'],'ground_physical_groups':ground['physical_ground_groups'],'confirmed_routing_errors':len(confirmed),'checker_diagnostics':len(raw),'compiler_diagnostics':len(compiler_errors),'filtered_diagnostics':0,'pour_clearance_errors':len(clearance['violations']),'scope':'Routing connectivity, trace/via/pad clearance, copper-to-board-edge clearance, and copper keepout checks. Original placement/courtyard errors are outside this routing scope.'}
(folder/'summary.json').write_text(json.dumps(summary,indent=2))
(folder/'confirmed-routing-errors.json').write_text(json.dumps(confirmed,indent=2))
(folder/'all-net-connectivity.json').write_text(json.dumps(reports,indent=2))
print(f'{path.parent.name}: {len(confirmed)} confirmed routing errors; {len(reports)} nets checked; {ground["ground_port_count"]} GND pads in {ground["physical_ground_groups"]} physical group; {len(raw)} checker diagnostics; {len(compiler_errors)} compiler diagnostics',flush=True)
failed|=bool(confirmed)
if failed:sys.exit(1)