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.48
7fce739
"""Existing project rules produce honest run evidence without mutating rule files."""
import hashlib,json,os,pathlib,subprocess,sys,tempfile
binary=str(pathlib.Path(sys.argv[1]).resolve())
with tempfile.TemporaryDirectory(prefix='aiflow-rules-cli-') as td:
p=pathlib.Path(td);run=p/'run';env=dict(os.environ,AIFLOW_DASHBOARD='off')
def call(*args):
return subprocess.run([binary,'--run',str(run),'--ai-thread','rules-regression',*args],env=env,capture_output=True,text=True,timeout=30)
assert call('intake','--prompt-time','2026-10-10T00:00:00Z','--engine','test').returncode==0
board=p/'board.kicad_pcb';board.write_text('(kicad_pcb (version 20240108))\n')
rules=board.with_suffix('.kicad_dru');body='(version 1)\n(rule "project custom" (constraint clearance (min 0.2mm)))\n';rules.write_text(body)
spec=p/'spec.json';spec.write_text(json.dumps({'fab':{'rules':'fab'}}))
state=run/'run.json';d=json.loads(state.read_text());d['boards']=[str(board)];d['spec']=str(spec);d['sequence']=['rules'];d['steps']={'rules':{'visits':[{'at':'2026-10-10T00:00:00Z'}]}};state.write_text(json.dumps(d))
def outcome():return json.loads(state.read_text())['outcomes'].get('rules')
r=call('rules','check');assert r.returncode==0,(r.stdout,r.stderr)
o=outcome();assert o['pass'] and o['method']=='existing-project-check'
assert o['rulesSha256']==hashlib.sha256(body.encode()).hexdigest()
assert o['boardSha256']==hashlib.sha256(board.read_bytes()).hexdigest()
assert rules.read_text()==body
g=json.loads(call('finish-guard','--json').stdout);assert 'rules' not in g['remaining'] and not g['engineeringComplete']
other=p/'other.kicad_pcb';other.write_text(board.read_text());other.with_suffix('.kicad_dru').write_text(body)
assert call('rules','check','--board',str(other)).returncode==0
assert outcome()==o,'unrelated board changed this run proof'
r=call('rules','check','--profile','jlcpcb');assert r.returncode==0 and 'FINDINGS' in r.stdout,(r.stdout,r.stderr)
assert outcome()==o,'profile override changed selected-profile proof'
alias=p/'same-board.kicad_pcb';alias.symlink_to(board);alias.with_suffix('.kicad_dru').write_text(body)
assert call('rules','check','--board',str(alias)).returncode==0
assert outcome()==o,'alias with a different rules file changed the selected project proof'
alias.with_suffix('.kicad_dru').unlink();alias.with_suffix('.kicad_dru').symlink_to(rules)
assert call('rules','check','--board',str(alias)).returncode==0
assert outcome()['pass']
rules.unlink();r=call('rules','check');assert r.returncode==0 and 'FINDINGS' in r.stdout,(r.stdout,r.stderr)
assert outcome()['pass'] is False,'failed recheck left a stale passing outcome'
g=json.loads(call('finish-guard','--json').stdout);assert any('rules' in x for x in g['remaining']) and not g['mayStop']
assert not rules.exists(),'check rewrote rules'
print('PASS: current-board proof, immutable custom rules, hashes, unrelated-board/profile isolation, alias binding and stale-success invalidation; engineering gates remain open.')