"""EXPERIMENTAL adapter; inherited bounded process/socket cleanup stays intact.""" import argparse from pathlib import Path import subprocess import sys from campaign import Campaign from scenario import SCENARIO p = argparse.ArgumentParser() p.add_argument('lab', type=Path) p.add_argument('mode', choices=('control', 'private_standard', 'private_mosaic')) a = p.parse_args() lab = a.lab.resolve() repo = Path(__file__).resolve().parents[3] # WHY: one lock covers all modes, dynamic reservations and complete child cleanup. # CONTRACT: repeated/failed runs cannot silently replenish campaign budgets. # INVARIANT: no hide/return camera pair is generated by this adapter. campaign = Campaign(lab) campaign.begin(a.mode) s = (repo / 'tooling/probes/step20c-applied-state-input/run.py').read_text() s = s.replace("f'{args.mode}-{args.kind}-asi{args.asi_mode}-{time.time_ns()}'", "f'{args.mode}-dynamic-{time.time_ns()}'") s = s.replace('output HEADLESS-1 resolution 800x600 position -800 0', 'output HEADLESS-1 resolution 1000x750 scale 1.25 position -800 0') s = s.replace("Path('/usr/bin/sway')", "lab / 'standard-build/sway/sway'") s = s.replace('import argparse', 'import argparse\nfrom PIL import Image\nimport sys\nsys.path.insert(0, '+repr(str(Path(__file__).parent.resolve()))+')\nfrom campaign import reserve') s = s.replace("run.mkdir(parents=True, mode=0o700)", "run.mkdir(parents=True, mode=0o700)\n(run / 'fixture-source.py').write_text(Path(__file__).read_text())") start = s.index(" expected = {'HEADLESS-1':") end = s.index(" for output, side in", start) s = s[:start]+''' expected = {'HEADLESS-1': (-960, 0, 960, 600) if globals().get('dynamic_stage') == 'D1' else (-800, 0, 800, 600), 'HEADLESS-2': (0, 0, 800, 600)} actual = {o['name']: tuple(o['rect'][k] for k in ('x','y','width','height')) for o in outputs if o['active']} if actual != expected or any(o['transform'] != 'normal' or o['scale'] != (1.25 if o['name']=='HEADLESS-1' else 1) for o in outputs if o['active']): raise RuntimeError(f'output geometry/scale/transform mismatch: {actual}') record('state', tag=tag, workspaces=ipc('-t','get_workspaces'), workspace=workspace(), owner=owner(), outputs=outputs) '''+s[end:] s = s.replace("['grim', '-o', output, str(path)]", "['grim', '-s', str(next(o['scale'] for o in outputs if o['name']==output)), '-o', output, str(path)]") s = s.replace(" record('capture', tag=tag", """ out = next(o for o in outputs if o['name']==output) dimensions = list(Image.open(path).size) if dimensions != [out['current_mode']['width'],out['current_mode']['height']]: raise RuntimeError('physical PNG/mode mismatch') record('capture_geometry',tag=tag,output=output,dimensions=dimensions,rect=out['rect'],scale=out['scale'],transform=out['transform'],mode=out['current_mode']) record('capture', tag=tag""") start=s.index('def inject(action, x, y):');end=s.index('\ndef client_command',start) s=s[:start]+'''def inject(action, x, y): outputs = [o for o in ipc('-t','get_outputs') if o['active']] min_x = min(o['rect']['x'] for o in outputs) min_y = min(o['rect']['y'] for o in outputs) max_x = max(o['rect']['x']+o['rect']['width'] for o in outputs) max_y = max(o['rect']['y']+o['rect']['height'] for o in outputs) if not any(o['rect']['x']<=xbefore) '''+s[end:] start=s.index(" if args.kind == 'cycles':\n");end=s.index('except Exception as exc:',start) scenario=SCENARIO s=s[:start]+scenario+'\n'+s[end:] generated=lab/f'dynamic-{a.mode}.py' generated.write_text(s) raise SystemExit(subprocess.call([sys.executable,str(generated),str(lab),a.mode,'cycles','--max-seconds','240','--max-captures','100','--max-bytes','60000000'], pass_fds=(campaign.lock.fileno(),)))