the source & build layer · tbzl.dev

One graph,
from source to build.

tomato-bazel is the Bazel-native layer beneath the platform: a single depot with no repos to name, a queryable code graph, and hermetic builds on your own remote executors. Truss holds the source, modgraph answers the graph — every build reproducible, every cache shared.

$ curl -fsSL tbzl.dev/install | sh
modgraph · query_rdeps //lib:greet live
5,142 targets· 18,903 edges· blast radius
the truss thesis

Two source-control lineages each got half of it right.

from git

The model you think in — a content-addressed Merkle DAG, cheap branches, an explicit commit graph.

What it gets wrong: welded to the working copy, doesn't scale to a monorepo, worktrees bolted on.

from Perforce

The operational shape — carve a small view out of one enormous depot; thin clients hold only what they need.

What it gets wrong: makes you check out, versions per file, not as a graph, history is not rewritable.

Truss takes the union and discards the friction of both. One global depot, so there are no repos to create, split, or name. Everything is a lazily materialized virtual worktree. You author one change with a stable identity — and a layered code graph does the decomposition, review routing, and affected-set for you. A truss is both a cluster of tomatoes on one stem and a load-bearing frame — the graph is the structure that bears the source.

the load path

One graph carries it, source to build.

Every layer reads the same graph. A change enters as a diff and leaves as a reproducible, cache-shared artifact — and nothing in between is guessed from folder names.

receipts

Mechanisms, not marketing.

Each of these is a property of how the layer is built — reproducible, and true by construction rather than by promise.

rdeps
Blast radius is computed.

The set of targets a change can break is a reverse-dependency traversal of the real graph — not a guess by directory, and not "run everything."

modgraph · query_rdeps
content-
addressed
Cache hits, org-wide.

Every action is keyed by the hash of its inputs. Build an artifact once and the whole org — and every agent — reuses it. Reproducible or it isn't cached.

RBE · buildbarn · shared CAS
no repos
Nothing to name.

One depot means the single largest source of incidental cognitive load — deciding what belongs in which repo — simply disappears. You mount a view.

truss · one global depot
the constellation

Small, sharp, Bazel-native services.

Each piece is its own repo and its own control plane — composed, not monolithic. Read-only where it can be, confirm-gated where it writes.

Reusable rulesets & toolkits — published to registry.tbzl.dev, resolvable from any Bazel workspace, hermetic and dockerless.
// rules_lean // rules_tap // rules_tla // rules_vscode // rules_ci // rules_mdbook // rules_render // cred-helper // fvkit …50+ on registry.tbzl.dev
config as data

Every service is a control plane.

No bespoke controller loops you own. State lives in Kubernetes CRDs; operators reconcile them. The desired graph, build, and registry are declarative — a CR to add, not a pipeline to maintain.

truss.tbzl.dev
CRD: TrussInstance

Provisions a depot server. Single-writer by invariant — no replicas knob, because trussd owns the depot and serializes landing.

graph.tbzl.dev
CRDs: GraphInstance · ModuleRegistry

Point a GraphInstance at repo@ref; graphd serves rdeps/deps/stats the moment git-sync reloads. Lazy at replicas:0, activate on demand.

build.tbzl.dev
CRDs: BuildRun · RbeCluster

A push becomes a BuildRun CR; the operator reconciles it into a graph-scoped job on your RBE.

registry.tbzl.dev
served: bazel-registry

Integrity-checked module versions with a Bazel-native source.json; the content-addressed store behind every resolve.

get started

Point one Bazel workspace at tbzl.

The rulesets and the registry are open. Add the registry, install the CLI, and browse your own module graph. Full guides live at docs.tbzl.dev .

01 · INSTALL

Get the CLI

The tomato-bazel developer CLI manages your MODULE.bazel, workspaces, worktrees, and credentials.

$ curl -fsSL tbzl.dev/install | sh
02 · RESOLVE

Add the registry

Resolve modules — and the whole rules_* family — from registry.tbzl.dev, integrity-checked.

# .bazelrc
common --registry=https://registry.tbzl.dev/
03 · QUERY

Ask the graph

See a change's real blast radius before you push — reverse-dependencies from the graph, not a guess.

$ tbzl graph rdeps //lib:greet

Stop naming repos. Start reading the graph.

One depot, one graph, hermetic builds on your own cloud — the substrate the whole platform is built on. Open at the edges, yours at the core.