Skip to content

Navigate the workspace

Clinker isn’t one file, or even one crate — it’s thirteen crates in a single workspace. That sounds like a lot to hold in your head. It isn’t, once you see that the crates are layered, and the layering itself is the map.

You’ll be able to: read the crate layout, predict which crate a given symbol lives in, and find it quickly — using the dependency direction as your compass.

A crate is Rust’s unit of compilation — a library or a binary. A workspace groups related crates that build together and depend on one another; the top-level Cargo.toml lists the members. Inside a crate, a lib.rs is the table of contents: a stack of pub mod ...; lines, each naming a module (a file) and exposing it.

Here’s the real top of the clinker-record crate — the engine’s vocabulary layer:

clinker-record ·lib.rs module @47d2e12
crates/clinker-record/src/lib.rs
pub mod value; // the Value type lives in value.rs
pub mod schema; // Schema in schema.rs
pub mod resolver; // FieldResolver in resolver.rs
// ... one line per module, then re-exports of the public vocabulary

pub mod value; means “there is a module value, its code is in value.rs, and it is public.” So clinker_record::value::Value is exactly where you’d expect.

The crates stack from low-level vocabulary up to the command-line edge. Dependencies only ever point upward — a lower crate never depends on a higher one:

clinker cxl-cli ← the binaries (edge)
clinker-net clinker-channel clinker-schema
clinker-exec ← runtime: executor, operators, memory, spill
clinker-plan ← planning: config, validation, the DAG
clinker-format ← streaming readers / writers
cxl ← the CXL expression language
clinker-record / clinker-core-types ← the vocabulary everything shares

This direction is your compass. Reading records? That’s vocabulary → clinker-record. Parsing a pipeline? clinker-plan. Running it? clinker-exec. Decoding a CSV? clinker-format. The AI onboarding docs spell out every crate’s job — start there, then verify against the source:

clinker ·20_CRATE_MAP.md doc @47d2e12

The layering predicts most locations, but not all. The clearest example: the top-level runtime error type, PipelineError, is the error the executor returns — so you’d reasonably look in clinker-exec. It actually lives in clinker-plan:

clinker-plan ·error.rs ·PipelineError type @47d2e12
pub enum PipelineError {
Config(ConfigError),
Format(FormatError),
Eval(EvalError),
Io(std::io::Error),
// ... ~25 variants in all — the planning layer's full failure vocabulary
}

There’s a reason (the planning layer owns the vocabulary of what can go wrong, and the executor consumes it) — but the lesson for now is procedural: find the symbol, don’t guess its home. cargo doc --workspace --no-deps builds browsable docs, and a quick grep -rn "enum PipelineError" crates/ settles it in a second.

// quick check

`PipelineError` is the error type the executor returns. Which crate defines it?

You can now navigate the engine by its layers. Next, the last orientation skill: reading what a pipeline will do, straight from its plan.