From 9f49e20463862699ffccba394e1f59af3bc6d6ad Mon Sep 17 00:00:00 2001 From: tannevaled Date: Tue, 3 Nov 2026 15:14:16 +0100 Subject: [PATCH 1/3] Ruby 4.0.9: the figure, and the version it is counted at MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rbgo reports RUBY_VERSION 4.0.9 (ruby#882) and BASELINE was re-recorded at that version on the pinned runner that enforces it: 23,511 -> 23,673. Six claims on this page move, and the lane's own checker named every one of them rather than my reading the page: hugo.toml:74 claims 23673, the gate records 23511 layouts/_default/list.html:76 " layouts/index.html:27 " layouts/index.html:62 " layouts/index.html:71 " layouts/index.html:62: says the gate measures at 4.0.9, it measures at 3.4.1 That last line is the v0.6.0 version claim, and it is the one that mattered most here. The page said: Those guards resolve at Ruby 3.4.1 -- the version this runtime reports -- so every example behind a `ruby_version_is "4.0"` guard is removed from the suite before anything is counted: 61 block guards and 5 inline sites sit at that boundary, while the latest MRI release is 4.0.9. Every word of that is now false, and none of it is a number, so only the version check could catch it. It now says the opposite, and states what the move cost: +144 passing and 27 examples that WENT RED -- a figure no pass total shows, found by comparing the two runs' failure descriptions. `layouts/_default/list.html:73` is a DATED claim and therefore exempt from the check; it is updated anyway, because exempt from the gate is not the same as allowed to be wrong. ⛔ This cannot land before ruby#882. The checker reads the interpreter repository's main, so until the bump merges it refuses this page -- verified, not assumed: run against main today it prints the six disagreements above and exits 1. Co-Authored-By: Claude Opus 5 --- hugo.toml | 2 +- layouts/_default/list.html | 4 ++-- layouts/index.html | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hugo.toml b/hugo.toml index 1abc759..b01461c 100644 --- a/hugo.toml +++ b/hugo.toml @@ -71,4 +71,4 @@ disableKinds = ["taxonomy", "term", "RSS", "sitemap", "404"] [[params.phases]] name = "Phase 8 — Conformance & performance" status = "active" - blurb = "Since July the work has been **runtime** conformance, measured against [ruby/spec](https://github.com/ruby/spec)'s `language/` + `core/` suites: **23,511 examples pass** — the total that `BASELINE` sums to on `main` (2026-10-30; 2,202 of 2,206 spec files produce a result, the other 4 recorded as FILEFAIL), gated in CI by a **per-file baseline** — one record per spec file, so a file that regresses is named rather than absorbed. It replaced a single shrink-only floor, which needed a margin wider than the largest spec file and was therefore blind to any regression smaller than that: the floor had climbed from 6,000 when the ratchet first landed on 2026-08-03 to 22,475, while sitting 211 below the measured total. **Only `language/` and `core/` are swept** — ruby/spec's `library/`, `optional/` and `security/` trees are not run at all, so this is not a percentage of Ruby. Two of the recent jumps were fixes to the **measurement** rather than the interpreter — the mspec shim, and a parser upgrade that made 13 previously-unparseable spec files visible — and those are gains in what the measurement can *see*, not in what the VM can *do*. Earlier, a conformance campaign brought the pure-Go **front-end** to ~**100% of all valid Ruby** parsed across Rails + Puppet (99.96% of files; 2 misses are syntax-error fixtures MRI rejects) and **parse + compile** of **Rails 99.82% / Puppet 100%**, with **0 over-permissive** — and RuboCop 99.7%, Sinatra/Jekyll/Thor/Kramdown/dry-struct 100%, RSpec DSL 10/10. On the runtime side, that road is now underway: **the real `puppet apply` CLI runs end-to-end** on a pure-Go CGO=0 `rbgo` — `require \"puppet\"` boots Puppet 8.11.0 (all pure-Ruby gem deps on the path), and the genuine `Puppet::Util::CommandLine` → `Puppet::Application::Apply` path (real `OptionParser`, all types + providers, settings catalog applied to disk, then the user catalog via the transaction/RAL) converges `notify`, `file` and `exec` resources (the `exec` provider runs commands via pure-Go process execution with `onlyif`/`unless`/`creates`/`path` guards), emits real Puppet output (`Notice: hi from rbgo cli`) and exits 0 with the YAML run report round-tripped. Broader resource **providers** are the active next milestone (`user`/`group` provider-ready; `package`/`service` need a host package manager/systemd + root). rbgo is also increasingly composed from the standalone pure-Go **go-ruby-* family** — **178 modules across 176 orgs are now bound into rbgo as native modules** (parser, regexp, erb, marshal, yaml, format, optparse, strscan, json, date, … a selection is on the landing page), each its own 100%-coverage 6-arch org. (`Set` is not among them: it is implemented in-tree, over rbgo's own Hash.) Of the six 64-bit arches, amd64 and arm64 are tested on every pull request, as is 32-bit 386 (since v0.8.2; 32-bit arm runs nightly under qemu), and since v0.8.3 every pull request also compiles rbgo for every GOOS/GOARCH Go supports, plan9 included since v0.8.5 (vetted, not run: there is no Plan 9 kernel in CI); riscv64, loong64, ppc64le and s390x are validated on a **nightly schedule** — under qemu, and natively on the GCC Compile Farm plus an IBM LinuxONE s390x host — not on the pull-request path. On performance, a 6-runtime suite (rbgo/rbgo+AOT vs MRI/YJIT/JRuby/TruffleRuby): **rbgo+AOT beats MRI+YJIT on integer-bound kernels — measured here at 8.7× on the tight-loop benchmark and 2.0× on recursive `fib(35)`** (darwin/arm64, whole-process wall time); plus inline method caches, small-integer interning (a small-int loop drops from ~245k allocations to 1) and capture-tracked frame recycling (~14% faster on fib)." + blurb = "Since July the work has been **runtime** conformance, measured against [ruby/spec](https://github.com/ruby/spec)'s `language/` + `core/` suites: **23,673 examples pass** — the total that `BASELINE` sums to on `main` (re-recorded 2026-11-03 at Ruby 4.0.9, on the pinned runner that enforces it; 2,202 of 2,206 spec files produce a result, the other 4 recorded as FILEFAIL), gated in CI by a **per-file baseline** — one record per spec file, so a file that regresses is named rather than absorbed. It replaced a single shrink-only floor, which needed a margin wider than the largest spec file and was therefore blind to any regression smaller than that: the floor had climbed from 6,000 when the ratchet first landed on 2026-08-03 to 22,475, while sitting 211 below the measured total. **Only `language/` and `core/` are swept** — ruby/spec's `library/`, `optional/` and `security/` trees are not run at all, so this is not a percentage of Ruby. Two of the recent jumps were fixes to the **measurement** rather than the interpreter — the mspec shim, and a parser upgrade that made 13 previously-unparseable spec files visible — and those are gains in what the measurement can *see*, not in what the VM can *do*. Earlier, a conformance campaign brought the pure-Go **front-end** to ~**100% of all valid Ruby** parsed across Rails + Puppet (99.96% of files; 2 misses are syntax-error fixtures MRI rejects) and **parse + compile** of **Rails 99.82% / Puppet 100%**, with **0 over-permissive** — and RuboCop 99.7%, Sinatra/Jekyll/Thor/Kramdown/dry-struct 100%, RSpec DSL 10/10. On the runtime side, that road is now underway: **the real `puppet apply` CLI runs end-to-end** on a pure-Go CGO=0 `rbgo` — `require \"puppet\"` boots Puppet 8.11.0 (all pure-Ruby gem deps on the path), and the genuine `Puppet::Util::CommandLine` → `Puppet::Application::Apply` path (real `OptionParser`, all types + providers, settings catalog applied to disk, then the user catalog via the transaction/RAL) converges `notify`, `file` and `exec` resources (the `exec` provider runs commands via pure-Go process execution with `onlyif`/`unless`/`creates`/`path` guards), emits real Puppet output (`Notice: hi from rbgo cli`) and exits 0 with the YAML run report round-tripped. Broader resource **providers** are the active next milestone (`user`/`group` provider-ready; `package`/`service` need a host package manager/systemd + root). rbgo is also increasingly composed from the standalone pure-Go **go-ruby-* family** — **178 modules across 176 orgs are now bound into rbgo as native modules** (parser, regexp, erb, marshal, yaml, format, optparse, strscan, json, date, … a selection is on the landing page), each its own 100%-coverage 6-arch org. (`Set` is not among them: it is implemented in-tree, over rbgo's own Hash.) Of the six 64-bit arches, amd64 and arm64 are tested on every pull request, as is 32-bit 386 (since v0.8.2; 32-bit arm runs nightly under qemu), and since v0.8.3 every pull request also compiles rbgo for every GOOS/GOARCH Go supports, plan9 included since v0.8.5 (vetted, not run: there is no Plan 9 kernel in CI); riscv64, loong64, ppc64le and s390x are validated on a **nightly schedule** — under qemu, and natively on the GCC Compile Farm plus an IBM LinuxONE s390x host — not on the pull-request path. On performance, a 6-runtime suite (rbgo/rbgo+AOT vs MRI/YJIT/JRuby/TruffleRuby): **rbgo+AOT beats MRI+YJIT on integer-bound kernels — measured here at 8.7× on the tight-loop benchmark and 2.0× on recursive `fib(35)`** (darwin/arm64, whole-process wall time); plus inline method caches, small-integer interning (a small-int loop drops from ~245k allocations to 1) and capture-tracked frame recycling (~14% faster on fib)." diff --git a/layouts/_default/list.html b/layouts/_default/list.html index 91f6127..5aae9d6 100644 --- a/layouts/_default/list.html +++ b/layouts/_default/list.html @@ -70,10 +70,10 @@

C · Application conformance & performance

Runtime conformance — ruby/spec

22,488 examples pass in ruby/spec's language/ + core/ suites, measured 2026-09-26 on main (3e8e3cc). Three independent runs — two through the ratchet at different timeouts, one through a separate sweep — reported the same total.

diff --git a/layouts/index.html b/layouts/index.html index ac4dabf..7420929 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -24,7 +24,7 @@

A Ruby you can embed,
written in Go.{{ partial "icons/rocket.html" . }}Get started → {{ partial "icons/graph.html" . }}See the benchmarks

-
23,511 ruby/spec language/+core/ examples passing~100% of real Ruby parsed6 64-bit + 2 32-bit arches
+
23,673 ruby/spec language/+core/ examples passing~100% of real Ruby parsed6 64-bit + 2 32-bit arches
rbgo — zsh
@@ -59,7 +59,7 @@

Everything a Ruby runtime gives you — as a Go library.

🧩

Embeddable

A real object model — classes, mixins, method_missing, metaprogramming, Fiber. The Go API is deliberately small today: ruby.Run(src, out) runs a program on a fresh VM and writes its output to one writer. Calling a Ruby method from Go is not exposed yet.

📦

One static binary

CGO=0 by default. Tested on amd64, arm64, riscv64, loong64, ppc64le, s390x, 386 and arm; compiles for every GOOS/GOARCH Go supports — 47 targets, the BSDs, AIX, Solaris, mips and Plan 9 included (Plan 9 is vetted, not run).

⚡

AOT for integer kernels

Ahead-of-time compilation of integer-bound methods to unboxed Go. Measured on this project’s own micro-benchmarks (darwin/arm64, whole-process wall time): 8.7× MRI+YJIT on the tight-loop case, 2.0× on recursive fib(35). Only methods the compiler can lower benefit.

-
✅

Conformance, measured

23,511 ruby/spec language/ + core/ examples pass, gated in CI file by file: no spec file may pass fewer examples than its recorded row, so a regression is named rather than absorbed in a total. Only language/ and core/ are swept: library/, optional/ and security/ are not run, so this is not a percentage of Ruby. Those guards resolve at Ruby 3.4.1 — the version this runtime reports — so every example behind a ruby_version_is "4.0" guard is removed from the suite before anything is counted: 61 block guards and 5 inline sites sit at that boundary, while the latest MRI release is 4.0.9. Front-end: ~100% of valid Ruby parsed across Rails + Puppet (2026-06).

+
✅

Conformance, measured

23,673 ruby/spec language/ + core/ examples pass, gated in CI file by file: no spec file may pass fewer examples than its recorded row, so a regression is named rather than absorbed in a total. Only language/ and core/ are swept: library/, optional/ and security/ are not run, so this is not a percentage of Ruby. Those guards now resolve at Ruby 4.0.9 — the version this runtime reports, and the latest MRI release — so the examples behind a ruby_version_is "4.0" guard are counted, and those behind ruby_version_is ""..."4.0" are no longer asked for. The move was measured before it was made, both engines built from one commit minus the version string: +144 passing, and 27 examples that went red — a figure no pass total shows, found by comparing the two runs' failure descriptions. Front-end: ~100% of valid Ruby parsed across Rails + Puppet (2026-06).

🔒

Closed-world builds

rbgo build --closed bakes the program to bytecode and drops the front-end for a smaller binary.

🌿

A real ecosystem

Built from the go-ruby-* family — each a 100%-coverage, 6-arch stdlib module, bound natively.

@@ -68,7 +68,7 @@

Everything a Ruby runtime gives you — as a Go library.

8.7×
rbgo+AOT vs MRI+YJIT, tight-loop benchmark (2.0× on fib(35))
-
23,511
ruby/spec language/+core/ examples passing · gated per file, not by a total
+
23,673
ruby/spec language/+core/ examples passing · gated per file, not by a total
178
go-ruby-* modules bound into rbgo
CGO=0
across 6 arches · 3 OSes
From 8627f642d631ad90cb1ad3dc576c525702bff2a8 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Wed, 4 Nov 2026 12:48:37 +0100 Subject: [PATCH 2/3] The figure is 23,672, and the page now says why it went down by one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit core/random/bytes_spec.rb draws 8 or 9 passing examples from run to run. The 2026-11-03 re-record banked the 9, the next ordinary CI run went red, and ruby#885 pinned that row to its floor. The gate's total is 23,672. All six claims on this site move: hugo.toml's blurb, the hero trust line, the conformance card, the stat tile, and the two baseline bullets in list.html. The blurb and the first bullet also say what happened, because "23,673 → 23,672" with no explanation reads as a regression and it is the opposite: the number went down so that the gate stops passing on a coin toss. conformancefigure could not see one of those six. "The sum of those rows is 23,673" puts two words between "sum" and "is", and its vocabulary spelled out only "the sum is", "its sum is", "whose sum is" — so the line was never a candidate and the run reported "5 checked" on a page holding six. That is fixed in go-embedded-ruby/docs; this PR will bump the pinned version in deploy-pages.yml once the fix is released, so the gate here can refuse the line it just missed. Verified locally with the fixed tool: 6 claims checked, 0 disagreements, against the gate's 23672 at Ruby 4.0.9. Co-Authored-By: Claude Opus 5 --- hugo.toml | 2 +- layouts/_default/list.html | 4 ++-- layouts/index.html | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hugo.toml b/hugo.toml index b01461c..07b31b6 100644 --- a/hugo.toml +++ b/hugo.toml @@ -71,4 +71,4 @@ disableKinds = ["taxonomy", "term", "RSS", "sitemap", "404"] [[params.phases]] name = "Phase 8 — Conformance & performance" status = "active" - blurb = "Since July the work has been **runtime** conformance, measured against [ruby/spec](https://github.com/ruby/spec)'s `language/` + `core/` suites: **23,673 examples pass** — the total that `BASELINE` sums to on `main` (re-recorded 2026-11-03 at Ruby 4.0.9, on the pinned runner that enforces it; 2,202 of 2,206 spec files produce a result, the other 4 recorded as FILEFAIL), gated in CI by a **per-file baseline** — one record per spec file, so a file that regresses is named rather than absorbed. It replaced a single shrink-only floor, which needed a margin wider than the largest spec file and was therefore blind to any regression smaller than that: the floor had climbed from 6,000 when the ratchet first landed on 2026-08-03 to 22,475, while sitting 211 below the measured total. **Only `language/` and `core/` are swept** — ruby/spec's `library/`, `optional/` and `security/` trees are not run at all, so this is not a percentage of Ruby. Two of the recent jumps were fixes to the **measurement** rather than the interpreter — the mspec shim, and a parser upgrade that made 13 previously-unparseable spec files visible — and those are gains in what the measurement can *see*, not in what the VM can *do*. Earlier, a conformance campaign brought the pure-Go **front-end** to ~**100% of all valid Ruby** parsed across Rails + Puppet (99.96% of files; 2 misses are syntax-error fixtures MRI rejects) and **parse + compile** of **Rails 99.82% / Puppet 100%**, with **0 over-permissive** — and RuboCop 99.7%, Sinatra/Jekyll/Thor/Kramdown/dry-struct 100%, RSpec DSL 10/10. On the runtime side, that road is now underway: **the real `puppet apply` CLI runs end-to-end** on a pure-Go CGO=0 `rbgo` — `require \"puppet\"` boots Puppet 8.11.0 (all pure-Ruby gem deps on the path), and the genuine `Puppet::Util::CommandLine` → `Puppet::Application::Apply` path (real `OptionParser`, all types + providers, settings catalog applied to disk, then the user catalog via the transaction/RAL) converges `notify`, `file` and `exec` resources (the `exec` provider runs commands via pure-Go process execution with `onlyif`/`unless`/`creates`/`path` guards), emits real Puppet output (`Notice: hi from rbgo cli`) and exits 0 with the YAML run report round-tripped. Broader resource **providers** are the active next milestone (`user`/`group` provider-ready; `package`/`service` need a host package manager/systemd + root). rbgo is also increasingly composed from the standalone pure-Go **go-ruby-* family** — **178 modules across 176 orgs are now bound into rbgo as native modules** (parser, regexp, erb, marshal, yaml, format, optparse, strscan, json, date, … a selection is on the landing page), each its own 100%-coverage 6-arch org. (`Set` is not among them: it is implemented in-tree, over rbgo's own Hash.) Of the six 64-bit arches, amd64 and arm64 are tested on every pull request, as is 32-bit 386 (since v0.8.2; 32-bit arm runs nightly under qemu), and since v0.8.3 every pull request also compiles rbgo for every GOOS/GOARCH Go supports, plan9 included since v0.8.5 (vetted, not run: there is no Plan 9 kernel in CI); riscv64, loong64, ppc64le and s390x are validated on a **nightly schedule** — under qemu, and natively on the GCC Compile Farm plus an IBM LinuxONE s390x host — not on the pull-request path. On performance, a 6-runtime suite (rbgo/rbgo+AOT vs MRI/YJIT/JRuby/TruffleRuby): **rbgo+AOT beats MRI+YJIT on integer-bound kernels — measured here at 8.7× on the tight-loop benchmark and 2.0× on recursive `fib(35)`** (darwin/arm64, whole-process wall time); plus inline method caches, small-integer interning (a small-int loop drops from ~245k allocations to 1) and capture-tracked frame recycling (~14% faster on fib)." + blurb = "Since July the work has been **runtime** conformance, measured against [ruby/spec](https://github.com/ruby/spec)'s `language/` + `core/` suites: **23,672 examples pass** — the total that `BASELINE` sums to on `main` (re-recorded 2026-11-03 at Ruby 4.0.9, on the pinned runner that enforces it; 2,202 of 2,206 spec files produce a result, the other 4 recorded as FILEFAIL). One file, `core/random/bytes_spec.rb`, draws 8 or 9 passing examples from run to run; on 2026-11-04 its row was pinned to **8**, its floor, rather than to the 9 that re-recording happened to observe — a baseline recorded at a high draw turns the next ordinary run red, gated in CI by a **per-file baseline** — one record per spec file, so a file that regresses is named rather than absorbed. It replaced a single shrink-only floor, which needed a margin wider than the largest spec file and was therefore blind to any regression smaller than that: the floor had climbed from 6,000 when the ratchet first landed on 2026-08-03 to 22,475, while sitting 211 below the measured total. **Only `language/` and `core/` are swept** — ruby/spec's `library/`, `optional/` and `security/` trees are not run at all, so this is not a percentage of Ruby. Two of the recent jumps were fixes to the **measurement** rather than the interpreter — the mspec shim, and a parser upgrade that made 13 previously-unparseable spec files visible — and those are gains in what the measurement can *see*, not in what the VM can *do*. Earlier, a conformance campaign brought the pure-Go **front-end** to ~**100% of all valid Ruby** parsed across Rails + Puppet (99.96% of files; 2 misses are syntax-error fixtures MRI rejects) and **parse + compile** of **Rails 99.82% / Puppet 100%**, with **0 over-permissive** — and RuboCop 99.7%, Sinatra/Jekyll/Thor/Kramdown/dry-struct 100%, RSpec DSL 10/10. On the runtime side, that road is now underway: **the real `puppet apply` CLI runs end-to-end** on a pure-Go CGO=0 `rbgo` — `require \"puppet\"` boots Puppet 8.11.0 (all pure-Ruby gem deps on the path), and the genuine `Puppet::Util::CommandLine` → `Puppet::Application::Apply` path (real `OptionParser`, all types + providers, settings catalog applied to disk, then the user catalog via the transaction/RAL) converges `notify`, `file` and `exec` resources (the `exec` provider runs commands via pure-Go process execution with `onlyif`/`unless`/`creates`/`path` guards), emits real Puppet output (`Notice: hi from rbgo cli`) and exits 0 with the YAML run report round-tripped. Broader resource **providers** are the active next milestone (`user`/`group` provider-ready; `package`/`service` need a host package manager/systemd + root). rbgo is also increasingly composed from the standalone pure-Go **go-ruby-* family** — **178 modules across 176 orgs are now bound into rbgo as native modules** (parser, regexp, erb, marshal, yaml, format, optparse, strscan, json, date, … a selection is on the landing page), each its own 100%-coverage 6-arch org. (`Set` is not among them: it is implemented in-tree, over rbgo's own Hash.) Of the six 64-bit arches, amd64 and arm64 are tested on every pull request, as is 32-bit 386 (since v0.8.2; 32-bit arm runs nightly under qemu), and since v0.8.3 every pull request also compiles rbgo for every GOOS/GOARCH Go supports, plan9 included since v0.8.5 (vetted, not run: there is no Plan 9 kernel in CI); riscv64, loong64, ppc64le and s390x are validated on a **nightly schedule** — under qemu, and natively on the GCC Compile Farm plus an IBM LinuxONE s390x host — not on the pull-request path. On performance, a 6-runtime suite (rbgo/rbgo+AOT vs MRI/YJIT/JRuby/TruffleRuby): **rbgo+AOT beats MRI+YJIT on integer-bound kernels — measured here at 8.7× on the tight-loop benchmark and 2.0× on recursive `fib(35)`** (darwin/arm64, whole-process wall time); plus inline method caches, small-integer interning (a small-int loop drops from ~245k allocations to 1) and capture-tracked frame recycling (~14% faster on fib)." diff --git a/layouts/_default/list.html b/layouts/_default/list.html index 5aae9d6..f9e7cc5 100644 --- a/layouts/_default/list.html +++ b/layouts/_default/list.html @@ -70,10 +70,10 @@

C · Application conformance & performance

Runtime conformance — ruby/spec

22,488 examples pass in ruby/spec's language/ + core/ suites, measured 2026-09-26 on main (3e8e3cc). Three independent runs — two through the ratchet at different timeouts, one through a separate sweep — reported the same total.

    -
  • CI gates file by file, not on a total: no spec file may pass fewer examples than its recorded row, and none may stop loading. The sum of those rows is 23,673, re-recorded at Ruby 4.0.9 (2026-11-03) on the pinned runner that enforces it — it is what CI guarantees, while the measured total above is what one dated run did. This replaced a single shrink-only floor of 22,475, which needed a margin wider than the largest spec file and so could not see a regression smaller than that.
  • +
  • CI gates file by file, not on a total: no spec file may pass fewer examples than its recorded row, and none may stop loading. The sum of those rows is 23,672, re-recorded at Ruby 4.0.9 (2026-11-03) on the pinned runner that enforces it — it is what CI guarantees, while the measured total above is what one dated run did. One file (core/random/bytes_spec.rb) is unstable between 8 and 9 passing examples; since 2026-11-04 its row holds 8, its floor, because a row recorded at the high draw makes the next ordinary run a red build. This replaced a single shrink-only floor of 22,475, which needed a margin wider than the largest spec file and so could not see a regression smaller than that.
  • Only language/ and core/ are swept. ruby/spec's library/, optional/ and security/ trees are not run at all, so this figure is not a percentage of Ruby, and most of the standard library sits outside it.
  • Of the examples that ran, 93.3% pass (22,488 of 24,116); 477 more are skipped because our shim stubs the matcher they need, and 10 of 2,206 spec files produce no result. Skips and unreadable files sit outside the ratio entirely.
  • -
  • The guarantee has climbed from a floor of 6,000 on 2026-08-03 to a per-file baseline summing 23,673. Two earlier jumps were fixes to the measurement — the mspec shim, and a parser upgrade that made 13 previously-unparseable spec files visible — which are gains in what the measurement can see, not in what the VM can do.
  • +
  • The guarantee has climbed from a floor of 6,000 on 2026-08-03 to a per-file baseline summing 23,672. Two earlier jumps were fixes to the measurement — the mspec shim, and a parser upgrade that made 13 previously-unparseable spec files visible — which are gains in what the measurement can see, not in what the VM can do.
diff --git a/layouts/index.html b/layouts/index.html index 7420929..e35a4f8 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -24,7 +24,7 @@

A Ruby you can embed,
written in Go.{{ partial "icons/rocket.html" . }}Get started → {{ partial "icons/graph.html" . }}See the benchmarks

-
23,673 ruby/spec language/+core/ examples passing~100% of real Ruby parsed6 64-bit + 2 32-bit arches
+
23,672 ruby/spec language/+core/ examples passing~100% of real Ruby parsed6 64-bit + 2 32-bit arches
rbgo — zsh
@@ -59,7 +59,7 @@

Everything a Ruby runtime gives you — as a Go library.

🧩

Embeddable

A real object model — classes, mixins, method_missing, metaprogramming, Fiber. The Go API is deliberately small today: ruby.Run(src, out) runs a program on a fresh VM and writes its output to one writer. Calling a Ruby method from Go is not exposed yet.

📦

One static binary

CGO=0 by default. Tested on amd64, arm64, riscv64, loong64, ppc64le, s390x, 386 and arm; compiles for every GOOS/GOARCH Go supports — 47 targets, the BSDs, AIX, Solaris, mips and Plan 9 included (Plan 9 is vetted, not run).

⚡

AOT for integer kernels

Ahead-of-time compilation of integer-bound methods to unboxed Go. Measured on this project’s own micro-benchmarks (darwin/arm64, whole-process wall time): 8.7× MRI+YJIT on the tight-loop case, 2.0× on recursive fib(35). Only methods the compiler can lower benefit.

-
✅

Conformance, measured

23,673 ruby/spec language/ + core/ examples pass, gated in CI file by file: no spec file may pass fewer examples than its recorded row, so a regression is named rather than absorbed in a total. Only language/ and core/ are swept: library/, optional/ and security/ are not run, so this is not a percentage of Ruby. Those guards now resolve at Ruby 4.0.9 — the version this runtime reports, and the latest MRI release — so the examples behind a ruby_version_is "4.0" guard are counted, and those behind ruby_version_is ""..."4.0" are no longer asked for. The move was measured before it was made, both engines built from one commit minus the version string: +144 passing, and 27 examples that went red — a figure no pass total shows, found by comparing the two runs' failure descriptions. Front-end: ~100% of valid Ruby parsed across Rails + Puppet (2026-06).

+
✅

Conformance, measured

23,672 ruby/spec language/ + core/ examples pass, gated in CI file by file: no spec file may pass fewer examples than its recorded row, so a regression is named rather than absorbed in a total. Only language/ and core/ are swept: library/, optional/ and security/ are not run, so this is not a percentage of Ruby. Those guards now resolve at Ruby 4.0.9 — the version this runtime reports, and the latest MRI release — so the examples behind a ruby_version_is "4.0" guard are counted, and those behind ruby_version_is ""..."4.0" are no longer asked for. The move was measured before it was made, both engines built from one commit minus the version string: +144 passing, and 27 examples that went red — a figure no pass total shows, found by comparing the two runs' failure descriptions. Front-end: ~100% of valid Ruby parsed across Rails + Puppet (2026-06).

🔒

Closed-world builds

rbgo build --closed bakes the program to bytecode and drops the front-end for a smaller binary.

🌿

A real ecosystem

Built from the go-ruby-* family — each a 100%-coverage, 6-arch stdlib module, bound natively.

@@ -68,7 +68,7 @@

Everything a Ruby runtime gives you — as a Go library.

8.7×
rbgo+AOT vs MRI+YJIT, tight-loop benchmark (2.0× on fib(35))
-
23,673
ruby/spec language/+core/ examples passing · gated per file, not by a total
+
23,672
ruby/spec language/+core/ examples passing · gated per file, not by a total
178
go-ruby-* modules bound into rbgo
CGO=0
across 6 arches · 3 OSes
From 91fa48f8b8dca2fbf385bbbe77071e297d33c084 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Wed, 4 Nov 2026 13:07:34 +0100 Subject: [PATCH 3/3] Pin the figure gate to v0.7.0, which can see one more line of this page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v0.6.0's vocabulary spelled out "the sum is", "its sum is" and "whose sum is", so this page's "The sum of those rows is 23,673" was never a candidate. The lane printed "5 total claim(s) checked" and passed, on a page holding six, one of them stale. go-embedded-ruby/docs#44 widened the pattern; v0.7.0 carries it. Run with the exact published command this lane runs, fetched through the proxy against this tree: $ go run github.com/go-embedded-ruby/docs/tools/conformancefigure@v0.7.0 --root . go: downloading github.com/go-embedded-ruby/docs v0.7.0 6 total claim(s) and 1 version claim(s) checked against the gate's 23672 at Ruby 4.0.9 (derived from RUBY_VERSION) Six, not five, and no disagreement. The other number that moved was already predicted in the comment this replaces: "1 version claim … derived from RUBY_VERSION" is go-embedded-ruby/ruby#845 collapsing the two copies of the version into one, and nothing on the page had to change for it. Co-Authored-By: Claude Opus 5 --- .github/workflows/deploy-pages.yml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index 25ac87f..2a16eb9 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -118,14 +118,23 @@ jobs: # Verified with the exact published command this lane runs, fetched # through the proxy: # - # $ go run github.com/go-embedded-ruby/docs/tools/conformancefigure@v0.6.0 --root . - # 5 total claim(s) and 2 version claim(s) checked against the gate's 23511 at Ruby 3.4.1 (two copies, agreeing) + # $ go run github.com/go-embedded-ruby/docs/tools/conformancefigure@v0.7.0 --root . + # 6 total claim(s) and 1 version claim(s) checked against the gate's 23672 at Ruby 4.0.9 (derived from RUBY_VERSION) # - # "two copies, agreeing" is the interpreter repository's state today; - # go-embedded-ruby/ruby#845 collapses it to one and the same line will - # then read "derived from RUBY_VERSION", with nothing here to change. + # Two numbers in that line moved for reasons worth keeping apart. "1 + # version claim … derived from RUBY_VERSION" is what the earlier comment + # here predicted: go-embedded-ruby/ruby#845 collapsed the two copies of + # the version into one, and nothing on this page had to change. + # + # SIX total claims, where v0.6.0 counted five, is a defect that version + # could not report. Its vocabulary spelled out "the sum is", "its sum is" + # and "whose sum is", so "The sum of those rows is 23,673" in + # layouts/_default/list.html was never a candidate: the lane printed "5 + # checked" and passed while that line held a stale figure. v0.7.0 reads + # it. Keep this pin moving forward -- a gate pinned to a version that + # cannot see a line is indistinguishable from a page with nothing wrong. - name: The stated conformance total, and the version it was counted at, match rbgo's gate - run: go run github.com/go-embedded-ruby/docs/tools/conformancefigure@v0.6.0 --root . + run: go run github.com/go-embedded-ruby/docs/tools/conformancefigure@v0.7.0 --root . - name: Build landing page run: hugo --minify --baseURL "${{ steps.pages.outputs.base_url }}/"