639 lines
21 KiB
Python
639 lines
21 KiB
Python
from __future__ import annotations
|
|
|
|
ACTIONS = [
|
|
'container.status',
|
|
'container.logs',
|
|
'container.clear_logs',
|
|
'container.restart',
|
|
'container.stop',
|
|
'runner.fleet.upgrade_v2',
|
|
'runner.fleet.specialize',
|
|
'runner.statistics.configure',
|
|
'controller.artifact.promote',
|
|
'controller.managed-storage.initialize',
|
|
'hub.migration.prepare_permissions',
|
|
'gateway.clear_cache',
|
|
'stack.status',
|
|
'stack.redeploy',
|
|
'deployment.preflight',
|
|
'deployment.targets.sync',
|
|
'deployment.runnerless.provision',
|
|
'deployment.target.deploy_workmesh',
|
|
'deployment.target.promote_workmesh',
|
|
'deployment.target.register_portfolio',
|
|
'deployment.target.register_privatemuse',
|
|
'deployment.target.reconcile_media_codec_dashboard',
|
|
'deployment.webhook.repair_privatemuse',
|
|
'privatemuse.comfyui.install_artifact',
|
|
'deployment.apply',
|
|
'deployment.rollback',
|
|
'volume.delete',
|
|
'unraid.health_summary',
|
|
'unraid.vms',
|
|
'unraid.vm.start',
|
|
'unraid.vm.resume',
|
|
'unraid.vm.pause',
|
|
'unraid.vm.stop',
|
|
'unraid.vm.reboot',
|
|
'unraid.vm.force_stop',
|
|
'unraid.vm.reset',
|
|
'unraid.mover.start',
|
|
'setup.status',
|
|
'safety.summary',
|
|
'media_pipeline.check',
|
|
'media_pipeline.diagnose',
|
|
'notifications.summary',
|
|
'notifications.evaluate_safety',
|
|
'sonarr.search_series',
|
|
'sonarr.add_series',
|
|
'sonarr.health',
|
|
'sonarr.queue_status',
|
|
'sonarr.wanted_missing',
|
|
'sonarr.delete_series',
|
|
'sonarr.mass_edit',
|
|
'radarr.search_movie',
|
|
'radarr.add_movie',
|
|
'radarr.health',
|
|
'radarr.queue_status',
|
|
'radarr.wanted_missing',
|
|
'radarr.delete_movie',
|
|
'radarr.delete_files',
|
|
'radarr.mass_edit',
|
|
'jellyfin.scan_library',
|
|
'widefrog.health',
|
|
'widefrog.queue_status',
|
|
'widefrog.failed_jobs',
|
|
'widefrog.activity',
|
|
'widefrog.retry_failed',
|
|
'widefrog.scan_library',
|
|
'widefrog.download_status',
|
|
'prowlarr.health',
|
|
'prowlarr.indexer_status',
|
|
'prowlarr.application_status',
|
|
'prowlarr.indexer_health',
|
|
'prowlarr.search_test',
|
|
'prowlarr.sync_status',
|
|
'prowlarr.delete_indexer',
|
|
'prowlarr.delete_application',
|
|
'prowlarr.update_indexer',
|
|
'prowlarr.update_application',
|
|
'prowlarr.grab_release',
|
|
'prowlarr.push_release',
|
|
'prowlarr.mass_edit',
|
|
'prowlarr.test_all_indexers',
|
|
'deluge.health',
|
|
'deluge.session_status',
|
|
'deluge.torrent_status',
|
|
'deluge.active_downloads',
|
|
'deluge.stalled_downloads',
|
|
'deluge.paused_downloads',
|
|
'deluge.speed_status',
|
|
'deluge.pause_torrent',
|
|
'deluge.resume_torrent',
|
|
'deluge.pause_all',
|
|
'deluge.resume_all',
|
|
'deluge.remove_torrent',
|
|
'deluge.remove_torrent_data',
|
|
'deluge.delete_data',
|
|
'deluge.force_recheck',
|
|
'deluge.move_storage',
|
|
'deluge.add_torrent',
|
|
'deluge.add_magnet',
|
|
'deluge.mass_edit',
|
|
'deluge.set_options',
|
|
'deluge.unknown_mutation',
|
|
'plex.health',
|
|
'plex.server_status',
|
|
'plex.library_status',
|
|
'plex.active_sessions',
|
|
'plex.recent_media',
|
|
'plex.scan_library',
|
|
'plex.scan_all_libraries',
|
|
'plex.stream_summary',
|
|
'tautulli.health',
|
|
'tautulli.status',
|
|
'tautulli.activity',
|
|
'tautulli.history',
|
|
'tautulli.users',
|
|
'tautulli.libraries',
|
|
'tautulli.recently_added',
|
|
'tautulli.watch_stats',
|
|
'tautulli.stream_summary',
|
|
'tautulli.plex_info',
|
|
'npm.health',
|
|
'npm.proxy_hosts',
|
|
'npm.certificates',
|
|
'npm.expiring_certificates',
|
|
'npm.access_lists',
|
|
'npm.exposure_summary',
|
|
'npm.host_reachability',
|
|
'npm.security_warnings',
|
|
'npm.create_proxy_host',
|
|
'npm.update_proxy_host',
|
|
'npm.delete_proxy_host',
|
|
'npm.enable_proxy_host',
|
|
'npm.disable_proxy_host',
|
|
'npm.renew_certificate',
|
|
'npm.delete_certificate',
|
|
'npm.modify_access_list',
|
|
'npm.create_user',
|
|
'npm.update_user',
|
|
'npm.delete_user',
|
|
'npm.mass_edit',
|
|
'npm.unknown_mutation',
|
|
'authentik.health',
|
|
'authentik.system_status',
|
|
'authentik.applications',
|
|
'authentik.providers',
|
|
'authentik.proxy_providers',
|
|
'authentik.oauth2_providers',
|
|
'authentik.outposts',
|
|
'authentik.outpost_health',
|
|
'authentik.flows_summary',
|
|
'authentik.policies_summary',
|
|
'authentik.events',
|
|
'authentik.auth_coverage',
|
|
'authentik.security_warnings',
|
|
'authentik.create_application',
|
|
'authentik.update_application',
|
|
'authentik.delete_application',
|
|
'authentik.create_provider',
|
|
'authentik.update_provider',
|
|
'authentik.delete_provider',
|
|
'authentik.create_outpost',
|
|
'authentik.update_outpost',
|
|
'authentik.delete_outpost',
|
|
'authentik.create_policy',
|
|
'authentik.update_policy',
|
|
'authentik.delete_policy',
|
|
'authentik.create_user',
|
|
'authentik.update_user',
|
|
'authentik.delete_user',
|
|
'authentik.create_group',
|
|
'authentik.update_group',
|
|
'authentik.delete_group',
|
|
'authentik.rotate_token',
|
|
'authentik.force_sync',
|
|
'authentik.mass_edit',
|
|
'authentik.unknown_mutation',
|
|
'forge.oidc.provision',
|
|
'forge.secrets.prepare',
|
|
'tautulli.terminate_session',
|
|
'tautulli.delete_newsletter',
|
|
'tautulli.delete_notification_log',
|
|
'tautulli.delete_notifier',
|
|
'tautulli.delete_recently_added',
|
|
'tautulli.download_config',
|
|
'tautulli.download_database',
|
|
'tautulli.download_export',
|
|
'tautulli.download_log',
|
|
'tautulli.download_plex_log',
|
|
'tautulli.notify',
|
|
'tautulli.user_management',
|
|
'tautulli.mass_edit',
|
|
'tautulli.unknown_mutation',
|
|
'plex.delete_media',
|
|
'plex.delete_library',
|
|
'plex.empty_trash',
|
|
'plex.clean_bundles',
|
|
'plex.optimize_database',
|
|
'plex.kill_session',
|
|
'plex.user_management',
|
|
'plex.force_refresh_all_metadata',
|
|
'plex.mass_edit',
|
|
'plex.unknown_mutation',
|
|
'widefrog.delete_job',
|
|
'widefrog.delete_media',
|
|
'widefrog.clear_library',
|
|
'widefrog.clear_queue',
|
|
'widefrog.reset_database',
|
|
'widefrog.delete_downloads',
|
|
'widefrog.prune',
|
|
'playbook.run',
|
|
]
|
|
|
|
ACTION_RISK = {
|
|
'container.status': 'low',
|
|
'container.logs': 'low',
|
|
'container.clear_logs': 'high',
|
|
'container.restart': 'medium',
|
|
'container.stop': 'high',
|
|
'runner.fleet.upgrade_v2': 'high',
|
|
'runner.fleet.specialize': 'high',
|
|
'runner.statistics.configure': 'high',
|
|
'controller.artifact.promote': 'high',
|
|
'controller.managed-storage.initialize': 'high',
|
|
'hub.migration.prepare_permissions': 'high',
|
|
'gateway.clear_cache': 'high',
|
|
'stack.status': 'low',
|
|
'stack.redeploy': 'high',
|
|
'deployment.preflight': 'low',
|
|
'deployment.targets.sync': 'high',
|
|
'deployment.runnerless.provision': 'high',
|
|
'deployment.target.deploy_workmesh': 'high',
|
|
'deployment.target.promote_workmesh': 'high',
|
|
'deployment.target.register_portfolio': 'high',
|
|
'deployment.target.register_privatemuse': 'high',
|
|
'deployment.target.reconcile_media_codec_dashboard': 'high',
|
|
'deployment.webhook.repair_privatemuse': 'high',
|
|
'privatemuse.comfyui.install_artifact': 'high',
|
|
'deployment.apply': 'high',
|
|
'deployment.rollback': 'high',
|
|
'volume.delete': 'critical',
|
|
'unraid.health_summary': 'low',
|
|
'unraid.vms': 'low',
|
|
'unraid.vm.start': 'medium',
|
|
'unraid.vm.resume': 'medium',
|
|
'unraid.vm.pause': 'high',
|
|
'unraid.vm.stop': 'critical',
|
|
'unraid.vm.reboot': 'critical',
|
|
'unraid.vm.force_stop': 'critical',
|
|
'unraid.vm.reset': 'critical',
|
|
'unraid.mover.start': 'high',
|
|
'setup.status': 'low',
|
|
'safety.summary': 'low',
|
|
'media_pipeline.check': 'low',
|
|
'media_pipeline.diagnose': 'low',
|
|
'notifications.summary': 'low',
|
|
'notifications.evaluate_safety': 'medium',
|
|
'sonarr.search_series': 'low',
|
|
'sonarr.add_series': 'low',
|
|
'sonarr.health': 'low',
|
|
'sonarr.queue_status': 'low',
|
|
'sonarr.wanted_missing': 'low',
|
|
'sonarr.delete_series': 'critical',
|
|
'sonarr.mass_edit': 'critical',
|
|
'radarr.search_movie': 'low',
|
|
'radarr.add_movie': 'low',
|
|
'radarr.health': 'low',
|
|
'radarr.queue_status': 'low',
|
|
'radarr.wanted_missing': 'low',
|
|
'radarr.delete_movie': 'critical',
|
|
'radarr.delete_files': 'critical',
|
|
'radarr.mass_edit': 'critical',
|
|
'jellyfin.scan_library': 'medium',
|
|
'widefrog.health': 'low',
|
|
'widefrog.queue_status': 'low',
|
|
'widefrog.failed_jobs': 'low',
|
|
'widefrog.activity': 'low',
|
|
'widefrog.retry_failed': 'medium',
|
|
'widefrog.scan_library': 'medium',
|
|
'widefrog.download_status': 'low',
|
|
'prowlarr.health': 'low',
|
|
'prowlarr.indexer_status': 'low',
|
|
'prowlarr.application_status': 'low',
|
|
'prowlarr.indexer_health': 'low',
|
|
'prowlarr.search_test': 'medium',
|
|
'prowlarr.sync_status': 'low',
|
|
'prowlarr.delete_indexer': 'critical',
|
|
'prowlarr.delete_application': 'critical',
|
|
'prowlarr.update_indexer': 'high',
|
|
'prowlarr.update_application': 'high',
|
|
'prowlarr.grab_release': 'critical',
|
|
'prowlarr.push_release': 'critical',
|
|
'prowlarr.mass_edit': 'critical',
|
|
'prowlarr.test_all_indexers': 'medium',
|
|
'deluge.health': 'low',
|
|
'deluge.session_status': 'low',
|
|
'deluge.torrent_status': 'low',
|
|
'deluge.active_downloads': 'low',
|
|
'deluge.stalled_downloads': 'low',
|
|
'deluge.paused_downloads': 'low',
|
|
'deluge.speed_status': 'low',
|
|
'deluge.pause_torrent': 'medium',
|
|
'deluge.resume_torrent': 'medium',
|
|
'deluge.pause_all': 'high',
|
|
'deluge.resume_all': 'high',
|
|
'deluge.remove_torrent': 'critical',
|
|
'deluge.remove_torrent_data': 'critical',
|
|
'deluge.delete_data': 'critical',
|
|
'deluge.force_recheck': 'high',
|
|
'deluge.move_storage': 'high',
|
|
'deluge.add_torrent': 'high',
|
|
'deluge.add_magnet': 'high',
|
|
'deluge.mass_edit': 'critical',
|
|
'deluge.set_options': 'critical',
|
|
'deluge.unknown_mutation': 'critical',
|
|
'plex.health': 'low',
|
|
'plex.server_status': 'low',
|
|
'plex.library_status': 'low',
|
|
'plex.active_sessions': 'low',
|
|
'plex.recent_media': 'low',
|
|
'plex.scan_library': 'medium',
|
|
'plex.scan_all_libraries': 'high',
|
|
'plex.stream_summary': 'low',
|
|
'tautulli.health': 'low',
|
|
'tautulli.status': 'low',
|
|
'tautulli.activity': 'low',
|
|
'tautulli.history': 'medium',
|
|
'tautulli.users': 'medium',
|
|
'tautulli.libraries': 'low',
|
|
'tautulli.recently_added': 'low',
|
|
'tautulli.watch_stats': 'medium',
|
|
'tautulli.stream_summary': 'low',
|
|
'tautulli.plex_info': 'low',
|
|
'npm.health': 'low',
|
|
'npm.proxy_hosts': 'medium',
|
|
'npm.certificates': 'low',
|
|
'npm.expiring_certificates': 'low',
|
|
'npm.access_lists': 'medium',
|
|
'npm.exposure_summary': 'medium',
|
|
'npm.host_reachability': 'low',
|
|
'npm.security_warnings': 'low',
|
|
'npm.create_proxy_host': 'critical',
|
|
'npm.update_proxy_host': 'critical',
|
|
'npm.delete_proxy_host': 'critical',
|
|
'npm.enable_proxy_host': 'high',
|
|
'npm.disable_proxy_host': 'high',
|
|
'npm.renew_certificate': 'high',
|
|
'npm.delete_certificate': 'critical',
|
|
'npm.modify_access_list': 'critical',
|
|
'npm.create_user': 'critical',
|
|
'npm.update_user': 'critical',
|
|
'npm.delete_user': 'critical',
|
|
'npm.mass_edit': 'critical',
|
|
'npm.unknown_mutation': 'critical',
|
|
'authentik.health': 'low',
|
|
'authentik.system_status': 'low',
|
|
'authentik.applications': 'medium',
|
|
'authentik.providers': 'medium',
|
|
'authentik.proxy_providers': 'medium',
|
|
'authentik.oauth2_providers': 'medium',
|
|
'authentik.outposts': 'medium',
|
|
'authentik.outpost_health': 'low',
|
|
'authentik.flows_summary': 'medium',
|
|
'authentik.policies_summary': 'medium',
|
|
'authentik.events': 'medium',
|
|
'authentik.auth_coverage': 'medium',
|
|
'authentik.security_warnings': 'low',
|
|
'authentik.create_application': 'critical',
|
|
'authentik.update_application': 'critical',
|
|
'authentik.delete_application': 'critical',
|
|
'authentik.create_provider': 'critical',
|
|
'authentik.update_provider': 'critical',
|
|
'authentik.delete_provider': 'critical',
|
|
'authentik.create_outpost': 'critical',
|
|
'authentik.update_outpost': 'critical',
|
|
'authentik.delete_outpost': 'critical',
|
|
'authentik.create_policy': 'critical',
|
|
'authentik.update_policy': 'critical',
|
|
'authentik.delete_policy': 'critical',
|
|
'authentik.create_user': 'critical',
|
|
'authentik.update_user': 'critical',
|
|
'authentik.delete_user': 'critical',
|
|
'authentik.create_group': 'critical',
|
|
'authentik.update_group': 'critical',
|
|
'authentik.delete_group': 'critical',
|
|
'authentik.rotate_token': 'critical',
|
|
'authentik.force_sync': 'high',
|
|
'authentik.mass_edit': 'critical',
|
|
'authentik.unknown_mutation': 'critical',
|
|
'forge.oidc.provision': 'critical',
|
|
'forge.secrets.prepare': 'critical',
|
|
'tautulli.terminate_session': 'high',
|
|
'tautulli.delete_newsletter': 'critical',
|
|
'tautulli.delete_notification_log': 'critical',
|
|
'tautulli.delete_notifier': 'critical',
|
|
'tautulli.delete_recently_added': 'critical',
|
|
'tautulli.download_config': 'critical',
|
|
'tautulli.download_database': 'critical',
|
|
'tautulli.download_export': 'critical',
|
|
'tautulli.download_log': 'critical',
|
|
'tautulli.download_plex_log': 'critical',
|
|
'tautulli.notify': 'high',
|
|
'tautulli.user_management': 'critical',
|
|
'tautulli.mass_edit': 'critical',
|
|
'tautulli.unknown_mutation': 'critical',
|
|
'plex.delete_media': 'critical',
|
|
'plex.delete_library': 'critical',
|
|
'plex.empty_trash': 'critical',
|
|
'plex.clean_bundles': 'critical',
|
|
'plex.optimize_database': 'critical',
|
|
'plex.kill_session': 'high',
|
|
'plex.user_management': 'critical',
|
|
'plex.force_refresh_all_metadata': 'critical',
|
|
'plex.mass_edit': 'critical',
|
|
'plex.unknown_mutation': 'critical',
|
|
'widefrog.delete_job': 'critical',
|
|
'widefrog.delete_media': 'critical',
|
|
'widefrog.clear_library': 'critical',
|
|
'widefrog.clear_queue': 'critical',
|
|
'widefrog.reset_database': 'critical',
|
|
'widefrog.delete_downloads': 'critical',
|
|
'widefrog.prune': 'critical',
|
|
'playbook.run': 'medium',
|
|
}
|
|
|
|
READ_ONLY_VERBS = {
|
|
'activity',
|
|
'active_downloads',
|
|
'active_sessions',
|
|
'application_status',
|
|
'applications',
|
|
'auth_coverage',
|
|
'certificates',
|
|
'check',
|
|
'download_status',
|
|
'diagnose',
|
|
'events',
|
|
'expiring_certificates',
|
|
'exposure_summary',
|
|
'failed_jobs',
|
|
'flows_summary',
|
|
'health',
|
|
'health_summary',
|
|
'history',
|
|
'host_reachability',
|
|
'indexer_health',
|
|
'indexer_status',
|
|
'libraries',
|
|
'library_status',
|
|
'logs',
|
|
'oauth2_providers',
|
|
'outpost_health',
|
|
'outposts',
|
|
'paused_downloads',
|
|
'plex_info',
|
|
'preflight',
|
|
'policies_summary',
|
|
'providers',
|
|
'proxy_hosts',
|
|
'proxy_providers',
|
|
'queue_status',
|
|
'recent_media',
|
|
'recently_added',
|
|
'search_movie',
|
|
'search_series',
|
|
'security_warnings',
|
|
'server_status',
|
|
'session_status',
|
|
'speed_status',
|
|
'stalled_downloads',
|
|
'status',
|
|
'stream_summary',
|
|
'summary',
|
|
'sync_status',
|
|
'system_status',
|
|
'torrent_status',
|
|
'users',
|
|
'wanted_missing',
|
|
'watch_stats',
|
|
'vms',
|
|
}
|
|
|
|
DESTRUCTIVE_VERBS = {
|
|
'clear_cache',
|
|
'clear_library',
|
|
'clear_logs',
|
|
'clear_queue',
|
|
'clean_bundles',
|
|
'delete_application',
|
|
'delete_certificate',
|
|
'delete_data',
|
|
'delete_downloads',
|
|
'delete_files',
|
|
'delete_group',
|
|
'delete_indexer',
|
|
'delete_job',
|
|
'delete_library',
|
|
'delete_media',
|
|
'delete_movie',
|
|
'delete_newsletter',
|
|
'delete_notification_log',
|
|
'delete_notifier',
|
|
'delete_outpost',
|
|
'delete_policy',
|
|
'delete_provider',
|
|
'delete_proxy_host',
|
|
'delete_recently_added',
|
|
'delete_series',
|
|
'delete_user',
|
|
'download_config',
|
|
'download_database',
|
|
'download_export',
|
|
'download_log',
|
|
'download_plex_log',
|
|
'empty_trash',
|
|
'force_refresh_all_metadata',
|
|
'grab_release',
|
|
'mass_edit',
|
|
'modify_access_list',
|
|
'prune',
|
|
'push_release',
|
|
'remove_torrent',
|
|
'remove_torrent_data',
|
|
'reset_database',
|
|
'rotate_token',
|
|
'set_options',
|
|
'stop',
|
|
'unknown_mutation',
|
|
}
|
|
|
|
|
|
def action_category(action: str) -> str:
|
|
return action.split('.', 1)[0] if '.' in action else 'general'
|
|
|
|
|
|
def action_default_target(action: str) -> str:
|
|
if action == 'forge.oidc.provision':
|
|
return 'itworx-forge'
|
|
if action == 'forge.secrets.prepare':
|
|
return 'itworx-forge'
|
|
if action == 'controller.artifact.promote':
|
|
return 'tower/deployment-controller'
|
|
if action == 'controller.managed-storage.initialize':
|
|
return 'tower/deployment-controller'
|
|
if action == 'hub.migration.prepare_permissions':
|
|
return 'tower/itworx-mcp-hub-permissions'
|
|
if action == 'runner.fleet.upgrade_v2':
|
|
return 'tower/runner-fleet-v2'
|
|
if action == 'runner.fleet.specialize':
|
|
return 'tower/runner-fleet-specialized'
|
|
if action == 'runner.statistics.configure':
|
|
return 'tower/projectbrain-runner-statistics'
|
|
if action == 'deployment.targets.sync':
|
|
return 'jens/*'
|
|
if action == 'deployment.target.deploy_workmesh':
|
|
return 'jens/workmesh'
|
|
if action == 'deployment.target.promote_workmesh':
|
|
return 'jens/workmesh'
|
|
if action == 'deployment.target.register_portfolio':
|
|
return 'jens/portfolio'
|
|
if action in {
|
|
'deployment.target.register_privatemuse',
|
|
'deployment.webhook.repair_privatemuse',
|
|
}:
|
|
return 'jens/privatemuse'
|
|
if action == 'deployment.target.reconcile_media_codec_dashboard':
|
|
return 'jens/media-codec-dashboard'
|
|
category = action_category(action)
|
|
if category == 'container':
|
|
return 'container'
|
|
if category == 'volume':
|
|
return 'volume'
|
|
if category == 'media_pipeline':
|
|
return 'media-pipeline'
|
|
return category
|
|
|
|
|
|
def action_label(action: str) -> str:
|
|
return action.replace('_', ' ').replace('.', ' / ').title()
|
|
|
|
|
|
def action_capability(action: str) -> str:
|
|
verb = action.split('.', 1)[1] if '.' in action else action
|
|
if action in {'unraid.vm.stop', 'unraid.vm.reboot', 'unraid.vm.force_stop', 'unraid.vm.reset'}:
|
|
return 'destructive'
|
|
if verb in DESTRUCTIVE_VERBS or ACTION_RISK.get(action) == 'critical':
|
|
return 'destructive'
|
|
if verb in READ_ONLY_VERBS:
|
|
return 'read_only'
|
|
return 'operator'
|
|
|
|
|
|
def action_blast_radius(action: str, capability: str) -> list[str]:
|
|
category = action_category(action)
|
|
if capability == 'read_only':
|
|
return [f'Read-only visibility for {category}; no state changes are performed.']
|
|
if category == 'volume':
|
|
return ['Storage volume data and dependent apps could be affected if execution were ever enabled.']
|
|
if category == 'container':
|
|
return ['Target container availability and dependent routes may be affected.']
|
|
if category == 'stack':
|
|
return ['Multiple containers in the stack may restart or change state.']
|
|
if category == 'gateway':
|
|
return ['AppOps runtime visibility, cached connector state or operator context may be affected if execution were ever enabled.']
|
|
if category in {'authentik', 'npm'}:
|
|
return ['Authentication, exposure, routing or access-control behavior may be affected.']
|
|
if category in {'sonarr', 'radarr', 'prowlarr', 'deluge', 'plex', 'tautulli', 'widefrog'}:
|
|
return ['Media pipeline state, queues or user-facing media availability may be affected.']
|
|
if category == 'unraid':
|
|
return ['Unraid host or array operations may be affected.']
|
|
return [f'{category} operational state may be affected.']
|
|
|
|
|
|
def action_safeguards(action: str, decision: str, capability: str) -> list[str]:
|
|
safeguards = ['Registry detail is read-only and cannot execute this action.']
|
|
if capability == 'destructive':
|
|
safeguards.append('Destructive or critical actions stay blocked unless an explicit future policy path is designed.')
|
|
if decision == 'blocked':
|
|
safeguards.append('AppOps Gateway V1 exposes this only as a blocked boundary; no executor is registered.')
|
|
safeguards.append('Current policy decision is blocked.')
|
|
elif decision == 'approval_required':
|
|
safeguards.append('Current policy decision requires operator approval before execution.')
|
|
else:
|
|
safeguards.append('Allowed policy preview does not bypass preflight, audit or runtime checks.')
|
|
if 'token' in action or 'secret' in action:
|
|
safeguards.append('Secret-like values are never returned by the registry.')
|
|
return safeguards
|
|
|
|
|
|
def action_operator_guidance(action: str, decision: str, capability: str) -> str:
|
|
if decision == 'blocked':
|
|
return 'AppOps Gateway V1 blocks this action; treat it as governance visibility only and use external/manual tooling until a separate safe execution design exists.'
|
|
if decision == 'approval_required':
|
|
return 'Use approved operational flows only after reviewing impact and maintenance context.'
|
|
if capability == 'read_only':
|
|
return 'Safe to inspect for operational awareness.'
|
|
return 'Use the existing preflight and audited action flow before any live operation.'
|