Architecture: Composition (3 of 5)
How tebako v2 works, concept by concept — this post: composition.
The Tebako team
github.com/tamatebako|
Note
|
Post 3 of 5 in the series Tebako v2 architecture. ○ ○ ● ○ ○
|
The first two posts covered the parts: packages, runtimes, payload slices. This post covers the grammar that ties them together — how a package says what it needs, and how those needs become mounts in one process.
Everything is declared in the payload’s manifest, under requires::
Figure 1 — The manifest declares requirements; resolution turns them into mounted runtimes, spawned runtimes, and toolkits inside one process.
requires:
- kind: language
engine: ruby
constraint: "~> 3.3.0"
- kind: runtime
engine: java
constraint: ">= 21, < 26"
expose: [java]
- kind: toolkit
name: inkscape
constraint: ">= 1.3"
mount: /opt/inkscape
Three kinds of requirement, three mechanisms:
-
A language runtime boots the application: its two artifacts mount as described in the previous post.
-
A runtime requirement like java is spawned, not mounted: when the application runs
java, tebako starts that runtime’s own executable with its own environment image, as a child process. Theexpose:list names the commands that appear. -
A toolkit requirement mounts at a declared path, exactly like a data slice.
Resolution
Resolution picks, per platform triplet, the newest artifact that satisfies every constraint. The result is deterministic and recorded — the same package resolves the same way on the same machine, and a payload with native code can pin an ABI line so a wrong runtime is a named error, never a crash.
Declarative, per invocation
The same declaration drives dispatch: an installed payload provides commands, and each invocation resolves the declared composition before it starts. Because nothing is implied, pinned and side-by-side versions of the same tool are ordinary — the next post covers what those processes may touch on the host.
|
Note
|
Continue with part 4 of 5: The host boundary. |