@@ -100,6 +100,38 @@ def _console_script(root: Path) -> Path:
100100 )
101101
102102
103+ def _inspect_opencv_provider (
104+ python : Path ,
105+ * ,
106+ cwd : Path ,
107+ env : dict [str , str ],
108+ log : Path ,
109+ ) -> str :
110+ """Require one reviewed distribution to own the installed ``cv2`` package."""
111+
112+ probe = _run (
113+ [
114+ str (python ),
115+ "-c" ,
116+ (
117+ "import importlib.metadata as m, json; "
118+ "names={d.metadata['Name'].lower() for d in m.distributions() "
119+ "if d.metadata.get('Name')}; "
120+ "providers=sorted(names & {'opencv-python','opencv-python-headless',"
121+ "'opencv-contrib-python','opencv-contrib-python-headless'}); "
122+ "import cv2; "
123+ "print(json.dumps({'providers':providers,'cv2_version':cv2.__version__})); "
124+ "assert providers == ['opencv-python'], providers"
125+ ),
126+ ],
127+ cwd = cwd ,
128+ env = env ,
129+ log = log ,
130+ )
131+ payload = json .loads (probe .stdout .splitlines ()[- 1 ])
132+ return str (payload ["providers" ][0 ])
133+
134+
103135def _load_report (path : Path ) -> dict :
104136 if not path .is_file ():
105137 raise AssertionError (f"missing machine-readable run report: { path } " )
@@ -290,14 +322,20 @@ def run_lifecycle(
290322 log = logs / "01-install.log" ,
291323 )
292324 installed = True
325+ summary ["opencv_provider" ] = _inspect_opencv_provider (
326+ python ,
327+ cwd = artifacts ,
328+ env = env ,
329+ log = logs / "02-opencv-provider.log" ,
330+ )
293331 console = _console_script (venv_dir )
294332 if not console .is_file ():
295333 raise AssertionError (f"console entry point was not installed: { console } " )
296334 _run (
297335 [str (console ), "--help" ],
298336 cwd = artifacts ,
299337 env = env ,
300- log = logs / "02 -cli-help.log" ,
338+ log = logs / "03 -cli-help.log" ,
301339 )
302340
303341 # Linux needs host libraries that the ordinary unprivileged first-run
@@ -312,7 +350,7 @@ def run_lifecycle(
312350 browser_command ,
313351 cwd = artifacts ,
314352 env = env ,
315- log = logs / "03 -browser-install.log" ,
353+ log = logs / "04 -browser-install.log" ,
316354 )
317355
318356 cli = [str (python ), "-m" , "openadapt_flow" ]
@@ -322,7 +360,7 @@ def run_lifecycle(
322360 [* cli , "demo-record" , "--out" , str (recording )],
323361 cwd = artifacts ,
324362 env = env ,
325- log = logs / "04 -record.log" ,
363+ log = logs / "05 -record.log" ,
326364 )
327365 _run (
328366 [
@@ -336,7 +374,7 @@ def run_lifecycle(
336374 ],
337375 cwd = artifacts ,
338376 env = env ,
339- log = logs / "05 -compile.log" ,
377+ log = logs / "06 -compile.log" ,
340378 )
341379
342380 # The bundled tutorial is deliberately not production-certified. The
@@ -349,20 +387,20 @@ def run_lifecycle(
349387 [* cli , "lint" , str (bundle ), "--strict" ],
350388 cwd = artifacts ,
351389 env = env ,
352- log = logs / "06 -strict-lint-expected-refusal.log" ,
390+ log = logs / "07 -strict-lint-expected-refusal.log" ,
353391 expected = 1 ,
354392 )
355393 _run (
356394 [* cli , "certify" , str (bundle ), "--policy" , "permissive" ],
357395 cwd = artifacts ,
358396 env = env ,
359- log = logs / "07 -certify-permissive.log" ,
397+ log = logs / "08 -certify-permissive.log" ,
360398 )
361399 _run (
362400 [* cli , "certify" , str (bundle ), "--policy" , "clinical-write" ],
363401 cwd = artifacts ,
364402 env = env ,
365- log = logs / "08 -certify-clinical-expected-refusal.log" ,
403+ log = logs / "09 -certify-clinical-expected-refusal.log" ,
366404 expected = 2 ,
367405 )
368406 _run (
@@ -375,7 +413,7 @@ def run_lifecycle(
375413 ],
376414 cwd = artifacts ,
377415 env = env ,
378- log = logs / "09 -replay-baseline.log" ,
416+ log = logs / "10 -replay-baseline.log" ,
379417 )
380418 _run (
381419 [
@@ -391,15 +429,15 @@ def run_lifecycle(
391429 ],
392430 cwd = artifacts ,
393431 env = env ,
394- log = logs / "10 -replay-drift.log" ,
432+ log = logs / "11 -replay-drift.log" ,
395433 )
396434 # The COMPOSED free path. Every command above passed while this loop
397435 # was broken; only running it end to end catches that.
398436 _run (
399437 [* cli , "tutorial" , "--out" , str (artifacts / "tutorial" )],
400438 cwd = artifacts ,
401439 env = env ,
402- log = logs / "11 -tutorial-verified.log" ,
440+ log = logs / "12 -tutorial-verified.log" ,
403441 )
404442 summary .update (_inspect_artifacts (artifacts ))
405443 finally :
@@ -408,7 +446,7 @@ def run_lifecycle(
408446 [str (python ), "-m" , "pip" , "uninstall" , "-y" , "openadapt-flow" ],
409447 cwd = artifacts ,
410448 env = env ,
411- log = logs / "12 -uninstall.log" ,
449+ log = logs / "13 -uninstall.log" ,
412450 )
413451 probe = _run (
414452 [
@@ -421,7 +459,7 @@ def run_lifecycle(
421459 ],
422460 cwd = artifacts ,
423461 env = env ,
424- log = logs / "13 -uninstall-probe.log" ,
462+ log = logs / "14 -uninstall-probe.log" ,
425463 )
426464 summary ["uninstall_verified" ] = probe .returncode == 0
427465 (work_dir / "summary.json" ).write_text (
0 commit comments