Release v2.8.78 closes the jail's last open boundary — an unplanned child process on Windows now inherits the jail's verdict as a refusal, not an escape — and completes the shim ladder's install-time half, so a package claims exactly the command names its operator allows, at exactly the position on the path its operator chooses. A bare press in a Python project directory now works the way the Node.js and Ruby presses already did.
Release v2.8.76 stops paying macOS's first-seen malware scan on every launch of a packaged app. Native extensions now materialize to a stable, content-segregated path, so the scan prices once per image build — and a silent failure class in native-extension builds is fixed in the same release.
Release v2.8.75 teaches the shim layer to free a command name without disabling its dispatch, proves the jail against Windows alternate data streams, rides out minute-scale network flaps on every fetch, and closes the documentation drift the interoperability audit found.
Release v2.8.74 seals a lazily fetched runtime into a bundle before packing, so an air-gapped machine never meets a descriptor without its bytes; materializes an in-image working directory for a spawned child; and teaches the runtime-owning commands to warn before shadowing a tool the machine already has.
Release v2.8.73 corrects one constant in the macOS loader-interposition gate, restoring class-L coverage for signed runtimes on macOS 15, and proves that one dispatch composes a payload and a runtime fetched through two different registry channels.
Release v2.8.64 interposes the raw syscall entry, because two runtimes reach the file system without passing through a single interposable symbol. On Linux that made every mounted file answer ENOENT to stat, while the mount itself was armed and readable.
Release v2.8.63 settles how the wrapper hands an entry to its interpreter. Two defects sat on that one surface: a script entry was copied out of the image, so its relative includes found nothing, and the close of a descriptor opened through the mount never reached the shim on arm64. Both were found by a factory smoke rather than by our own tests.
Release v2.8.62 teaches the composition path two facts it needed about links: a declared command whose link resolves to the interpreter takes the direct form, which is what bun's `bunx` required, and a link entry keeps its virtual spelling under preload, which is what node's `npm` required on macOS. Both defects were found by a factory smoke rather than by a test of ours.
Release v2.8.61 makes a declared runtime entrypoint compose through the interpreter that runs it instead of being executed as a program, which is what `tebako run node:npm` required; it adds the host-guard predicate that reports whether the installed policy judges a path outside every mount, which is the product half of the jail defect filed as tebako#917, together with the working-directory anchor a relative path needs at the interface entry; it prunes DWARF bundles before the strip pass on macOS; and it makes the release pipeline dispatch the benchmark suite itself.
Release v2.8.60 makes a symlink inside a payload image readable through the C ABI, so a mounted link behaves as a link for every interpreter and every libc caller. The same release makes the interposed realpath answer a canonical target, teaches tebako doctor to probe a lock instead of assuming it is stale, lets a re-press reuse the cached runtime layout, and adds the release gate that refuses a tag cut from a red commit.
The tebako packaging and loading ecosystem now presses a full Rails application on Windows, compiles its native extensions from source against the packaged runtime, and boots the result as a single executable. This post records what shipped, the twelve defect layers the work separated, and the instruments the chain left behind.
v2.8.9 has paired with the 0.16.25 runtime factory to make ruby 4.0 a first-class tebako target: one payload version can ship per interpreter line, the user picks the line with one pin, extension slices bind to the exact line they were built against, and windows runtimes whose files the OS loader must see gain the materialize boot tier.
v2.8.2 is the operability release: a doctor verb that diagnoses the store end to end, payloads that trust the corporate proxy's CA without a rebuild, offline bundles and signed system installers, and a release pipeline in which one broken platform no longer blocks the rest.
The architecture series ended with trust as a concept; this week it became a feature set. Every tebako release asset has been OpenPGP-signed, the CLI carries the tamatebako root key, and a signed payload has verified on a fresh machine with zero key registration — demonstrated, not merely described.
The Python runtime line has received the same instruments as the Ruby line: CPython 3.13.15 and 3.14.7, plain and JIT-flavored, on synthetic kernels and on a real xml2rfc standards-document render, all through the real tebako dispatch path. The result mirrors Ruby's, with one difference: the 3.14 JIT flavor defaults on, and it still does not matter at the measured horizons.
The tebako project has measured five Ruby runtime arms through the real tebako dispatch path — MRI 3.3.12, MRI 4.0.6 with YJIT and ZJIT, TruffleRuby native and JVM, and JRuby on OpenJDK 25 — on synthetic kernels and on a real Metanorma document compile. The result is not a single fastest engine; the fastest engine depends on the shape of the process, and the packaging layer is where that choice belongs.
Every packaged application raises two questions: what it actually touches on the machine, and whether it actually works. The trace commands answer the first question, payload checks answer the second, and this post presents both with worked examples.
Tebako v2 has shipped. To show what its portability means in practice, a complete standards document — figures, fonts, and the Java conversion pipeline included — has been built entirely from mounted disk images, with an empty PATH and nothing on the host but tebako itself.
The Tebako project is not dead: maintenance continues under the tamatebako organization, and the recurring build breakage has been addressed at its root by removing folly and Thrift from the stack entirely.
Thanks to Brad Gessler for his Tebako blog post! Here we clarify macOS Intel build capabilities and the intended gem release workflow to help developers implement Tebako more efficiently.
Tebako 0.9.0 introduces the ability to mount host folders to memfs, providing seamless packaging support for Ruby on Rails applications. This feature helps overcome the challenge of dealing with Rails' hardcoded paths for temporary files, caches, and sockets.
Tebako now officially supports Windows, including Windows 2019, Windows 2022 targets using MinGW ucrt64, at version 0.6.0 released today. Now Tebako supports packaging for most major platforms: Linux, macOS and Windows.
Building Ruby with minimal external dependencies is a challenging task loosely supported by the community. We faced numerous issues on this path and had to resolve them creatively.
A Tebako package created from a Ruby application introduces four features that can negatively affect performance. In this post we discuss performance comparison of Tebako package and original application and show that negative impact is minimal.
The distribution of Ruby applications can be considered an unsolved problem. By itself, Ruby does not provide a consistent and easy method for setting up and running a running application.
The distribution of Ruby applications can be considered an unsolved problem. By itself, Ruby does not provide a consistent and easy method for setting up and running a complex application.
The distribution of Ruby applications can be considered an unsolved problem. By itself, Ruby does not provide a consistent and easy method for setting up and running a complex application.