Project settings
project.conf holds a project's operational settings: the name on its output
files, its Docker names, and how a build behaves. How the book looks and what
metadata it carries is pandoc.yaml.
This page is the complete key reference. The file ships commented — a line per setting, grouped, each group linking the page that owns it.
How settings are applied
A value may reference one set above it:
KEYSTONE_DOCKER_COMPOSE_PROJECT=keystone-${KEYSTONE_PROJECT} expands as
written.
Some settings also take a one-run override on the command line, which wins over the file:
| Setting | One-run override |
|---|---|
KEYSTONE_USING |
make publish using=<name> |
KEYSTONE_WARNINGS_AS_ERRORS |
make publish strict=true |
KEYSTONE_PROGRESS |
make publish progress=<mode> |
KEYSTONE_HOOKS_KEEP_ALIVE |
make publish down=true |
Project identity
| Setting | Notes |
|---|---|
KEYSTONE_PROJECT |
Names the output files — <project>-<target>-<date>, e.g. my-project-book-20260101.pdf. A short, lowercase string without spaces. Defaults to keystone. |
This is the project's name, not the book's — the title on the cover is title:.
Left at keystone, the build warns and your artifacts carry Keystone's name.
Docker
| Setting | Notes |
|---|---|
KEYSTONE_DOCKER_COMPOSE_PROJECT |
The Compose project namespace — the prefix on the networks, containers, and volumes a build creates. Defaults to keystone-${KEYSTONE_PROJECT}. |
KEYSTONE_DOCKER_IMAGE |
core only. The image make image builds and the build runs; override it for the tag you push, or for a CI pipeline. Defaults to ${KEYSTONE_DOCKER_COMPOSE_PROJECT}:local. |
The namespace is what keeps two Keystone projects on one machine from sharing a
container. core-slim runs the published image, pinned by tag in its compose
file — see Choosing a template.
Builds
| Setting | Notes |
|---|---|
KEYSTONE_WARNINGS_AS_ERRORS |
true makes any warning fail the build and write no new file. Defaults to false. See Strict builds. |
KEYSTONE_PROGRESS |
How much of a build is reported: auto (the default), plain, off, or verbose. See Watching a build run. |
Build configurations
A configuration is a named set of symbols that gates parts of the manuscript, so one source produces several editions.
| Setting | Notes |
|---|---|
KEYSTONE_DEFINE_<name> |
Declares one configuration: KEYSTONE_DEFINE_private="personal annotations drafts". The name takes letters, digits and underscores. Declare as many as you need. |
KEYSTONE_USING |
The configuration to build when using= is omitted. Empty (the default) builds the plain edition. |
Fully covered in Conditional content.
Hooks
A hook hands a fenced code block to a program you wire in.
core-diagrams ships one, and its renderer starts a
browser — which is what KEYSTONE_HOOKS_TIMEOUT is for. With no hook wired,
nothing acts on the timeout or the cache settings. KEYSTONE_HOOKS_KEEP_ALIVE
applies either way: it decides whether a finished build stops the project's
containers, hook or no hook.
| Setting | Notes |
|---|---|
KEYSTONE_HOOKS_KEEP_ALIVE |
Leaves hook containers running when a build finishes, so the next build does not start them again. false stops them, build succeeded or not. The file ships true, and an empty value keeps them too. Read by make, so make publish down=true overrides it for one build. |
KEYSTONE_HOOKS_TIMEOUT |
Seconds a hook has to answer one block; a whole number of 1 or greater. Raise it for a renderer that starts a browser. Defaults to 30. |
KEYSTONE_HOOKS_CACHE |
Where replies are remembered. A path inside artifacts/ lets you open what a hook produced; anywhere else needs a writable mount of its own. Empty (the default) is a volume the engine owns, cleared by make reset. |
KEYSTONE_HOOKS_CACHE_MAX |
Megabytes the cache may hold before the least recently used replies are dropped; a whole number of 1 or greater. Defaults to 64. |
Hooks keep running after a build
A hook holds its resources — mostly memory — for as long as it is up, and
that is per project. Keeping it saves the next build a second or so on a
fast machine; stopping it leaves the machine free between builds, and the
hook cache stays either way. Decide once with
KEYSTONE_HOOKS_KEEP_ALIVE; make publish down=true covers a one-off.
A build that stops on the timeout or either cache setting names it — see
A hook that fails. KEYSTONE_HOOKS_KEEP_ALIVE is
make's rather than the engine's, so a value it does not recognize leaves
containers running instead of failing anything.
Diagrams
Shipped in core-diagrams, whose hook reads them. These
are the diagram hook's own settings — Keystone
passes them through untouched, and the vocabulary is mermaid's. Wiring
that hook into another template means adding these keys and passing them to its
service: Wiring a published hook.
Each is house style: a single diagram can name its own and what it names wins.
| Setting | Notes |
|---|---|
KEYSTONE_DIAGRAMS_THEME |
The palette every diagram is drawn with: default, neutral, base, forest, or dark. Empty is default. See Picking a theme. |
KEYSTONE_DIAGRAMS_FONT |
The typeface diagrams are lettered in, as a CSS font stack. Only what the renderer carries resolves — see Matching the book. Empty is Noto Sans, sans-serif. |
KEYSTONE_DIAGRAMS_LOOK |
How shapes are drawn: classic or handDrawn. Empty is classic. See Matching the book. |
KEYSTONE_DIAGRAMS_LAYOUT |
How nodes are placed: dagre or elk. Empty is dagre. See Matching the book. |
When the renderer does not know a value
A theme, look or layout it does not know stops the build, naming the value, so a typo cannot restyle a book in silence. A font it lacks only warns — a font stack falls through, and the fallback is legible. The checking is the renderer's own, so a different one answers for its settings its own way.