#!/usr/bin/env python3
"""Synthetic context-recovery reproduction; run from either tested checkout.
Start `T3CODE_DEV_SEED=0 T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD=0 vp run dev`.
Run seed with PROOF_MODEL set to an available Codex model; stop the server;
run break; restart the server; open the returned thread in the web client;
record the browser while running third. Uses only this checkout's .t3 state.
"""
import argparse, json, os, pathlib, sqlite3, subprocess, datetime
p=argparse.ArgumentParser();p.add_argument('phase',choices=['seed','break','third','verify']);p.add_argument('--output',required=True);a=p.parse_args()
out=pathlib.Path(a.output);out.mkdir(parents=True,exist_ok=True)
state=out/'thread.json'
def cli(*args):
    r=subprocess.run(['node','apps/server/src/bin.ts',*args,'--base-dir','.t3'],check=True,capture_output=True,text=True)
    return r.stdout
if a.phase=='seed':
    workspace=out/'context-workspace';workspace.mkdir(exist_ok=True)
    subprocess.run(['git','init','--quiet','--initial-branch=main',str(workspace)],check=True)
    subprocess.run(['git','-C',str(workspace),'-c','user.name=Example','-c','user.email=example@example.invalid','commit','--quiet','--allow-empty','-m','Initial commit'],check=True)
    cli('project','add',str(workspace),'--title','Context recovery')
    first=json.loads(cli('thread','start',str(workspace),'Remember the word PELICAN','--title','Recovery proof','--provider','codex','--model',os.environ['PROOF_MODEL'],'--wait','--json'))
    state.write_text(json.dumps({'threadId':first['threadId']}))
    second=json.loads(cli('thread','send',first['threadId'],'What word did I ask you to remember?','--wait','--json'))
    print(json.dumps({'phase':'seed','firstReply':first['reply'],'secondReply':second['reply']}))
else:
    tid=json.loads(state.read_text())['threadId']
    if a.phase=='third':
        r=json.loads(cli('thread','send',tid,'Which word did I ask you to remember earlier?','--wait','--json'))
        print(json.dumps({'phase':'third','status':r['status'],'reply':r['reply']}))
    else:
        c=sqlite3.connect('.t3/userdata/statev2.sqlite')
        if a.phase=='break':
            fake='00000000-0000-4000-8000-000000000195'
            c.execute("update orchestration_v2_projection_provider_threads set payload_json=json_set(payload_json,'$.nativeThreadRef.nativeId',?) where thread_id=?",(fake,tid))
            c.execute("update orchestration_v2_projection_run_attempts set payload_json=json_set(payload_json,'$.nativeThreadId',?) where thread_id=?",(fake,tid))
            c.commit(); print('Changed the synthetic native IDs; restart the server now.')
        else:
            rows=c.execute("select payload_json from orchestration_v2_projection_turn_items where thread_id=?",(tid,)).fetchall()
            items=[json.loads(x[0]) for x in rows]
            hs=[x for x in items if x['type']=='handoff']
            print(json.dumps({'handoffTurnItems':len(hs),'handoffSummaries':[x.get('summary') for x in hs]}))
