speaker-verification
audio
nemotron
tyger
experimental
tyger-speaker-predictor / code /final_verify.py
ChristophSchuhmann's picture
Publish audited Robby source and completed Nemotron speaker-prediction experiments
0efd0f1 verified
Raw History Blame Contribute Delete
4.44 kB
"""Sequential, fail-closed final QA. One live slot; never stop other sessions.
Uses only public synthetic fixtures/fake browser devices. Does not start/stop
services, publish files remotely, or change model weights.
"""
import argparse,hashlib,json,subprocess,sys,time
from pathlib import Path
ROOT=Path(__file__).resolve().parent
def runtime_signature():
files=[ROOT/n for n in ('server.py','speaker_session.py','speaker_turns.py','speaker_runtime.py','speaker_teacher.py',
'speaker_names.py','identity.py','audio_sync.py','feature_tap.py','paths.py','tts_bridge.py','shared_turn.py')]
for pattern in ('*.js','*.css','emotion-catalog.json','index.html','robby.svg'):files+=sorted((ROOT/'static').glob(pattern))
return hashlib.sha256(b''.join(p.read_bytes() for p in files)).hexdigest()
def main(url,max_repeats=0):
py=sys.executable
browser=['uv','run','--no-project','--with','playwright','--python',py]
stages=[('unit',[py,'run_unit_checks.py'],60),
('fixture_asr',[py,'-m','speaker_live.fixture_qa'],120),
('three_people',[py,'-m','speaker_live.multi_test','--extended','--background-shift','0','--max-repeats',str(max_repeats)],360),
('three_people_shifted',[py,'-m','speaker_live.multi_test','--extended','--background-shift','2.3','--max-repeats',str(max_repeats)],360),
('streamed_echo',[py,'-m','speaker_live.echo_test'],180),
('browser_original',browser+['browser_mic_checks.py','--url',url],180),
('browser_desk',browser+['browser_mic_checks.py','--url',url.rstrip('/')+'/desk-robot/'],180),
('microphone_lifecycle',browser+['browser_lifecycle_checks.py'],60),
('desk_cpu',browser+['desk_robot_checks.py','--url',url.rstrip('/')+'/desk-robot/'],90),
('clock_camera',['uv','run','--no-project','--with','playwright','--with','numpy==1.26.4','--python',py,
'browser_checks.py','--url',url.rstrip('/')+'/desk-robot/','--camera'],90),
('native_features',[py,'-m','speaker_v4.preflight'],90),
('selective_dataset_safety',[py,'-m','pytest','-q','speaker_v2/test_dataset_pipeline.py'],60)]
source_hash=runtime_signature()
report={'started':time.time(),'synthetic_only':True,'physical_microphone_used':False,
'runtime_source_sha256':source_hash,'url':url,'max_explicit_repeats_per_turn':max_repeats,
'first_pass_guaranteed':False,'stages':[],'passed':False}
target=ROOT/'logs/final-verification.json'
def save():target.write_text(json.dumps(report,indent=2))
save()
for name,command,timeout in stages:
print('START '+name,flush=True);start=time.monotonic()
record={'name':name,'passed':False,'started':time.time()};report['stages'].append(record);save()
with (ROOT/'logs'/('verify-'+name+'.log')).open('w') as output:
try:
result=subprocess.run(command,cwd=ROOT,stdout=output,stderr=subprocess.STDOUT,timeout=timeout)
record.update(exit_code=result.returncode,passed=result.returncode==0)
except subprocess.TimeoutExpired:record.update(exit_code=None,timed_out=True)
record['seconds']=time.monotonic()-start;save()
print(json.dumps(record),flush=True)
if not record['passed']:raise SystemExit('Final QA stopped at '+name+'; see its synthetic-only test log')
if name=='three_people':
# Keep both independently timed conversation receipts, not only
# the shifted-background rerun that uses the same output filename.
import shutil
source=Path('/mnt/nvme/robo-speaker-studies/speaker-live-results/three-user-live.json')
shutil.copyfile(source,source.with_name('three-user-unshifted.json'))
final_hash=runtime_signature()
report.update(finished=time.time(),passed=source_hash==final_hash,source_unchanged=source_hash==final_hash);save()
if not report['passed']:raise SystemExit('Runtime source changed during final QA; results are not a frozen-source pass')
print('All final checks passed on unchanged runtime source.',flush=True)
if __name__=='__main__':
p=argparse.ArgumentParser();p.add_argument('--url',default='https://diane-asylum-understood-invoice.trycloudflare.com/')
p.add_argument('--max-repeats',type=int,choices=(0,1),default=0,help='0: strict first pass; 1: explicitly reported bounded-recovery test')
args=p.parse_args();main(args.url,args.max_repeats)