Skip to content

ARCHITECTURE · 06

The factories.

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

Status: shipped — every stage on this page publishes today; the versions and pins named are the ones in force.

The chain.

Four factories and one product repo, each building its own platforms and publishing its own versioned releases. This is the ruby instance of the model; 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.27 · 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.9 · 22 rubies × 7 triplets · 334 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.

Stage by stage.

Each row names the artifact you can download and verify today.

Stage Repo What it ships Status

Upstream

ruby-lang.org

Official Ruby source tarballs — the ultimate input of the whole chain.

external

Release monitor

tamatebako/ruby · release-monitor.yml

Daily cron: diff upstream releases against versions.yml, onboard new rubies (entry + patch selection + lint → PR → tag → source release → pin-bump dispatch). A failing patch files a named issue carrying the hunk output — loud, never silent.

shipped

Source factory

tamatebako/ruby

v0.2.27: 149 assets — 37 rubies (3.1.6–4.0.6) × 4 scenario tarballs (linux-gnu unsuffixed, linux-musl, msys-pass1, msys-pass2) + SHA256SUMS. The only place ruby patches are ever applied; every upstream fetch is sha256-pinned in versions.yml.

shipped

Runtime factory

tebako-runtime-ruby

v0.16.9: 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) + SHA256SUMS.txt. Builds the pinned source in toolchain containers, links the pinned product link unit, boot-smokes every runtime before publish.

shipped

Format library

dwarfs-t

The only C++ in the stack: the DwarFS-T image format (FlatBuffers metadata — upstream dwarfs cannot read it) behind the dwarfs_c_* ABI. Read-only at runtime forever; the Writer runs at creation time only. Releases publish the pinned per-triplet vcpkg baselines the downstream builds compile against.

shipped

FFI bindings

dwarfs-t-rs

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: no mkdwarfs shell-out, ever.

shipped

Product

tamatebako/tebako

v0.2.5: five binaries (tebako, tfs, tebako-pkg, tebako-shim, tebako-bootstrap) × 7 triplets + the per-triplet link units + manifest.json + 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 toolchain container images the factory matrices build in — the tpkg-builder line, taking over from the pinned v1 container tags.

shipped

Toolkit factory

tebako-packages/*

The conda-forge model: one feedstock repo per package — recipe + patches + manifest templates + CI. A release carries the per-triplet payload .tfs artifacts + SHA256SUMS + 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

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; 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; 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 (a reader that predates a key ignores it). A real entry from the v0.16.9 line, hashes elided:

{
  "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 — 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; a developer pressing a payload compiles only their 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: 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: hello (native trivial), fontist (a ruby app payload, bound to its runtime’s ABI line), inkscape (a heavy dynamic toolkit), and metanorma — the flagship: 260 gems, a wired dependency on the inkscape payload, and a full PDF compile executed through the mounted images.