# Designing Builder Surfaces


A good builder surface starts from the domain, not from the generic build
machinery.

For a service builder, the domain might include runtime, entrypoint, port, health
path, and service protocol. For a native code generator, the domain might include
schema, compiler, defines, artifact kind, and generated outputs. The public
constructor should ask for those domain concepts and lower them into the shared
builder program.

## Start From The Artifact

Ask what the builder promises to produce. A runnable package, a generated source
tree, a static library, a CLI, a service unit, or a descriptor bundle each imply
different outputs, operations, tools, and runtime descriptors. The artifact tells
you which of those the builder needs.

## Name The Vocabulary

Use domain names in the public API and avoid exposing generic mechanics when a
domain term is clearer. A service builder should ask for a `port` or a
`healthPath` before it asks the user to construct a low-level runtime protocol
value.

## Keep The Constructor Small

A constructor should accept the smallest set of choices that define the build.
Everything derived from those choices should be generated by the builder. This
keeps the user-facing API stable while the internal program becomes more capable.

## Lower Into Operations

The constructor is responsible for lowering domain choices into operations. That
lowering is where tools, generated files, descriptors, output declarations, and
materialization steps enter the program. The domain fields capture what the user
said, and the operations capture what the build does.

## Expose Standard Views

A production builder should expose the same standard views during development.
Validation, dependency graph, dry-run, plan-view, describe, introspect, and
materialize together become the builder's debugging and documentation surface.

## Use Ornaments For Domain Shape

An ornament extends the base builder spec with domain-specific fields. Use one
when a builder needs a typed domain shape but should still behave like a normal
metaBuilder program. The ornament adds data only. It never extends the operation
alphabet, and a typed forget map projects the ornamented builder back to the
shared shape while keeping its program intact. That is what lets a domain builder
stay fully compatible with every standard view.
