diff --git a/.rubocop.yml b/.rubocop.yml
index 4543ad5bbe..fc7442001a 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,3 +1,5 @@
+inherit_from: .rubocop_todo.yml
+
 require:
   - rubocop-rake
 
diff --git a/Gemfile b/Gemfile
index 9847ad465a..96494282f9 100644
--- a/Gemfile
+++ b/Gemfile
@@ -12,11 +12,16 @@ gemspec
 
 group(:bolt_server) do
   # Bolt server gems are managed here not in the gemspec
+  gem "bundler", ">= 2.5.15"
   gem "hocon", '>= 1.2.5'
   gem "json-schema", '>= 2.8.0'
+  gem "octokit", ">= 4.0", "< 9"
   gem "puma", '>= 3.12.0'
+  gem "puppetlabs_spec_helper", ">= 5.0", "< 8"
   gem "rack", '>= 2.0.5'
   gem "rails-auth", '>= 2.1.4'
+  gem "rake", ">= 12.0", "< 14"
+  gem "rspec", ">= 3.0", "< 4"
   gem "sinatra", '>= 2.0.4'
 end
 
@@ -27,7 +32,7 @@ group(:test) do
   gem "beaker-hostgenerator"
   gem "mocha", '~> 1.4.0'
   gem "rack-test", '~> 1.0'
-  gem "rubocop", '~> 1.9.0', require: false
+  gem "rubocop", '~> 1.72.0', require: false
   gem "rubocop-rake", require: false
 end
 
diff --git a/acceptance/Rakefile b/acceptance/Rakefile
index 0b8a952792..fe96de8167 100644
--- a/acceptance/Rakefile
+++ b/acceptance/Rakefile
@@ -18,7 +18,7 @@ rototiller_task :host_config do |task|
     task.add_env(name: 'BOLT_CONTROLLER', default: 'debian12-64')
     task.add_env(name: 'BOLT_NODES',
                  default: 'redhat9-64,fedora40-64,windows10ent-64')
-    ns = [ENV['BOLT_CONTROLLER'], ENV['BOLT_NODES']].join(',')
+    ns = [ENV.fetch('BOLT_CONTROLLER', nil), ENV.fetch('BOLT_NODES', nil)].join(',')
     n  = ns.split(',')
     n_new = []
     n.each_with_index do |node, i|
@@ -109,7 +109,7 @@ def abs_targets
   end
   raw_targets = YAML.safe_load(output)
   abs_platforms = Hash.new(0)
-  raw_targets['HOSTS'].each do |_, raw_target|
+  raw_targets['HOSTS'].each_value do |raw_target|
     abs_platforms[raw_target['template']] += 1
   end
   abs_platforms.map { |platform, num| "#{platform}=#{num}" }.join(' ')
diff --git a/acceptance/setup/package/pre-suite/020_install.rb b/acceptance/setup/package/pre-suite/020_install.rb
index ceab0fb0cd..0e81f2212f 100644
--- a/acceptance/setup/package/pre-suite/020_install.rb
+++ b/acceptance/setup/package/pre-suite/020_install.rb
@@ -21,7 +21,7 @@
     end
   else
     dev_builds_url = ENV['DEV_BUILDS_URL'] || 'http://builds.delivery.puppetlabs.net'
-    sha_yaml_url = "#{dev_builds_url}/puppet-bolt/#{ENV['SHA']}/artifacts/#{ENV['SHA']}.yaml"
+    sha_yaml_url = "#{dev_builds_url}/puppet-bolt/#{ENV.fetch('SHA', nil)}/artifacts/#{ENV.fetch('SHA', nil)}.yaml"
     install_from_build_data_url('puppet-bolt', sha_yaml_url, bolt)
   end
 end
diff --git a/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb b/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb
index db9c5b5de5..91dd9a930c 100644
--- a/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb
+++ b/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb
@@ -143,7 +143,7 @@ def run_task(targets, task, args = {}, options = {})
       if unsupported_puppet?(result['clientversion'])
         Bolt::Logger.deprecate(
           "unsupported_puppet",
-          "Detected unsupported Puppet agent version #{result['clientversion']} on target "\
+          "Detected unsupported Puppet agent version #{result['clientversion']} on target " \
           "#{result.target}. Bolt supports Puppet agent 6.0.0 and higher."
         )
       end
diff --git a/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb b/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb
index f345dd0e5c..9e04a2644e 100644
--- a/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb
+++ b/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb
@@ -86,7 +86,7 @@ def puppetdb_command_with_instance(command, version, payload, instance)
     # Error if the PDB client does not implement :send_command
     unless puppetdb_client.respond_to?(:send_command)
       raise Bolt::Error.new(
-        "PuppetDB client #{puppetdb_client.class} does not implement :send_command, "\
+        "PuppetDB client #{puppetdb_client.class} does not implement :send_command, " \
         "unable to invoke command.",
         'bolt/pdb-command'
       )
diff --git a/bolt-modules/boltlib/lib/puppet/functions/run_container.rb b/bolt-modules/boltlib/lib/puppet/functions/run_container.rb
index f61f537d30..7475767607 100644
--- a/bolt-modules/boltlib/lib/puppet/functions/run_container.rb
+++ b/bolt-modules/boltlib/lib/puppet/functions/run_container.rb
@@ -127,8 +127,8 @@ def validate_options(options)
       end
 
       if (bad_vs = volumes.reject { |k, v| k.is_a?(String) && v.is_a?(String) }).any?
-        msg = "Option 'volumes' only accepts strings for keys and values. "\
-          "Received: #{bad_vs.map(&:inspect).join(', ')}"
+        msg = "Option 'volumes' only accepts strings for keys and values. " \
+              "Received: #{bad_vs.map(&:inspect).join(', ')}"
         raise Bolt::ValidationError, msg
       end
     end
@@ -153,8 +153,8 @@ def validate_options(options)
       end
 
       if (bad_ps = ports.reject { |k, v| k.is_a?(Integer) && v.is_a?(Integer) }).any?
-        msg = "Option 'ports' only accepts integers for keys and values. "\
-          "Received: #{bad_ps.map(&:inspect).join(', ')}"
+        msg = "Option 'ports' only accepts integers for keys and values. " \
+              "Received: #{bad_ps.map(&:inspect).join(', ')}"
         raise Bolt::ValidationError, msg
       end
     end
diff --git a/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb b/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb
index 81daae970c..8882c5b0f2 100644
--- a/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb
+++ b/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb
@@ -134,8 +134,8 @@ def set_resources(target, resources)
 
       unless resource.target == target
         file, line = Puppet::Pops::PuppetStack.top_of_stack
-        raise Bolt::ValidationError, "Cannot set resource #{resource.reference} for target "\
-                                     "#{resource.target} on target #{target}. "\
+        raise Bolt::ValidationError, "Cannot set resource #{resource.reference} for target " \
+                                     "#{resource.target} on target #{target}. " \
                                      "#{Puppet::Util::Errors.error_location(file, line)}"
       end
 
diff --git a/bolt-modules/boltlib/lib/puppet/functions/wait.rb b/bolt-modules/boltlib/lib/puppet/functions/wait.rb
index a98ad96f76..407854e638 100644
--- a/bolt-modules/boltlib/lib/puppet/functions/wait.rb
+++ b/bolt-modules/boltlib/lib/puppet/functions/wait.rb
@@ -111,8 +111,8 @@ def inner_wait(futures: nil, timeout: nil, options: {})
     valid, unknown = options.partition { |k, _v| %w[_catch_errors].include?(k) }.map(&:to_h)
     if unknown.any?
       file, line = Puppet::Pops::PuppetStack.top_of_stack
-      msg = "The wait() function call in #{file}#L#{line} received unknown options "\
-        "#{unknown.keys}. Removing unknown options and continuing..."
+      msg = "The wait() function call in #{file}#L#{line} received unknown options " \
+            "#{unknown.keys}. Removing unknown options and continuing..."
       Bolt::Logger.warn("plan_function_options", msg)
     end
 
diff --git a/bolt-modules/boltlib/spec/functions/run_container_spec.rb b/bolt-modules/boltlib/spec/functions/run_container_spec.rb
index 477d18bee8..915f73aed2 100644
--- a/bolt-modules/boltlib/spec/functions/run_container_spec.rb
+++ b/bolt-modules/boltlib/spec/functions/run_container_spec.rb
@@ -69,9 +69,9 @@ def image
       end
 
       let(:msg) {
-        "docker: Error response from daemon: OCI runtime create failed: "\
-                  "container_linux.go:367: starting container process caused: exec: "\
-                  "\"foo\": executable file not found in $PATH: unknown.\n"
+        "docker: Error response from daemon: OCI runtime create failed: " \
+          "container_linux.go:367: starting container process caused: exec: " \
+          "\"foo\": executable file not found in $PATH: unknown.\n"
       }
       let(:value) do
         { "_error" =>
diff --git a/bolt-modules/system/lib/puppet/functions/system/env.rb b/bolt-modules/system/lib/puppet/functions/system/env.rb
index 0e0ba90bfd..f135ee68d8 100644
--- a/bolt-modules/system/lib/puppet/functions/system/env.rb
+++ b/bolt-modules/system/lib/puppet/functions/system/env.rb
@@ -15,6 +15,6 @@ def env(name)
     # Send analytics report
     Puppet.lookup(:bolt_executor) {}&.report_function_call(self.class.name)
 
-    ENV[name]
+    ENV.fetch(name, nil)
   end
 end
diff --git a/bolt-modules/system/spec/functions/system/env_spec.rb b/bolt-modules/system/spec/functions/system/env_spec.rb
index 2a8e988d34..aa83e7b14e 100644
--- a/bolt-modules/system/spec/functions/system/env_spec.rb
+++ b/bolt-modules/system/spec/functions/system/env_spec.rb
@@ -4,7 +4,7 @@
 
 describe 'system::env' do
   it {
-    is_expected.to run.with_params('USER').and_return(ENV['USER'])
+    is_expected.to run.with_params('USER').and_return(ENV.fetch('USER', nil))
   }
 
   it "doesn't error for unknown envars" do
diff --git a/bolt.gemspec b/bolt.gemspec
index e0827a037e..4a54355fd0 100644
--- a/bolt.gemspec
+++ b/bolt.gemspec
@@ -66,9 +66,5 @@ Gem::Specification.new do |spec|
   spec.add_dependency "winrm", "~> 2.0"
   spec.add_dependency "winrm-fs", "~> 1.3"
 
-  spec.add_development_dependency "bundler", ">= 1.14"
-  spec.add_development_dependency "octokit", ">= 4.0", "< 9"
-  spec.add_development_dependency "puppetlabs_spec_helper", ">= 5.0", "< 8"
-  spec.add_development_dependency "rake", ">= 12.0", "< 14"
-  spec.add_development_dependency "rspec", ">= 3.0", "< 4"
+  spec.metadata['rubygems_mfa_required'] = 'true'
 end
diff --git a/developer-docs/examples/bolt_spec_example/tasks/init.rb b/developer-docs/examples/bolt_spec_example/tasks/init.rb
index b6cf3b5d67..30d43b9fa5 100755
--- a/developer-docs/examples/bolt_spec_example/tasks/init.rb
+++ b/developer-docs/examples/bolt_spec_example/tasks/init.rb
@@ -1,4 +1,4 @@
 #!/usr/bin/env ruby
 # frozen_string_literal: true
 
-File.write(ENV['PT_file'], ENV['PT_content'])
+File.write(ENV.fetch('PT_file', nil), ENV.fetch('PT_content', nil))
diff --git a/lib/bolt/analytics.rb b/lib/bolt/analytics.rb
index 7d6d953272..b507eea35d 100644
--- a/lib/bolt/analytics.rb
+++ b/lib/bolt/analytics.rb
@@ -59,7 +59,7 @@ def self.config_path
 
       if File.exist?(path)
         if File.exist?(old_path)
-          message = "Detected analytics configuration files at '#{old_path}' and '#{path}'. Loading "\
+          message = "Detected analytics configuration files at '#{old_path}' and '#{path}'. Loading " \
                     "analytics configuration from '#{path}'."
           Bolt::Logger.warn_once('duplicate_analytics', message)
         end
diff --git a/lib/bolt/application.rb b/lib/bolt/application.rb
index 3c52a5e114..661927d82d 100644
--- a/lib/bolt/application.rb
+++ b/lib/bolt/application.rb
@@ -57,10 +57,10 @@ def apply(manifest, targets, code: '', noop: false)
       if defined?(ast.body) &&
          (ast.body.is_a?(Puppet::Pops::Model::HostClassDefinition) ||
          ast.body.is_a?(Puppet::Pops::Model::ResourceTypeDefinition))
-        message = "Manifest only contains definitions and will result in no changes on the targets. "\
-                  "Definitions must be declared for their resources to be applied. You can read more "\
-                  "about defining and declaring classes and types in the Puppet documentation at "\
-                  "https://puppet.com/docs/puppet/latest/lang_classes.html and "\
+        message = "Manifest only contains definitions and will result in no changes on the targets. " \
+                  "Definitions must be declared for their resources to be applied. You can read more " \
+                  "about defining and declaring classes and types in the Puppet documentation at " \
+                  "https://puppet.com/docs/puppet/latest/lang_classes.html and " \
                   "https://puppet.com/docs/puppet/latest/lang_defined_types.html"
         Bolt::Logger.warn("empty_manifest", message)
       end
@@ -281,7 +281,7 @@ def install_modules(outputter, force: false, resolve: true)
 
       if config.project.modules.empty? && resolve
         outputter.print_message(
-          "Project configuration file #{config.project.project_file} does not "\
+          "Project configuration file #{config.project.project_file} does not " \
           "specify any module dependencies. Nothing to do."
         )
         return true
@@ -439,8 +439,8 @@ def apply_policies(policies, targets, noop: false)
 
         # CODEREVIEW: Phrasing
         raise Bolt::Error.new(
-          "The following policies are not available to the project: '#{unavailable_policies.join("', '")}'. "\
-          "You must list policies in a project's 'policies' setting before Bolt can apply them to targets. "\
+          "The following policies are not available to the project: '#{unavailable_policies.join("', '")}'. " \
+          "You must list policies in a project's 'policies' setting before Bolt can apply them to targets. " \
           "For a list of policies available to the project, run '#{command}'.",
           'bolt/unavailable-policy-error'
         )
@@ -460,7 +460,7 @@ def apply_policies(policies, targets, noop: false)
       # CODEREVIEW: Phrasing
       if unloadable_policies.any?
         raise Bolt::Error.new(
-          "The following policies cannot be loaded: '#{unloadable_policies.join("', '")}'. "\
+          "The following policies cannot be loaded: '#{unloadable_policies.join("', '")}'. " \
           "Policies must be a Puppet class saved to a project's or module's manifests directory.",
           'bolt/unloadable-policy-error'
         )
@@ -509,7 +509,7 @@ def new_policy(name)
       # Error if name is not namespaced to project
       unless prefix == @config.project.name
         raise Bolt::ValidationError,
-              "Policy name '#{name}' must begin with project name '#{@config.project.name}'. Did "\
+              "Policy name '#{name}' must begin with project name '#{@config.project.name}'. Did " \
               "you mean '#{@config.project.name}::#{name}'?"
       end
 
@@ -578,9 +578,9 @@ def list_policies
         command = Bolt::Util.powershell? ? 'New-BoltPolicy -Name <NAME>' : 'bolt policy new <NAME>'
 
         raise Bolt::Error.new(
-          "Project configuration file #{@config.project.project_file} does not "\
-          "specify any policies. You can add policies to the project by including "\
-          "a 'policies' key or creating a new policy using the '#{command}' "\
+          "Project configuration file #{@config.project.project_file} does not " \
+          "specify any policies. You can add policies to the project by including " \
+          "a 'policies' key or creating a new policy using the '#{command}' " \
           "command.",
           'bolt/no-policies-error'
         )
@@ -719,7 +719,7 @@ def list_tasks(filter: nil)
       unless project.project_file?
         command = Bolt::Util.powershell? ? 'New-BoltProject' : 'bolt project init'
 
-        msg = "Could not find project configuration file #{project.project_file}, unable "\
+        msg = "Could not find project configuration file #{project.project_file}, unable " \
               "to install modules. To create a Bolt project, run '#{command}'."
 
         raise Bolt::Error.new(msg, 'bolt/missing-project-config-error')
diff --git a/lib/bolt/applicator.rb b/lib/bolt/applicator.rb
index 11cf7a9923..e382c31165 100644
--- a/lib/bolt/applicator.rb
+++ b/lib/bolt/applicator.rb
@@ -90,7 +90,7 @@ def compile(target, scope)
       catalog_request = scope.merge(target: target_data).merge(future: @executor.future || {})
 
       bolt_catalog_exe = File.join(libexec, 'bolt_catalog')
-      old_path = ENV['PATH']
+      old_path = ENV.fetch('PATH', nil)
       ENV['PATH'] = "#{RbConfig::CONFIG['bindir']}#{File::PATH_SEPARATOR}#{old_path}"
       out, err, stat = Open3.capture3('ruby', bolt_catalog_exe, 'compile', stdin_data: catalog_request.to_json)
       ENV['PATH'] = old_path
diff --git a/lib/bolt/apply_inventory.rb b/lib/bolt/apply_inventory.rb
index 104442b54b..6890d7be2d 100644
--- a/lib/bolt/apply_inventory.rb
+++ b/lib/bolt/apply_inventory.rb
@@ -44,7 +44,6 @@ def get_target(*_params)
       raise InvalidFunctionCall, 'get_target'
     end
 
-    # rubocop:disable Naming/AccessorMethodName
     def set_var(*_params)
       raise InvalidFunctionCall, 'set_var'
     end
@@ -52,7 +51,6 @@ def set_var(*_params)
     def set_feature(*_params)
       raise InvalidFunctionCall, 'set_feature'
     end
-    # rubocop:enable Naming/AccessorMethodName
 
     def vars(target)
       @targets[target.name].vars
diff --git a/lib/bolt/bolt_option_parser.rb b/lib/bolt/bolt_option_parser.rb
index e1024d8d10..134c472e37 100644
--- a/lib/bolt/bolt_option_parser.rb
+++ b/lib/bolt/bolt_option_parser.rb
@@ -1119,8 +1119,8 @@ def initialize(options)
         if File.exist?(path) || Pathname.new(path).absolute? ||
            !%w[scripts files].include?(path.split(File::SEPARATOR)[1])
           raise Bolt::CLIError, "The script must be a detailed Puppet file reference, " \
-            "for example 'mymodule/scripts/myscript.sh'. See http://pup.pt/bolt-scripts for " \
-            "more information on detailed Puppet file references."
+                                "for example 'mymodule/scripts/myscript.sh'. See http://pup.pt/bolt-scripts for " \
+                                "more information on detailed Puppet file references."
         end
 
         @options[:plan_script] = path
@@ -1129,8 +1129,8 @@ def initialize(options)
       separator "\n#{self.class.colorize(:cyan, 'Display options')}"
       define('--filter FILTER', 'Filter tasks and plans by a matching substring.') do |filter|
         unless /^[a-z0-9_:]+$/.match(filter)
-          msg = "Illegal characters in filter string '#{filter}'. Filters can "\
-          "only include lowercase letters, numbers, underscores, and colons."
+          msg = "Illegal characters in filter string '#{filter}'. Filters can " \
+                "only include lowercase letters, numbers, underscores, and colons."
           raise Bolt::CLIError, msg
         end
         @options[:filter] = filter
@@ -1214,7 +1214,7 @@ def parse_params(params)
     end
 
     def permute(args)
-      super(args)
+      super
     rescue OptionParser::MissingArgument => e
       raise Bolt::CLIError, "Option '#{e.args.first}' needs a parameter"
     rescue OptionParser::InvalidArgument => e
diff --git a/lib/bolt/catalog/logging.rb b/lib/bolt/catalog/logging.rb
index f9df6e7554..7f45dc2a15 100644
--- a/lib/bolt/catalog/logging.rb
+++ b/lib/bolt/catalog/logging.rb
@@ -9,7 +9,7 @@ def initialize
   # Emits message as a single line of JSON mapping level to message string.
   def handle(msg)
     str = msg.respond_to?(:multiline) ? msg.multiline : msg.to_s
-    str = msg.source == "Puppet" ? str : "#{msg.source}: #{str}"
+    str = "#{msg.source}: #{str}" unless msg.source == "Puppet"
     warn({ level: msg.level, message: str }.to_json)
   end
 end
diff --git a/lib/bolt/cli.rb b/lib/bolt/cli.rb
index 803cf32a21..65d03f5347 100644
--- a/lib/bolt/cli.rb
+++ b/lib/bolt/cli.rb
@@ -145,7 +145,7 @@ def parse
             options[:params_parsed] = true
           elsif params.any?
             options[:params_parsed] = false
-            options[:params] = Hash[params.map { |a| a.split('=', 2) }]
+            options[:params] = params.map { |a| a.split('=', 2) }.to_h
           else
             options[:params_parsed] = true
             options[:params] = {}
@@ -271,7 +271,7 @@ def parse
       end
 
       if options[:subcommand] == 'secret' &&
-         (options[:action] == 'decrypt' || options[:action] == 'encrypt') &&
+         %w[decrypt encrypt].include?(options[:action]) &&
          !options[:object]
         raise Bolt::CLIError, "Must specify a value to #{options[:action]}"
       end
@@ -294,8 +294,8 @@ def parse
         end
 
         if options[:action] == 'apply' && options[:leftovers].any?
-          raise Bolt::CLIError, "Unknown argument(s) #{options[:leftovers].join(', ')}. "\
-                                "To apply multiple policies, provide a comma-separated list of "\
+          raise Bolt::CLIError, "Unknown argument(s) #{options[:leftovers].join(', ')}. " \
+                                "To apply multiple policies, provide a comma-separated list of " \
                                 "policy names."
         end
 
@@ -310,7 +310,7 @@ def parse
 
       if options[:subcommand] == 'module' && options[:action] == 'install' && options[:object]
         command = Bolt::Util.powershell? ? 'Add-BoltModule -Module' : 'bolt module add'
-        raise Bolt::CLIError, "Invalid argument '#{options[:object]}'. To add a new module to "\
+        raise Bolt::CLIError, "Invalid argument '#{options[:object]}'. To add a new module to " \
                               "the project, run '#{command} #{options[:object]}'."
       end
 
@@ -475,9 +475,9 @@ def execute(options)
           config.check_path_case('modulepath', config.modulepath)
 
           if options[:clear_cache]
-            FileUtils.rm(config.project.plugin_cache_file) if File.exist?(config.project.plugin_cache_file)
-            FileUtils.rm(config.project.task_cache_file) if File.exist?(config.project.task_cache_file)
-            FileUtils.rm(config.project.plan_cache_file) if File.exist?(config.project.plan_cache_file)
+            FileUtils.rm_f(config.project.plugin_cache_file)
+            FileUtils.rm_f(config.project.task_cache_file)
+            FileUtils.rm_f(config.project.plan_cache_file)
           end
 
           case command
@@ -827,7 +827,7 @@ def execute(options)
     #
     private def parse_vars(vars)
       return unless vars
-      Hash[vars.map { |a| a.split('=', 2) }]
+      vars.map { |a| a.split('=', 2) }.to_h
     end
 
     # TODO: See if this can be moved to Bolt::Analytics.
@@ -880,7 +880,7 @@ def execute(options)
     #
     private def validate_ps_version
       if Bolt::Util.powershell?
-        command = "powershell.exe -NoProfile -NonInteractive -NoLogo -ExecutionPolicy "\
+        command = "powershell.exe -NoProfile -NonInteractive -NoLogo -ExecutionPolicy " \
                   "Bypass -Command $PSVersionTable.PSVersion.Major"
         stdout, _stderr, _status = Open3.capture3(command)
 
@@ -909,7 +909,7 @@ def execute(options)
         acc.concat(Bolt::BoltOptionParser::OPTIONS[key])
       end
 
-      inventory_cli_opts.concat(%w[no-host-key-check no-ssl no-ssl-verify no-tty])
+      inventory_cli_opts.push("no-host-key-check", "no-ssl", "no-ssl-verify", "no-tty")
 
       conflicting_options = Set.new(opts.keys.map(&:to_s)).intersection(inventory_cli_opts)
 
@@ -935,7 +935,7 @@ def execute(options)
     private def with_signal_handling
       handler = Signal.trap :INT do |signo|
         Bolt::Logger.logger(self).info(
-          "Exiting after receiving SIG#{Signal.signame(signo)} signal. "\
+          "Exiting after receiving SIG#{Signal.signame(signo)} signal. " \
           "There might be processes left executing on some targets."
         )
         exit!
diff --git a/lib/bolt/config.rb b/lib/bolt/config.rb
index 05d0964a75..2d56849b79 100644
--- a/lib/bolt/config.rb
+++ b/lib/bolt/config.rb
@@ -64,7 +64,7 @@ def self.defaults_schema
 
     def self.system_path
       if Bolt::Util.windows?
-        Pathname.new(File.join(ENV['ALLUSERSPROFILE'], 'PuppetLabs', 'bolt', 'etc'))
+        Pathname.new(File.join(ENV.fetch('ALLUSERSPROFILE', nil), 'PuppetLabs', 'bolt', 'etc'))
       else
         Pathname.new(File.join('/etc', 'puppetlabs', 'bolt'))
       end
@@ -101,7 +101,7 @@ def self.load_bolt_defaults_yaml(dir)
 
         Bolt::Logger.warn(
           "unsupported_project_config",
-          "Unsupported project configuration detected in '#{filepath}': #{project_config.keys}. "\
+          "Unsupported project configuration detected in '#{filepath}': #{project_config.keys}. " \
           "Project configuration should be set in 'bolt-project.yaml'."
         )
       end
@@ -114,8 +114,8 @@ def self.load_bolt_defaults_yaml(dir)
 
         Bolt::Logger.warn(
           "unsupported_inventory_config",
-          "Unsupported inventory configuration detected in '#{filepath}': #{transport_config.keys}. "\
-          "Transport configuration should be set under the 'inventory-config' option or "\
+          "Unsupported inventory configuration detected in '#{filepath}': #{transport_config.keys}. " \
+          "Transport configuration should be set under the 'inventory-config' option or " \
           "in 'inventory.yaml'."
         )
       end
@@ -126,13 +126,13 @@ def self.load_bolt_defaults_yaml(dir)
       if data.key?('inventory-config')
         unless data['inventory-config'].is_a?(Hash)
           raise Bolt::ValidationError,
-                "Option 'inventory-config' must be of type Hash, received #{data['inventory-config']} "\
+                "Option 'inventory-config' must be of type Hash, received #{data['inventory-config']} " \
                 "#{data['inventory-config']} (file: #{filepath})"
         end
 
         if data['inventory-config'].key?('_plugin')
           raise Bolt::ValidationError,
-                "Found unsupported key '_plugin' for option 'inventory-config'; supported keys are "\
+                "Found unsupported key '_plugin' for option 'inventory-config'; supported keys are " \
                 "'#{INVENTORY_OPTIONS.keys.join("', '")}' (file: #{filepath})"
         end
 
@@ -334,7 +334,7 @@ def deep_clone
     def validate
       if @data['modulepath']&.include?(@project.managed_moduledir.to_s)
         raise Bolt::ValidationError,
-              "Found invalid path in modulepath: #{@project.managed_moduledir}. This path "\
+              "Found invalid path in modulepath: #{@project.managed_moduledir}. This path " \
               "is automatically appended to the modulepath and cannot be configured."
       end
 
diff --git a/lib/bolt/config/options.rb b/lib/bolt/config/options.rb
index 6a6ec53d54..b27b710cac 100644
--- a/lib/bolt/config/options.rb
+++ b/lib/bolt/config/options.rb
@@ -93,9 +93,9 @@ module Options
           _plugin: true
         },
         "server_urls" => {
-          description: "An array containing the PuppetDB host to connect to. Include the protocol `https` "\
-                        "and the port, which is usually `8081`. For example, "\
-                        "`https://my-puppetdb-server.com:8081`.",
+          description: "An array containing the PuppetDB host to connect to. Include the protocol `https` " \
+                       "and the port, which is usually `8081`. For example, " \
+                       "`https://my-puppetdb-server.com:8081`.",
           type: Array,
           _example: ["https://puppet.example.com:8081"],
           _plugin: true
@@ -112,26 +112,26 @@ module Options
       # https://github.com/puppetlabs/bolt/blob/main/schemas/README.md
       OPTIONS = {
         "analytics" => {
-          description: "Whether to disable analytics. Setting this option to 'false' in the system-wide "\
-                       "or user-level configuration will disable analytics for all projects, even if this "\
+          description: "Whether to disable analytics. Setting this option to 'false' in the system-wide " \
+                       "or user-level configuration will disable analytics for all projects, even if this " \
                        "option is set to 'true' at the project level.",
           type: [TrueClass, FalseClass],
           _example: false
         },
         "apply-settings" => {
-          description: "A map of Puppet settings to use when applying Puppet code using the `apply` "\
+          description: "A map of Puppet settings to use when applying Puppet code using the `apply` " \
                        "plan function or the `bolt apply` command.",
           type: Hash,
           properties: {
             "evaltrace" => {
-              description: "Whether each resource should log when it is being evaluated. This allows "\
+              description: "Whether each resource should log when it is being evaluated. This allows " \
                            "you to interactively see exactly what is being done.",
               type: [TrueClass, FalseClass],
               _example: true,
               _default: false
             },
             "log_level" => {
-              description: "The log level for logs in apply reports from Puppet. These can be seen "\
+              description: "The log level for logs in apply reports from Puppet. These can be seen " \
                            "in ApplyResults.",
               type: String,
               enum: %w[debug info notice warning err alert emerg crit],
@@ -145,7 +145,7 @@ module Options
               _default: false
             },
             "trace" => {
-              description: "Whether to print stack traces on some errors. Will print internal Ruby "\
+              description: "Whether to print stack traces on some errors. Will print internal Ruby " \
                            "stack trace interleaved with Puppet function frames.",
               type: [TrueClass, FalseClass],
               _example: true,
@@ -178,8 +178,8 @@ module Options
           _default: "100 or 1/7 the ulimit, whichever is lower."
         },
         "disable-warnings" => {
-          description: "An array of IDs of warnings to suppress. Warnings with a matching ID will not be logged "\
-                       "by Bolt. If you are upgrading Bolt to a new major version, you should re-enable all warnings "\
+          description: "An array of IDs of warnings to suppress. Warnings with a matching ID will not be logged " \
+                       "by Bolt. If you are upgrading Bolt to a new major version, you should re-enable all warnings " \
                        "until you have finished upgrading.",
           type: Array,
           items: {
@@ -205,11 +205,11 @@ module Options
               type: [TrueClass, FalseClass],
               _example: true,
               _default: false,
-              _deprecation: "Bolt no longer honors this option and enables loading scripts from the scripts "\
+              _deprecation: "Bolt no longer honors this option and enables loading scripts from the scripts " \
                             "directory by default."
             },
             "script_interpreter" => {
-              description: "Use a target's [`interpreters` configuration](bolt_transports_reference.md#interpreters) "\
+              description: "Use a target's [`interpreters` configuration](bolt_transports_reference.md#interpreters) " \
                            "when running a script.",
               type: [TrueClass, FalseClass],
               _example: true,
@@ -227,8 +227,8 @@ module Options
           _default: "project/hiera.yaml"
         },
         "inventory-config" => {
-          description: "A map of default configuration options for the inventory. This includes options "\
-                       "for setting the default transport to use when connecting to targets, as well as "\
+          description: "A map of default configuration options for the inventory. This includes options " \
+                       "for setting the default transport to use when connecting to targets, as well as " \
                        "options for configuring the default behavior of each transport.",
           type: Hash,
           _plugin: false,
@@ -249,11 +249,11 @@ module Options
           _example: { "ttl" => 3600 }
         },
         "log" => {
-          description: "A map of configuration for the logfile output. Under `log`, you can configure log options "\
-                       "for `console` and add configuration for individual log files, such as "\
-                       "`~/.puppetlabs/bolt/debug.log`. Individual log files must be valid filepaths. If the log "\
-                       "file does not exist, then Bolt will create it before logging information. Set the value to "\
-                       "`disable` to remove a log file defined at an earlier level of the config hierarchy. By "\
+          description: "A map of configuration for the logfile output. Under `log`, you can configure log options " \
+                       "for `console` and add configuration for individual log files, such as " \
+                       "`~/.puppetlabs/bolt/debug.log`. Individual log files must be valid filepaths. If the log " \
+                       "file does not exist, then Bolt will create it before logging information. Set the value to " \
+                       "`disable` to remove a log file defined at an earlier level of the config hierarchy. By " \
                        "default, Bolt logs to a bolt-debug.log file in the Bolt project directory.",
           type: Hash,
           properties: {
@@ -294,7 +294,7 @@ module Options
                       "~/logs/debug.log" => { "append" => false, "level" => "debug" } }
         },
         "modulepath" => {
-          description: "An array of directories that Bolt loads content such as plans and tasks from. Read more "\
+          description: "An array of directories that Bolt loads content such as plans and tasks from. Read more " \
                        "about modules in [Module structure](module_structure.md).",
           type: [Array, String],
           items: {
@@ -305,8 +305,8 @@ module Options
           _default: ["project/modules"]
         },
         "module-install" => {
-          description: "Options that configure where Bolt downloads modules from. This option is only used when "\
-                       "installing modules using the `bolt module add|install` commands and "\
+          description: "Options that configure where Bolt downloads modules from. This option is only used when " \
+                       "installing modules using the `bolt module add|install` commands and " \
                        "`Add|Install-BoltModule` cmdlets.",
           type: Hash,
           properties: {
@@ -315,7 +315,7 @@ module Options
               type: Hash,
               properties: {
                 "authorization_token" => {
-                  description: "The token used to authorize requests to the Forge host. Must also specify "\
+                  description: "The token used to authorize requests to the Forge host. Must also specify " \
                                "`baseurl` when using this option.",
                   type: String,
                   _example: "Bearer eyJhbGciOiJIUzI1NiIsInR5c...",
@@ -350,9 +350,9 @@ module Options
           _plugin: false
         },
         "modules" => {
-          description: "A list of module dependencies for the project. Each dependency is a map of data specifying "\
-                       "the module to install. To install the project's module dependencies, run the `bolt module "\
-                       "install` command. For more information about specifying modules, see [the "\
+          description: "A list of module dependencies for the project. Each dependency is a map of data specifying " \
+                       "the module to install. To install the project's module dependencies, run the `bolt module " \
+                       "install` command. For more information about specifying modules, see [the " \
                        "documentation](https://pup.pt/bolt-module-specs).",
           type: Array,
           items: {
@@ -370,7 +370,7 @@ module Options
                     type: [TrueClass, FalseClass]
                   },
                   "version_requirement" => {
-                    description: "The version requirement for the module. Accepts a specific version (1.2.3), version "\
+                    description: "The version requirement for the module. Accepts specific version (1.2.3), version " \
                                  "shorthand (1.2.x), or a version range (>= 1.2.0).",
                     type: String
                   }
@@ -411,36 +411,36 @@ module Options
           ]
         },
         "name" => {
-          description: "The name of the Bolt project. When this option is configured, the project is considered a "\
-                       "[Bolt project](projects.md), allowing Bolt to load content from the project directory "\
+          description: "The name of the Bolt project. When this option is configured, the project is considered a " \
+                       "[Bolt project](projects.md), allowing Bolt to load content from the project directory " \
                        "as though it were a module.",
           type: String,
           _plugin: false,
           _example: "myproject"
         },
         "plans" => {
-          description: "A list of plan names and glob patterns to filter the project's plans by. This option is used "\
-                       "to limit the visibility of plans for users of the project. For example, project authors "\
-                       "might want to limit the visibility of plans that are bundled with Bolt or plans that should "\
-                       "only be run as part of another plan. When this option is not configured, all plans are "\
-                       "visible. This option does not prevent users from running plans that are not part of this "\
+          description: "A list of plan names and glob patterns to filter the project's plans by. This option is used " \
+                       "to limit the visibility of plans for users of the project. For example, project authors " \
+                       "might want to limit the visibility of plans that are bundled with Bolt or plans that should " \
+                       "only be run as part of another plan. When this option is not configured, all plans are " \
+                       "visible. This option does not prevent users from running plans that are not part of this " \
                        "list.",
           type: Array,
           _plugin: false,
           _example: ["myproject", "myproject::foo", "myproject::bar", "myproject::deploy::*"]
         },
         "plugin-hooks" => {
-          description: "A map of [plugin hooks](writing_plugins.md#hooks) and which plugins a hook should use. "\
-                       "The only configurable plugin hook is `puppet_library`, which can use two possible plugins: "\
-                       "[`puppet_agent`](https://github.com/puppetlabs/puppetlabs-puppet_agent#puppet_agentinstall) "\
+          description: "A map of [plugin hooks](writing_plugins.md#hooks) and which plugins a hook should use. " \
+                       "The only configurable plugin hook is `puppet_library`, which can use two possible plugins: " \
+                       "[`puppet_agent`](https://github.com/puppetlabs/puppetlabs-puppet_agent#puppet_agentinstall) " \
                        "and [`task`](using_plugins.md#task).",
           type: Hash,
           _plugin: true,
           _example: { "puppet_library" => { "plugin" => "puppet_agent", "version" => "6.15.0", "_run_as" => "root" } }
         },
         "plugins" => {
-          description: "A map of plugins and their configuration data, where each key is the name of a plugin and "\
-                       "its value is a map of configuration data. Configurable options are specified by the plugin. "\
+          description: "A map of plugins and their configuration data, where each key is the name of a plugin and " \
+                       "its value is a map of configuration data. Configurable options are specified by the plugin. " \
                        "Read more about configuring plugins in [Using plugins](using_plugins.md#configuring-plugins).",
           type: Hash,
           additionalProperties: {
@@ -451,24 +451,24 @@ module Options
           _example: { "pkcs7" => { "keysize" => 1024 } }
         },
         "policies" => {
-          description: "A list of policy names and glob patterns to filter the project's policies by. This option "\
-                       "is used to specify which policies are available to a project and can be applied to targets. "\
-                       "When this option is not configured, policies are not available to the project and cannot "\
+          description: "A list of policy names and glob patterns to filter the project's policies by. This option " \
+                       "is used to specify which policies are available to a project and can be applied to targets. " \
+                       "When this option is not configured, policies are not available to the project and cannot " \
                        "be applied to targets.",
           type: Array,
           _plugin: false,
           _example: ["myproject::apache", "myproject::postgres"]
         },
         "puppetdb" => {
-          description: "A map containing options for [configuring the Bolt PuppetDB "\
+          description: "A map containing options for [configuring the Bolt PuppetDB " \
                        "client](bolt_connect_puppetdb.md).",
           type: Hash,
           properties: PUPPETDB_OPTIONS,
           _plugin: true
         },
         "puppetdb-instances" => {
-          description: "A map of named PuppetDB instances and their configuration, where keys are the name "\
-                       "of a PuppetDB instance and values are maps of configuration options. For more "\
+          description: "A map of named PuppetDB instances and their configuration, where keys are the name " \
+                       "of a PuppetDB instance and values are maps of configuration options. For more " \
                        "information, see [Connecting Bolt to PuppetDB](bolt_connect_puppetdb.md).",
           type: Hash,
           additionalProperties: {
@@ -478,15 +478,15 @@ module Options
           _plugin: true
         },
         "rerunfile" => {
-          description: "The path to the project's rerun file. The rerun file is used to store information "\
+          description: "The path to the project's rerun file. The rerun file is used to store information " \
                        "about targets from the most recent run. Expands relative to the project directory.",
           type: String,
           _example: "/Users/bolt/project/rerun.json",
           _plugin: true
         },
         "save-rerun" => {
-          description: "Whether to update `.rerun.json` in the Bolt project directory. If "\
-                       "your target names include passwords, set this value to `false` to avoid "\
+          description: "Whether to update `.rerun.json` in the Bolt project directory. If " \
+                       "your target names include passwords, set this value to `false` to avoid " \
                        "writing passwords to disk.",
           type: [TrueClass, FalseClass],
           _plugin: false,
@@ -501,7 +501,7 @@ module Options
           _default: true
         },
         "stream" => {
-          description: "Whether to stream output from scripts and commands to the console. "\
+          description: "Whether to stream output from scripts and commands to the console. " \
                        "**This option is experimental**.",
           type: [TrueClass, FalseClass],
           _plugin: false,
@@ -509,11 +509,11 @@ module Options
           _example: true
         },
         "tasks" => {
-          description: "A list of task names and glob patterns to filter the project's tasks by. This option is used "\
-                       "to limit the visibility of tasks for users of the project. For example, project authors "\
-                       "might want to limit the visibility of tasks that are bundled with Bolt or plans that should "\
-                       "only be run as part of a larger workflow. When this option is not configured, all tasks "\
-                       "are visible. This option does not prevent users from running tasks that are not part of "\
+          description: "A list of task names and glob patterns to filter the project's tasks by. This option is used " \
+                       "to limit the visibility of tasks for users of the project. For example, project authors " \
+                       "might want to limit the visibility of tasks that are bundled with Bolt or plans that should " \
+                       "only be run as part of a larger workflow. When this option is not configured, all tasks " \
+                       "are visible. This option does not prevent users from running tasks that are not part of " \
                        "this list.",
           type: Array,
           items: {
@@ -523,8 +523,8 @@ module Options
           _example: ["myproject", "myproject::foo", "myproject::bar", "myproject::deploy_*"]
         },
         "trusted-external-command" => {
-          description: "The path to an executable on the Bolt controller that can produce external trusted facts. "\
-                       "**External trusted facts are experimental in both Puppet and Bolt and this API might "\
+          description: "The path to an executable on the Bolt controller that can produce external trusted facts. " \
+                       "**External trusted facts are experimental in both Puppet and Bolt and this API might " \
                        "change or be removed.**",
           type: String,
           _plugin: false,
@@ -538,7 +538,7 @@ module Options
       # 'config'.
       INVENTORY_OPTIONS = {
         "transport" => {
-          description: "The default transport to use when the transport for a target is not "\
+          description: "The default transport to use when the transport for a target is not " \
                        "specified in the URI.",
           type: String,
           enum: TRANSPORT_CONFIG.keys,
@@ -559,14 +559,14 @@ module Options
           _example: { cleanup: false }
         },
         "local" => {
-          description: "A map of configuration options for the local transport. The set of available options is "\
+          description: "A map of configuration options for the local transport. The set of available options is " \
                        "platform dependent.",
           type: Hash,
           _plugin: true,
           _example: { "cleanup" => false, "tmpdir" => "/tmp/bolt" }
         },
         "lxd" => {
-          description: "A map of configuration options for the LXD transport. The LXD transport is "\
+          description: "A map of configuration options for the LXD transport. The LXD transport is " \
                        "experimental and might include breaking changes between minor versions.",
           type: Hash,
           _plugin: true,
diff --git a/lib/bolt/config/transport/options.rb b/lib/bolt/config/transport/options.rb
index 7f7fca4e45..a9f8544dc0 100644
--- a/lib/bolt/config/transport/options.rb
+++ b/lib/bolt/config/transport/options.rb
@@ -18,11 +18,11 @@ module Options
           },
           "batch-mode" => {
             type: [TrueClass, FalseClass],
-            description: "Whether to disable password querying. When set to `false`, SSH will fall back to "\
-                         "prompting for a password if key authentication fails. This might cause Bolt to hang. "\
-                         "To prevent Bolt from hanging, you can configure `ssh-command` to use an SSH utility "\
-                         "such as sshpass that supports providing a password non-interactively. For more "\
-                         "information, see [Providing a password non-interactively using "\
+            description: "Whether to disable password querying. When set to `false`, SSH will fall back to " \
+                         "prompting for a password if key authentication fails. This might cause Bolt to hang. " \
+                         "To prevent Bolt from hanging, you can configure `ssh-command` to use an SSH utility " \
+                         "such as sshpass that supports providing a password non-interactively. For more " \
+                         "information, see [Providing a password non-interactively using " \
                          "`native-ssh`](troubleshooting.md#providing-a-password-non-interactively-using-native-ssh).",
             _plugin: true,
             _default: true,
@@ -43,9 +43,9 @@ module Options
           },
           "cleanup" => {
             type: [TrueClass, FalseClass],
-            description: "Whether to clean up temporary files created on targets. When running commands on a target, "\
-                         "Bolt might create temporary files. After completing the command, these files are "\
-                         "automatically deleted. This value can be set to 'false' if you wish to leave these "\
+            description: "Whether to clean up temporary files created on targets. When running commands on a target, " \
+                         "Bolt might create temporary files. After completing the command, these files are " \
+                         "automatically deleted. This value can be set to 'false' if you wish to leave these " \
                          "temporary files on the target.",
             _plugin: true,
             _default: true,
@@ -53,7 +53,7 @@ module Options
           },
           "connect-timeout" => {
             type: Integer,
-            description: "How long to wait in seconds when establishing connections. Set this value higher if you "\
+            description: "How long to wait in seconds when establishing connections. Set this value higher if you " \
                          "frequently encounter connection timeout errors when running Bolt.",
             minimum: 1,
             _plugin: true,
@@ -62,9 +62,9 @@ module Options
           },
           "copy-command" => {
             type: [Array, String],
-            description: "The command to use when copying files using native SSH. Bolt runs `<copy-command> <src> "\
-                         "<dest>`. This option is used when you need support for features or algorithms that are not "\
-                         "supported by the net-ssh Ruby library. **This option is experimental.** You can read more "\
+            description: "The command to use when copying files using native SSH. Bolt runs `<copy-command> <src> " \
+                         "<dest>`. This option is used when you need support for features or algorithms that are not " \
+                         "supported by the net-ssh Ruby library. **This option is experimental.** You can read more " \
                          "about this option in [Native SSH transport](experimental_features.md#native-ssh-transport).",
             items: {
               type: String
@@ -83,11 +83,11 @@ module Options
           },
           "encryption-algorithms" => {
             type: Array,
-            description: "A list of encryption algorithms to use when establishing a connection "\
-                         "to a target. Supported algorithms are defined by the Ruby net-ssh library and can be "\
-                         "viewed [here](https://github.com/net-ssh/net-ssh#supported-algorithms). All supported, "\
-                         "non-deprecated algorithms are available by default when this option is not used. To "\
-                         "reference all default algorithms using this option, add 'defaults' to the list of "\
+            description: "A list of encryption algorithms to use when establishing a connection " \
+                         "to a target. Supported algorithms are defined by the Ruby net-ssh library and can be " \
+                         "viewed [here](https://github.com/net-ssh/net-ssh#supported-algorithms). All supported, " \
+                         "non-deprecated algorithms are available by default when this option is not used. To " \
+                         "reference all default algorithms using this option, add 'defaults' to the list of " \
                          "supported algorithms.",
             uniqueItems: true,
             items: {
@@ -98,11 +98,11 @@ module Options
           },
           "extensions" => {
             type: Array,
-            description: "A list of file extensions that are accepted for scripts or tasks on "\
-                         "Windows. Scripts with these file extensions rely on the target's file "\
-                         "type association to run. For example, if Python is installed on the "\
-                         "system, a `.py` script runs with `python.exe`. The extensions `.ps1`, "\
-                         "`.rb`, and `.pp` are always allowed and run via hard-coded "\
+            description: "A list of file extensions that are accepted for scripts or tasks on " \
+                         "Windows. Scripts with these file extensions rely on the target's file " \
+                         "type association to run. For example, if Python is installed on the " \
+                         "system, a `.py` script runs with `python.exe`. The extensions `.ps1`, " \
+                         "`.rb`, and `.pp` are always allowed and run via hard-coded " \
                          "executables.",
             uniqueItems: true,
             items: {
@@ -113,7 +113,7 @@ module Options
           },
           "file-protocol" => {
             type: String,
-            description: "Which file transfer protocol to use. Either `winrm` or `smb`. Using `smb` is "\
+            description: "Which file transfer protocol to use. Either `winrm` or `smb`. Using `smb` is " \
                          "recommended for large file transfers.",
             enum: %w[smb winrm],
             _plugin: true,
@@ -128,11 +128,11 @@ module Options
           },
           "host-key-algorithms" => {
             type: Array,
-            description: "A list of host key algorithms to use when establishing a connection "\
-                         "to a target. Supported algorithms are defined by the Ruby net-ssh library and can be "\
-                         "viewed [here](https://github.com/net-ssh/net-ssh#supported-algorithms). All supported, "\
-                         "non-deprecated algorithms are available by default when this option is not used. To "\
-                         "reference all default algorithms using this option, add 'defaults' to the list of "\
+            description: "A list of host key algorithms to use when establishing a connection " \
+                         "to a target. Supported algorithms are defined by the Ruby net-ssh library and can be " \
+                         "viewed [here](https://github.com/net-ssh/net-ssh#supported-algorithms). All supported, " \
+                         "non-deprecated algorithms are available by default when this option is not used. To " \
+                         "reference all default algorithms using this option, add 'defaults' to the list of " \
                          "supported algorithms.",
             uniqueItems: true,
             items: {
@@ -149,10 +149,10 @@ module Options
           },
           "interpreters" => {
             type: Hash,
-            description: "A map of an extension name to the absolute path of an executable,  enabling you to "\
-                         "override the shebang defined in a task executable. The extension can optionally be "\
-                         "specified with the `.` character (`.py` and `py` both map to a task executable "\
-                         "`task.py`) and the extension is case sensitive. When a target's name is `localhost`, "\
+            description: "A map of an extension name to the absolute path of an executable,  enabling you to " \
+                         "override the shebang defined in a task executable. The extension can optionally be " \
+                         "specified with the `.` character (`.py` and `py` both map to a task executable " \
+                         "`task.py`) and the extension is case sensitive. When a target's name is `localhost`, " \
                          "Ruby tasks run with the Bolt Ruby interpreter by default.",
             additionalProperties: {
               type: [String, Array],
@@ -181,11 +181,11 @@ module Options
           },
           "kex-algorithms" => {
             type: Array,
-            description: "A list of key exchange algorithms to use when establishing a connection "\
-                         "to a target. Supported algorithms are defined by the Ruby net-ssh library and can be "\
-                         "viewed [here](https://github.com/net-ssh/net-ssh#supported-algorithms). All supported, "\
-                         "non-deprecated algorithms are available by default when this option is not used. To "\
-                         "reference all default algorithms using this option, add 'defaults' to the list of "\
+            description: "A list of key exchange algorithms to use when establishing a connection " \
+                         "to a target. Supported algorithms are defined by the Ruby net-ssh library and can be " \
+                         "viewed [here](https://github.com/net-ssh/net-ssh#supported-algorithms). All supported, " \
+                         "non-deprecated algorithms are available by default when this option is not used. To " \
+                         "reference all default algorithms using this option, add 'defaults' to the list of " \
                          "supported algorithms.",
             uniqueItems: true,
             items: {
@@ -212,11 +212,11 @@ module Options
           },
           "mac-algorithms" => {
             type: Array,
-            description: "List of message authentication code algorithms to use when establishing a connection "\
-                         "to a target. Supported algorithms are defined by the Ruby net-ssh library and can be "\
-                         "viewed [here](https://github.com/net-ssh/net-ssh#supported-algorithms). All supported, "\
-                         "non-deprecated algorithms are available by default when this option is not used. To "\
-                         "reference all default algorithms using this option, add 'defaults' to the list of "\
+            description: "List of message authentication code algorithms to use when establishing a connection " \
+                         "to a target. Supported algorithms are defined by the Ruby net-ssh library and can be " \
+                         "viewed [here](https://github.com/net-ssh/net-ssh#supported-algorithms). All supported, " \
+                         "non-deprecated algorithms are available by default when this option is not used. To " \
+                         "reference all default algorithms using this option, add 'defaults' to the list of " \
                          "supported algorithms.",
             uniqueItems: true,
             items: {
@@ -227,7 +227,7 @@ module Options
           },
           "native-ssh" => {
             type: [TrueClass, FalseClass],
-            description: "This enables the native SSH transport, which shells out to SSH instead of using the "\
+            description: "This enables the native SSH transport, which shells out to SSH instead of using the " \
                          "net-ssh Ruby library",
             _default: false,
             _example: true
@@ -247,9 +247,9 @@ module Options
           },
           "private-key" => {
             type: [Hash, String],
-            description: "Either the path to the private key file to use for authentication, or "\
-            "a hash with the key `key-data` and the contents of the private key. Note that "\
-            "the key cannot be encrypted if using the `key-data` hash.",
+            description: "Either the path to the private key file to use for authentication, or " \
+                         "a hash with the key `key-data` and the contents of the private key. Note that " \
+                         "the key cannot be encrypted if using the `key-data` hash.",
             required: ["key-data"],
             properties: {
               "key-data" => {
@@ -289,16 +289,16 @@ module Options
           },
           "run-as" => {
             type: String,
-            description: "The user to run commands as after login. The run-as user must be different than the "\
+            description: "The user to run commands as after login. The run-as user must be different than the " \
                          "login user.",
             _plugin: true,
             _example: "root"
           },
           "run-as-command" => {
             type: Array,
-            description: "The command to elevate permissions. Bolt appends the user and command strings to the "\
-                         "configured `run-as-command` before running it on the target. This command must not require "\
-                         " aninteractive password prompt, and the `sudo-password` option is ignored when "\
+            description: "The command to elevate permissions. Bolt appends the user and command strings to the " \
+                         "configured `run-as-command` before running it on the target. This command must not require " \
+                         "aninteractive password prompt, and the `sudo-password` option is ignored when " \
                          "`run-as-command` is specified. The `run-as-command` must be specified as an array.",
             items: {
               type: String
@@ -316,9 +316,9 @@ module Options
           },
           "script-dir" => {
             type: String,
-            description: "The subdirectory of the tmpdir to use in place of a randomized "\
-                         "subdirectory for uploading and executing temporary files on the "\
-                         "target. It's expected that this directory already exists as a subdir "\
+            description: "The subdirectory of the tmpdir to use in place of a randomized " \
+                         "subdirectory for uploading and executing temporary files on the " \
+                         "target. It's expected that this directory already exists as a subdir " \
                          "of tmpdir, which is either configured or defaults to `/tmp`.",
             _plugin: true,
             _example: "bolt_scripts"
@@ -345,9 +345,9 @@ module Options
           },
           "ssh-command" => {
             type: [Array, String],
-            description: "The command and options to use when SSHing. This option is used when you need support for "\
-                         "features or algorithms that are not supported by the net-ssh Ruby library. **This option "\
-                         "is experimental.** You can read more about this  option in [Native SSH "\
+            description: "The command and options to use when SSHing. This option is used when you need support for " \
+                         "features or algorithms that are not supported by the net-ssh Ruby library. **This option " \
+                         "is experimental.** You can read more about this  option in [Native SSH " \
                          "transport](experimental_features.md#native-ssh-transport).",
             items: {
               type: String
@@ -372,10 +372,10 @@ module Options
           },
           "sudo-executable" => {
             type: String,
-            description: "The executable to use when escalating to the configured `run-as` user. This is useful "\
-                         "when you want to escalate using the configured `sudo-password`, since `run-as-command` "\
-                         "does not use `sudo-password` or support prompting. The command executed on the target "\
-                         "is `<sudo-executable> -S -u <user> -p custom_bolt_prompt <command>`. **This option is "\
+            description: "The executable to use when escalating to the configured `run-as` user. This is useful " \
+                         "when you want to escalate using the configured `sudo-password`, since `run-as-command` " \
+                         "does not use `sudo-password` or support prompting. The command executed on the target " \
+                         "is `<sudo-executable> -S -u <user> -p custom_bolt_prompt <command>`. **This option is " \
                          "experimental.**",
             _plugin: true,
             _example: "dzdo"
diff --git a/lib/bolt/config/transport/ssh.rb b/lib/bolt/config/transport/ssh.rb
index 7577fa92ad..a4b945c980 100644
--- a/lib/bolt/config/transport/ssh.rb
+++ b/lib/bolt/config/transport/ssh.rb
@@ -65,7 +65,7 @@ class SSH < Base
         def initialize(data = {}, project = nil)
           assert_hash_or_config(data)
           @native = true if data['native-ssh']
-          super(data, project)
+          super
         end
 
         # This method is used to filter CLI options in the Config class. This
diff --git a/lib/bolt/error.rb b/lib/bolt/error.rb
index 374121126e..f8fab162b3 100644
--- a/lib/bolt/error.rb
+++ b/lib/bolt/error.rb
@@ -131,7 +131,7 @@ def initialize(results, failed_indices)
 
   class PlanFailure < Error
     def initialize(*args)
-      super(*args)
+      super
       @error_code = 2
     end
   end
diff --git a/lib/bolt/executor.rb b/lib/bolt/executor.rb
index bbd926b3da..4a3f67d07d 100644
--- a/lib/bolt/executor.rb
+++ b/lib/bolt/executor.rb
@@ -129,10 +129,10 @@ def shutdown
     def queue_execute(targets)
       if @warn_concurrency && targets.length > @concurrency
         @warn_concurrency = false
-        msg = "The ulimit is low, which might cause file limit issues. Default concurrency has been set to "\
-              "'#{@concurrency}' to mitigate those issues, which might cause Bolt to run slow. "\
-              "Disable this warning by configuring ulimit using 'ulimit -n <limit>' in your shell "\
-              "configuration, or by configuring Bolt's concurrency. "\
+        msg = "The ulimit is low, which might cause file limit issues. Default concurrency has been set to " \
+              "'#{@concurrency}' to mitigate those issues, which might cause Bolt to run slow. " \
+              "Disable this warning by configuring ulimit using 'ulimit -n <limit>' in your shell " \
+              "configuration, or by configuring Bolt's concurrency. " \
               "See https://puppet.com/docs/bolt/latest/bolt_known_issues.html for details."
         Bolt::Logger.warn("low_ulimit", msg)
       end
diff --git a/lib/bolt/fiber_executor.rb b/lib/bolt/fiber_executor.rb
index 5296f754ec..02dc42093a 100644
--- a/lib/bolt/fiber_executor.rb
+++ b/lib/bolt/fiber_executor.rb
@@ -145,7 +145,7 @@ def wait(futures, timeout: nil, catch_errors: false, **_kwargs)
         # futures being waited on.
         until (futures = get_futures_for_plan(plan_id: plan_id)).map(&:alive?).none?
           if futures.map(&:fiber).include?(Fiber.current)
-            msg = "The wait() function cannot be called with no arguments inside a "\
+            msg = "The wait() function cannot be called with no arguments inside a " \
                   "background block in the same plan."
             raise Bolt::Error.new(msg, 'bolt/infinite-wait')
           end
diff --git a/lib/bolt/inventory/options.rb b/lib/bolt/inventory/options.rb
index 81f6c48b75..99cba6059a 100644
--- a/lib/bolt/inventory/options.rb
+++ b/lib/bolt/inventory/options.rb
@@ -21,7 +21,7 @@ module Options
       # https://github.com/puppetlabs/bolt/blob/main/schemas/README.md
       DEFINITIONS = {
         "alias" => {
-          description: "A unique alias to refer to the target. Aliases cannot conflict "\
+          description: "A unique alias to refer to the target. Aliases cannot conflict " \
                        "with the name of a group, the name of a target, or another alias.",
           type: [String, Array],
           uniqueItems: true,
@@ -74,16 +74,16 @@ module Options
           _plugin: true
         },
         "name" => {
-          description: "A human-readable name to refer to the group or target. Names "\
-                       "cannot conflict with the name of a group, the name of a target, "\
-                       "or the alias of a target. A name is required for a group and is "\
+          description: "A human-readable name to refer to the group or target. Names " \
+                       "cannot conflict with the name of a group, the name of a target, " \
+                       "or the alias of a target. A name is required for a group and is " \
                        "required for a target unless the uri option is set.",
           type: String,
           _plugin: true
         },
         "plugin_hooks" => {
-          description: "Configuration for the Puppet library plugin used to install the "\
-                       "Puppet agent on the target. For more information, see "\
+          description: "Configuration for the Puppet library plugin used to install the " \
+                       "Puppet agent on the target. For more information, see " \
                        "https://pup.pt/bolt-plugin-hooks",
           type: Hash,
           properties: {
@@ -115,7 +115,7 @@ module Options
           _plugin: true
         },
         "uri" => {
-          description: "The URI of the target. This option is required unless the name "\
+          description: "The URI of the target. This option is required unless the name " \
                        "option is set.",
           type: String,
           format: "uri",
diff --git a/lib/bolt/inventory/target.rb b/lib/bolt/inventory/target.rb
index 0496c37b3a..ee03e13159 100644
--- a/lib/bolt/inventory/target.rb
+++ b/lib/bolt/inventory/target.rb
@@ -176,8 +176,8 @@ def validate
         if (dotted = facts.keys.select { |name| name.include?('.') }).any?
           Bolt::Logger.deprecate(
             'dotted_fact_name',
-            "Target '#{safe_name}' includes dotted fact names: '#{dotted.join("', '")}'. Dotted fact "\
-            "names are deprecated and Bolt does not automatically convert facts with dotted names to "\
+            "Target '#{safe_name}' includes dotted fact names: '#{dotted.join("', '")}'. Dotted fact " \
+            "names are deprecated and Bolt does not automatically convert facts with dotted names to " \
             "structured facts. For more information, see https://pup.pt/bolt-dotted-facts"
           )
         end
diff --git a/lib/bolt/module.rb b/lib/bolt/module.rb
index b0f2ca6609..9382f52d59 100644
--- a/lib/bolt/module.rb
+++ b/lib/bolt/module.rb
@@ -44,8 +44,8 @@ def plugin_data_file
     def plugin?
       if File.exist?(File.join(path, 'bolt-plugin.json'))
         msg = "Found bolt-plugin.json in module #{name} at #{path}. Bolt looks for " \
-          "bolt_plugin.json to determine if the module contains plugins. " \
-          "Rename the file for Bolt to recognize it."
+              "bolt_plugin.json to determine if the module contains plugins. " \
+              "Rename the file for Bolt to recognize it."
         Bolt::Logger.warn_once('plugin_file_name', msg)
       end
       File.exist?(plugin_data_file)
diff --git a/lib/bolt/module_installer.rb b/lib/bolt/module_installer.rb
index da549273f2..6008699599 100644
--- a/lib/bolt/module_installer.rb
+++ b/lib/bolt/module_installer.rb
@@ -23,7 +23,7 @@ def add(name, specs, puppetfile_path, moduledir, project_file, config)
       # Exit early if project config already includes a spec with this name.
       if project_specs.include?(name)
         @outputter.print_message(
-          "Project configuration file #{project_file} already includes specification "\
+          "Project configuration file #{project_file} already includes specification " \
           "with name #{name}. Nothing to do."
         )
         return true
diff --git a/lib/bolt/module_installer/puppetfile.rb b/lib/bolt/module_installer/puppetfile.rb
index d768a93005..d42ef89c41 100644
--- a/lib/bolt/module_installer/puppetfile.rb
+++ b/lib/bolt/module_installer/puppetfile.rb
@@ -56,7 +56,7 @@ def self.parse(path, skip_unsupported_modules: false)
           else
             unless skip_unsupported_modules
               raise Bolt::ValidationError,
-                    "Cannot parse Puppetfile at #{path}, module '#{mod.title}' is not a "\
+                    "Cannot parse Puppetfile at #{path}, module '#{mod.title}' is not a " \
                     "Puppet Forge or Git module."
             end
           end
diff --git a/lib/bolt/module_installer/resolver.rb b/lib/bolt/module_installer/resolver.rb
index 7985b8abb1..86816f9e8a 100644
--- a/lib/bolt/module_installer/resolver.rb
+++ b/lib/bolt/module_installer/resolver.rb
@@ -98,8 +98,8 @@ def resolve(specs, config = {})
         # names, but we error early here to provide a more helpful message.
         if (name_conflicts = modules.map(&:name) & unresolved.map(&:name)).any?
           raise Bolt::Error.new(
-            "Detected unresolved module specifications with the same name as a resolved module "\
-            "dependency: #{name_conflicts.join(', ')}. Either remove the unresolved module specification "\
+            "Detected unresolved module specifications with the same name as a resolved module " \
+            "dependency: #{name_conflicts.join(', ')}. Either remove the unresolved module specification " \
             "or set the module with the conflicting dependency to not resolve.",
             "bolt/module-name-conflict-error"
           )
diff --git a/lib/bolt/module_installer/specs/forge_spec.rb b/lib/bolt/module_installer/specs/forge_spec.rb
index 65ede484dc..bb56749cd9 100644
--- a/lib/bolt/module_installer/specs/forge_spec.rb
+++ b/lib/bolt/module_installer/specs/forge_spec.rb
@@ -38,9 +38,9 @@ def self.implements?(hash)
         private def parse_name(name)
           unless (match = name.match(NAME_REGEX))
             raise Bolt::ValidationError,
-                  "Invalid name for Forge module specification: #{name}. Name must match "\
-                  "'owner/name'. Owner segment can only include letters or digits. Name "\
-                  "segment must start with a lowercase letter and can only include lowercase "\
+                  "Invalid name for Forge module specification: #{name}. Name must match " \
+                  "'owner/name'. Owner segment can only include letters or digits. Name " \
+                  "segment must start with a lowercase letter and can only include lowercase " \
                   "letters, digits, and underscores."
           end
 
@@ -53,7 +53,7 @@ def self.implements?(hash)
           [version_requirement, SemanticPuppet::VersionRange.parse(version_requirement || '>= 0')]
         rescue StandardError
           raise Bolt::ValidationError,
-                "Invalid version requirement for Forge module specification #{@full_name}: "\
+                "Invalid version requirement for Forge module specification #{@full_name}: " \
                 "#{version_requirement.inspect}"
         end
 
diff --git a/lib/bolt/module_installer/specs/git_spec.rb b/lib/bolt/module_installer/specs/git_spec.rb
index e4543f3bf2..49567289c3 100644
--- a/lib/bolt/module_installer/specs/git_spec.rb
+++ b/lib/bolt/module_installer/specs/git_spec.rb
@@ -39,7 +39,7 @@ def initialize(init_hash, config = {})
 
           if @name.nil? && @resolve == false
             raise Bolt::ValidationError,
-                  "Missing name for Git module specification: #{@git}. Git module specifications "\
+                  "Missing name for Git module specification: #{@git}. Git module specifications " \
                   "must include a 'name' key when 'resolve' is false."
           end
 
@@ -61,9 +61,9 @@ def self.implements?(hash)
 
           unless (match = name.match(NAME_REGEX))
             raise Bolt::ValidationError,
-                  "Invalid name for Git module specification: #{name}. Name must match "\
-                  "'name' or 'owner/name'. Owner segment can only include letters or digits. "\
-                  "Name segment must start with a lowercase letter and can only include "\
+                  "Invalid name for Git module specification: #{name}. Name must match " \
+                  "'name' or 'owner/name'. Owner segment can only include letters or digits. " \
+                  "Name segment must start with a lowercase letter and can only include " \
                   "lowercase letters, digits, and underscores."
           end
 
@@ -123,8 +123,8 @@ def sha
 
             unless module_id
               raise Bolt::Error.new(
-                "Unable to locate metadata and calculate SHA for ref #{@ref} at #{@git}. This may "\
-                "not be a valid module. For more information about how Bolt attempted to locate "\
+                "Unable to locate metadata and calculate SHA for ref #{@ref} at #{@git}. This may " \
+                "not be a valid module. For more information about how Bolt attempted to locate " \
                 "this information, check the debugging logs.",
                 'bolt/missing-module-metadata-error'
               )
diff --git a/lib/bolt/module_installer/specs/id/github.rb b/lib/bolt/module_installer/specs/id/github.rb
index 57afffd833..ebdbd71dc4 100644
--- a/lib/bolt/module_installer/specs/id/github.rb
+++ b/lib/bolt/module_installer/specs/id/github.rb
@@ -72,8 +72,8 @@ class GitHub < Base
               message = "GitHub API rate limit exceeded, unable to calculate SHA."
 
               unless ENV['GITHUB_TOKEN']
-                message += " To increase your rate limit, set the GITHUB_TOKEN environment "\
-                          "variable with a GitHub personal access token."
+                message += " To increase your rate limit, set the GITHUB_TOKEN environment " \
+                           "variable with a GitHub personal access token."
               end
 
               Bolt::Logger.debug(message)
diff --git a/lib/bolt/module_installer/specs/id/gitlab.rb b/lib/bolt/module_installer/specs/id/gitlab.rb
index 870dce4eef..dd07d71714 100644
--- a/lib/bolt/module_installer/specs/id/gitlab.rb
+++ b/lib/bolt/module_installer/specs/id/gitlab.rb
@@ -74,8 +74,8 @@ class GitLab < Base
               message = "GitLab API rate limit exceeded, unable to calculate SHA."
 
               unless ENV['GITLAB_TOKEN']
-                message += " To increase your rate limit, set the GITLAB_TOKEN environment "\
-                          "variable with a GitLab personal access token."
+                message += " To increase your rate limit, set the GITLAB_TOKEN environment " \
+                           "variable with a GitLab personal access token."
               end
 
               Bolt::Logger.debug(message)
diff --git a/lib/bolt/outputter/human.rb b/lib/bolt/outputter/human.rb
index 5aeab22ac0..d60aeda407 100644
--- a/lib/bolt/outputter/human.rb
+++ b/lib/bolt/outputter/human.rb
@@ -786,8 +786,8 @@ def print_target_info(adhoc:, inventory:, flag:, **_kwargs)
         info = +''
 
         # Add target count summary
-        count = "#{inventory_count + adhoc_count} total, "\
-                "#{inventory_count} from inventory, "\
+        count = "#{inventory_count + adhoc_count} total, " \
+                "#{inventory_count} from inventory, " \
                 "#{adhoc_count} adhoc"
         info << colorize(:cyan, "Target count\n")
         info << indent(2, count)
diff --git a/lib/bolt/outputter/rainbow.rb b/lib/bolt/outputter/rainbow.rb
index cb1a811abf..fa9a41b1b0 100644
--- a/lib/bolt/outputter/rainbow.rb
+++ b/lib/bolt/outputter/rainbow.rb
@@ -27,9 +27,9 @@ def initialize(color, verbose, trace, spin, stream = $stdout)
       # The algorithm is from lolcat (https://github.com/busyloop/lolcat)
       # lolcat is released with WTFPL
       def rainbow
-        red = Math.sin(0.3 * @color + 0) * 127 + 128
-        green = Math.sin(0.3 * @color + 2 * Math::PI / 3) * 127 + 128
-        blue  = Math.sin(0.3 * @color + 4 * Math::PI / 3) * 127 + 128
+        red = (Math.sin((0.3 * @color) + 0) * 127) + 128
+        green = (Math.sin((0.3 * @color) + (2 * Math::PI / 3)) * 127) + 128
+        blue  = (Math.sin((0.3 * @color) + (4 * Math::PI / 3)) * 127) + 128
         @color += 1 / 8.0
         format("%<red>02X%<green>02X%<blue>02X", red: red, green: green, blue: blue)
       end
diff --git a/lib/bolt/pal.rb b/lib/bolt/pal.rb
index 7e0d4e534b..47e1c725fa 100644
--- a/lib/bolt/pal.rb
+++ b/lib/bolt/pal.rb
@@ -192,7 +192,7 @@ def in_bolt_compiler(compiler_params: {})
             rescue Puppet::PreformattedError => e
               if e.issue_code == :UNKNOWN_VARIABLE &&
                  %w[facts trusted server_facts settings].include?(e.arguments[:name])
-                message = "Evaluation Error: Variable '#{e.arguments[:name]}' is not available in the current scope "\
+                message = "Evaluation Error: Variable '#{e.arguments[:name]}' is not available in the current scope " \
                           "unless explicitly defined."
                 details = { file: e.file, line: e.line, column: e.pos }
                 PALError.new(message, details)
@@ -292,7 +292,7 @@ def with_puppet_settings
       # Delete the tmpdir if it still exists. This check is needed to
       # prevent Bolt from erroring if the tmpdir is somehow deleted
       # before reaching this point.
-      FileUtils.remove_entry_secure(dir) if File.exist?(dir)
+      FileUtils.rm_rf(dir)
     end
 
     # Parses a snippet of Puppet manifest code and returns the AST represented
@@ -666,7 +666,7 @@ def list_modules
           module_group = internal_module_groups[path]
 
           values = modules.map do |mod|
-            mod_info = { name: (mod.forge_name || mod.name),
+            mod_info = { name: mod.forge_name || mod.name,
                          version: mod.version }
             mod_info[:internal_module_group] = module_group unless module_group.nil?
 
diff --git a/lib/bolt/pal/yaml_plan/parameter.rb b/lib/bolt/pal/yaml_plan/parameter.rb
index 15e6977e91..f0a26831b2 100644
--- a/lib/bolt/pal/yaml_plan/parameter.rb
+++ b/lib/bolt/pal/yaml_plan/parameter.rb
@@ -26,8 +26,8 @@ def validate_param(param, definition)
           definition_keys = definition.keys.to_set
           unless PARAMETER_KEYS.superset?(definition_keys)
             invalid_keys = definition_keys - PARAMETER_KEYS
-            raise Bolt::Error.new("Plan parameter #{param.inspect} contains illegal key(s)" \
-                                  " #{invalid_keys.to_a.inspect}",
+            raise Bolt::Error.new("Plan parameter #{param.inspect} contains illegal key(s) " \
+                                  "#{invalid_keys.to_a.inspect}",
                                   "bolt/invalid-plan")
           end
         end
@@ -42,9 +42,9 @@ def transpile
 
           # Param type
           if @type_expr.respond_to?(:type_string)
-            result << @type_expr.type_string + " "
+            result << (@type_expr.type_string + " ")
           elsif !@type_expr.nil?
-            result << @type_expr.to_s + " "
+            result << (@type_expr.to_s + " ")
           end
 
           # Param name
diff --git a/lib/bolt/pal/yaml_plan/step/eval.rb b/lib/bolt/pal/yaml_plan/step/eval.rb
index e3f5664e10..fafc09ba7f 100644
--- a/lib/bolt/pal/yaml_plan/step/eval.rb
+++ b/lib/bolt/pal/yaml_plan/step/eval.rb
@@ -27,7 +27,7 @@ def transpile
             # If we're trying to assign the result of a multi-line eval to a name
             # variable, we need to wrap it in `with()`.
             if body['name'] && code_body.lines.count > 1
-              indented = code_body.gsub(/\n/, "\n    ").chomp("  ")
+              indented = code_body.gsub("\n", "\n    ").chomp("  ")
               code << "with() || {\n    #{indented}}"
             else
               code << code_body
diff --git a/lib/bolt/plan_creator.rb b/lib/bolt/plan_creator.rb
index e2411dcd6b..c7b16f3deb 100644
--- a/lib/bolt/plan_creator.rb
+++ b/lib/bolt/plan_creator.rb
@@ -10,8 +10,8 @@ module PlanCreator
     def self.validate_plan_name(project, plan_name)
       if project.name.nil?
         raise Bolt::Error.new(
-          "Project directory '#{project.path}' is not a named project. Unable to create "\
-          "a project-level plan. To name a project, set the 'name' key in the 'bolt-project.yaml' "\
+          "Project directory '#{project.path}' is not a named project. Unable to create " \
+          "a project-level plan. To name a project, set the 'name' key in the 'bolt-project.yaml' " \
           "configuration file.",
           "bolt/unnamed-project-error"
         )
@@ -36,8 +36,8 @@ def self.validate_plan_name(project, plan_name)
       prefix, _, basename = segment_plan_name(plan_name)
 
       unless prefix == project.name
-        message = "Incomplete plan name: A plan name must be prefixed with the name of the "\
-          "project or module. Did you mean '#{project.name}::#{plan_name}'?"
+        message = "Incomplete plan name: A plan name must be prefixed with the name of the " \
+                  "project or module. Did you mean '#{project.name}::#{plan_name}'?"
 
         raise Bolt::ValidationError, message
       end
diff --git a/lib/bolt/plugin/env_var.rb b/lib/bolt/plugin/env_var.rb
index 4b213cfafe..0db2e269fa 100644
--- a/lib/bolt/plugin/env_var.rb
+++ b/lib/bolt/plugin/env_var.rb
@@ -39,7 +39,7 @@ def validate_resolve_reference(opts)
       end
 
       def resolve_reference(opts)
-        reference = ENV[opts['var']]
+        reference = ENV.fetch(opts['var'], nil)
         if opts['json'] && reference
           begin
             reference = JSON.parse(reference)
diff --git a/lib/bolt/plugin/module.rb b/lib/bolt/plugin/module.rb
index 9565502e30..94c285b2d2 100644
--- a/lib/bolt/plugin/module.rb
+++ b/lib/bolt/plugin/module.rb
@@ -187,7 +187,7 @@ def extract_task_parameter_schema
           acc.merge!(schema)
         end
         # Convert Set to string
-        type_set.each do |_param, schema|
+        type_set.each_value do |schema|
           next unless schema['type']
           schema['type'] = if schema['type'].size > 1
                              "Optional[Variant[#{schema['type'].to_a.join(', ')}]]"
diff --git a/lib/bolt/project.rb b/lib/bolt/project.rb
index 072f01b497..042180cae1 100644
--- a/lib/bolt/project.rb
+++ b/lib/bolt/project.rb
@@ -55,7 +55,7 @@ def self.create_project(path, type = 'option')
         rescue StandardError
           Bolt::Logger.warn(
             "non_writeable_project",
-            "Could not create default project at #{path}. Continuing without a writeable project. "\
+            "Could not create default project at #{path}. Continuing without a writeable project. " \
             "Log and rerun files will not be written."
           )
         end
@@ -67,7 +67,7 @@ def self.create_project(path, type = 'option')
 
       if !Bolt::Util.windows? && type != 'environment' && fullpath.world_writable?
         raise Bolt::Error.new(
-          "Project directory '#{fullpath}' is world-writable which poses a security risk. Set "\
+          "Project directory '#{fullpath}' is world-writable which poses a security risk. Set " \
           "BOLT_PROJECT='#{fullpath}' to force the use of this project directory.",
           "bolt/world-writable-error"
         )
@@ -203,8 +203,8 @@ def validate
           and can include lowercase letters, numbers, and underscores.
           ERROR_STRING
         elsif Dir.children(Bolt::Config::Modulepath::BOLTLIB_PATH).include?(name)
-          raise Bolt::ValidationError, "The project '#{name}' will not be loaded. The project name conflicts "\
-            "with a built-in Bolt module of the same name."
+          raise Bolt::ValidationError, "The project '#{name}' will not be loaded. The project name conflicts " \
+                                       "with a built-in Bolt module of the same name."
         end
       elsif name.nil? &&
             (File.directory?(plans_path) ||
diff --git a/lib/bolt/project_manager.rb b/lib/bolt/project_manager.rb
index 7316f60d1c..2a1c294c6c 100644
--- a/lib/bolt/project_manager.rb
+++ b/lib/bolt/project_manager.rb
@@ -70,14 +70,14 @@ def create(path, name, modules)
         if modules
           command = Bolt::Util.powershell? ? 'Add-BoltModule -Module' : 'bolt module add'
           raise Bolt::Error.new(
-            "Found existing project directory with #{config.basename} at #{project}, "\
-            "unable to initialize project with modules. To add modules to the project, "\
+            "Found existing project directory with #{config.basename} at #{project}, " \
+            "unable to initialize project with modules. To add modules to the project, " \
             "run '#{command} <module>' instead.",
             'bolt/existing-project-error'
           )
         else
           raise Bolt::Error.new(
-            "Found existing project directory with #{config.basename} at #{project}, "\
+            "Found existing project directory with #{config.basename} at #{project}, " \
             "unable to initialize project.",
             'bolt/existing-project-error'
           )
@@ -85,27 +85,27 @@ def create(path, name, modules)
       elsif old_config.exist?
         command = Bolt::Util.powershell? ? 'Update-BoltProject' : 'bolt project migrate'
         raise Bolt::Error.new(
-          "Found existing project directory with #{old_config.basename} at #{project}, "\
-          "unable to initialize project. #{old_config.basename} is deprecated. To "\
+          "Found existing project directory with #{old_config.basename} at #{project}, " \
+          "unable to initialize project. #{old_config.basename} is deprecated. To " \
           "update the project to current best practices, run '#{command}'.",
           'bolt/existing-project-error'
         )
       elsif modules && puppetfile.exist?
         raise Bolt::Error.new(
-          "Found existing Puppetfile at #{puppetfile}, unable to initialize project "\
+          "Found existing Puppetfile at #{puppetfile}, unable to initialize project " \
           "with modules.",
           'bolt/existing-puppetfile-error'
         )
       elsif project_name !~ Bolt::Module::MODULE_NAME_REGEX
         if name
           raise Bolt::ValidationError,
-                "The provided project name '#{project_name}' is invalid; project name must "\
-                "begin with a lowercase letter and can include lowercase letters, "\
+                "The provided project name '#{project_name}' is invalid; project name must " \
+                "begin with a lowercase letter and can include lowercase letters, " \
                 "numbers, and underscores."
         else
           command = Bolt::Util.powershell? ? 'New-BoltProject -Name' : 'bolt project init'
           raise Bolt::ValidationError,
-                "The current directory name '#{project_name}' is an invalid project name. "\
+                "The current directory name '#{project_name}' is an invalid project name. " \
                 "Please specify a name using '#{command} <name>'."
         end
       end
@@ -162,8 +162,8 @@ def migrate
       @outputter.print_message("Migrating project #{@config.project.path}\n\n")
 
       @outputter.print_action_step(
-        "Migrating a Bolt project might make irreversible changes to the project's "\
-        "configuration and inventory files. Before continuing, make sure the "\
+        "Migrating a Bolt project might make irreversible changes to the project's " \
+        "configuration and inventory files. Before continuing, make sure the " \
         "project has a backup or uses a version control system."
       )
 
diff --git a/lib/bolt/project_manager/config_migrator.rb b/lib/bolt/project_manager/config_migrator.rb
index 35fb343e1c..5250dcdefe 100644
--- a/lib/bolt/project_manager/config_migrator.rb
+++ b/lib/bolt/project_manager/config_migrator.rb
@@ -41,7 +41,7 @@ def migrate(config_file, project_file, inventory_file, backup_dir)
 
           begin
             @outputter.print_action_step(
-              "Moving transportation configuration options '#{transport_data.keys.join(', ')}' "\
+              "Moving transportation configuration options '#{transport_data.keys.join(', ')}' " \
               "from bolt.yaml to inventory.yaml"
             )
 
@@ -57,8 +57,8 @@ def migrate(config_file, project_file, inventory_file, backup_dir)
 
         command = Bolt::Util.powershell? ? 'Get-Help about_bolt_project' : 'bolt guide project'
         @outputter.print_action_step(
-          "Successfully migrated config. Please add a 'name' key to bolt-project.yaml "\
-          "to use project-level tasks and plans. Learn more about projects by running "\
+          "Successfully migrated config. Please add a 'name' key to bolt-project.yaml " \
+          "to use project-level tasks and plans. Learn more about projects by running " \
           "'#{command}'."
         )
 
diff --git a/lib/bolt/project_manager/inventory_migrator.rb b/lib/bolt/project_manager/inventory_migrator.rb
index cce49fdfca..dc0bec2531 100644
--- a/lib/bolt/project_manager/inventory_migrator.rb
+++ b/lib/bolt/project_manager/inventory_migrator.rb
@@ -34,7 +34,7 @@ def migrate(inventory_file, backup_dir)
           true
         rescue StandardError => e
           raise Bolt::FileError.new(
-            "Unable to write to #{inventory_file}: #{e.message}. See "\
+            "Unable to write to #{inventory_file}: #{e.message}. See " \
             "http://pup.pt/bolt-inventory to manually update.",
             inventory_file
           )
diff --git a/lib/bolt/project_manager/module_migrator.rb b/lib/bolt/project_manager/module_migrator.rb
index e3cb639c44..6d98d1caa4 100644
--- a/lib/bolt/project_manager/module_migrator.rb
+++ b/lib/bolt/project_manager/module_migrator.rb
@@ -21,8 +21,8 @@ def migrate(project, configured_modulepath)
         # Notify user to manually migrate modules if using non-default modulepath
         if configured_modulepath != new_modulepath && configured_modulepath != old_modulepath
           @outputter.print_action_step(
-            "Project has a non-default configured modulepath, unable to automatically "\
-            "migrate project modules. To migrate project modules manually, see "\
+            "Project has a non-default configured modulepath, unable to automatically " \
+            "migrate project modules. To migrate project modules manually, see " \
             "http://pup.pt/bolt-modules"
           )
           true
@@ -106,7 +106,7 @@ def migrate(project, configured_modulepath)
           Bolt::ModuleInstaller::Installer.new.install(puppetfile_path, managed_moduledir)
         else
           @outputter.print_action_step(
-            "Project does not include any managed modules, deleting Puppetfile "\
+            "Project does not include any managed modules, deleting Puppetfile " \
             "at #{puppetfile_path}"
           )
           FileUtils.rm(puppetfile_path)
@@ -118,9 +118,9 @@ def migrate(project, configured_modulepath)
       #
       private def select_modules(modules)
         @outputter.print_action_step(
-          "Select modules that are direct dependencies of your project. Bolt will "\
-          "automatically manage dependencies for each module selected, so do not "\
-          "select a module's dependencies unless you use content from it directly "\
+          "Select modules that are direct dependencies of your project. Bolt will " \
+          "automatically manage dependencies for each module selected, so do not " \
+          "select a module's dependencies unless you use content from it directly " \
           "in your project."
         )
 
diff --git a/lib/bolt/puppetdb/config.rb b/lib/bolt/puppetdb/config.rb
index 914ac196da..4699614b32 100644
--- a/lib/bolt/puppetdb/config.rb
+++ b/lib/bolt/puppetdb/config.rb
@@ -6,8 +6,8 @@
 module Bolt
   module PuppetDB
     class Config
-      if ENV['HOME'].nil?
-        DEFAULT_TOKEN = Bolt::Util.windows? ? 'nul' : '/dev/null'
+      if Dir.home.nil?
+        DEFAULT_TOKEN = Bolt::Util.windows? File::NULL
         DEFAULT_CONFIG = { user: '/etc/puppetlabs/puppet/puppetdb.conf',
                            global: '/etc/puppetlabs/puppet/puppetdb.conf' }.freeze
       else
@@ -32,7 +32,7 @@ def initialize(config:, project: nil, load_defaults: false)
       # @return [String]
       #
       def self.default_windows_config
-        File.expand_path(File.join(ENV['ALLUSERSPROFILE'], 'PuppetLabs/client-tools/puppetdb.conf'))
+        File.expand_path(File.join(ENV.fetch('ALLUSERSPROFILE', nil), 'PuppetLabs/client-tools/puppetdb.conf'))
       end
 
       # Loads default configuration from the puppetdb.conf file on system. If
diff --git a/lib/bolt/rerun.rb b/lib/bolt/rerun.rb
index a103e8fe6f..5e1cd6aa79 100644
--- a/lib/bolt/rerun.rb
+++ b/lib/bolt/rerun.rb
@@ -44,7 +44,6 @@ def update(result_set)
           data = result_set.map { |res| { target: res.target.name, status: res.status } }
           FileUtils.mkdir_p(File.dirname(@path))
           File.write(@path, data.to_json)
-        elsif File.exist?(@path)
           FileUtils.rm(@path)
         end
       end
diff --git a/lib/bolt/resource_instance.rb b/lib/bolt/resource_instance.rb
index 3e9f5a685e..cf4a3cd9e9 100644
--- a/lib/bolt/resource_instance.rb
+++ b/lib/bolt/resource_instance.rb
@@ -14,7 +14,7 @@ def self._pcore_type
 
     # Needed by Puppet to serialize with _pcore_init_hash instead of the object's attributes
     def self._pcore_init_from_hash(_init_hash)
-      raise "ResourceInstance shouldn't be instantiated from a pcore_init class method. "\
+      raise "ResourceInstance shouldn't be instantiated from a pcore_init class method. " \
             "How did this get called?"
     end
 
diff --git a/lib/bolt/result.rb b/lib/bolt/result.rb
index a2964a0e13..c9a7384e2a 100644
--- a/lib/bolt/result.rb
+++ b/lib/bolt/result.rb
@@ -81,7 +81,7 @@ def self.for_task(target, stdout, stderr, exit_code, task, position)
         unless value['_error'].is_a?(Hash) && value['_error'].key?('msg')
           details['original_error'] = value['_error']
           value['_error'] = {
-            'msg'     => "Invalid error returned from task #{task}: #{value['_error'].inspect}. Error "\
+            'msg'     => "Invalid error returned from task #{task}: #{value['_error'].inspect}. Error " \
                          "must be an object with a msg key.",
             'kind'    => 'bolt/invalid-task-error',
             'details' => details
diff --git a/lib/bolt/shell.rb b/lib/bolt/shell.rb
index aa19dd4501..6acf5ad03e 100644
--- a/lib/bolt/shell.rb
+++ b/lib/bolt/shell.rb
@@ -11,7 +11,7 @@ def initialize(target, conn)
 
       if Bolt::Logger.stream
         Bolt::Logger.warn_once("stream_experimental",
-                               "The 'stream' option is experimental, and might "\
+                               "The 'stream' option is experimental, and might " \
                                "include breaking changes between minor versions.")
         @stream_logger = Bolt::Logger.logger(:stream)
         # Don't send stream messages to the parent logger
diff --git a/lib/bolt/shell/bash.rb b/lib/bolt/shell/bash.rb
index 5c533b0b95..0c4725c206 100644
--- a/lib/bolt/shell/bash.rb
+++ b/lib/bolt/shell/bash.rb
@@ -461,7 +461,7 @@ def execute(command, sudoable: false, **options)
         end
         # Read any remaining data in the pipe. Do not wait for
         # EOF in case the pipe is inherited by a child process.
-        read_streams.each do |stream, _|
+        read_streams.each_key do |stream|
           stream_name = stream == out ? 'out' : 'err'
           loop {
             to_print = stream.read_nonblock(CHUNK_SIZE)
@@ -482,8 +482,8 @@ def execute(command, sudoable: false, **options)
         when 0
           @logger.trace { "Command `#{command_str}` returned successfully" }
         when 126
-          msg = "\n\nThis might be caused by the default tmpdir being mounted "\
-            "using 'noexec'. See http://pup.pt/task-failure for details and workarounds."
+          msg = "\n\nThis might be caused by the default tmpdir being mounted " \
+                "using 'noexec'. See http://pup.pt/task-failure for details and workarounds."
           result_output.stderr        << msg
           result_output.merged_output << msg
           @logger.trace { "Command #{command_str} failed with exit code #{result_output.exit_code}" }
diff --git a/lib/bolt/shell/powershell.rb b/lib/bolt/shell/powershell.rb
index 2dfbba8c9b..0502ac0e14 100644
--- a/lib/bolt/shell/powershell.rb
+++ b/lib/bolt/shell/powershell.rb
@@ -22,9 +22,9 @@ def validate_ps_version
         if !version.empty? && version.to_i < 3
           # This lets us know how many targets have Powershell 2, and lets the
           # user know how many targets they have with PS2
-          msg = "Detected PowerShell 2 on one or more targets.\nPowerShell 2 "\
-            "is unsupported. See bolt-debug.log or run with '--log-level debug' to see the full "\
-            "list of targets with PowerShell 2."
+          msg = "Detected PowerShell 2 on one or more targets.\nPowerShell 2 " \
+                "is unsupported. See bolt-debug.log or run with '--log-level debug' to see the full " \
+                "list of targets with PowerShell 2."
 
           Bolt::Logger.deprecate_once("powershell_2", msg)
           @logger.debug("Detected PowerShell 2 on #{target}.")
@@ -45,7 +45,7 @@ def powershell_file?(path)
 
       def validate_extensions(ext)
         unless @extensions.include?(ext)
-          raise Bolt::Node::FileError.new("File extension #{ext} is not enabled, "\
+          raise Bolt::Node::FileError.new("File extension #{ext} is not enabled, " \
                                           "to run it please add to 'winrm: extensions'", 'FILETYPE_ERROR')
         end
       end
diff --git a/lib/bolt/transport/lxd.rb b/lib/bolt/transport/lxd.rb
index a04d9b6708..dc92cb5251 100644
--- a/lib/bolt/transport/lxd.rb
+++ b/lib/bolt/transport/lxd.rb
@@ -13,7 +13,7 @@ def provided_features
 
       def with_connection(target, options = {})
         Bolt::Logger.warn_once("lxd_experimental",
-                               "The LXD transport is experimental, and might "\
+                               "The LXD transport is experimental, and might " \
                                "include breaking changes between minor versions.")
         conn = Connection.new(target, options)
         conn.connect
diff --git a/lib/bolt/transport/orch.rb b/lib/bolt/transport/orch.rb
index abd2d1d22d..833ff32f4e 100644
--- a/lib/bolt/transport/orch.rb
+++ b/lib/bolt/transport/orch.rb
@@ -49,7 +49,7 @@ def get_connection(conn_opts)
       end
 
       def process_run_results(targets, results, task_name, position = [])
-        targets_by_name = Hash[targets.map { |t| t.host || t.name }.zip(targets)]
+        targets_by_name = targets.map { |t| t.host || t.name }.zip(targets).to_h
         results.map do |node_result|
           target = targets_by_name[node_result['name']]
           state = node_result['state']
@@ -120,7 +120,7 @@ def batch_script(targets, script, arguments, options = {}, position = [], &callb
           raise NotImplementedError, "pcp transport does not support setting environment variables"
         end
 
-        content = File.open(script, &:read)
+        content = File.read(script)
         content = Base64.encode64(content)
         params = {
           'content' => content,
@@ -174,7 +174,7 @@ def batch_upload(targets, source, destination, options = {}, position = [], &cal
         content = if stat.directory?
                     pack(source)
                   else
-                    File.open(source, &:read)
+                    File.read(source)
                   end
         content = Base64.encode64(content)
         mode = File.stat(source).mode
diff --git a/lib/bolt/transport/orch/connection.rb b/lib/bolt/transport/orch/connection.rb
index 0eb61448d5..84f4f77f23 100644
--- a/lib/bolt/transport/orch/connection.rb
+++ b/lib/bolt/transport/orch/connection.rb
@@ -45,7 +45,7 @@ def initialize(opts, plan_context, logger)
         def start_plan(plan_context)
           if plan_context
             begin
-              opts = plan_context.select { |k, _| CONTEXT_KEYS.include? k }
+              opts = plan_context.slice(*CONTEXT_KEYS)
               opts[:params] = opts[:params].reject { |k, _| plan_context[:sensitive].include?(k) }
               @client.command.plan_start(opts)['name']
             rescue OrchestratorClient::ApiError => e
diff --git a/lib/bolt/transport/ssh/connection.rb b/lib/bolt/transport/ssh/connection.rb
index 7757f375c4..9c59298ba2 100644
--- a/lib/bolt/transport/ssh/connection.rb
+++ b/lib/bolt/transport/ssh/connection.rb
@@ -227,8 +227,8 @@ def execute(command_str)
           end
           [in_wr, out_rd, err_rd, th]
         rescue Errno::EMFILE => e
-          msg = "#{e.message}. This might be resolved by increasing your user limit "\
-            "with 'ulimit -n 1024'. See https://puppet.com/docs/bolt/latest/bolt_known_issues.html for details."
+          msg = "#{e.message}. This might be resolved by increasing your user limit " \
+                "with 'ulimit -n 1024'. See https://puppet.com/docs/bolt/latest/bolt_known_issues.html for details."
           raise Bolt::Error.new(msg, 'bolt/too-many-files')
         end
 
diff --git a/lib/bolt/transport/winrm/connection.rb b/lib/bolt/transport/winrm/connection.rb
index 2f34ffa037..bf9570f499 100644
--- a/lib/bolt/transport/winrm/connection.rb
+++ b/lib/bolt/transport/winrm/connection.rb
@@ -81,8 +81,8 @@ def connect
             theres_your_problem = "\nAre you using SSL to connect to a non-SSL port?"
           end
           if target.options['ssl-verify'] && e.message.include?('certificate verify failed')
-            theres_your_problem = "\nIs the remote host using a self-signed SSL "\
-                                  "certificate? Use --no-ssl-verify to disable "\
+            theres_your_problem = "\nIs the remote host using a self-signed SSL " \
+                                  "certificate? Use --no-ssl-verify to disable " \
                                   "remote host SSL verification."
           end
           raise Bolt::Node::ConnectError.new(
@@ -137,8 +137,8 @@ def execute(command)
 
           [inp, out_rd, err_rd, th]
         rescue Errno::EMFILE => e
-          msg = "#{e.message}. This might be resolved by increasing your user limit "\
-            "with 'ulimit -n 1024'. See https://puppet.com/docs/bolt/latest/bolt_known_issues.html for details."
+          msg = "#{e.message}. This might be resolved by increasing your user limit " \
+                "with 'ulimit -n 1024'. See https://puppet.com/docs/bolt/latest/bolt_known_issues.html for details."
           raise Bolt::Error.new(msg, 'bolt/too-many-files')
         rescue StandardError
           @logger.trace { "Command aborted" }
@@ -254,6 +254,8 @@ def max_command_length
           nil
         end
 
+        SMB_PORT = 445
+
         private
 
         def smb_client_login
@@ -280,8 +282,6 @@ def smb_client_login
           @client
         end
 
-        SMB_PORT = 445
-
         def smb_socket_connect
           # It's lame that TCPSocket doesn't take a connect timeout
           # Using Timeout.timeout is bad, but is done elsewhere...
diff --git a/lib/bolt/util.rb b/lib/bolt/util.rb
index 56a4615fa7..922dea589b 100644
--- a/lib/bolt/util.rb
+++ b/lib/bolt/util.rb
@@ -41,7 +41,7 @@ def read_json_file(path, filename)
       end
 
       def read_optional_json_file(path, file_name)
-        File.exist?(path) && !File.zero?(path) ? read_yaml_hash(path, file_name) : {}
+        File.exist?(path) && !File.empty?(path) ? read_yaml_hash(path, file_name) : {}
       end
 
       def read_yaml_hash(path, file_name)
@@ -52,7 +52,7 @@ def read_yaml_hash(path, file_name)
         content = File.open(path, "r:UTF-8") { |f| YAML.safe_load(f.read) } || {}
         unless content.is_a?(Hash)
           raise Bolt::FileError.new(
-            "Invalid content for #{file_name} file at #{path}\nContent should be a Hash or empty, "\
+            "Invalid content for #{file_name} file at #{path}\nContent should be a Hash or empty, " \
             "not #{content.class}",
             path
           )
@@ -62,11 +62,11 @@ def read_yaml_hash(path, file_name)
       rescue Errno::ENOENT
         raise Bolt::FileError.new("Could not read #{file_name} file at #{path}", path)
       rescue Psych::SyntaxError => e
-        raise Bolt::FileError.new("Could not parse #{file_name} file at #{path}, line #{e.line}, "\
+        raise Bolt::FileError.new("Could not parse #{file_name} file at #{path}, line #{e.line}, " \
                                   "column #{e.column}\n#{e.problem}",
                                   path)
       rescue Psych::BadAlias => e
-        raise Bolt::FileError.new('Bolt does not support the use of aliases in YAML files. Alias '\
+        raise Bolt::FileError.new('Bolt does not support the use of aliases in YAML files. Alias ' \
                                   "detected in #{file_name} file at #{path}\n#{e.message}", path)
       rescue Psych::Exception => e
         raise Bolt::FileError.new("Could not parse #{file_name} file at #{path}\n#{e.message}",
@@ -147,8 +147,8 @@ def module_name(path)
 
         # Only accept paths with '/plans/' or '/tasks/'
         unless path.match?(regex)
-          msg = "Could not determine module from #{path}. "\
-            "The path must include 'plans' or 'tasks' directory"
+          msg = "Could not determine module from #{path}. " \
+                "The path must include 'plans' or 'tasks' directory"
           raise Bolt::Error.new(msg, 'bolt/modulepath-error')
         end
 
diff --git a/lib/bolt/validator.rb b/lib/bolt/validator.rb
index 10a05b30d9..c418981719 100644
--- a/lib/bolt/validator.rb
+++ b/lib/bolt/validator.rb
@@ -172,8 +172,8 @@ def validate(data, schema, location = nil)
     private def plugin_reference?(value, plugin_supported)
       if value.is_a?(Hash) && value.key?('_plugin')
         unless plugin_supported
-          @errors << "Value at '#{path}' is a plugin reference, which is unsupported at "\
-                      "this location"
+          @errors << "Value at '#{path}' is a plugin reference, which is unsupported at " \
+                     "this location"
         end
 
         true
@@ -189,7 +189,7 @@ def validate(data, schema, location = nil)
     # this will safeguard against any dev mistakes).
     #
     private def valid_type?(value, definition)
-      return unless definition.key?(:type)
+      return false unless definition.key?(:type)
 
       types = Array(definition[:type])
 
diff --git a/lib/bolt_server/acl.rb b/lib/bolt_server/acl.rb
index 5fdbc0c8c3..a6c5338ede 100644
--- a/lib/bolt_server/acl.rb
+++ b/lib/bolt_server/acl.rb
@@ -17,9 +17,8 @@ def match(env)
     end
 
     def initialize(app, allowlist)
-      acls = []
-      allowlist.each do |entry|
-        acls << {
+      acls = allowlist.map do |entry|
+        {
           'resources' => [
             {
               'method' => 'ALL',
diff --git a/lib/bolt_server/base_config.rb b/lib/bolt_server/base_config.rb
index 50c66e1dfe..09c6f9d97a 100644
--- a/lib/bolt_server/base_config.rb
+++ b/lib/bolt_server/base_config.rb
@@ -45,7 +45,7 @@ def service_name
 
     def initialize(config = nil)
       @data = defaults
-      @data = @data.merge(config.select { |key, _| config_keys.include?(key) }) if config
+      @data = @data.merge(config.slice(*config_keys)) if config
       @config_path = nil
     end
 
@@ -63,7 +63,7 @@ def load_file_config(path)
 
       raise "Could not find service config at #{path}" if parsed_hocon.nil?
 
-      parsed_hocon = parsed_hocon.select { |key, _| config_keys.include?(key) }
+      parsed_hocon = parsed_hocon.slice(*config_keys)
 
       @data = @data.merge(parsed_hocon)
     end
diff --git a/lib/bolt_server/config.rb b/lib/bolt_server/config.rb
index 0572e4f803..35974082cc 100644
--- a/lib/bolt_server/config.rb
+++ b/lib/bolt_server/config.rb
@@ -44,7 +44,7 @@ def load_env_config
         @data[key] = if int_keys.include?(key)
                        ENV[transformed_key].to_i
                      else
-                       ENV[transformed_key]
+                       ENV.fetch(transformed_key, nil)
                      end
       end
     end
diff --git a/lib/bolt_server/file_cache.rb b/lib/bolt_server/file_cache.rb
index 241842572c..5f2710256a 100644
--- a/lib/bolt_server/file_cache.rb
+++ b/lib/bolt_server/file_cache.rb
@@ -194,7 +194,7 @@ def get_cached_project_file(versioned_project, file_name)
     def cache_project_file(versioned_project, file_name, data)
       file_dir = create_cache_dir(versioned_project)
       file_path = File.join(file_dir, file_name)
-      serial_execute { File.open(file_path, 'w') { |f| f.write(data) } }
+      serial_execute { File.write(file_path, data) }
     end
   end
 end
diff --git a/lib/bolt_server/transport_app.rb b/lib/bolt_server/transport_app.rb
index 252f765024..921bdf8f73 100644
--- a/lib/bolt_server/transport_app.rb
+++ b/lib/bolt_server/transport_app.rb
@@ -47,9 +47,9 @@ class TransportApp < Sinatra::Base
 
     def initialize(config)
       @config = config
-      @schemas = Hash[REQUEST_SCHEMAS.map do |basename|
+      @schemas = REQUEST_SCHEMAS.map do |basename|
         [basename, JSON.parse(File.read(File.join(__dir__, ['schemas', "#{basename}.json"])))]
-      end]
+      end.to_h
 
       PARTIAL_SCHEMAS.each do |basename|
         schema_content = JSON.parse(File.read(File.join(__dir__, ['schemas', 'partials', "#{basename}.json"])))
@@ -229,7 +229,7 @@ def with_pe_pal_init_settings(codedir, environmentpath, basemodulepath)
       Dir.mktmpdir('pe-bolt') do |dir|
         cli = []
         Puppet::Settings::REQUIRED_APP_SETTINGS.each do |setting|
-          dir = setting == :codedir ? codedir : dir
+          dir = codedir if setting == :codedir
           cli << "--#{setting}" << dir
         end
         cli << "--environmentpath" << environmentpath
diff --git a/lib/bolt_spec/plans/action_stubs.rb b/lib/bolt_spec/plans/action_stubs.rb
index 3010b28090..dfeeaf7ed8 100644
--- a/lib/bolt_spec/plans/action_stubs.rb
+++ b/lib/bolt_spec/plans/action_stubs.rb
@@ -178,7 +178,7 @@ def error_with(data, clazz = Bolt::Error)
           @data[:default] = clazz.new(data['msg'], data['kind'], data['details'], data['issue_code'])
         else
           $stderr.puts "In the future 'error_with()' might require msg and kind, and " \
-                      "optionally accept only details and issue_code."
+                       "optionally accept only details and issue_code."
           @data[:default] = data
         end
         @data_set = true
diff --git a/lib/bolt_spec/plans/action_stubs/plan_stub.rb b/lib/bolt_spec/plans/action_stubs/plan_stub.rb
index 9c70400afd..bc4d630dc7 100644
--- a/lib/bolt_spec/plans/action_stubs/plan_stub.rb
+++ b/lib/bolt_spec/plans/action_stubs/plan_stub.rb
@@ -48,7 +48,7 @@ def return_for_targets(_data)
       end
 
       def error_with(data, clazz = Bolt::PlanFailure)
-        super(data, clazz)
+        super
       end
     end
   end
diff --git a/libexec/apply_catalog.rb b/libexec/apply_catalog.rb
index de12b8cc44..c475b166ab 100755
--- a/libexec/apply_catalog.rb
+++ b/libexec/apply_catalog.rb
@@ -74,7 +74,7 @@
     begin
       require 'puppet/resource_api/transport'
     rescue LoadError
-      msg = "Could not load 'puppet/resource_api/transport', puppet-resource_api "\
+      msg = "Could not load 'puppet/resource_api/transport', puppet-resource_api " \
             "gem version 1.8.0 or greater is required on the proxy target"
       puts msg
       exit 1
diff --git a/libexec/bolt_catalog b/libexec/bolt_catalog
index 9688c702be..66d465bdfa 100755
--- a/libexec/bolt_catalog
+++ b/libexec/bolt_catalog
@@ -34,7 +34,7 @@ require 'json'
 command = ARGV[0]
 case command
 when "parse"
-  code = File.open(ARGV[1], &:read)
+  code = File.read(ARGV[1])
   puts JSON.pretty_generate(Bolt::Catalog.new.generate_ast(code, ARGV[1]))
 when "compile"
   request = if ARGV[1]
diff --git a/libexec/custom_facts.rb b/libexec/custom_facts.rb
index db65e93c37..3bdbd0ffc8 100755
--- a/libexec/custom_facts.rb
+++ b/libexec/custom_facts.rb
@@ -39,7 +39,7 @@
     begin
       require 'puppet/resource_api/transport'
     rescue LoadError
-      msg = "Could not load 'puppet/resource_api/transport', puppet-resource_api "\
+      msg = "Could not load 'puppet/resource_api/transport', puppet-resource_api " \
             "gem version 1.8.0 or greater is required on the proxy target"
       puts msg
       exit 1
diff --git a/libexec/query_resources.rb b/libexec/query_resources.rb
index c044520fd3..eadf6f4621 100755
--- a/libexec/query_resources.rb
+++ b/libexec/query_resources.rb
@@ -46,7 +46,7 @@ def instance(type_name, resource_name)
     begin
       require 'puppet/resource_api/transport'
     rescue LoadError
-      msg = "Could not load 'puppet/resource_api/transport', puppet-resource_api "\
+      msg = "Could not load 'puppet/resource_api/transport', puppet-resource_api " \
             "gem version 1.8.0 or greater is required on the proxy target"
       puts msg
       exit 1
diff --git a/rakelib/docs.rake b/rakelib/docs.rake
index 846ac4df76..0e08a20bd0 100644
--- a/rakelib/docs.rake
+++ b/rakelib/docs.rake
@@ -229,7 +229,7 @@ begin
         data = Bolt::Util.walk_vals(data) do |val|
           if val.is_a?(String)
             val.gsub(/TypeReference\['(\w*)'\]/, '\1')
-               .gsub(/String\[1\]/, 'String')
+               .gsub('String[1]', 'String')
           else
             val
           end
@@ -284,14 +284,14 @@ begin
 
       apply = {
         "name"       => "apply",
-        "desc"       => "Applies a block of manifest code to the targets.\n\nApplying manifest "\
-                        "code requires facts to compile a catalog. Targets must also have "\
-                        "the Puppet agent package installed to apply manifest code. To prep "\
-                        "targets for an apply, call the [apply_prep](#apply-prep) function before "\
-                        "the apply function.\n\nTo learn more about applying manifest code from a plan, "\
-                        "see [Applying manifest blocks from a Puppet "\
-                        "plan](applying_manifest_blocks.md#applying-manifest-blocks-from-a-puppet-plan).\n\n"\
-                        "> **Note:** The `apply` function returns a `ResultSet` object containing `ApplyResult`\n"\
+        "desc"       => "Applies a block of manifest code to the targets.\n\nApplying manifest " \
+                        "code requires facts to compile a catalog. Targets must also have " \
+                        "the Puppet agent package installed to apply manifest code. To prep " \
+                        "targets for an apply, call the [apply_prep](#apply-prep) function before " \
+                        "the apply function.\n\nTo learn more about applying manifest code from a plan, " \
+                        "see [Applying manifest blocks from a Puppet " \
+                        "plan](applying_manifest_blocks.md#applying-manifest-blocks-from-a-puppet-plan).\n\n" \
+                        "> **Note:** The `apply` function returns a `ResultSet` object containing `ApplyResult`\n" \
                         "> objects.",
         "examples"   => [
           {
@@ -300,8 +300,8 @@ begin
           },
           {
             "desc" => "Apply manifest code as another user, catching any errors.",
-            "exmp" => "$apply_results = apply($targets, '_catch_errors' => true, '_run_as' => 'bolt') {\n"\
-                      "  file { '/etc/puppetlabs':\n    ensure => present\n  }\n}"
+            "exmp" => "$apply_results = apply($targets, '_catch_errors' => true, '_run_as' => 'bolt') {\n  " \
+                      "file { '/etc/puppetlabs':\n    ensure => present\n  }\n}"
           }
         ],
         "signatures" => [
@@ -310,27 +310,27 @@ begin
             "return"    => "ResultSet",
             "options"   => {
               "_catch_errors" => {
-                "desc" => "When `true`, returns a `ResultSet` including failed results, rather "\
+                "desc" => "When `true`, returns a `ResultSet` including failed results, rather " \
                           "than failing the plan.",
                 "type" => "Boolean"
               },
               "_description" => {
-                "desc" => "Adds a description to the apply block, allowing you to distinguish "\
+                "desc" => "Adds a description to the apply block, allowing you to distinguish " \
                           "apply blocks.",
                 "type" => "String"
               },
               "_noop" => {
-                "desc" => "When `true`, applies the manifest block in Puppet no-operation mode, "\
+                "desc" => "When `true`, applies the manifest block in Puppet no-operation mode, " \
                           "returning a report of the changes it would make while taking no action.",
                 "type" => "Boolean"
               },
               "_puppetdb" => {
-                "desc" => "The named PuppetDB instance to connect to when making PuppetDB queries "\
+                "desc" => "The named PuppetDB instance to connect to when making PuppetDB queries " \
                           "during catalog compilation.",
                 "type" => "String"
               },
               "_run_as" => {
-                "desc" => "The user to apply the manifest block as. Only available for transports "\
+                "desc" => "The user to apply the manifest block as. Only available for transports " \
                           "that support the `run-as` option.",
                 "type" => "String"
               }
diff --git a/rakelib/pwsh.rake b/rakelib/pwsh.rake
index 9a44f8aa0d..a6d972ae9d 100644
--- a/rakelib/pwsh.rake
+++ b/rakelib/pwsh.rake
@@ -7,7 +7,7 @@ namespace :pwsh do
   desc "Generate the PowerShell module structure and supporting files"
   task generate_module: :generate_powershell_cmdlets do
     dest = File.expand_path(File.join(__dir__, '..', 'pwsh_module', 'PuppetBolt', 'en-US'))
-    FileUtils.mkdir_p(dest) unless File.exist?(dest)
+    FileUtils.mkdir_p(dest)
 
     begin
       source = File.expand_path(File.join(__dir__, '..', 'guides'))
@@ -355,7 +355,7 @@ namespace :pwsh do
         # verbose is a commonparameter and is already present in the
         # pwsh cmdlets, so it is omitted here to prevent it from being
         # added twice
-        help_text[:flags].reject { |o| o =~ /verbose|help|version/ }.map do |option|
+        help_text[:flags].grep_v(/verbose|help|version/).map do |option|
           ruby_param = parser.top.long[option]
           pwsh_name = option.split("-").map(&:capitalize).join
           case pwsh_name
diff --git a/rakelib/schemas.rake b/rakelib/schemas.rake
index e1467315e9..a170101bc4 100644
--- a/rakelib/schemas.rake
+++ b/rakelib/schemas.rake
@@ -202,7 +202,7 @@ def to_schema(data, plugin = false)
   data[:type] = to_json_types(data[:type]) if data.key?(:type)
 
   # Add a plugin definition if supported by the option.
-  data = plugin ? add_plugin_reference(data) : data
+  data = add_plugin_reference(data) if plugin
 
   # Stringify keys
   data.transform_keys(&:to_s)
diff --git a/scripts/generate_changelog.rb b/scripts/generate_changelog.rb
index f6ad34c17c..5c1d946ef5 100755
--- a/scripts/generate_changelog.rb
+++ b/scripts/generate_changelog.rb
@@ -27,7 +27,7 @@ def labels
   def client
     unless @client
       unless ENV['GITHUB_TOKEN']
-        warn "Missing GitHub personal access token. Set $GITHUB_TOKEN with a "\
+        warn "Missing GitHub personal access token. Set $GITHUB_TOKEN with a " \
              "personal access token to use this script."
         exit 1
       end
@@ -36,7 +36,7 @@ def client
         c.auto_paginate = true
       end
 
-      @client = Octokit::Client.new(access_token: ENV['GITHUB_TOKEN'])
+      @client = Octokit::Client.new(access_token: ENV.fetch('GITHUB_TOKEN', nil))
     end
 
     @client
diff --git a/spec/fixtures/hiera/modules/test/lib/puppet/functions/custom_backend.rb b/spec/fixtures/hiera/modules/test/lib/puppet/functions/custom_backend.rb
index 187e52bfdc..ffaa176e53 100644
--- a/spec/fixtures/hiera/modules/test/lib/puppet/functions/custom_backend.rb
+++ b/spec/fixtures/hiera/modules/test/lib/puppet/functions/custom_backend.rb
@@ -31,7 +31,7 @@ def custom_backend(options, context)
   end
 
   def missing_path(_options, _context)
-    "one of 'path', 'paths' 'glob', 'globs' or 'mapped_paths' must be declared in hiera.yaml when "\
-    "using this data_hash function"
+    "one of 'path', 'paths' 'glob', 'globs' or 'mapped_paths' must be declared in hiera.yaml when " \
+      "using this data_hash function"
   end
 end
diff --git a/spec/fixtures/modules/env_var/lib/puppet/functions/env_var/get_var.rb b/spec/fixtures/modules/env_var/lib/puppet/functions/env_var/get_var.rb
index ea1ed0e363..8f7d5b585b 100644
--- a/spec/fixtures/modules/env_var/lib/puppet/functions/env_var/get_var.rb
+++ b/spec/fixtures/modules/env_var/lib/puppet/functions/env_var/get_var.rb
@@ -6,6 +6,6 @@
   end
 
   def get(var)
-    ENV[var]
+    ENV.fetch(var, nil)
   end
 end
diff --git a/spec/fixtures/modules/sample/tasks/bolt_ruby.rb b/spec/fixtures/modules/sample/tasks/bolt_ruby.rb
index 08e2d60bb4..f8ebe36212 100755
--- a/spec/fixtures/modules/sample/tasks/bolt_ruby.rb
+++ b/spec/fixtures/modules/sample/tasks/bolt_ruby.rb
@@ -3,5 +3,5 @@
 
 require 'json'
 
-result = { 'env' => ENV['PT_message'], 'stdin' => JSON.parse(gets)['message'] }
+result = { 'env' => ENV.fetch('PT_message', nil), 'stdin' => JSON.parse(gets)['message'] }
 puts result.to_json
diff --git a/spec/fixtures/scripts/bolt_cli_loader.rb b/spec/fixtures/scripts/bolt_cli_loader.rb
index 6b687f2dcb..f0cfe830ea 100755
--- a/spec/fixtures/scripts/bolt_cli_loader.rb
+++ b/spec/fixtures/scripts/bolt_cli_loader.rb
@@ -7,7 +7,7 @@
 require 'bolt/cli'
 
 def suppress_outputs
-  null_io = !!File::ALT_SEPARATOR ? 'NUL' : '/dev/null'
+  null_io = !!File::ALT_SEPARATOR ? File::NULL : FILE::SEPARATOR
   out = $stdout.clone
   err = $stderr.clone
   $stderr.reopen(null_io, 'w')
diff --git a/spec/integration/apply_compile_spec.rb b/spec/integration/apply_compile_spec.rb
index 01a783e8af..27e08c4768 100644
--- a/spec/integration/apply_compile_spec.rb
+++ b/spec/integration/apply_compile_spec.rb
@@ -64,7 +64,7 @@ def get_notifies(result)
       notify = get_notifies(result)
       expect(notify.count).to eq(1)
       expect(notify[0]['title']).to eq(
-        "trusted {authenticated => local, certname => #{uri}, extensions => {}, "\
+        "trusted {authenticated => local, certname => #{uri}, extensions => {}, " \
         "hostname => #{uri}, domain => , external => {}}"
       )
     end
@@ -76,7 +76,7 @@ def get_notifies(result)
         notify = get_notifies(result)
         expect(notify.count).to eq(1)
         expect(notify[0]['title']).to eq(
-          "trusted {authenticated => local, certname => #{uri}, extensions => {}, "\
+          "trusted {authenticated => local, certname => #{uri}, extensions => {}, " \
           "hostname => #{uri}, domain => , external => {hot => cocoa, pepper => mint}}"
         )
       end
diff --git a/spec/integration/cli/cli_spec.rb b/spec/integration/cli/cli_spec.rb
index 03de8ecafb..90b85012c8 100644
--- a/spec/integration/cli/cli_spec.rb
+++ b/spec/integration/cli/cli_spec.rb
@@ -308,7 +308,7 @@
 
     context 'running in no-op mode' do
       before(:each) do
-        flags.concat(['--noop'])
+        flags.push('--noop')
       end
 
       it 'errors on a task that does not support noop' do
diff --git a/spec/integration/inventory_spec.rb b/spec/integration/inventory_spec.rb
index bd5be4a233..43bd08ed9f 100644
--- a/spec/integration/inventory_spec.rb
+++ b/spec/integration/inventory_spec.rb
@@ -18,29 +18,29 @@
 
   let(:inventory) do
     { targets: [
-      { uri: conn[:host],
-        config: {
-          transport: conn[:protocol],
-          conn[:protocol] => {
-            user: conn[:user],
-            port: conn[:port],
-            'connect-timeout': conn[:'connect-timeout'] || 120
-          }
-        } },
-      { name: 'uriless',
-        config: {
-          transport: conn[:protocol],
-          conn[:protocol] => {
-            host: conn[:host],
-            user: conn[:user],
-            port: conn[:port]
-          }
-        } },
-      { name: 'hostless',
-        config: {
-          transport: conn[:protocol]
-        } }
-    ],
+        { uri: conn[:host],
+          config: {
+            transport: conn[:protocol],
+            conn[:protocol] => {
+              user: conn[:user],
+              port: conn[:port],
+              'connect-timeout': conn[:'connect-timeout'] || 120
+            }
+          } },
+        { name: 'uriless',
+          config: {
+            transport: conn[:protocol],
+            conn[:protocol] => {
+              host: conn[:host],
+              user: conn[:user],
+              port: conn[:port]
+            }
+          } },
+        { name: 'hostless',
+          config: {
+            transport: conn[:protocol]
+          } }
+      ],
       groups: [{
         name: "group1",
         targets: [
@@ -161,7 +161,7 @@ def var_plan(name = 'vars')
       # This also asserts the deep_merge works
       let(:output) {
         "Facts for localhost: {scooby => doo, cloud => {provider => AWS, " \
-        "foo => bar}, kernel => Linux}"
+          "foo => bar}, kernel => Linux}"
       }
 
       def fact_plan(name = 'facts_test')
diff --git a/spec/integration/jail_spec.rb b/spec/integration/jail_spec.rb
index 6a7c067030..f329bac264 100644
--- a/spec/integration/jail_spec.rb
+++ b/spec/integration/jail_spec.rb
@@ -85,8 +85,7 @@
     let(:default_inv) do
       {
         'config' => {
-          'jail' => {
-          }
+          'jail' => {}
         }
       }
     end
@@ -102,8 +101,7 @@
     let(:run_as_conf) do
       {
         'config' => {
-          'jail' => {
-          }
+          'jail' => {}
         }
       }
     end
diff --git a/spec/integration/local_spec.rb b/spec/integration/local_spec.rb
index 1af096db5f..dab89cf476 100644
--- a/spec/integration/local_spec.rb
+++ b/spec/integration/local_spec.rb
@@ -12,7 +12,7 @@
 
   let(:modulepath) { fixtures_path('modules') }
   let(:uri) { 'localhost,local://foo' }
-  let(:user) { ENV['USER'] }
+  let(:user) { ENV.fetch('USER', nil) }
   let(:sudo_user) { 'root' }
   let(:sudo_password) { 'runner' }
   let(:stdin_task) { "sample::stdin" }
@@ -61,7 +61,7 @@
         cmd = %W[task run env_var::ruby_env --project #{@project.path}]
         result = run_one_node(cmd + config_flags)
         env = Bundler.with_unbundled_env do
-          ENV['GEM_HOME']
+          ENV.fetch('GEM_HOME', nil)
         end
         expect(result['_output'].strip).to eq(env.to_s)
       end
@@ -227,7 +227,7 @@
 
     it 'runs a task with complex parameters', :reset_puppet_settings do
       complex_input_file = fixtures_path('complex_params', 'input.json')
-      expected = File.open(fixtures_path('complex_params', 'output'), 'rb', &:read)
+      expected = File.binread(fixtures_path('complex_params', 'output'))
       result = run_one_node(%W[task run sample::complex_params --params @#{complex_input_file}] + config_flags)
       expect(result['_output']).to eq(expected)
     end
diff --git a/spec/integration/puppetdb/client_spec.rb b/spec/integration/puppetdb/client_spec.rb
index 9ca4f8ac97..5cc9d78557 100644
--- a/spec/integration/puppetdb/client_spec.rb
+++ b/spec/integration/puppetdb/client_spec.rb
@@ -126,9 +126,9 @@
 
     def facts_hash
       { 'node1' => {
-        'foo' => 'bar',
-        'name' => 'node1'
-      },
+          'foo' => 'bar',
+          'name' => 'node1'
+        },
         'node2' => {
           'foo' => 'bar',
           '1' => 'the loneliest number',
diff --git a/spec/integration/remote_spec.rb b/spec/integration/remote_spec.rb
index 39ab6272f4..bf16cf42f1 100644
--- a/spec/integration/remote_spec.rb
+++ b/spec/integration/remote_spec.rb
@@ -14,28 +14,28 @@
   let(:conn) { conn_info('ssh') }
   let(:inventory) do
     { 'targets' => [
-      { 'uri' => conn[:host],
-        'config' => {
-          'transport' => conn[:protocol],
-          conn[:protocol] => {
-            'user' => conn[:user],
-            'port' => conn[:port],
-            'password' => conn[:password]
-          }
-        } },
-      { 'uri' => 'remote://simple.example.com',
-        'config' => {
-          'remote' => {
-            'run-on' => conn[:host],
-            'token' => 'token_val'
-          }
-        } },
-      { 'uri' => 'https://www.example.com',
-        'config' => {
-          'transport' => 'remote',
-          'remote' => { 'run-on': conn[:host] }
-        } }
-    ],
+        { 'uri' => conn[:host],
+          'config' => {
+            'transport' => conn[:protocol],
+            conn[:protocol] => {
+              'user' => conn[:user],
+              'port' => conn[:port],
+              'password' => conn[:password]
+            }
+          } },
+        { 'uri' => 'remote://simple.example.com',
+          'config' => {
+            'remote' => {
+              'run-on' => conn[:host],
+              'token' => 'token_val'
+            }
+          } },
+        { 'uri' => 'https://www.example.com',
+          'config' => {
+            'transport' => 'remote',
+            'remote' => { 'run-on': conn[:host] }
+          } }
+      ],
       'config' => {
         'ssh' => { 'host-key-check' => false },
         'winrm' => { 'ssl' => false, 'ssl-verify' => false }
diff --git a/spec/integration/shareable_task_spec.rb b/spec/integration/shareable_task_spec.rb
index 746a844706..e1b6f8f024 100644
--- a/spec/integration/shareable_task_spec.rb
+++ b/spec/integration/shareable_task_spec.rb
@@ -35,7 +35,7 @@
   end
 
   it 'fails with an invalid path' do
-    msg = Regexp.new('Files must be saved in module directories that Puppet makes '\
+    msg = Regexp.new('Files must be saved in module directories that Puppet makes ' \
                      'available via mount points: files, lib, scripts, tasks')
     expect {
       run_cli_json(%w[task run shareable::invalid_path] + config_flags)
@@ -45,7 +45,7 @@
   it 'fails with a file referenced as a directory' do
     msg = if Bolt::Util.windows?
             'Files specified in task metadata cannot include a trailing slash: ' \
-            'results/lib/puppet/functions/results/make_result.rb/'
+              'results/lib/puppet/functions/results/make_result.rb/'
           else
             %r{Could not find .*results/lib/puppet/functions/results/make_result.rb/ on disk}
           end
diff --git a/spec/integration/transport/ssh_spec.rb b/spec/integration/transport/ssh_spec.rb
index 95bf013ff1..bddcabfe21 100644
--- a/spec/integration/transport/ssh_spec.rb
+++ b/spec/integration/transport/ssh_spec.rb
@@ -211,7 +211,7 @@ def make_target(host_: hostname, port_: port)
   end
 
   context "when executing with private key data" do
-    let(:key_data) { File.open(key, 'r', &:read) }
+    let(:key_data) { File.read(key) }
     let(:transport_config) do
       {
         'host-key-check' => false,
diff --git a/spec/integration/transport/winrm_spec.rb b/spec/integration/transport/winrm_spec.rb
index 336a4f15fc..62da90b808 100644
--- a/spec/integration/transport/winrm_spec.rb
+++ b/spec/integration/transport/winrm_spec.rb
@@ -117,7 +117,7 @@ def stub_winrm_to_raise(klass, message)
       let(:password) { 'whoops wrong password' }
 
       it "raises Node::ConnectError" do
-        stub_winrm_to_raise(::WinRM::WinRMAuthorizationError, "")
+        stub_winrm_to_raise(WinRM::WinRMAuthorizationError, "")
 
         expect_node_error(
           Bolt::Node::ConnectError, 'AUTH_ERROR',
@@ -514,7 +514,7 @@ def stub_winrm_to_raise(klass, message)
       with_tempfile_containing('script-test-winrm', contents, '.ps1') do |file|
         result = winrm.run_script(target, file.path, [])
         expect(result).to be_success
-        expected_nulls = ("\0" * (1024 * 4 + 1)) + "\r\n"
+        expected_nulls = ("\0" * ((1024 * 4) + 1)) + "\r\n"
         expect(result['stderr']).to eq(expected_nulls)
       end
     end
@@ -551,7 +551,7 @@ def stub_winrm_to_raise(klass, message)
     it "can run a task remotely", winrm: true do
       contents = 'Write-Host "$env:PT_message_one ${env:PT_message two}"'
       arguments = { message_one: 'task is running',
-                    "message two": 'task has run' }
+                    'message two': 'task has run' }
       with_task_containing('task-test-winrm', contents, 'environment', '.ps1') do |task|
         expect(winrm.run_task(target, task, arguments).message)
           .to eq("task is running task has run\r\n")
diff --git a/spec/integration/winrm_spec.rb b/spec/integration/winrm_spec.rb
index 325ebc32f6..47288c13aa 100644
--- a/spec/integration/winrm_spec.rb
+++ b/spec/integration/winrm_spec.rb
@@ -60,7 +60,7 @@
 
     it 'runs a task with complex parameters', :reset_puppet_settings do
       complex_input_file = fixtures_path('complex_params', 'input.json')
-      expected = File.open(fixtures_path('complex_params', 'output'), 'rb', &:read)
+      expected = File.binread(fixtures_path('complex_params', 'output'))
 
       result = run_one_node(%W[task run sample::complex_params --params @#{complex_input_file}] + config_flags)
       expect(result['_output']).to eq(expected)
diff --git a/spec/lib/bolt_spec/env_var.rb b/spec/lib/bolt_spec/env_var.rb
index 7b60525456..7301bdba15 100644
--- a/spec/lib/bolt_spec/env_var.rb
+++ b/spec/lib/bolt_spec/env_var.rb
@@ -6,7 +6,7 @@ def with_env_vars(new_vars)
       new_vars.transform_keys!(&:to_s)
 
       begin
-        old_vars = new_vars.keys.collect { |var| [var, ENV[var]] }.to_h
+        old_vars = new_vars.keys.collect { |var| [var, ENV.fetch(var, nil)] }.to_h
         ENV.update(new_vars)
         yield
       ensure
diff --git a/spec/lib/bolt_spec/pal.rb b/spec/lib/bolt_spec/pal.rb
index 3c40ce172a..f67ca6a8ba 100644
--- a/spec/lib/bolt_spec/pal.rb
+++ b/spec/lib/bolt_spec/pal.rb
@@ -41,7 +41,7 @@ def mk_files(path, content)
         if cont.is_a? Hash
           mk_files(full_path, cont)
         else
-          File.open(full_path, 'w') { |f| f.write(cont) }
+          File.write(full_path, cont)
         end
       end
     end
diff --git a/spec/lib/bolt_spec/puppetdb.rb b/spec/lib/bolt_spec/puppetdb.rb
index c78be71e01..e7e0e2da34 100644
--- a/spec/lib/bolt_spec/puppetdb.rb
+++ b/spec/lib/bolt_spec/puppetdb.rb
@@ -32,20 +32,20 @@ def make_command(command:, version:, payload:, wait: nil)
 
     def replace_facts(certname, facts, wait: nil)
       make_command(command: 'replace facts', version: 5, payload: {
-                     certname: certname,
-                     environment: 'production',
-                     producer_timestamp: Time.now.iso8601(3),
-                     producer: 'bolt',
-                     values: facts
-                   },
+                                                           certname: certname,
+                                                           environment: 'production',
+                                                           producer_timestamp: Time.now.iso8601(3),
+                                                           producer: 'bolt',
+                                                           values: facts
+                                                         },
                    wait: wait)
     end
 
     def deactivate_node(certname, wait: nil)
       make_command(command: 'deactivate node', version: 3, payload: {
-                     certname: certname,
-                     producer_timestamp: Time.now.iso8601(3)
-                   },
+                                                             certname: certname,
+                                                             producer_timestamp: Time.now.iso8601(3)
+                                                           },
                    wait: wait)
     end
 
diff --git a/spec/unit/apply_result_spec.rb b/spec/unit/apply_result_spec.rb
index 5ce2c57159..9c281970c5 100644
--- a/spec/unit/apply_result_spec.rb
+++ b/spec/unit/apply_result_spec.rb
@@ -57,7 +57,7 @@
       expect(error['kind']).to eq('bolt/apply-error')
       expect(error['msg'])
         .to eq('Found a Ruby without Puppet present, please install Puppet ' \
-              "or remove Ruby from $env:Path to enable 'apply'")
+               "or remove Ruby from $env:Path to enable 'apply'")
     end
   end
 
diff --git a/spec/unit/executor_spec.rb b/spec/unit/executor_spec.rb
index ecd811c0e0..28414e3c56 100644
--- a/spec/unit/executor_spec.rb
+++ b/spec/unit/executor_spec.rb
@@ -425,7 +425,7 @@ def mock_node_results
 
   context 'waiting until targets are available' do
     it 'waits on all nodes' do
-      node_results.each do |target, _|
+      node_results.each_key do |target|
         expect(ssh)
           .to receive(:connected?)
           .with(target)
diff --git a/spec/unit/logger_spec.rb b/spec/unit/logger_spec.rb
index a450edc09f..aafcc8ce58 100644
--- a/spec/unit/logger_spec.rb
+++ b/spec/unit/logger_spec.rb
@@ -53,8 +53,7 @@ def initialize(*args)
   describe '::configure' do
     let(:appenders) {
       {
-        'file:/bolt.log' => {
-        },
+        'file:/bolt.log' => {},
         'file:/debug.log' => {
           level: :debug,
           append: false
diff --git a/spec/unit/module_installer_spec.rb b/spec/unit/module_installer_spec.rb
index 6a58311dcd..061050a2a4 100644
--- a/spec/unit/module_installer_spec.rb
+++ b/spec/unit/module_installer_spec.rb
@@ -144,10 +144,10 @@
     end
 
     it 'prints added modules' do
-      updated_modules.concat([
-                               mod,
-                               double('updated_module', full_name: 'puppetlabs/bar', version: '1.0.0', type: :forge)
-                             ])
+      updated_modules.push(
+        mod,
+        double('updated_module', full_name: 'puppetlabs/bar', version: '1.0.0', type: :forge)
+      )
 
       expect(outputter).to receive(:print_action_step).with(
         %r{Adding the following modules:\s*puppetlabs/bar 1.0.0}
@@ -165,9 +165,9 @@
     end
 
     it 'prints upgraded modules' do
-      updated_modules.concat([
-                               double('updated_module', full_name: 'puppetlabs/foo', version: '2.0.0', type: :forge)
-                             ])
+      updated_modules.push(
+        double('updated_module', full_name: 'puppetlabs/foo', version: '2.0.0', type: :forge)
+      )
 
       expect(outputter).to receive(:print_action_step).with(
         %r{Upgrading the following modules:\s*puppetlabs/foo 1.0.0 to 2.0.0}
@@ -177,9 +177,9 @@
     end
 
     it 'prints downgraded modules' do
-      updated_modules.concat([
-                               double('updated_module', full_name: 'puppetlabs/foo', version: '0.5.0', type: :forge)
-                             ])
+      updated_modules.push(
+        double('updated_module', full_name: 'puppetlabs/foo', version: '0.5.0', type: :forge)
+      )
 
       expect(outputter).to receive(:print_action_step).with(
         %r{Downgrading the following modules:\s*puppetlabs/foo 1.0.0 to 0.5.0}
diff --git a/spec/unit/pal/yaml_plan/step_spec.rb b/spec/unit/pal/yaml_plan/step_spec.rb
index cf91c851dd..ba18fc3875 100644
--- a/spec/unit/pal/yaml_plan/step_spec.rb
+++ b/spec/unit/pal/yaml_plan/step_spec.rb
@@ -92,8 +92,8 @@ def make_string(str)
           "parameters" => { "butter" => "crunchy peanut" } }
       end
       let(:output) {
-        "  run_task('jam::raspberry', $bread, 'delicious',"\
-                     " {'butter' => 'crunchy peanut'})\n"
+        "  run_task('jam::raspberry', $bread, 'delicious', " \
+          "{'butter' => 'crunchy peanut'})\n"
       }
 
       include_examples 'metaparameters'
diff --git a/spec/unit/transport/local_spec.rb b/spec/unit/transport/local_spec.rb
index 17af46e39d..f4bcabe2d7 100644
--- a/spec/unit/transport/local_spec.rb
+++ b/spec/unit/transport/local_spec.rb
@@ -156,7 +156,8 @@ def get_target(inventory, name, alia = nil)
     it 'does not issue the warning' do
       expect(Bolt::Logger).not_to receive(:warn_once)
         .with(anything, /The local transport will default/)
-      subject.with_connection(get_target(inventory, uri)) do |conn|; end
+      subject.with_connection(get_target(inventory, uri)) do |conn|
+      end
     end
 
     it 'unbundles the env' do