diff --git a/.github/workflows/audit.yaml b/.github/workflows/audit.yaml
index 49961a32..7161880a 100644
--- a/.github/workflows/audit.yaml
+++ b/.github/workflows/audit.yaml
@@ -16,10 +16,10 @@ jobs:
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4.2.0
+        uses: actions/checkout@v4.2.2
 
       - name: Install Ruby toolchain
-        uses: ruby/setup-ruby@c04af2bb7258bb6a03df1d3c1865998ac9390972 # v1.194.0
+        uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc # v1.202.0
         with:
           ruby-version: ".ruby-version"
           bundler-cache: true
@@ -41,7 +41,7 @@ jobs:
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4.2.0
+        uses: actions/checkout@v4.2.2
 
       - name: Install Rust toolchain
         uses: artichoke/setup-rust/audit@v1.12.1
@@ -52,7 +52,7 @@ jobs:
             cargo generate-lockfile --verbose
           fi
 
-      - uses: EmbarkStudios/cargo-deny-action@8371184bd11e21dcf8ac82ebf8c9c9f74ebf7268 # v2.0.1
+      - uses: EmbarkStudios/cargo-deny-action@2d8c9929d8f9f42bedba73f1287cb0b479f07acb # v2.0.3
         with:
           arguments: --locked --all-features
           command: check ${{ matrix.checks }}
diff --git a/.github/workflows/bench.yaml b/.github/workflows/bench.yaml
index 7f786b52..e315c4bc 100644
--- a/.github/workflows/bench.yaml
+++ b/.github/workflows/bench.yaml
@@ -19,7 +19,7 @@ jobs:
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4.2.0
+        uses: actions/checkout@v4.2.2
 
       - name: Install Rust toolchain
         uses: artichoke/setup-rust/build-and-test@v1.12.1
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 2f281e66..611c1ea5 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -22,7 +22,7 @@ jobs:
       RUST_BACKTRACE: 1
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4.2.0
+        uses: actions/checkout@v4.2.2
 
       - name: Install Rust toolchain
         uses: artichoke/setup-rust/build-and-test@v1.12.1
@@ -61,7 +61,7 @@ jobs:
       RUST_BACKTRACE: 1
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4.2.0
+        uses: actions/checkout@v4.2.2
 
       - name: Install Rust toolchain
         uses: artichoke/setup-rust/build-and-test@v1.12.1
@@ -104,7 +104,7 @@ jobs:
       RUST_BACKTRACE: 1
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4.2.0
+        uses: actions/checkout@v4.2.2
 
       - name: Install Rust toolchain
         uses: artichoke/setup-rust/build-and-test@v1.12.1
@@ -125,7 +125,7 @@ jobs:
       RUST_BACKTRACE: 1
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4.2.0
+        uses: actions/checkout@v4.2.2
 
       - name: Install Rust toolchain
         uses: artichoke/setup-rust/lint-and-format@v1.12.1
@@ -143,10 +143,10 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4.2.0
+        uses: actions/checkout@v4.2.2
 
       - name: Install Ruby toolchain
-        uses: ruby/setup-ruby@c04af2bb7258bb6a03df1d3c1865998ac9390972 # v1.194.0
+        uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc # v1.202.0
         with:
           ruby-version: ".ruby-version"
           bundler-cache: true
@@ -159,10 +159,10 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4.2.0
+        uses: actions/checkout@v4.2.2
 
       - name: Setup Node.js runtime
-        uses: actions/setup-node@v4.0.4
+        uses: actions/setup-node@v4.1.0
         with:
           node-version: "lts/*"
 
diff --git a/.github/workflows/markdown-link-check.yaml b/.github/workflows/markdown-link-check.yaml
index 4b7ad63f..e515e228 100644
--- a/.github/workflows/markdown-link-check.yaml
+++ b/.github/workflows/markdown-link-check.yaml
@@ -23,7 +23,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4.2.0
+        uses: actions/checkout@v4.2.2
 
       - name: Check for broken links in markdown files
         uses: gaurav-nelson/github-action-markdown-link-check@d53a906aa6b22b8979d33bc86170567e619495ec # v1.0.15
diff --git a/.github/workflows/miri.yaml b/.github/workflows/miri.yaml
index 90b02707..23d21cda 100644
--- a/.github/workflows/miri.yaml
+++ b/.github/workflows/miri.yaml
@@ -18,7 +18,7 @@ jobs:
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4.2.0
+        uses: actions/checkout@v4.2.2
 
       - name: Install Rust toolchain
         uses: artichoke/setup-rust/miri@v1.12.1
diff --git a/.github/workflows/repo-labels.yaml b/.github/workflows/repo-labels.yaml
index bdeb52dd..65d29cc6 100644
--- a/.github/workflows/repo-labels.yaml
+++ b/.github/workflows/repo-labels.yaml
@@ -20,10 +20,10 @@ jobs:
     name: Synchronize repository labels
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4.2.0
+      - uses: actions/checkout@v4.2.2
 
       - name: Sync GitHub Issue Labels
-        uses: crazy-max/ghaction-github-labeler@de749cf181958193cb7debf1a9c5bb28922f3e1b # v5.0.0
+        uses: crazy-max/ghaction-github-labeler@b54af0c25861143e7c8813d7cbbf46d2c341680c # v5.1.0
         with:
           github-token: ${{ secrets.GITHUB_TOKEN }}
           yaml-file: .github/labels.yaml
diff --git a/.github/workflows/rustdoc.yaml b/.github/workflows/rustdoc.yaml
index bac92db3..9ca2fbf0 100644
--- a/.github/workflows/rustdoc.yaml
+++ b/.github/workflows/rustdoc.yaml
@@ -23,7 +23,7 @@ jobs:
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v4.2.0
+        uses: actions/checkout@v4.2.2
 
       - name: Install Rust toolchain
         uses: artichoke/setup-rust/rustdoc@v1.12.1
diff --git a/Gemfile b/Gemfile
index 0d7f5c51..ec7ae14d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,5 +4,5 @@ source 'https://rubygems.org'
 
 gem 'bundler-audit', '~> 0.9', require: false
 gem 'rake', '>= 12.3.3', require: false
-gem 'rubocop', '~> 1.66', require: false
+gem 'rubocop', '~> 1.69', require: false
 gem 'rubocop-rake', '~> 0.6', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 4cd39b1c..0edf838c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -5,33 +5,35 @@ GEM
     bundler-audit (0.9.2)
       bundler (>= 1.2.0, < 3)
       thor (~> 1.0)
-    json (2.7.2)
+    json (2.8.2)
     language_server-protocol (3.17.0.3)
     parallel (1.26.3)
-    parser (3.3.5.0)
+    parser (3.3.6.0)
       ast (~> 2.4.1)
       racc
     racc (1.8.1)
     rainbow (3.1.1)
     rake (13.2.1)
-    regexp_parser (2.9.2)
-    rubocop (1.66.1)
+    regexp_parser (2.9.3)
+    rubocop (1.69.0)
       json (~> 2.3)
       language_server-protocol (>= 3.17.0)
       parallel (~> 1.10)
       parser (>= 3.3.0.2)
       rainbow (>= 2.2.2, < 4.0)
       regexp_parser (>= 2.4, < 3.0)
-      rubocop-ast (>= 1.32.2, < 2.0)
+      rubocop-ast (>= 1.36.1, < 2.0)
       ruby-progressbar (~> 1.7)
-      unicode-display_width (>= 2.4.0, < 3.0)
-    rubocop-ast (1.32.3)
+      unicode-display_width (>= 2.4.0, < 4.0)
+    rubocop-ast (1.36.2)
       parser (>= 3.3.1.0)
     rubocop-rake (0.6.0)
       rubocop (~> 1.0)
     ruby-progressbar (1.13.0)
     thor (1.3.2)
-    unicode-display_width (2.5.0)
+    unicode-display_width (3.1.2)
+      unicode-emoji (~> 4.0, >= 4.0.4)
+    unicode-emoji (4.0.4)
 
 PLATFORMS
   ruby
@@ -39,7 +41,7 @@ PLATFORMS
 DEPENDENCIES
   bundler-audit (~> 0.9)
   rake (>= 12.3.3)
-  rubocop (~> 1.66)
+  rubocop (~> 1.69)
   rubocop-rake (~> 0.6)
 
 BUNDLED WITH
diff --git a/package-lock.json b/package-lock.json
index cb88a615..8d3035a4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,14 +8,15 @@
       "name": "@artichokeruby/strudel",
       "version": "0.0.0",
       "devDependencies": {
-        "prettier": "^3.3.3"
+        "prettier": "^3.4.1"
       }
     },
     "node_modules/prettier": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
-      "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.1.tgz",
+      "integrity": "sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg==",
       "dev": true,
+      "license": "MIT",
       "bin": {
         "prettier": "bin/prettier.cjs"
       },
diff --git a/package.json b/package.json
index 4a59c38a..1974a33a 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
   "homepage": "https://www.artichokeruby.org",
   "bugs": "https://github.com/artichoke/cactusref/issues",
   "devDependencies": {
-    "prettier": "^3.3.3"
+    "prettier": "^3.4.1"
   },
   "scripts": {
     "fmt": "prettier --write \"**/*\""