Skip to content

ARCHITECTURE · 07

The factories.

This page describes how an upstream language release becomes a runtime, how a runtime becomes a package, and how a recipe becomes a payload, across a fleet of repositories that talk to each other only through published, sha256-anchored releases.

Note

Every stage on this page publishes today, and the versions and pins named are the ones in force.

The chain

Four factories and one product repo each build their own platforms and publish their own versioned releases. This is the ruby instance of the model, and the model itself is language-agnostic; a python factory would take the same shape.

ruby-lang.org official Ruby source tarballs release monitor · daily cron tamatebako/ruby source factory · patches + versions.yml → tfs-ruby-<v>-src[-<scenario>].tar.gz + SHA256SUMS v0.2.34 · 37 rubies × 4 scenarios · 149 assets release-src → pin-bump PR → dispatch tebako-runtime-ruby runtime factory · builds per version × triplet → tebako-runtime-<ver>-<lang>-<triplet>[.exe] v0.16.22 · 22 rubies × 7 triplets · 816 assets publishes the runtime release exe + env .tfs + manifest.json + SHA256SUMS keep-forever · never deleted, never replaced resolved through manifest.json — by tebako press at package build time, and by the bootstrap and shims at run time: downloaded once, verified, cached dwarfs-t — the only C++ the image format lib · FlatBuffers metadata read-only at runtime · creation-time Writer per-triplet vcpkg baselines · SHIPPED dwarfs-t-rs — Rust FFI standalone bindings · not tebako-specific the dwarfs-t crate behind crates/tfs in-process imaging · SHIPPED tamatebako/tebako the product · tpkg · tfs · cli · pkg · shim bootstrap · driver · resolve · http · signer v0.2.5 · 5 binaries × 7 triplets · size-gated pinned link unit the product CLI images the payloads tebako-ci-containers the toolchain images the factories build in · the tpkg-builder line build infrastructure · SHIPPED tebako-packages/* one feedstock repo per package release: payloads + registry, per repo hello · fontist · inkscape · metanorma Every arrow crosses a repository boundary — each stage consumes the previous stage's published release, never its source tree. Releases are the interface.

Figure 1 — The artifact chain: ruby-lang.org through the source and runtime factories to the published runtime release; dwarfs-t through dwarfs-t-rs into the product repo; the product’s link unit back into the runtime factory; feedstocks publishing payload releases.

The stages of the chain

Each row names the artifact that can be downloaded and verified today.

Stage Repo What it ships Status

Upstream

ruby-lang.org

The artifacts are the official Ruby source tarballs, the ultimate input of the whole chain.

external

Release monitor

tamatebako/ruby · release-monitor.yml

A daily cron diffs upstream releases against versions.yml and onboards new rubies (entry + patch selection + lint → PR → tag → source release → pin-bump dispatch). A failing patch files a named issue carrying the hunk output, loudly, never silently.

shipped

Source factory

tamatebako/ruby

Release v0.2.27 carries 149 assets: 37 rubies (3.1.6–4.0.6) × 4 scenario tarballs (linux-gnu unsuffixed, linux-musl, msys-pass1, msys-pass2) plus SHA256SUMS. This repo is the only place ruby patches are ever applied, and every upstream fetch is sha256-pinned in versions.yml.

shipped

Runtime factory

tebako-runtime-ruby

Release v0.16.9 carries 334 assets: 22 catalog rubies (3.1.6–4.0.6) × 7 triplets, each an interpreter exe + env .tfs (windows adds the ruby DLL), plus manifest.json (154 entries) and SHA256SUMS.txt. The factory builds the pinned source in toolchain containers, links the pinned product link unit, and boot-smokes every runtime before publish.

shipped

Format library

dwarfs-t

This repo holds the only C++ in the stack: the DwarFS-T image format (FlatBuffers metadata, which upstream dwarfs cannot read) behind the dwarfs_c_* ABI. It is read-only at runtime forever, and the writer runs at creation time only. Releases publish the pinned per-triplet vcpkg baselines that the downstream builds compile against.

shipped

FFI bindings

dwarfs-t-rs

The artifacts are standalone Rust bindings for the format library (the dwarfs-t crate), deliberately not tebako-specific. This is how the product’s tfs crate reads and writes images in-process, with no mkdwarfs shell-out, ever.

shipped

Product

tamatebako/tebako

Release v0.2.5 carries five binaries (tebako, tfs, tebako-pkg, tebako-shim, tebako-bootstrap) × 7 triplets, plus the per-triplet link units, manifest.json, and SHA256SUMS. The bootstrap is size-gated under 3 MB on every triplet, and a partial asset set fails the release outright.

shipped

Build infrastructure

tebako-ci-containers

The artifacts are the toolchain container images that the factory matrices build in, the tpkg-builder line, which takes over from the pinned v1 container tags.

shipped

Toolkit factory

tebako-packages/*

The org follows the conda-forge model: one feedstock repo per package, with recipe, patches, manifest templates, and CI. A release carries the per-triplet payload .tfs artifacts, SHA256SUMS, and the repo’s own tpkg-registry.yaml; tags are the upstream version plus a packaging revision on re-release (metanorma 1.16.9 → 1.16.9-3).

shipped

Catalog

tebako-packages/index

This repo is the registry-of-registries: one tpkg-registry.yaml listing each feedstock’s registry ref and summary. tebako add-registry tfs:github:tebako-packages/index exposes the whole catalog, and nothing is hosted centrally.

shipped

Releases are the interface

No repo consumes another repo’s source tree. Each boundary is a published, sha256-anchored release, and each consumer holds a pin it moves deliberately, never silently:

  • The runtime factory pins the source release: DEFAULT_RELEASE names a tamatebako/ruby tag (v0.2.27 today), and every source tarball is sha256-verified against that release’s SHA256SUMS. When a source release publishes, a pin-bump PR opens on its own, the full matrix runs on the PR, and nothing auto-merges.

  • The runtime factory also pins the product’s link unit: link_unit_release names the tamatebako/tebako release whose prebuilt unit (the runtime driver plus the scoped tfs closure, per triplet) the build legs download instead of compiling. The closure depends on the triplet and the product release only, never on the ruby version, so one unit serves every ruby leg on that triplet.

  • The product resolves runtimes through the release index. Press-time (the packager fetching a runtime to build against) and run-time (the bootstrap or shim fetching at first run) are different moments with different actors; both read the same manifest.json, and neither hardcodes a runtime matrix.

  • The feedstocks consume the product binaries and the runtime index the same way. There is no central service and no special channel; releases are the only interface.

The index entry is the contract between the runtime factory and everything downstream: one entry per runtime package, additive forever, where a reader that predates a key ignores it. A real entry from the v0.16.9 line, hashes elided, follows:

{
  "tebako_version": "0.16.9",
  "contract_era": 2,
  "contract_version": 2,
  "ruby_version": "3.3.12",
  "platform": "macos-arm64",
  "filename": "tebako-runtime-0.16.9-3.3.12-macos-arm64",
  "sha256": "f32c9c13…",
  "size_bytes": 41110296,
  "abi": "arm64-darwin-23",
  "mount_root": "/__tfs__",
  "built_from": { "sources": [{ "name": "tfs-ruby-3.3.12-src.tar.gz", "sha256": "3adafef3…" }] },
  "image": {
    "filename": "tebako-runtime-0.16.9-3.3.12-macos-arm64.tfs",
    "sha256": "efa94afe…",
    "size_bytes": 8090578
  }
}
  • contract_era / contract_version negotiate the loader↔runtime handoff, fail-closed: a loader that cannot speak the runtime’s contract refuses with a named exit (75), never a guess.

  • abi is the runtime’s own platform string. Native-extension payloads constrain both the version line and this line, so a wrong-ABI runtime is a named resolution error, never a segfault.

  • mount_root records the runtime root compiled into the interpreter, which is where the env image mounts at boot.

  • built_from names the exact source-factory tarball this runtime was compiled from: the chain’s provenance, recorded in the artifact itself.

The discipline pays off at the far end: a user running a package needs no compiler and no libraries, and a developer pressing a payload compiles only the developer’s own code. Only people working on tebako itself ever compile tebako. Prebuilt artifacts flow downward; compilation never flows outward.

The toolkit factory: one repo per package

GitHub releases are per-repo tag namespaces, so a single ports repository would force every tool into one version line. The toolkit factory is therefore the conda-forge feedstock model: a tebako-packages org with one repo per package, each owning its recipe, its patch sets, and its release line:

tebako-packages/inkscape/         # one repo per package (a "feedstock")
  recipe.yml            # upstream url+sha256, versions, build system,
                        # link mode, deps (other toolkits), platforms
  patches/              # per-version patch sets, ruby-factory naming rules
  manifests/            # payload manifest templates (provides, exec tier)
  .github/workflows/    # build matrix per triplet + boot-smoke + release
  tpkg-registry.yaml    # the repo's own registry, at the default-branch root

tebako-packages/index/            # the catalog: a registry-of-registries
  tpkg-registry.yaml    # each feedstock's registry ref + summary
  • Release lines are the upstream version, plus a packaging revision only for a re-release of the same upstream; metanorma shipped 1.16.9, then 1.16.9-2 and 1.16.9-3 as packaging fixes.

  • Release hosting is per-repo, locked. Every built payload, platform-specific or universal, publishes as a GitHub release in the feedstock’s own repo, with the artifacts, the SHA256SUMS, and the registry. The index carries only catalog entries pointing at those releases; nothing is hosted centrally.

  • References name the release in registry mode (tfs:github:tebako-packages/inkscape:1.4.3) or a single artifact directly (…#inkscape-1.4.3-aarch64-macos.tfs).

  • Discovery is one explicit step: tebako add-registry tfs:github:tebako-packages/index exposes the whole catalog, and nickname installs like tebako install inkscape@1.4.3 resolve through it.

The proven line is hello (native trivial), fontist (a ruby app payload, bound to its runtime’s ABI line), inkscape (a heavy dynamic toolkit), and metanorma, the flagship with 260 gems, a wired dependency on the inkscape payload, and a full PDF compile executed through the mounted images.