@@ -273,15 +273,35 @@ def test_runtime_preflight_records_daytona_computer_use(tmp_path):
273273 allow_inferred_runtime = True ,
274274 provider = "test-provider" ,
275275 model = "test-model" ,
276- sandbox_mode = "docker " ,
276+ sandbox_mode = "local " ,
277277 computer_use = "daytona" ,
278278 )
279279
280280 assert result .preflight ["computer_use" ] == "daytona"
281+ assert result .preflight ["ready" ] is True
281282 assert result .preflight ["computer_use_daytona" ]["local_api_url" ] == DAYTONA_LOCAL_API_URL
282283 assert "cu-screenshot" in result .preflight ["computer_use_daytona" ]["commands" ]
283284 assert result .profile .verification ["computer_use" ] == "daytona"
284- assert any ("Daytona computer use controls the outer" in w for w in result .preflight ["warnings" ])
285+
286+
287+ def test_runtime_preflight_rejects_daytona_without_local_runtime (tmp_path ):
288+ repo = tmp_path / "app"
289+ repo .mkdir ()
290+ out_dir = tmp_path / "results" / "app" / "run" / "verify"
291+
292+ result = run_runtime_preflight (
293+ repo_path = repo ,
294+ results_dir = out_dir ,
295+ execute_app = True ,
296+ allow_inferred_runtime = True ,
297+ provider = "test-provider" ,
298+ model = "test-model" ,
299+ sandbox_mode = "docker" ,
300+ computer_use = "daytona" ,
301+ )
302+
303+ assert result .preflight ["ready" ] is False
304+ assert any ("Daytona computer use controls the outer" in i for i in result .preflight ["issues" ])
285305
286306
287307def test_runtime_preflight_reports_discovered_env_sources (tmp_path , monkeypatch ):
@@ -709,11 +729,23 @@ async def fake_run_agent_process(prompt, **kwargs):
709729 {
710730 "status" : "not_reproduced" ,
711731 "confidence" : "high" ,
712- "evidence" : ["ran Daytona computer-use verification" ],
732+ "evidence" : ["ran cu-info and cu-screenshot before verification" ],
713733 }
714734 )
715735 return SimpleNamespace (
716736 error = None ,
737+ messages = [
738+ {
739+ "role" : "assistant" ,
740+ "content" : [
741+ {
742+ "type" : "toolCall" ,
743+ "name" : "bash" ,
744+ "arguments" : {"command" : "cu-info && cu-screenshot before.png" },
745+ }
746+ ],
747+ }
748+ ],
717749 last_assistant_message = payload ,
718750 find_tagged_message = lambda _tag : payload ,
719751 )
@@ -740,6 +772,85 @@ async def fake_run_agent_process(prompt, **kwargs):
740772 assert summary ["environment" ]["computer_use" ] == "daytona"
741773
742774
775+ def test_daytona_computer_use_blocks_live_agent_without_cu_evidence (tmp_path , monkeypatch ):
776+ repo = tmp_path / "app"
777+ repo .mkdir ()
778+ profile = repo / ".pithos" / "runtime.yaml"
779+ profile .parent .mkdir ()
780+ profile .write_text (
781+ """
782+ verification:
783+ execute_app: true
784+ environment:
785+ sandbox: local
786+ """ ,
787+ encoding = "utf-8" ,
788+ )
789+ results = tmp_path / "results" / "app" / "run"
790+ results .mkdir (parents = True )
791+ (results / "run-summary.json" ).write_text (json .dumps ({"repo" : {"path" : str (repo )}}))
792+ (results / "VULN-FINDINGS.json" ).write_text (
793+ json .dumps (
794+ [
795+ {
796+ "id" : "F001" ,
797+ "title" : "Generic live authorization bypass" ,
798+ "category" : "authorization bypass" ,
799+ "files" : ["src/server.ts" ],
800+ }
801+ ]
802+ )
803+ )
804+ (results / "TRIAGE.json" ).write_text (
805+ json .dumps ({"findings" : [{"id" : "F001" , "title" : "Generic live authorization bypass" }]})
806+ )
807+
808+ async def fake_run_agent_process (prompt , ** kwargs ):
809+ payload = json .dumps (
810+ {
811+ "status" : "not_reproduced" ,
812+ "confidence" : "high" ,
813+ "evidence" : ["ran source-only verification" ],
814+ }
815+ )
816+ return SimpleNamespace (
817+ error = None ,
818+ messages = [
819+ {
820+ "role" : "assistant" ,
821+ "content" : [
822+ {
823+ "type" : "toolCall" ,
824+ "name" : "bash" ,
825+ "arguments" : {"command" : "npm test" },
826+ }
827+ ],
828+ }
829+ ],
830+ last_assistant_message = payload ,
831+ find_tagged_message = lambda _tag : payload ,
832+ )
833+
834+ monkeypatch .setattr (runtime_plugins , "run_agent_process" , fake_run_agent_process )
835+ monkeypatch .setattr (
836+ runtime_plugins .docker_ops ,
837+ "run" ,
838+ lambda * args , ** kwargs : (_ for _ in ()).throw (AssertionError ("docker was called" )),
839+ )
840+
841+ result = run_verify_repo (
842+ triage_path = results ,
843+ execute_app = True ,
844+ provider = "anthropic" ,
845+ model = "claude-sonnet-4-5" ,
846+ sandbox_mode = "local" ,
847+ computer_use = "daytona" ,
848+ )
849+
850+ assert result .verdicts [0 ].status == "blocked"
851+ assert result .verdicts [0 ].error == "missing Daytona computer-use evidence"
852+
853+
743854def test_verify_repo_confirms_polar_style_source_oracles (tmp_path ):
744855 repo = tmp_path / "polar"
745856 (repo / "server/polar/oauth2/grants" ).mkdir (parents = True )
0 commit comments