The build tasks

The bb entry points a data repo drives: validate, build, compose, print.

bb doctor

bb doctor <dir> validates a data directory before anything is built: schema on every file, and a scan for secret-shaped content in the working tree and, on a git repo, its whole history. The shapes it validates are the data model the handbook walks through.

bb build

bb build :dir <data> :out <dist> [:as-of <instant>] is the whole site build: masters verified by hash, derivatives generated, every page rendered, internal links checked against the files the build actually wrote. The :as-of argument is what makes builds reproducible — the handbook explains why determinism is the engine's spine.

bb assembly

bb assembly :config <assembly.edn> composes several portfolios under one domain via path prefixes — the shape this very demo is served in. Multi-document sites are assemblies of :mode :document members: the assembly build checks every cross-document link and generates each document's "Referenced by" list from the links the pages actually carry.

CV emissions

A :mode :cv portfolio has two projections beside its page. bb cv-json emits the JSON Resume document; bb cv-pdf typesets a print PDF through the same pinned toolchain as the other print artefacts, with a template derived from the document mode's. Both take a tier: the public tier provably excludes every :tier :private node and entry, and the full tier's PDF carries a -full suffix so the two can never be confused.

The page can link its own PDF: declare :cv {:pdf "<path>"} and run bb cv-pdf :publish true with a pinned :as-of — the task writes the PDF and a provenance sidecar into the data repo for review and commit. The build then copies the file, links it quietly, and checks the sidecar's input hash against the current data on every run: change the CV and forget to republish, and the build says so loudly. The build itself never runs the typesetter — generation is an authoring act, verification a hash comparison. The CV demo shows the whole surface, private entry included (you will not find it on the public page — that is the point).