"""Record real MCP requests/responses. Inputs are private; output redacts operational metadata.
Usage: python3 evidence-driver.py URL AUTH_FILE OUTPUT_ROOT SIDE COMMIT
Servers: each revision's development server, T3CODE_DEV_SEED=0, fresh state.
Pair a companion server at the same revision with Auto access via `t3 environment link`.
Enable linkedEnvironmentsEnabled in both isolated servers' settings first.
AUTH_FILE holds an OAuth MCP Full access client token obtained using public registration,
PKCE authorization, a Full access pairing approval, and the token exchange endpoints.
No provider turn is started. No model identifier or credential is written to recordings.
"""
import urllib.request, json, sys, os, time, datetime, textwrap
url,auth_file,output_root,side,commit=sys.argv[1:]
auth=open(auth_file).read().strip(); session=None
run=os.path.join(output_root,datetime.datetime.now(datetime.timezone.utc).strftime('%Y%m%dT%H%M%S%fZ')+'-'+side)
os.makedirs(run); cast=open(os.path.join(run,side+'.cast'),'w'); transcript=open(os.path.join(run,side+'.txt'),'w')
cast.write(json.dumps({'version':2,'width':110,'height':40,'timestamp':int(time.time()),'env':{'TERM':'xterm-256color'},'title':side+' real-server MCP evidence'})+'\n'); started=time.monotonic()
redactions={}
def clean(v):
 s=str(v)
 for a,b in redactions.items():s=s.replace(a,b)
 return s
header=f'{side.upper()} | {commit}\nLinux real server | isolated synthetic state | MCP over HTTP\nFull access OAuth client | default interaction mode | terminal 110x40\nMachine label, workspace path, model identifier and credentials redacted.\n'
def show(title,body):
 text=header+'\n'+title+'\n\n'+clean(body)
 wrapped='\r\n'.join(line for l in text.splitlines() for line in (textwrap.wrap(l,106,replace_whitespace=False) or ['']))+'\r\n'
 transcript.write(text+'\n\n');transcript.flush()
 cast.write(json.dumps([round(time.monotonic()-started,3),'o','\u001b[2J\u001b[H'+wrapped])+'\n');cast.flush()
 print(text,flush=True);time.sleep(3)
def request(body):
 global session
 headers={'Authorization':'Bearer '+auth,'Content-Type':'application/json','Accept':'application/json, text/event-stream'}
 if session:headers['MCP-Session-Id']=session
 with urllib.request.urlopen(urllib.request.Request(url+'/mcp',json.dumps(body).encode(),headers)) as r:
  session=r.headers.get('MCP-Session-Id',session); text=r.read().decode()
 return json.loads(next(l[6:] for l in text.splitlines() if l.startswith('data: '))) if text.startswith('event:') else json.loads(text)
request({'jsonrpc':'2.0','id':0,'method':'initialize','params':{'protocolVersion':'2025-03-26','capabilities':{},'clientInfo':{'name':'Evidence recorder','version':'1'}}})
def call(name,args):
 r=request({'jsonrpc':'2.0','id':1,'method':'tools/call','params':{'name':name,'arguments':args}})
 if 'error' in r:raise RuntimeError(r['error'])
 result=r['result'];return result.get('structuredContent') or json.loads(result['content'][0]['text'])
cap=call('orchestrator_capabilities',{});provider=next(p for p in cap['providers'] if p['models'] and p['canRunChildTask'])
selection={'instanceId':provider['providerInstanceId'],'model':provider['models'][0]['id']}
show('1. Authenticate and obtain capabilities',f"runtimeMode={cap['runtimeMode']}\ninteractionMode={cap['interactionMode']}\nSelected a valid advertised model (identifier withheld).")
link=call('t3_environment_links',{})['links'][0];redactions[link['label']]='Evidence origin'
show('2. Inspect actual linked environment',f"status={link['status']}\naccess={link['access']}\nlabel=Evidence origin (redacted)")
workspace=os.path.join(run,'workspace');redactions[workspace]='<synthetic-workspace>'
for name,args in [('t3_project_create',{'title':'Evidence linked project','workspaceRoot':workspace+'-linked','createWorkspaceRootIfMissing':True}),('t3_project_clone',{'sourceUrl':'https://example.com/synthetic.git','destinationPath':workspace+'-clone'})]:
 args['environmentId']=link['environmentId']
 show('3. Request '+name,'Target: linked environment with Auto access\n'+clean(json.dumps({k:v for k,v in args.items() if k!='environmentId'},indent=2)))
 result=call(name,args);show('3. Response '+name,json.dumps(result,indent=2))
initial=call('t3_project_list',{})['projects'];matches=[p for p in initial if p['title']=='Evidence model default']
show('4. Local initial state',f'Projects titled "Evidence model default": {len(matches)}')
args={'title':'Evidence model default','workspaceRoot':workspace,'createWorkspaceRootIfMissing':True,'defaultModelSelection':selection}
show('5. Request t3_project_create locally','title="Evidence model default"\nworkspaceRoot=<synthetic-workspace>\ncreateWorkspaceRootIfMissing=true\ndefaultModelSelection=<valid selection from capabilities>')
result=call('t3_project_create',args);show('5. Actual create response',json.dumps(result,indent=2))
if 'id' in result:
 read=call('t3_project_read',{'projectId':result['id']});show('6. Actual t3_project_read response',json.dumps(read,indent=2))
projects=call('t3_project_list',{})['projects'];matches=[p for p in projects if p['title']=='Evidence model default']
show('7. Actual final project-list observation',json.dumps({'matchingProjectCount':len(matches),'defaults':[p['defaultModelSelection'] for p in matches],'workspaceExists':os.path.exists(workspace)},indent=2))
cast.close();transcript.close();print('Recording directory: '+run)
