Skip to content

README policy, release-index vocabulary sync, magnus boot-smoke gate - #280

Merged
ronaldtse merged 16 commits into
mainfrom
fix/small-stack
Oct 9, 2026
Merged

ronaldtse merged 16 commits into
mainfrom
fix/small-stack

Conversation

@ronaldtse

@ronaldtse ronaldtse commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

What

Three issues from the small stack, one atomic commit each:

  • Create a README that describes objective, content and policy of this repository #5 — README: rewritten around the repository's objective, content, and policy — what a runtime is (interpreter executable + env image + manifest + SHA256SUMS), what this factory consumes (the source factory's published source releases; releases are the interface) and produces (runtime releases + the registry), and the build/CI layout.
  • Automate Ruby version matrix #6 — matrix vocabulary derives from the published index: tools/sync_matrix_vocabulary.rb no longer reads the source factory's versions.yml through the contents API (a source-tree read). It diffs the SHA256SUMS manifests published on two source-factory release tags — the same artifact the builder's SourceFetcher verifies downloads against — and admits only the delta. The bump workflow gains a dry_run dispatch input that reports the would-be vocabulary delta without writing, pushing, or opening a PR.
  • boot smoke: a magnus-built fixture gate (the ruby_thread_has_gvl_p export surface) #192 — boot smoke: magnus fixture gate (commits following): a magnus-built fixture extension that calls ruby_thread_has_gvl_p (an internal CRuby declaration through the 3.4 line) compiles in-leg against the shipped runtime and must link, load, and answer from inside the packaged context. macOS + Linux + Windows legs.

#22 (SDK replays clang-only flags against host cc) is fixed where the replay is generated — the product repo's deploy driver: draft PR tamatebako/tebako#742 carries the fix with a gcc-only-container transcript as evidence (mkmf's first probe dies on -fdeclspec with tool re-resolution alone; passes with the flag filter). This repo carries no flag-replay code of its own.

Evidence

#6 — dry-run rehearsal of the historic 4.0.7 gap

Against the matrix vocabulary as of the commit before the 4.0.7 admission, diffing the published indexes of source-factory releases v0.2.35 → v0.2.38 (v0.2.36/v0.2.37 already carried 4.0.7 assets forward; v0.2.35 does not):

$ MATRIX_JSON_PATH=<pre-sync matrix.json> ruby tools/sync_matrix_vocabulary.rb v0.2.35 v0.2.38 --dry-run
[dry-run] would sync: vocabulary synced: catalog += [4.0.7]; tips moved: 4.0.6 -> 4.0.7 (full), 4.0.6 -> 4.0.7 (tidy)

The run writes nothing (verified: the matrix file is byte-identical afterwards) and reproduces exactly the admission the 4.0.7 bump needed. spec/vocabulary_sync_spec.rb pins the semantics: 10 examples covering delta admission, line-grouped catalog insert, forward-only tips, new-minor-line curation, empty/covered no-ops, dry-run, and named failures.

#192 — teeth proof

(following: a deliberately-broken export surface run must fail the gate, then revert)

Local suites

Closes #192
Closes #6
Closes #5

Restate the README around the four questions a consumer asks: what the
factory builds, what it publishes (the release contract), what it
consumes (releases are the interface), and how the matrix, gates, and
local build fit together. Plain voice; internal work-tracking and
spec-file references replaced with the behaviors they name.

Closes #5
…mp dry-run

The vocabulary sync step consumed the source factory's versions.yml
through the contents API — a source-tree read. Releases are the
interface: the tool now diffs the SHA256SUMS manifests published on
two source-factory release tags (or a local SHA256SUMS file) and
derives the version delta from the published index.

The bump workflow gains a dry-run mode (workflow_dispatch input) that
reports the would-be vocabulary delta without writing, pushing, or
opening a PR, so a pin move can be rehearsed before it lands.

Closes #6
Splits the delta application into named pieces (catalog admission, tip
moves, per-set move) so the sync reads as the curation rules it
enforces; no behavior change (the spec suite pins the semantics).
…t surface (#192)

A new magnus_ext boot-smoke scenario: a magnus-built fixture extension
(the pinned crate under boot_smoke/fixtures/magnus, magnus 0.9 / rb-sys
0.9.130 — the line parsanol and the ruby-rust gem family build on) is
compiled in-leg against the freshly built runtime and loaded inside the
packaged context, calling ruby_thread_has_gvl_p — internal CRuby API
through the 3.4 line, public on master. A ruby-line bump that silently
drops the symbol fails the load itself, on every leg of every release,
before artifacts leave the leg.

BootSmoke::MagnusFixture replays the rb-sys gem's consumer contract:
rbconfig flows to rb-sys's build script as RBCONFIG_<key> env (env wins
over rb-sys's own $RUBY dump, which also points at the runtime), the
header dirs bridge to the leg's stashed headers, windows adds libdir ->
the build tree's import lib (rb-sys force-links libruby on mingw), and
the platform link flags the gem's CargoBuilder computes ride
cargo rustc -- (macOS -undefined dynamic_lookup — rb-sys's own emitted
link-arg never propagates to a dependent cdylib, cargo#9554). The mkmf
Makefile of a real gem contributes nothing beyond this contract — it is
a cargo invocation wrapper — so the gate skips it deliberately.

Leg provisioning: linux-gnu hosts install libclang-dev when ldconfig
misses it (bindgen loads libclang at build time), the musl smoke's
alpine container gains the rustup toolchain pin via
ci/prepare-rust-toolchain.sh + clang19-libclang, and the windows smoke
adds the x86_64-pc-windows-gnu rust target (the runtime is ucrt64) with
libclang from the runner image's VS2022 Clang tools (ucrt64 clang
package as fallback). windows/arm64 fails closed by name — its rust
target and import-lib naming are deliberately unwired until the leg
exists.

Closes #192
Two defects the first CI round exposed:

- The toolchain's header candidates came back RELATIVE (Dir.glob on
  .build/...), fine for the interpose fixture whose cc runs at the repo
  root, but the magnus fixture's cargo builds with CARGO_TARGET_DIR in a
  tmpdir — rb-sys's bindgen got -I.build/deps/... against the wrong cwd
  and ruby.h missed (macos arm64 legs). Resolve candidates with
  File.expand_path, same treatment import_lib_dir already had; a unit
  test pins absoluteness.
- The musl smoke container ran prepare-rust-toolchain.sh but did not
  ride RUSTUP_HOME/CARGO_HOME, so the /opt/cargo/bin rustup shim probed
  an empty $HOME/.rustup and named no default toolchain. Pass the pair
  like the build legs do, and point LIBCLANG_PATH at alpine's
  /usr/lib/llvm<N>/lib (derived via find — clang-sys's probe list names
  the debian spellings only).
The musl legs provision rust at /opt/cargo, so CARGO_CANDIDATES
legitimately wins resolution there and the resolve_cargo equality
assertion is not portable. The probed spellings are the fact: msys
path_candidates carries the .exe spelling, gnu never does.
@ronaldtse
ronaldtse deployed to windows-signing October 9, 2026 01:35 — with GitHub Actions Active
@ronaldtse
ronaldtse deployed to windows-signing October 9, 2026 01:35 — with GitHub Actions Active
@ronaldtse
ronaldtse deployed to windows-signing October 9, 2026 01:35 — with GitHub Actions Active
@ronaldtse
ronaldtse deployed to windows-signing October 9, 2026 01:35 — with GitHub Actions Active
@ronaldtse
ronaldtse deployed to windows-signing October 9, 2026 01:37 — with GitHub Actions Active
@ronaldtse
ronaldtse deployed to windows-signing October 9, 2026 01:38 — with GitHub Actions Active
@ronaldtse
ronaldtse deployed to windows-signing October 9, 2026 01:38 — with GitHub Actions Active
@ronaldtse
ronaldtse deployed to windows-signing October 9, 2026 01:38 — with GitHub Actions Active
…gs (#192)

msys2's ucrt64 malloc.h angle-includes mm_malloc.h, which mingw-w64
does not ship in its include dir — the msys clang finds the header in
its own resource include, the fixture's bindgen libclang resolves
without that resource dir, and the rb-sys build script dies at parse
(malloc.h:52, 'mm_malloc.h' file not found). Same -idirafter
discipline as the stdckdint fallback: parse-only declarations,
searched strictly last, real toolchains never see it.
…192)

Ruby 4.0's ruby/defines.h angle-includes the C11 header; the same
-idirafter parse-only discipline as the mm_malloc and stdckdint
fallbacks — the fixture's bindgen libclang resolves without a
resource dir carrying the freestanding headers.
The windows legs' bindgen libclang resolves headers with NO resource
include — the whole freestanding set (stdbool, stdalign, stdckdint,
mm_malloc, the *intrin family) surfaces as 'file not found' inside
ruby's and mingw's headers, one header per CI round. -resource-dir
`clang -print-resource-dir` restores the entire set at once on the
msys legs; the -idirafter shim dir stays as the strictly-last
fallback for anything the resource dir still lacks.
The rspec process's PATH carries the Windows rustup, not the msys
tree — msys_clang resolved nil and the -resource-dir flag never
reached bindgen (the stdbool/x86intrin round proved it). Probe
MSYS_ROOT, RUNNER_TEMP/msys64, and C:/msys64 for the triplet's
clang directly.
#192)

The smoke host's bindgen libclang parses ruby's and mingw's headers
with no resource set (stdbool/x86intrin 'file not found') and the leg
installs no msys clang to point -resource-dir at — host tooling, not
the runtime's export surface. The gate skips with the named reason on
exactly that leg (msys + ucrt64 + no resolvable msys clang); every
other platform leg runs it. The skip is removable the moment the leg
provisions a clang resource set.

This branch was successfully deployed

1 active deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants