4646]
4747WORKFLOW_TRIGGER_EVENTS = ("push" , "pull_request" )
4848CANONICAL_PLANNING_DOCS_TEST_PATH = "tests/planning_docs/**"
49+ CANONICAL_PLANNING_DOCS_TEST_COMMAND = "uv run --with pytest python -m pytest tests/planning_docs"
4950STALE_PLANNING_DOCS_TEST_PATH = "tests/planningdocs/**"
51+ STALE_PLANNING_DOCS_TEST_COMMAND_PATH = "tests/planningdocs"
5052CLEAN_HELP_DESCRIPTION = "Remove root generated search index and backend dist."
5153STALE_WORK_ENGINE_HELP_PHRASE = "work-engine dist"
5254TASK_TEMPLATE_SECTIONS = [
@@ -409,7 +411,6 @@ def validate_workflow(repo_root: Path) -> list[str]:
409411 "workflow_dispatch:" ,
410412 "permissions:" ,
411413 "contents: read" ,
412- "uv run --with pytest python -m pytest tests/planning_docs" ,
413414 "uv run --with pytest python -m pytest tests/infra" ,
414415 "npm --prefix backend run validate:docs-links" ,
415416 ]
@@ -420,6 +421,10 @@ def validate_workflow(repo_root: Path) -> list[str]:
420421 if protected_path not in text :
421422 violations .append (f"{ _repo_path (repo_root , workflow )} : path filter missing { protected_path } " )
422423 workflow_label = _repo_path (repo_root , workflow )
424+ violations .extend (
425+ f"{ workflow_label } : { violation } "
426+ for violation in validate_workflow_execution_command (text )
427+ )
423428 violations .extend (
424429 f"{ workflow_label } : { violation } "
425430 for violation in validate_workflow_trigger_paths (text )
@@ -444,6 +449,28 @@ def validate_workflow(repo_root: Path) -> list[str]:
444449 return violations
445450
446451
452+ def validate_workflow_execution_command (workflow_text : str ) -> list [str ]:
453+ """Require the planning-doc test step to use the exact canonical command."""
454+ run_commands = [
455+ match .group ("command" ).strip ()
456+ for match in re .finditer (
457+ r"(?m)^\s*run:\s*(?P<command>\S.*?)\s*$" , workflow_text
458+ )
459+ ]
460+ violations : list [str ] = []
461+ if any (STALE_PLANNING_DOCS_TEST_COMMAND_PATH in command for command in run_commands ):
462+ violations .append (
463+ "planning docs test command must not use the retired path "
464+ f"{ STALE_PLANNING_DOCS_TEST_COMMAND_PATH } "
465+ )
466+ if CANONICAL_PLANNING_DOCS_TEST_COMMAND not in run_commands :
467+ violations .append (
468+ "planning docs test command must be exactly "
469+ f"{ CANONICAL_PLANNING_DOCS_TEST_COMMAND } "
470+ )
471+ return violations
472+
473+
447474def validate_workflow_trigger_paths (workflow_text : str ) -> list [str ]:
448475 """Validate the planning workflow's protected-path contract without YAML dependencies."""
449476 try :
0 commit comments