Skip to content

ARCHITECTURE · 11

The driver contract.

The driver is the code inside every runtime executable: it mounts the environment image and the payload slices, applies the jail, and rewrites argv to the entrypoint. This page is the wire that the driver speaks, language-agnostic by construction: ruby is the first runtime, and python or julia follow the same contract unchanged.

Note

The contract is shipped: the reference implementation is crates/tebako-driver (Rust, staticlib + rlib), and the v1 C++ tebako-main driver is retired.

The invocation surface

One grammar serves every platform. Everything before the first --tebako- is the loader’s, and everything after --tebako-entry is the user’s, verbatim. An unknown --tebako- flag is a named error, never silently ignored.

<runtime> --tebako-image <self|image-path>:<slot|->:<mount> ...
          [--tebako-trace <host-path>]
          --tebako-entry <argv0> <user args...>

<self>        the running executable's own package file; <slot> picks the
              trailer-described region
<image-path>  a standalone file — BARE (no trailer): slot 0 ≡ - ≡ whole file;
              PACKAGED: numeric slot only, "-" is a named error
<mount>       a POSIX absolute path on EVERY platform — on windows the driver
              qualifies it onto the runtime root's drive (A:/t/…) before
              mounting; a declared mount naming a drive is malformed

Mount order + failure rule

The env image mounts first (whole-file, from TEBAKO_RUNTIME_IMAGE), then payload triples in argv order. The table is longest-prefix; nested mounts are legal, and a duplicate exclusive mount point is EEXIST. Any failure unmounts everything, never a partial mount. A runtime-role slot (format_id = 4) is never mounted.

Mount modes

Every mount is exclusive (default) or union, declared per slot in the package manifest’s mounts: block, never on the argv wire, so the launcher ABI is unchanged and older drivers refuse a union package loudly. Union conflicts resolve by declared precedence (after-env or after:<slot>), and the union set is journaled at boot. Shim-dispatched payloads (no package manifest) are always exclusive.

The entry, and the argv rewrite

--tebako-entry separates loader args from user args. The entry resolves against the first --tebako-image mount (the app payload), or the runtime root when no image spec is given, and the driver verifies its presence against the mounts the boot itself established (named 65 when absent). A bare NAME with no / (e.g. ruby) is the interpreter keyword: the boot starts the interpreter itself and drops the keyword. With images but no entry at all, the boot mounts and starts the interpreter with its own args (the smoke form).

On success the process argv is replaced with [<original argv0>, <entry resolved in the VFS>, <user args…>], the program name stays at index 0, so the interpreter parses its argv conventionally and takes the entry as its script. The jail installs after the mounts; --tebako-trace arms the trace bus before any mount (a channel that cannot be opened is a loud stderr note and a disarmed bus, because observability never gates a boot).

The mount root is a default, not a constant

The runtime root is a per-platform baked default owned by the runtime factory (ruby: /tfs on POSIX, A:/t on windows); it flows from the source patches through the factory into the exe, and nothing downstream re-authors it. TEBAKO_MOUNT_ROOT redirects the env-image mount at boot:

Note

The override, stated plainly. The value is validated before any mount: it must be absolute, with no trailing slash and no .., and a malformed value is exit 65, naming the variable. The override is then gated post-mount on the env image’s layout grant (mount_root_override: true): an image without the grant predates the override era, because its rbconfig is pinned to the baked root, so the driver refuses with exit 78, naming both the override and the image, and there is never a boot whose load paths point at an unmounted root. Era-2 rbconfig emits ENV["TEBAKO_MOUNT_ROOT"] || <baked>, so the interpreter follows.

The handoff environment

The loader speaks to the driver through a small, fixed set of variables. Each one is a single-owner flow: declared by the factory or the manifest, consumed verbatim, and never re-authored downstream. The exhaustive table of every TEBAKO_* variable in the system lives in the reference section; the contract’s own variables follow:

VARIABLE MEANING

TEBAKO_RUNTIME_IMAGE

The absolute path of the runtime’s own env .tfs, mounted whole at the runtime root first, before any payload triple.

TEBAKO_TFS_MOUNTS

The image:mount,… list; it is the mount table a spawned child re-establishes through the preload shim (the spawn-hook path).

TEBAKO_JAIL

The jail policy in env form; it is enforced by the driver and installed after the mounts, and a malformed policy is exit 73.

TEBAKO_TRACE / --tebako-trace

The trace bus channel (JSONL), armed at boot before any mount; the argument wins when both are set, and it is never policy-gated.

TEBAKO_MOUNT_<SLUG>

Per co-mounted payload, its physical mount point (/tools/inkscape → TEBAKO_MOUNT_TOOLS_INKSCAPE); two mounts slugging alike is a named 65, and the root mount exports nothing.

PATH

The boot rebuilds it: launcher wrap-bin dir → co-mounted dependency bin dirs (from each image’s own manifest, in triple order; the app payload never contributes) → windows alias dirs → the inherited PATH. A corrupt manifest or an unmaterializable declared executable is a named 65.

The named exit codes

Note

The exit-code table is shipped, with no silent fallbacks.

Loader-side failures keep the loader’s named codes, and runtime-side failures use the interpreter’s own codes. There is no catch-all, and no code does double duty; the shared constants live in crates/tpkg, and every emitter references them.

CODE NAME RAISED WHEN EMITTER

65

EX_TEBAKO_MANIFEST

The tpkg trailer or package manifest is corrupt or internally inconsistent; TEBAKO_MOUNT_ROOT is malformed; the --tebako-entry is not present in the established mounts; or a co-mounted image has a corrupt in-image manifest.

bootstrap · driver

66

EX_TEBAKO_ABI

The package declares a launcher ABI this loader does not speak.

bootstrap

67

EX_TEBAKO_RUNTIME_REF

The runtime_ref is unparseable (type / version / constraint grammar).

bootstrap

68

EX_TEBAKO_OVERLAY

An overlay/decrypt binding failed: an unbound retained store, missing or non-opening key material, an unwritable store, an orphan binding, or malformed TEBAKO_OVERLAYS / TEBAKO_DECRYPT.

resolver · driver mount path

69

EX_TEBAKO_UNAVAILABLE

The runtime cannot be obtained: the download failed, or TEBAKO_OFFLINE=1 found no cache hit.

bootstrap

70

EX_TEBAKO_SHA

A sha256 mismatch occurred on a downloaded artifact (exe, env image, dll) against the release index.

bootstrap

71

EX_TEBAKO_SIGNATURE

A signed package’s signature fails verification (strict, always).

bootstrap

72

EX_TEBAKO_TRUST

The signer’s key is not in the trust store, or TEBAKO_REQUIRE_SIGNED=1 met an unsigned package.

bootstrap · install path

73

EX_TEBAKO_JAIL

The jail policy is malformed or unusable; it is parsed and applied after the mounts, never before them.

driver

74

EX_TEBAKO_IO

A host I/O failure occurred on the cache/install/lock paths.

bootstrap · resolve

75

EX_TEBAKO_CONTRACT

The runtime is pre-era (it declares no contract set) or speaks a contract the loader refuses; the check fails closed before any install or execute.

bootstrap

76

EX_TEBAKO_INSTALL

A store install cannot complete (lock timeout, disagreeing digest anchors, or partial state that tmp+rename cannot hide).

resolve · cli

77

EX_TEBAKO_CONTRACT_ERA

A package/payload contract-era mismatch in either direction, raised by any trailer or manifest reader.

tpkg · pkg · cli

78

EX_TEBAKO_LAYOUT

The env-image layout mismatches: a mount_root override the image never granted, a missing preload-shim grant, or an interp ABI pair the image does not declare; it is also the preload shim’s EX_CONFIG.

driver · libtfs-preload

79

EX_TEBAKO_CHECK

A payload check FAILed, and the verdict line names the check and the failed expectation (SKIP never fails the aggregate).

tebako check

Two out-of-band codes complete the picture: the runtime factory uses 132 for a pre-era or corrupt source tarball, and --tebako-extract (the runtime-side option, carried through the user-arg passthrough) dumps mounted images to disk and exits 0. The trace subcommands carry their own verdict codes (0 clean / 1 finding / 2 error); see observability.

Negotiation is fail-closed

A runtime whose driver implements this widened grammar (image-path triples, bare-file slot tokens, env-image-first multi-mount, and direct entry execution) declares contract_version 2 in its release manifest, and the compiled-in constant (tebako_driver_contract_version()) must agree with the manifest. A runtime that declares no contract set is pre-era: the loader refuses it by name with exit 75, before any install or execute. Runtime provenance is declared in the payload manifest (provides, naming engine, version, abi_line, and platform, plus built_from), and the dispatcher’s compatibility check consumes exactly those fields.