Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Repo & source layout

Each top-level directory under src/ is a layer with one job, and dependencies point downward only.

src/
  main.zig / root.zig    CLI + library root — the only place that wires layers together
    │
    ├── starlark/        the Starlark front-end (lexer → parser → eval → rules)
    ├── crates/          the crates.io importer (lock, fetch, metadata, gen)
    ├── exec/            the sandboxed executor + cache orchestration
    ├── dice/            the incremental engine
    ├── graph/           target identity (labels) and the build graph
    ├── core/            the content-addressed substrate: digest, codec, cas,
    │                      merkle, action_cache
    ├── cache/           the remote-cache tier on top of core: remote.zig
    │                      (RemoteStore tiering + backends), objframe.zig (envelope)
    ├── rules/           the built-in @builtin prelude (rust.bzl, zig.bzl)
    ├── aws/             STANDALONE AWS SDK — sigv4, credentials, s3 (own module)
    ├── gcs/             STANDALONE GCS SDK — storage (own module)
    └── log.zig          STANDALONE leveled logger (own module, std-only)

Why some pieces are standalone modules

aws, gcs, and log are separate build modules, not just directories. That gives a compiler-enforced boundary: they cannot reach into zut internals, so they stay reusable on their own.

  • aws / gcs are the seeds of general-purpose Zig SDKs (aws.s3.Client, gcs.storage.Client) that have nothing to do with build systems. zut’s remote cache is a thin adapter over them; framing/compression (objframe) stays on zut’s side so the SDKs only move opaque bytes. Each can later be extracted to its own package.

  • log depends on nothing but std, so every layer imports it as @import("log") — no ../log.zig reaching across directories — and there is exactly one module instance, hence one process-global log threshold.

The dependency arrows

The front-end and importer sit on top; core/ is the content-addressed substrate everything stands on; cache/ builds the remote tier on core/ using the SDKs as backends without leaking them. Nothing imports main.

The full rationale and the migration history are in docs/design/layout.md.