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
"""Actual CLI refusal and read-only guard; no CAD, real dashboard or AI queue."""
import json, os, pathlib, subprocess, sys, tempfile
binary=str(pathlib.Path(sys.argv[1]).resolve())
with tempfile.TemporaryDirectory(prefix='aiflow-continuation-') 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','continuation-test',*args],env=env,capture_output=True,text=True,timeout=30)
assert call('intake','--prompt-time','2026-10-10T00:00:00Z','--engine','test').returncode==0
assert call('prompt','--text','Finish the entire design').returncode==0
before={f.name:f.read_bytes() for f in run.iterdir() if f.is_file()}
r=call('finish-guard','--json');assert r.returncode==2,r.stderr
d=json.loads(r.stdout);assert d['decision']=='continue' and not d['mayStop']
assert before=={f.name:f.read_bytes() for f in run.iterdir() if f.is_file()},'guard mutated run files'
data=json.loads((run/'run.json').read_text());data['sequence']=['current'];data['currentStep']='current';data['steps']={'current':{'visits':[{'at':'2026-10-10T00:00:00Z'}]}};data['outcomeAt']={'analyze-current':'2026-10-10T00:01:00Z'};data['outcomes']={'analyze-current':{'pass':False}};(run/'run.json').write_text(json.dumps(data))
r=call('finish-guard','--json');assert 'current' in json.loads(r.stdout)['remaining'],'failed analysis was counted as proof'
# never refused (John, 2026-11-04): done closes the session and notes that the finish line is not reached
r=call('done','--message','Made good progress');assert r.returncode==0 and 'before the finish line' in r.stderr,(r.stdout,r.stderr)
assert call('finish-guard','--json','--stop-evidence',str(p/'missing.json')).returncode==2
pause=p/'pause.json';pause.write_text(json.dumps(dict(kind='user-pause',reason='User requested pause',userInstruction='pause until I resume',instructionAt='2026-10-10T00:01:00Z')))
r=call('finish-guard','--json','--stop-evidence',str(pause));assert r.returncode==0
assert not json.loads(r.stdout)['engineeringComplete']
assert call('done','--message','Paused by user','--stop-evidence',str(pause)).returncode==0
assert call('prompt','--text','Resume').returncode==0
r=call('done','--message','Stop again');assert r.returncode==0 and 'before the finish line' in r.stderr,'an old pause is not reused after resume: done still notes the open finish line'
assert call('finish-guard','--json').returncode==2
print('PASS: done closes with a note (never refused), guard read-only, missing evidence fails closed, explicit pause recorded without passing gates, resume requires fresh decision')