@@ -681,6 +681,35 @@ def test_plugin_smoke_runbooks_match_auditd_search_user_schema():
681681 assert search_substeps
682682 assert all (isinstance ((substep .get ("with" ) or {}).get ("user" ), str ) for substep in search_substeps )
683683
684+
685+ def test_plugin_smoke_runbooks_validate_against_builtin_schemas ():
686+ from automax .plugins .registry import build_builtin_registry
687+
688+ registry = build_builtin_registry ()
689+ failures = []
690+ for runbook_path in sorted (Path ("examples/runbooks/runbooks" ).glob ("*.check.yaml" )):
691+ data = yaml .safe_load (runbook_path .read_text (encoding = "utf-8" ))
692+ for task in data .get ("tasks" , []):
693+ for step in task .get ("steps" , []):
694+ for substep in step .get ("substeps" , []):
695+ plugin_name = substep .get ("use" )
696+ params = substep .get ("with" ) or {}
697+ try :
698+ registry .get (plugin_name ).validate (params )
699+ except Exception as exc : # pragma: no cover - assertion reports all offenders
700+ failures .append (f"{ runbook_path } :{ substep .get ('id' )} :{ plugin_name } : { exc } " )
701+
702+ assert failures == []
703+
704+
705+ def test_plugin_specific_user_and_boolean_value_schemas_do_not_use_global_fallbacks ():
706+ from automax .plugins .registry import build_builtin_registry
707+
708+ registry = build_builtin_registry ()
709+ registry .get ("cron.list" ).validate ({"user" : "deploy" , "sudo" : True })
710+ registry .get ("selinux.boolean" ).validate ({"name" : "httpd_can_network_connect" , "value" : True , "persist" : True })
711+
712+
684713def test_docs_show_sudo_password_env_for_runs_and_capability_installs ():
685714 docs = "\n " .join (
686715 path .read_text (encoding = "utf-8" )
0 commit comments