app
AI Flow
Public Made by Adomby adom
Adom's AI Flow: a tool to help the AI follow all of the steps it takes to build a board.
main
John Lauer
Publish 0.2.15
bb17f84
#!/usr/bin/env python3
"""Fail-closed whole-board rectangular obstacle audit. Native CAD supplies the
transformed fitted-body/mask/hole envelopes and rendered text/leader bounds.
The inventory is independent of the obstacle export: missing geometry is an error.
"""
import argparse,json
from pathlib import Path
def overlaps(a,b):
return a[0]<b[2] and b[0]<a[2] and a[1]<b[3] and b[1]<a[3]
def rects(item,what):
# "box" | "boxes": dict.get(k, default) evaluates the default eagerly, so test the key.
if 'boxes' in item:return item['boxes']
if 'box' in item:return [item['box']]
raise ValueError(f"{what} {item.get('id','?')!r} has neither 'box' nor 'boxes'")
def check(data):
obs=data['obstacles'];inventory=data['inventory'];missing=[];collisions=[]
present={(o['id'],o['kind'],o['layer']) for o in obs}
for item in inventory:
for layer in item['layers']:
if (item['id'],item['kind'],layer) not in present:missing.append(dict(id=item['id'],kind=item['kind'],layer=layer))
for label in data['marks']:
for o in obs:
if label['layer']==o['layer'] and any(overlaps(a,b) for a in rects(label,'mark') for b in rects(o,'obstacle')):collisions.append(dict(mark=label['id'],obstacle=o['id'],kind=o['kind'],layer=o['layer']))
return dict(schemaVersion=1,passed=bool(inventory) and not missing and not collisions,coverageErrors=[] if inventory else ['Whole-board inventory is empty'],missingObstacles=missing,collisions=collisions,inventoryItems=len(inventory),obstacles=len(obs),marks=len(data['marks']),nativeVerified=False,note='Conservative rectangle audit only; geometry provenance, fitted transforms, label association and native 2D/3D review remain required.')
if __name__=='__main__':
p=argparse.ArgumentParser();p.add_argument('--input',required=True,type=Path);p.add_argument('--out',required=True,type=Path);a=p.parse_args();result=check(json.loads(a.input.read_text()));a.out.write_text(json.dumps(result,indent=2));print(('OK' if result['passed'] else 'ERROR')+f": {len(result['coverageErrors'])} coverage errors; {len(result['missingObstacles'])} missing obstacles; {len(result['collisions'])} collisions");raise SystemExit(0 if result['passed'] else 2)