Skip to content

ARCHITECTURE · 01

Concepts.

The pieces every other page in this section builds on: the three-part package format, the three press modes, the machine-wide runtime cache, and the two distinct moments at which a runtime gets resolved.

HOW TO READ THIS SECTION:SHIPPEDreleased and downloadable today — every claim links its artifactPLANNEDlocked design, not yet shipped

The three-part package.

SHIPPED

Every modern tebako product is a composition of three independently distributable parts — a bootstrap launcher, a language runtime, and one or more filesystem images — glued together by a manifest trailer appended to the end of the file. The definition lives in the tebako-bootstrap README.

byte 0 →→ EOFA · Bootstraptebako-bootstrap32 KB – 908 KBthe executable partC · Image slot 0.tfs image — the applicationdwarfs / squashfs / zipmounted at run timeC · Image slot 1…7optional extra imagesdata, assets, …multi-mount, own mount pointB · Runtime payloadfat packages onlyformat_id = TPKG_FORMAT_RUNTIMEinstalled, never mountedtpkg trailer166 B header at EOF+ slot records (280 B each)magic · CRC · runtime_reflean = A + C + trailer · fat = A + B + C + trailer · classic = runtime and image stitched into one binary (no bootstrap, no trailer)

PART A

Bootstrap

A tiny C99 launcher — no libtfs, no dependencies beyond the C runtime. It parses the trailer of its own executable, resolves the runtime into the shared cache (cache → embedded payload → download), and execs it. v0.2.0 ships six platform binaries, 32 KB (macos-x86_64) to 908 KB (linux-gnu-x86_64).

PART B

Language runtime

A patched Ruby plus the tebako entry driver and libtfs, built and published by tebako-runtime-ruby — v0.15.9 carries 114 packages (19 rubies × 6 POSIX platforms) plus a manifest.json index. Lean packages download it on first run; fat packages carry it as a payload slot and install it offline.

PART C

Data image(s)

.tfs filesystem images — the application tree, gems, extra data — created in-process via the dwarfs-t Writer binding (mkdwarfs remains the human-facing tool) and embedded as trailer-described slots. The runtime mounts each slot straight out of the package file: no extraction, no temp copies. The runtime's own files ship as a .tfs too — see runtime as image.

The tpkg trailer.

SHIPPED · format v1

The trailer is the byte-level contract of the whole stack. It is defined once — include/tebako/tpkg.h in libtfs — and vendored byte-for-byte into tebako-bootstrap. The reader checks magic and CRC, then walks the slot table backwards from EOF. A signed v2 extension (per-slot sha256 + OpenPGP signature, flagged — the version field stays 1) now exists in tebako-rs: see the chain of trust.

OFFSETBYTESFIELDMEANING
010magic"TEBAKOTFS\0" — absent-vs-corrupt is told apart by the "TEBA" prefix
104versiontpkg format version (currently 1)
144package_flagsbit 0 = TPKG_FLAG_LEAN (three-part package; unset = classic bundle)
184slot_count1–8 slots (TPKG_MAX_SLOTS)
30128runtime_ref"<type>@<version>;tebako=<abi>", e.g. ruby@3.3.7;tebako=0.15.0 — fat appends ;sha256=<hex>
1584launcher_abilauncher ABI the package requires (currently 1)
1624header_crc32CRC32 over header bytes [0, 162)

Each slot record (280 bytes) carries the image's offset and size inside the package file, a format_id (0 auto · 1 dwarfs · 2 squashfs · 3 zip · 4 runtime payload) and its mount point. Corrupt magic or CRC is a hard startup error — never partial behavior.

Press modes.

SHIPPED

tebako press from the tebako gem produces all three package shapes (the Rust tebako-cli presses lean/fat with golden byte-parity). See the manual for the full CLI reference.

Lean default

Bootstrap + image slot(s) + trailer (TPKG_FLAG_LEAN, runtime_ref filled). The smallest download; the first run resolves the runtime into the shared cache.

Fat

A lean package that additionally carries the runtime itself as a payload slot. First run installs the payload into the shared cache — SHA256-verified — so fat packages never touch the network.

Classic

The application image stitched onto a prebuilt runtime: one monolithic binary, no bootstrap, no trailer. The original tebako package shape, fully supported.

The shared runtime cache.

SHIPPED

Runtimes are installed once per machine, not once per package. The cache root is $TEBAKO_HOME (default ~/.tebako, %LOCALAPPDATA%\tebako on Windows), with entries of the form runtimes/<type>-<version>-<tebakoabi>-<platform>/. Installs are atomic (build in tmp/, then rename) and guarded by per-entry locks, so concurrent first runs of many tebako packages are safe and partial installs are impossible. Every tebako package on the machine — gem-pressed or not — shares the same cache.

The image-era form. With the runtime-as-image split, an entry holds immutable artifacts and their trusted markers only: the interpreter, the .tfs image (read-only, 0444), and .sha256/.origin markers proving it was verified at install. No extracted layout/ tree lives in the cache anymore — when the press side needs the runtime's files it extracts the image in-process, per press, into the build prefix. The marker is the trust anchor: re-verify on re-fetch, never per run.

Press-time vs run-time resolution.

Two different actors can fetch a runtime, at two different moments. They are kept deliberately distinct — conflating them is a locked-off design error.

PRESS-TIME · PACKAGER SIDE

The gem (and later the Rust CLI) downloads the runtime into the shared cache while packaging — needed for classic stitching and for running bundler under the target runtime. Resolution reads the runtime release's manifest.json.

RUN-TIME · BOOTSTRAP SIDE

The bootstrap resolves the runtime when the packaged binary is run: cache hit → exec; fat payload → verify + install; otherwise download from the runtime release. TEBAKO_OFFLINE=1 forces cache-only mode; TEBAKO_RUNTIME_MIRROR redirects downloads.

The launcher ABI.

SHIPPED · v1

The bootstrap never mounts anything — it hands the image slots to the runtime by reference. The handoff is versioned (currently v1) and specified in the gem's launcher_abi.rb, with matching constants in the runtime entry driver:

<runtime> --tebako-image <file>:<slot>:<mount-point> … \
          --tebako-entry <original-argv0> <user args…>

One --tebako-image per image slot (runtime payload slots are never handed over). Parsers split on the last two colons, so Windows drive letters in paths are safe. A package whose launcher_abi exceeds what the runtime supports is refused, naming both versions.