@@ -423,6 +423,42 @@ def _validate_run_id(cls, run_id: str) -> None:
423423 "alphanumeric character)."
424424 )
425425
426+ @staticmethod
427+ def _validate_installed_origin (
428+ installed_workflow_id : str | None ,
429+ installed_registry_root : str | None ,
430+ ) -> None :
431+ """Validate persisted installed-workflow ownership metadata."""
432+ if installed_workflow_id is not None :
433+ if not isinstance (installed_workflow_id , str ):
434+ raise ValueError (
435+ "Invalid run state: 'installed_workflow_id' must be a "
436+ f"string or null, got { type (installed_workflow_id ).__name__ } "
437+ )
438+ if not _ID_PATTERN .fullmatch (installed_workflow_id ):
439+ raise ValueError (
440+ "Invalid run state: 'installed_workflow_id' must be a "
441+ "lowercase alphanumeric workflow ID with hyphens"
442+ )
443+ if installed_registry_root is not None :
444+ if not isinstance (installed_registry_root , str ):
445+ raise ValueError (
446+ "Invalid run state: 'installed_registry_root' must be a "
447+ f"string or null, got { type (installed_registry_root ).__name__ } "
448+ )
449+ if not installed_registry_root or not Path (
450+ installed_registry_root
451+ ).is_absolute ():
452+ raise ValueError (
453+ "Invalid run state: 'installed_registry_root' must be "
454+ "an absolute path or null"
455+ )
456+ if installed_workflow_id is None :
457+ raise ValueError (
458+ "Invalid run state: 'installed_registry_root' requires "
459+ "'installed_workflow_id'"
460+ )
461+
426462 def __init__ (
427463 self ,
428464 run_id : str | None = None ,
@@ -442,6 +478,9 @@ def __init__(
442478 else :
443479 self .run_id = run_id
444480 self ._validate_run_id (self .run_id )
481+ self ._validate_installed_origin (
482+ installed_workflow_id , installed_registry_root
483+ )
445484 self .workflow_id = workflow_id
446485 self .project_root = project_root or Path ("." )
447486 # Identifies the installed workflow (if any) this run was started
@@ -601,36 +640,7 @@ def load(cls, run_id: str, project_root: Path) -> RunState:
601640 )
602641
603642 installed_workflow_id = state_data .get ("installed_workflow_id" )
604- if installed_workflow_id is not None :
605- if not isinstance (installed_workflow_id , str ):
606- raise ValueError (
607- "Invalid run state: 'installed_workflow_id' must be a "
608- f"string or null, got { type (installed_workflow_id ).__name__ } "
609- )
610- if not _ID_PATTERN .fullmatch (installed_workflow_id ):
611- raise ValueError (
612- "Invalid run state: 'installed_workflow_id' must be a "
613- "lowercase alphanumeric workflow ID with hyphens"
614- )
615643 installed_registry_root = state_data .get ("installed_registry_root" )
616- if installed_registry_root is not None :
617- if not isinstance (installed_registry_root , str ):
618- raise ValueError (
619- "Invalid run state: 'installed_registry_root' must be a "
620- f"string or null, got { type (installed_registry_root ).__name__ } "
621- )
622- if not installed_registry_root or not Path (
623- installed_registry_root
624- ).is_absolute ():
625- raise ValueError (
626- "Invalid run state: 'installed_registry_root' must be "
627- "an absolute path or null"
628- )
629- if installed_workflow_id is None :
630- raise ValueError (
631- "Invalid run state: 'installed_registry_root' requires "
632- "'installed_workflow_id'"
633- )
634644
635645 state = cls (
636646 run_id = state_data ["run_id" ],
0 commit comments