@@ -337,6 +337,112 @@ def test_run_skill_references_git_metadata_write_capability() -> None:
337337 )
338338
339339
340+ def test_execute_dispatch_accepts_effective_backend_map () -> None :
341+ """execute_dispatch signature must include effective_backend_map parameter."""
342+ import inspect
343+
344+ from autoskillit .fleet ._api import execute_dispatch
345+
346+ sig = inspect .signature (execute_dispatch )
347+ assert "effective_backend_map" in sig .parameters , (
348+ "execute_dispatch must accept effective_backend_map — "
349+ "without it the CLI and dispatch_food_truck cannot thread the per-step map "
350+ "into the engine's internal load_and_validate call."
351+ )
352+
353+
354+ def _find_load_and_validate_call_in_run_dispatch (src : str ) -> ast .Call | None :
355+ """Return the load_and_validate Call node inside _run_dispatch, or None."""
356+ tree = ast .parse (src )
357+ for node in ast .walk (tree ):
358+ if isinstance (node , ast .AsyncFunctionDef ) and node .name == "_run_dispatch" :
359+ for child in ast .walk (node ):
360+ if (
361+ isinstance (child , ast .Call )
362+ and isinstance (child .func , ast .Attribute )
363+ and child .func .attr == "load_and_validate"
364+ ):
365+ return child
366+ return None
367+
368+
369+ def test_run_dispatch_passes_effective_backend_map_to_load_and_validate () -> None :
370+ """_run_dispatch must pass effective_backend_map kwarg to load_and_validate."""
371+ api_path = SRC_ROOT / "fleet" / "_api.py"
372+ src = api_path .read_text (encoding = "utf-8" )
373+ call_node = _find_load_and_validate_call_in_run_dispatch (src )
374+ assert call_node is not None , (
375+ "load_and_validate call not found inside _run_dispatch in fleet/_api.py"
376+ )
377+ kw_names = {kw .arg for kw in call_node .keywords if kw .arg is not None }
378+ assert "effective_backend_map" in kw_names , (
379+ "_run_dispatch must pass effective_backend_map to load_and_validate — "
380+ "without it the engine's validation always runs without per-step routing context."
381+ )
382+
383+
384+ def test_execute_fleet_run_calls_provider_aware_capability_overrides () -> None :
385+ """_execute_fleet_run must call _provider_aware_capability_overrides (CLI admission parity)."""
386+ fleet_run_path = SRC_ROOT / "cli" / "fleet" / "_fleet_run.py"
387+ tree = ast .parse (fleet_run_path .read_text (encoding = "utf-8" ))
388+ assert _has_call_in_function (
389+ tree , "_execute_fleet_run" , "_provider_aware_capability_overrides"
390+ ), (
391+ "_execute_fleet_run must call _provider_aware_capability_overrides — "
392+ "without this, the CLI path does not compute provider-aware capability signals "
393+ "before dispatching, causing backend-incompatible-skill errors for Codex runs."
394+ )
395+
396+
397+ def test_execute_fleet_run_calls_compute_effective_backend_map () -> None :
398+ """_execute_fleet_run must call _compute_effective_backend_map (CLI admission parity)."""
399+ fleet_run_path = SRC_ROOT / "cli" / "fleet" / "_fleet_run.py"
400+ tree = ast .parse (fleet_run_path .read_text (encoding = "utf-8" ))
401+ assert _has_call_in_function (tree , "_execute_fleet_run" , "_compute_effective_backend_map" ), (
402+ "_execute_fleet_run must call _compute_effective_backend_map — "
403+ "without this, the CLI path never computes per-step routing and always "
404+ "evaluates backend-compat with a flat backend map."
405+ )
406+
407+
408+ def test_dispatch_food_truck_forwards_effective_backend_map_to_execute_dispatch () -> None :
409+ """dispatch_food_truck must pass effective_backend_map to execute_dispatch call."""
410+ fleet_path = SRC_ROOT / "server" / "tools" / "tools_fleet_dispatch.py"
411+ src = fleet_path .read_text (encoding = "utf-8" )
412+ tree = ast .parse (src )
413+ for node in ast .walk (tree ):
414+ if isinstance (node , ast .AsyncFunctionDef ) and node .name == "dispatch_food_truck" :
415+ for child in ast .walk (node ):
416+ if (
417+ isinstance (child , ast .Call )
418+ and isinstance (child .func , ast .Name )
419+ and child .func .id == "execute_dispatch"
420+ ):
421+ kw_names = {kw .arg for kw in child .keywords if kw .arg is not None }
422+ assert "effective_backend_map" in kw_names , (
423+ "dispatch_food_truck must pass effective_backend_map to "
424+ "execute_dispatch — without it, the per-step routing map "
425+ "computed by the preflight is silently dropped at the engine boundary."
426+ )
427+ return
428+ pytest .fail ("execute_dispatch call not found inside dispatch_food_truck" )
429+ pytest .fail ("dispatch_food_truck function not found in tools_fleet_dispatch.py" )
430+
431+
432+ def test_validate_from_path_accepts_effective_backend_map () -> None :
433+ """validate_from_path signature must accept effective_backend_map."""
434+ import inspect
435+
436+ from autoskillit .recipe ._api_listing import validate_from_path
437+
438+ sig = inspect .signature (validate_from_path )
439+ assert "effective_backend_map" in sig .parameters , (
440+ "validate_from_path must accept effective_backend_map — "
441+ "without it the validate_recipe MCP tool cannot thread per-step routing "
442+ "context into backend-compat rule evaluation."
443+ )
444+
445+
340446def test_compute_effective_backend_map_accepts_skill_resolver () -> None :
341447 """_compute_effective_backend_map must accept a skill_resolver parameter."""
342448 auto_overrides_path = SRC_ROOT / "server" / "tools" / "_auto_overrides.py"
0 commit comments