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')