SpinelKit
The Spinel stdlib-surface gem. A pure-Ruby, Spinel-safe toolkit holding the generic "stdlib substitute" shims that every Spinel-compiled project would otherwise hand-roll.
Spinel is a Ruby→native AOT compiler. It
cannot lower large chunks of the CRuby standard library — the json gem's
C-extension fast path and its metaprogrammed pure-Ruby fallback, stdlib
Logger, C-extension git bindings, and more. So every Spinel project re-derives
the same shims. toy and
tep grew theirs independently, and the
JSON escape/quote/hex code came out byte-identical. SpinelKit is that code,
consolidated once.
Installation
gem install spinel_kit
Or in a Gemfile:
gem "spinel_kit"
Pure Ruby, no native extension, no runtime dependencies — so it also vendors cleanly into a Spinel build via bundler-spinel.
Why a gem instead of reusing one?
The first thing we did was audit the
spinelgems compatibility catalog
(verdict ladder: verified > loaded > clean > risky > rejected) for an existing
gem to reuse — that would have been the biggest win. There wasn't one. These
shims are the ecosystem's gaps:
| Surface | Catalog finding | Decision |
|---|---|---|
| JSON | json rejected (C-ext + metaprogrammed fallback); oj risky (C-ext) |
implement |
| Log | logger rejected (unresolved calls) |
implement |
| Git | rugged rejected (C); gitkite/git_manager only clean, unmet needs: |
implement (read .git/HEAD) |
| Path | hike verified at an older rev, only loaded now; overkill for basename/join |
deferred |
| Bytes | unicode_utils/utf8-cleaner clean only; toy's need is tokenizer-specific |
deferred |
See docs/gem-audit-first.md for the full audit and
the verification-request issues we filed on spinelgems.
What's in it
require "spinel_kit" # everything (CRuby / convenience)
For a Spinel-compiled consumer, require only the surface you use — Spinel
has no tree-shaking, so every loaded method is compiled (and an uncalled one
can degrade). The Json surface is split into three files for exactly this
reason: spinel_kit/json (encoders), spinel_kit/json_decoder (decoders), and
spinel_kit/json_builder (the builder). e.g. tep requires json + json_decoder;
toy requires json_builder.
SpinelKit::Json— a JSON-over-HTTP codec: encoders (escape/quote/encode_pair_*/from_*, inspinel_kit/json) and flat-key decoders (get_str/get_int/get_float/get_int_array/has_key?, inspinel_kit/json_decoder).
SpinelKit::Json.get_int('{"age":33}', "age") # => 33
SpinelKit::Json.from_int_hash({"a" => 1, "b" => 2}) # => {"a":1,"b":2}
SpinelKit::Json::Builder— an incremental ordered-object builder (add_str/add_num/add_bool/add_raw/add_obj/dump), in its own file so a builder-only consumer never compiles the codec, and vice versa.
j = SpinelKit::Json::Builder.new
j.add_str("kind", "run_start")
j.add_num("t", 1715000000)
j.dump # => {"kind":"run_start","t":1715000000}
SpinelKit::Git— git provenance from.git/HEAD.
g = SpinelKit::Git.read
g.sha # => "a1b2c3..." (or "unknown" outside a repo)
g.branch # => "main"
SpinelKit::Log— a minimal levelled logger (CRubyLoggerdoesn't compile under Spinel).
log = SpinelKit::Log.new
log.set_level("info")
log.info("server up")
Design constraints (read before editing)
SpinelKit is pure Ruby, no native extension (spinel-ext.json is []) and
has no runtime dependencies, so it vendors cleanly via bundler-spinel. The
surface uses plain, standard names; the j_/tj_/gi_ prefixes the donor
copies carried were a workaround for a Spinel whole-program-inference bug that
has since been fixed upstream (verified with toy's gate-poly-degrade on the
current compiler). One numeric caveat remains for add_num — see
docs/spinel-discipline.md.
Status
Pre-alpha (0.1.0). The shims are implemented, CRuby-verified, and the surface
is the single canonical one (the donor prefixes and duplicated escapers are
gone — the Spinel inference bug that motivated them is fixed). Consumer adoption
is the next phase: because we author every repo in this set, tep and toy
migrate to SpinelKit::* directly and delete their donor modules — we
standardize and clean rather than leave compatibility aliases behind. See
docs/adoption.md. Tracking issue:
OriPekelman/toy#44.
Development
rake test # CRuby-side parity tests (never compiled)
rake rbs:validate # syntax-check the advisory RBS in sig/
gem build spinel_kit.gemspec
MIT licensed.