UPDATE gateway_runner_policies
SET failover_policy = failover_policy
    || jsonb_build_object(
      'allowCategories', jsonb_build_array('network', 'timeout', 'stream_error', 'rate_limit', 'provider_5xx', 'provider_overloaded', 'auth_error'),
      'denyCategories', jsonb_build_array('request_error', 'unsupported_model', 'user_permission', 'insufficient_balance'),
      'allowCodes', jsonb_build_array('auth_failed', 'invalid_api_key', 'missing_credentials'),
      'allowKeywords', jsonb_build_array('timeout', 'network', 'rate_limit', 'overloaded', 'temporarily_unavailable', 'server_error', 'auth_failed', 'invalid_api_key', 'missing_credentials', 'unauthorized', 'forbidden', '429', '5xx'),
      'denyKeywords', jsonb_build_array('invalid_parameter', 'missing required', 'bad request'),
      'allowStatusCodes', jsonb_build_array(401, 403, 408, 429, 500, 502, 503, 504),
      'denyStatusCodes', '[]'::jsonb,
      'actions', COALESCE(failover_policy->'actions', '{}'::jsonb) || jsonb_build_object('auth_error', 'disable_and_next')
    ),
    hard_stop_policy = hard_stop_policy
    || jsonb_build_object(
      'categories', jsonb_build_array('request_error', 'unsupported_model', 'user_permission', 'insufficient_balance'),
      'codes', jsonb_build_array('bad_request', 'invalid_request', 'invalid_parameter', 'missing_required', 'unsupported_kind', 'unsupported_model', 'insufficient_balance', 'permission_denied'),
      'statusCodes', '[]'::jsonb,
      'keywords', jsonb_build_array('invalid_parameter', 'missing required', 'bad request', 'insufficient balance')
    ),
    metadata = metadata || jsonb_build_object('platformAuthFailoverPolicy', '0028_runner_policy_platform_auth_failover'),
    updated_at = now()
WHERE policy_key = 'default-runner-v1';
