Skip to content

fix: derive the Ruby pin in mise.toml from .ruby-version - #26

Merged
developerz-ai[bot] merged 1 commit into
mainfrom
dz/make-ruby-version-the-single-source-of-truth-for--640893e3
Nov 10, 2026
Merged

developerz-ai[bot] merged 1 commit into
mainfrom
dz/make-ruby-version-the-single-source-of-truth-for--640893e3

Conversation

@developerz-ai

@developerz-ai developerz-ai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

What

mise.toml duplicated .ruby-version's literal (ruby = "4.0.9"), so the two could
drift silently: bin/setup's mise install would install the stale mise.toml
version while CI ran the bumped .ruby-version. mise.toml now reads the pin
from .ruby-version via a read_file template, bin/setup stays a bare 'mise
install' so the installed toolchain resolves through mise.toml from the same
single source, and a new spec/bin/ruby_version_spec.rb fails when any of the
three files reintroduces an independent version literal.

Acceptance

  • mise.toml states no Ruby version literal: its [tools] ruby entry is the read_file template of .ruby-version, so editing .ruby-version alone changes the version mise resolves and installs.
  • bin/setup keeps its single bare system!('mise install') call and gains no version literal; the toolchain it installs resolves mise.toml → .ruby-version.
  • spec/bin/ruby_version_spec.rb passes on the changed tree and fails if mise.toml re-adds a literal or references another file, if .ruby-version stops being an exact X.Y.Z, or if bin/setup passes an explicit ruby@ version to mise.
  • CI=1 bundle exec rspec includes and passes the new spec, and bundle exec rubocop is clean on the touched Ruby file.

Changes

  • mise.toml (edit) — Replace the duplicated literal on line 4 (ruby = "4.0.9") with ruby = "{{ read_file(path='.ruby-version') | trim }}" and reword the two header comments to state that .ruby-version is the single source of the Ruby pin and that bin/setup's mise install resolves it. Keep the [tools] table and everything else unchanged.
  • spec/bin/ruby_version_spec.rb (create) — New regression spec enforcing the single-source Ruby pin contract from sharedContext: (1) .ruby-version is an exact X.Y.Z after strip; (2) the ruby request in mise.toml must reference .ruby-version via read_file(path='.ruby-version') — a version literal or any other referenced file fails — and the referenced file's stripped content must equal .ruby-version; (3) bin/setup's only system!('mise ...') call is exactly 'mise install' with no version argument. Style per spec/bin/setup_spec.rb.

Verification

./bin/check passed (exit 0) in 24s.

What the editors ran to see the change working, and what they saw:

  • code_changes paths=["mise.toml"] (toolchain): modified; diff shows ruby = "4.0.9" replaced by ruby = "{{ read_file(path='.ruby-version') | trim }}", header comments reworded, [tools] table unchanged; no runtime check run (brief scoped none)
  • bundle exec rspec spec/bin/ruby_version_spec.rb (tests): 4 examples, 0 failures
  • drift matrix: same spec run against mutated scratch copies in /tmp (literal in mise.toml; other referenced file; .ruby-version=4.0; system!('mise install ruby@4.0.9')) (tests): control PASS; all four drift scenarios FAIL with the corresponding expectation failing (e.g. expected "4.0.9" to include "read_file(path='.ruby-version')", expected "4.0" to match /\A\d+.\d+.\d+\z/)

Notes

Premises of the request the team disproved:

  • The request implies bin/setup itself must gain version-resolution logic; survey shows bin/setup:27 already runs bare 'mise install' and resolves transitively through mise.toml, so once mise.toml derives from .ruby-version bin/setup needs no edit and must NOT gain a second resolver (declared, listed in noChangesNeeded).
  • Mise cannot be pointed at .ruby-version via a 'file:' request prefix or via idiomatic version files without per-machine settings: mise docs confirm no file: prefix exists and idiomatic_version_file_enable_tools is empty by default, so the only project-local derivation is the read_file template used here.

🤖 Opened by developerz.ai for task tsk_640893e36471b2e8dffe60bdbb0599b6 on sebyx07/ruby2html.

Raised automatically by the raw_task_triage lane.

🤖 developerz.ai, an automated agent, not a human — this PR is one slice of a stacked plan.
Dispatched automatically by a developerz.ai maintainer lane
Part 1/1

mise.toml duplicated .ruby-version's literal (ruby = "4.0.9"), so the two could
drift silently: bin/setup's mise install would install the stale mise.toml
version while CI ran the bumped .ruby-version. mise.toml now reads the pin
from .ruby-version via a read_file template, bin/setup stays a bare 'mise
install' so the installed toolchain resolves through mise.toml from the same
single source, and a new spec/bin/ruby_version_spec.rb fails when any of the
three files reintroduces an independent version literal.

Dz-Task-Id: tsk_640893e36471b2e8dffe60bdbb0599b6
@developerz-ai developerz-ai Bot added dz/fleet-pr Opened by developerz.ai, an automated agent, from a fleet run. dz/model:glm-5.3-flash developerz.ai: model that wrote this bot PR. dz/provider:router.ai.developerz.ai developerz.ai: provider that served this bot PR. labels Nov 10, 2026
@github-actions

Copy link
Copy Markdown

Benchmarks: x86_64 (linux)

ruby 4.0.9 (2026-10-23 revision 3e93b23afc) +PRISM [x86_64-linux] · commit 23ca711a8d · 2.0s per report
Δ is against main 09f01f322e (same runner type; expect a few % noise).

escape_bench (C ext) · peak RSS 119 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
escape_html short clean (10B) 704,872 ± 0.6% 0.0014 0.00 fastest -20.2%
escape_html medium clean (200B) 418,690 ± 0.4% 0.0024 0.00 1.68x slower -21.4%
append short clean (10B) 255,479 ± 2.6% 0.0039 0.02 2.76x slower -23.9%
append short dirty (10B) 186,529 ± 1.0% 0.0054 0.00 3.78x slower -24.6%
append medium clean (200B) 167,573 ± 3.8% 0.0060 0.00 4.21x slower -27.2%
escape_html short dirty (10B) 128,196 ± 1.8% 0.0078 100 5.50x slower -22.6%
append medium dirty (200B) 91,728 ± 0.7% 0.0109 0.00 7.68x slower -22.2%
escape_html medium dirty (200B) 71,789 ± 1.1% 0.0139 100 9.82x slower -21.9%
escape_html long clean (10KB) 16,228 ± 0.2% 0.0616 0.00 43.43x slower -12.5%
append long clean (10KB) 11,476 ± 0.4% 0.0871 0.00 61.42x slower -19.6%
append long dirty (10KB) 1,515 ± 0.3% 0.6603 0.00 465.41x slower -19.6%
escape_html long dirty (10KB) 1,459 ± 3.0% 0.6856 100 483.26x slower -20.7%

escape_bench (pure Ruby) · peak RSS 145 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
escape_html short clean (10B) 200,792 ± 0.5% 0.0050 0.00 fastest -24.4%
append short clean (10B) 151,218 ± 2.6% 0.0066 0.02 1.33x slower -24.0%
escape_html short dirty (10B) 84,528 ± 1.7% 0.0118 100 2.38x slower -28.7%
append short dirty (10B) 64,014 ± 3.3% 0.0156 100 3.14x slower -35.5%
escape_html medium clean (200B) 57,454 ± 0.3% 0.0174 0.00 3.49x slower -17.9%
append medium clean (200B) 48,554 ± 2.9% 0.0206 0.00 4.14x slower -20.6%
escape_html medium dirty (200B) 25,368 ± 1.9% 0.0394 200 7.92x slower -34.3%
append medium dirty (200B) 22,116 ± 1.3% 0.0452 200 9.08x slower -36.0%
escape_html long clean (10KB) 1,552 ± 0.3% 0.6442 0.00 129.35x slower -11.9%
append long clean (10KB) 1,484 ± 0.4% 0.6737 0.00 135.27x slower -11.5%
escape_html long dirty (10KB) 1,014 ± 1.7% 0.9864 200 198.06x slower -15.9%
append long dirty (10KB) 902 ± 3.2% 1.1086 200 222.59x slower -18.8%

render_bench (C ext) · peak RSS 132 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
erubi 8,065 ± 2.6% 0.1240 713 fastest -28.5%
ruby2html 5,414 ± 1.1% 0.1847 419 1.49x slower -33.6%
phlex 498 ± 2.2% 2.0090 6,374 16.20x slower -30.9%

render_bench (pure Ruby) · peak RSS 132 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
erubi 7,985 ± 1.6% 0.1252 713 fastest -28.8%
ruby2html 2,199 ± 0.7% 0.4547 1,029 3.63x slower -30.6%
phlex 503 ± 2.4% 1.9882 6,374 15.88x slower -29.8%

tag_bench (C ext) · peak RSS 40 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
br 251,108 ± 0.8% 0.0040 7.00 fastest -29.1%
li(text) 170,568 ± 1.9% 0.0059 7.02 1.47x slower -23.4%
li(dirty text) 144,584 ± 0.5% 0.0069 7.00 1.74x slower -25.0%
div { block } 112,539 ± 1.1% 0.0089 7.00 2.23x slower -25.8%
span(text, class:) 31,573 ± 1.7% 0.0317 207 7.95x slower -34.3%
div(class:) { block } 27,147 ± 1.2% 0.0368 207 9.25x slower -37.3%
a(text, href:, class:) 22,572 ± 1.5% 0.0443 207 11.12x slower -35.1%

tag_bench (pure Ruby) · peak RSS 27 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
br 97,501 ± 0.8% 0.0103 107 fastest -28.2%
div { block } 79,460 ± 0.8% 0.0126 107 1.23x slower -27.7%
li(text) 71,926 ± 1.1% 0.0139 107 1.36x slower -25.7%
li(dirty text) 47,789 ± 4.2% 0.0209 207 2.04x slower -30.4%
span(text, class:) 14,321 ± 0.7% 0.0698 207 6.81x slower -31.9%
div(class:) { block } 13,461 ± 2.7% 0.0743 207 7.24x slower -31.3%
a(text, href:, class:) 9,532 ± 0.6% 0.1049 207 10.23x slower -31.5%

Rails request (C ext) · peak RSS 242 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
Ruby2html::Component 509 ± 3.3% 1.9649 4,347 fastest -29.5%
ruby2html .html.rb templates 504 ± 3.6% 1.9822 4,474 1.01x slower -30.6%
Slim 500 ± 8.8% 2.0008 4,039 1.02x slower -34.7%
ViewComponent + ruby2html 478 ± 3.1% 2.0918 4,204 1.06x slower -31.2%
ERB 435 ± 17.7% 2.2997 2,887 1.17x slower -36.3%
Phlex 435 ± 3.7% 2.3011 5,648 1.17x slower -32.2%

@github-actions

Copy link
Copy Markdown

Benchmarks: aarch64 (linux)

ruby 4.0.9 (2026-10-23 revision 3e93b23afc) +PRISM [aarch64-linux] · commit 23ca711a8d · 2.0s per report
Δ is against main 09f01f322e (same runner type; expect a few % noise).

escape_bench (C ext) · peak RSS 118 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
escape_html short clean (10B) 610,588 ± 0.2% 0.0016 0.00 fastest -1.2%
escape_html medium clean (200B) 336,839 ± 0.2% 0.0030 0.00 1.81x slower +0.0%
append short clean (10B) 208,668 ± 0.3% 0.0048 0.02 2.93x slower -0.6%
append short dirty (10B) 160,861 ± 0.2% 0.0062 0.00 3.80x slower -0.0%
append medium clean (200B) 147,217 ± 0.2% 0.0068 0.00 4.15x slower -0.5%
escape_html short dirty (10B) 109,545 ± 1.3% 0.0091 100 5.57x slower -1.2%
append medium dirty (200B) 73,674 ± 0.2% 0.0136 0.00 8.29x slower -0.1%
escape_html medium dirty (200B) 58,331 ± 0.4% 0.0171 100 10.47x slower -0.6%
escape_html long clean (10KB) 11,460 ± 0.2% 0.0873 0.00 53.28x slower +0.0%
append long clean (10KB) 8,958 ± 0.3% 0.1116 0.00 68.16x slower -1.0%
append long dirty (10KB) 1,202 ± 0.3% 0.8317 0.00 507.82x slower -0.0%
escape_html long dirty (10KB) 1,125 ± 3.3% 0.8890 100 542.83x slower -1.4%

escape_bench (pure Ruby) · peak RSS 150 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
escape_html short clean (10B) 164,582 ± 0.2% 0.0061 0.00 fastest -0.0%
append short clean (10B) 104,426 ± 0.2% 0.0096 0.02 1.58x slower -0.0%
escape_html short dirty (10B) 69,249 ± 1.0% 0.0144 100 2.38x slower -1.6%
append short dirty (10B) 57,660 ± 0.6% 0.0173 100 2.85x slower -1.0%
escape_html medium clean (200B) 56,845 ± 0.2% 0.0176 0.00 2.90x slower -0.1%
append medium clean (200B) 45,650 ± 0.2% 0.0219 0.00 3.61x slower +0.3%
escape_html medium dirty (200B) 23,965 ± 2.6% 0.0417 200 6.87x slower -5.5%
append medium dirty (200B) 21,767 ± 0.4% 0.0459 200 7.56x slower -4.1%
escape_html long clean (10KB) 1,632 ± 0.2% 0.6126 0.00 100.83x slower -0.1%
append long clean (10KB) 1,560 ± 0.3% 0.6412 0.00 105.53x slower -0.2%
escape_html long dirty (10KB) 1,084 ± 0.6% 0.9224 200 151.81x slower -1.0%
append long dirty (10KB) 964 ± 2.4% 1.0375 200 170.75x slower -1.7%

render_bench (C ext) · peak RSS 131 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
erubi 7,592 ± 0.7% 0.1317 713 fastest -2.3%
ruby2html 5,800 ± 0.6% 0.1724 419 1.31x slower -1.2%
phlex 565 ± 0.9% 1.7694 6,374 13.43x slower -3.1%

render_bench (pure Ruby) · peak RSS 131 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
erubi 7,499 ± 1.3% 0.1334 713 fastest -2.7%
ruby2html 2,336 ± 0.7% 0.4282 1,029 3.21x slower -2.0%
phlex 563 ± 0.7% 1.7752 6,374 13.31x slower -4.3%

tag_bench (C ext) · peak RSS 39 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
br 218,694 ± 0.7% 0.0046 7.00 fastest -0.4%
li(text) 157,151 ± 1.0% 0.0064 7.02 1.39x slower -2.8%
li(dirty text) 124,918 ± 0.4% 0.0080 7.00 1.75x slower -1.5%
div { block } 98,874 ± 0.7% 0.0101 7.00 2.21x slower -0.9%
span(text, class:) 31,115 ± 0.4% 0.0321 207 7.03x slower -0.1%
div(class:) { block } 29,659 ± 0.3% 0.0337 207 7.37x slower +0.3%
a(text, href:, class:) 23,891 ± 0.3% 0.0419 207 9.15x slower +0.1%

tag_bench (pure Ruby) · peak RSS 26 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
br 81,141 ± 1.5% 0.0123 107 fastest +0.2%
div { block } 62,970 ± 0.4% 0.0159 107 1.29x slower -0.1%
li(text) 54,208 ± 1.4% 0.0184 107 1.50x slower +0.7%
li(dirty text) 41,332 ± 0.6% 0.0242 207 1.96x slower +0.8%
div(class:) { block } 15,732 ± 0.4% 0.0636 207 5.16x slower +0.7%
span(text, class:) 15,482 ± 1.9% 0.0646 207 5.24x slower -0.2%
a(text, href:, class:) 9,853 ± 0.4% 0.1015 207 8.24x slower +0.7%

Rails request (C ext) · peak RSS 228 MB

Benchmark i/s ms / call allocs / call vs fastest Δ vs main
Ruby2html::Component 465 ± 1.1% 2.1522 4,470 fastest +1.1%
ruby2html .html.rb templates 464 ± 1.3% 2.1565 4,612 1.00x slower +1.6%
Slim 459 ± 4.4% 2.1802 4,132 1.01x slower +1.6%
ViewComponent + ruby2html 435 ± 1.2% 2.3013 4,327 1.07x slower +0.7%
ERB 425 ± 9.2% 2.3507 2,946 1.09x slower -1.3%
Phlex 404 ± 1.5% 2.4733 5,839 1.15x slower +0.5%

@developerz-ai

developerz-ai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor Author

✅ Reviewed — nothing blocking

0 actionable comment(s) · grounded on your code

⏱ 45s wall clock · glm-5.3-flash via router · 2 model call(s) · 575 output token(s)

🤖 developerz.ai — automated review, running on your model and your box.

@developerz-ai developerz-ai Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary — 2 file(s), 0 finding(s).

Replaces mise.toml's duplicated Ruby literal with a read_file template of .ruby-version and adds a regression spec guarding the single-source pin; the spec's regexes correctly fail on literals, other referenced files, non-X.Y.Z pins and versioned mise args.

  • concern-tests: nothing to review — The added spec asserts the contract directly (X.Y.Z shape, read_file template referencing .ruby-version, resolved content equality, bare 'mise install') and the mise.toml template matches it; no loosened assertions or untested behaviour in the diff.

🤖 developerz.ai review — automated, running on your model and your box. What is this? · Reviewed by router/glm-5.3-flash — 22.8k in / 575 out over 2 calls, on your flat-rate plan: no per-token charge (~<$0.01 at list price).

@developerz-ai
developerz-ai Bot merged commit b69cba8 into main Nov 10, 2026
30 checks passed
@developerz-ai
developerz-ai Bot deleted the dz/make-ruby-version-the-single-source-of-truth-for--640893e3 branch November 10, 2026 11:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dz/fleet-pr Opened by developerz.ai, an automated agent, from a fleet run. dz/model:glm-5.3-flash developerz.ai: model that wrote this bot PR. dz/provider:router.ai.developerz.ai developerz.ai: provider that served this bot PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants