Skip to content

ARCHITECTURE · 22

The repository map.

The ecosystem is a fleet of small repositories, each owning one artifact and one contract. They consume each other's published releases, never source trees, so every repository builds its own platforms and publishes its own releases. Retired repositories stay readable, and oracle repositories stay frozen; neither is a graveyard.

The map

REPO ROLE STATE

tebako

This is the product: the Rust workspace and nothing else, namely the five shipped binaries (tebako, tfs, tebako-pkg, tebako-shim, tebako-bootstrap) plus every library crate behind them — wire format, VFS, resolver, driver, signer. It publishes its own per-platform releases across seven triplets, and from v2.8.13 it also publishes the windows-arm64 authoring tools and link unit on the eighth triplet of the axis.

Product — releases ship

ruby

This is the source factory: canonical ruby patches and versions.yml, with every upstream fetch sha256-verified, plus a daily monitor that onboards new ruby-lang.org releases or files a named drift issue. It publishes tfs-ruby-<ver>-src[-<scenario>].tar.gz + SHA256SUMS. The repo is Ruby tooling around vendored upstream C, and the patches are the only tebako-specific C consumers.

Factory — active

tebako-runtime-ruby

This is the runtime factory: it builds the patched source per (ruby version × triplet), boot-smokes each built runtime, and publishes the two runtime artifacts, the interpreter exe and the env .tfs image, with manifest.json + SHA256SUMS. It consumes only the source factory’s releases.

Factory — active

tebako-runtime-python

This is the runtime factory for CPython, including the experimental jit flavor lines. It publishes interpreter exe + env .tfs per (version, flavor, triplet) with signed manifests.

Factory — active

tebako-runtime-jruby

This is the runtime factory for JRuby: one universal env image composed on the OpenJDK owner, a runtime stacked on a runtime.

Factory — active

tebako-runtime-truffleruby

This is the runtime factory for TruffleRuby in native and jvm modes.

Factory — active

tebako-runtime-openjdk

This is the runtime factory for OpenJDK (Temurin JRE and GraalVM editions), the hermetic java that the composed runtimes sit on.

Factory — active

dwarfs-t

This is the only tebako-owned C++: the DwarFS-T image format library (FlatBuffers metadata, which upstream dwarfs cannot read) behind the dwarfs_c_* C ABI. It is read-only at runtime forever, and the writer exists at creation time only. It is never archived; it is the foundation, not a legacy repo.

Foundation — active

dwarfs-t-rs

This is the standalone Rust binding to dwarfs-t: the safe crate (reader + in-process writer) over the hand-pinned FFI sys crate. It is not tebako-specific, and the product consumes it as an ordinary external dependency.

Foundation — active

tebako-ci-containers

This repo provides the Docker toolchain images that the factories build in.

Tooling — active

tebako.org

This site hosts the docs, the blog, and the trust-anchor publication point.

Site — active

tebako-packages/*

This is the feedstock org on the conda-forge model: one repo per package (recipe + patch sets + manifest templates + CI), each owning its own release line. A feedstock’s releases host its payload artifacts and its tpkg-registry.yaml, and the index repo is the registry-of-registries behind tebako add-registry.

Org — active

tebako-v1

This is the C/gem era, frozen: the gem press, the C tebako-main driver, and the merged env+app image model. It is kept readable as the behavioral reference and the history. Nothing new lands there.

Retired

libtfs

This is the C++ tebako_fs_* engine that the Rust tfs crate superseded. It gains no new features; it stays because product CI still downloads its released binaries (tebakofs, mkdwarfs) as the golden-parity oracle.

Oracle — maintenance

tebako-bootstrap

This is the C99 v1 launcher, under the same arrangement: frozen, and still downloaded by product CI as the Rust bootstrap’s behavioral oracle and the printed size baseline.

Oracle — maintenance

Also in the tamatebako org, outside the stack itself: tebako-samples (packaging tutorials), fmem (a v1-era libc-streams dependency the modern stack no longer consumes), and aibika (a separate Windows Ruby application packager — not part of tebako).

The product repository

Note

The product is shipped as v2.8.x, five binaries across seven triplets, with the windows-arm64 authoring tools (tfs and tebako-pkg) and the aarch64 link unit joining from v2.8.13.

tamatebako/tebako is one Rust workspace and the whole product: no C/C++, no shell-outs, no system dependencies in anything it ships. Each release publishes the five binaries — tebako, tfs, tebako-pkg, tebako-shim, tebako-bootstrap — for macOS arm64/x86_64, linux-gnu x86_64/arm64, linux-musl x86_64/arm64, and windows ucrt64, with SHA256SUMS + manifest.json; from v2.8.13 the release additionally carries tfs, tebako-pkg, and the link unit for windows arm64 (ucrt). Every leg proves its staged binaries before any upload: a bare launch in the cleanest environment the leg claims, plus a hard dynamic-dependency whitelist audit (release.yml).

This point is stated plainly: every checksum bundle and manifest ships with a detached OpenPGP signature (the release trust chain, live since tebako v2.6.0); a release that is still rolling out platform by platform stays unsigned until it is complete, and unsigned releases remain first-class. The brew formula tracks the same five binaries.

The crate map

The wire

  • tpkg — the tpkg trailer and manifest format: it parses, serializes, and validates. The crate is the single source of truth for the wire format, with #![forbid(unsafe_code)].

  • tebako-json — minimal exact-format JSON: a writer plus a small parser, with no serde.

  • tebako-log — the stack’s one debug facility: TEBAKO_DEBUG levels, stderr/file sinks, and component filters.

The VFS

  • tfs — libtfs-rs: the tebako_fs_* C ABI in Rust (cdylib/staticlib). It is the shipping TFS implementation, and the C++ libtfs is its parity oracle.

  • sqfs-sys — hand-pinned FFI to libsquashfs (squashfs-tools-ng), with the same discipline as dwarfs-t-sys.

  • libtfs-preload — the preload interposition shim: DYLD_INSERT_LIBRARIES / LD_PRELOAD VFS injection for dynamic native binaries.

The CLI surface (four of the five binaries)

  • tebako-cli — the tebako binary: press / run / install / publish / check / trace / cache / info.

  • tfs-cli — the tfs binary: the generic VFS image tool, with info / ls / tree / cat / extract / find / mkimage / exec.

  • tebako-pkg — tpkg trailer surgery: bundle / unbundle / insert-image / set-runtime / sign / verify / validate / info.

  • tebako-shim — the dispatcher and version manager: argv0 resolution, the version chain, runtime resolution, and the handoff.

Load time

  • tebako-bootstrap — the Rust loader: the fifth binary and the process entry point of every stitched package. It is size-gated, below.

  • tebako-driver — the driver linked inside every runtime exe: it mounts the env image
    payload images, applies the jail, and rewrites argv. It is the Rust successor of the v1 C++ tebako-main.

Shared plumbing

  • tebako-resolve — MECE payload references, transport-agnostic fetchers, and the shared payload cache.

  • tebako-http — in-process HTTPS, with ureq + rustls and webpki-roots bundled. There is no curl anywhere.

  • tebako-signer — OpenPGP sign/verify via rnp-rs, vendored, with no system librnp provisioning.

  • tebako-info — the info/inspect surface: payload and package introspection as JSON documents.

  • tebako-term — terminal progress: TTY detect, a hand-rolled ANSI bar/spinner, and zero dependencies.

  • tebako-arscope — scopes Rust staticlib symbols for single-link embedding (the yjit-collision seal); it is pure Rust with no shell-outs.

Beside the workspace, not in it: dwarfs-t-rs, the standalone Rust binding to dwarfs-t — consumed as an ordinary external dependency, tracking dwarfs-t releases. dwarfs-t itself stays C++ forever; the dwarfs_c_* C ABI is the only Rust-consumable surface.

The bootstrap size gate

Note

The size gate is shipped, with a hard fail at or above 3 MB.

The bootstrap is the process entry point of every stitched package, so its size is a hard CI gate rather than a nice-to-have. Every CI run builds the release bootstrap per platform, prints it next to the C99 v0.2.0 baseline, and fails at 3,145,728 bytes. The discipline that keeps it there is opt-level="z", fat LTO, one codegen unit, panic="abort", and stripped symbols, with no async runtime, no clap, and no logging framework. The budget moved as the feature set did, and the moves are on record rather than swept under:

ERA GATE MEASURED

C99 bootstrap v0.2.0 — the baseline, six platform binaries

—

32,512–908,112 B

Rust bootstrap ships, downloads via curl

< 2 MB

371,776 B (macOS arm64)

Downloads go in-process (tebako-http)

< 3 MB — owner-raised when curl was dropped

1,238,384 B macOS arm64 · 1,664,336 B ubuntu (+867 KB of TLS stack)

Full static botan ships in the bootstrap

< 6 MB — temporary, owner 2026-07-27

—

Today — crypto feature-gated OUT of the shipped bootstrap (unverified-first)

< 3 MB, hard fail

per-platform table on every CI run, printed next to the C99 baseline

The in-process-downloads step and its byte counts are recorded in the M7a commit; the C99 baseline numbers are the published v0.2.0 release assets.

The golden-parity discipline

The order is law: if a C++ or gem predecessor exists, golden vectors and fixtures are generated from it first, because without an oracle there is no parity claim. Then the ported corpus runs unchanged against the Rust implementation, and the parity legs diff byte-for-byte. That is not a README promise; it is what CI does on every run:

  • CI downloads the C++ oracle binaries — tebakofs and mkdwarfs from libtfs v0.13.0, and the C99 bootstrap v0.2.0 — and diffs tebako-pkg / tfs-cli / tebako-bootstrap behavior against them byte-for-byte.

  • tebako-cli’s golden e2e presses side-by-side with the reference gem: same fixture, same prefix — the press stdout and the packaged binaries' output are diffed.

  • The C++ libtfs test corpus, ported to run through the Rust C ABI, lives in tests/contract; docs/parity.md is the audit of what was ported and why.

  • An exported-symbol audit passes only when nothing but the tebako_* surface leaks.

  • Anything ported from a C++/gem predecessor is byte-compared, or the deviation is documented. A mismatch means the contract moved, and both sides must move together.

This is why the two oracle repositories are not archived: the parity claim needs the oracle to exist. libtfs and the C99 bootstrap get no new features; they stay frozen, citable, and downloaded by the product’s own CI.

What retired: tebako-v1

The whole v1 implementation (the gem press, the C99 bootstrap as the shipped product, the C++ driver, and the merged env+app image model) is frozen in tebako-v1. It stays readable: it is the behavioral reference against which the parity story is proven, and the history of why v2 looks the way it does. Nothing new lands there. The piece-by-piece succession follows:

V1 (RETIRED) V2 (SHIPPING)

the tebako gem (press orchestrator)

crates/tebako-cli

the C99 bootstrap

crates/tebako-bootstrap

C++ libtfs (shipping VFS)

crates/tfs

the C++ tebako-main driver

crates/tebako-driver (linked into the runtime)

The lifecycle rules

Contracts outlive implementations

The tebako_fs_* ABI and the tpkg trailer are byte-level contracts. Consumers do not care which repository ships them; that is what let the Rust reimplementation ship without a flag day, and it is why the C++ side still matters as the oracle.

Releases are the interface

Repos consume each other’s published releases, never source trees. The factories and the product live in different repos with separate cadences, and the manifest.json contract sits between them, so the packager never hardcodes a runtime matrix.

C++ appears exactly once

dwarfs-t is the only tebako-owned C++ (upstream ruby’s own C is vendored upstream source, built in the two factories). Everything else is Rust, pure Ruby tooling, or Docker, with no exceptions and no "temporary" ports.

dwarfs-t is not legacy

A Rust DwarFS reader/writer is explicitly out of scope. dwarfs-t is read-only at runtime forever, with the writer at creation time only; the only Rust-consumable surface is the C ABI, co-versioned with the C++ it wraps, which is what dwarfs-t-rs binds.