Blueprint gives repository-owned commands declared environments and, when asked, a managed contract for producing artifacts. This chapter defines the model: what each part owns, the vocabulary, the stages, and the invariants that keep the model independent of any one package ecosystem. It describes the design Blueprint is built towards; What ships today says what ships.

Goals and non-goals§

Many tools turn a description of an environment into a working one for a single ecosystem, and tie the project’s intent to that ecosystem’s formats and commands. Blueprint separates the two. Shared contracts state intent, dependency authority and execution evidence; every ecosystem-specific concern belongs to a replaceable provider.

The protocol is the product; providers are adapters.

The protocol is the Spec, the Lock, the provider contract and the versioned reports and records. A provider implements part of it for one ecosystem, or for Blueprint’s own store.

Goals§

Non-goals§

What Blueprint owns§

A project keeps compilation, packaging and validation logic in its own scripts. Blueprint describes how to run them: tools, pinned inputs, selected project files, dependencies, outputs and ordered workflows. It does not discover arbitrary script dependencies or decide a project’s release policy.

OwnerResponsibility
RepositoryCommands, compilation and packaging logic, validation and release policy.
ConfigurationExplicit environments, tasks, builds, inputs, outputs and workflow order.
Pure core libraryTypes, semantic validation, dependency relationships, request planning and evidence comparison.
HostFilesystem, network and process effects described by constrained plans. The CLI is one host.
ProviderNative resolution, recipe preparation, execution and cache behavior for the capabilities it supports.
Release automationReviewing and admitting published artifacts, publication and advisory decisions.

A Task is a common runner around a command. A Build adds an explicit contract for producing an artifact from declared inputs. Both may invoke the same script; Blueprint does not take ownership of the script’s algorithm. A Workflow orders these operations rather than inferring their dependencies from script contents.

Provider neutrality is an enduring constraint§

Shared contracts define capabilities and guarantees independently of native formats. A provider owns package grammar, native recipes, process arguments, store paths and metadata. A provider need not imitate another or offer every capability. An unsupported capability fails before effects rather than silently weakening isolation or a reproducibility check.

A provider plays one or more roles:

Resolver

chooses and records pins for the sources it owns.

Realiser

materialises environment tools from those pins.

Executor

prepares and runs managed builds, and states the guarantees of a successful build.

Inspector

projects its native authority into provider-qualified identities and inert metadata for reports.

Source resolution, environment tools and build execution are separate roles. Sources name their resolver; builds select a named executor. Registering a provider that nothing selects must not change a request. An unsupported combination is refused explicitly; neutrality does not promise arbitrary mixed-provider composition or portable ecosystem-specific package names.

Providers own their native caches and substitution. Blueprint supplies the selected inputs and interprets typed results; it does not implement a second artifact cache or infer a cache hit from a successful command.

Terms§

Configuration and data§

TermDefinition
BlueprintThe authored Blueprint.roc configuration.
SpecIts normalized, validated, versioned description of intent.
SourceA declared external content origin, with explicit resolver ownership. Its reference is text the owning provider validates; the core reads no provider grammar.
ComponentA requested package within a source’s native package universe.
Execution systemThe operating system, architecture and platform on which an operation executes. Systems and BLUEPRINT_TARGET select it.
Artifact targetThe platform an artifact runs on, when it differs from the execution system. Cross-compilation settings belong to the script.
LockCommitted dependency authority: exact pins, declared resolution intent and the trust record of every download.
Trust recordFor each fetched program and system: the declared URLs, the hosts that actually served the bytes, the digest, how it was obtained (computed, published, both) and the witness it was read from.
ArtifactA produced or fetched file or tree. Its role is stated; a location alone does not identify its content.
StoreDisposable local materialization of pinned or produced content.
Host factsExplicitly observed machine requirements that Blueprint does not supply or pin.
EnvironmentSelected tools, fetched programs, variables and expected host requirements for execution.
TaskExact command argv executed in an environment, with repository-owned behavior and side effects.
BuildAn artifact-producing command with declared files, inputs, dependencies, executor and output.
WorkflowAn ordered sequence of tasks, builds and nested workflows.
ActivationStructured search-path and environment-variable operations for entering an environment.
Input snapshotCaptured selected project files and their executable bits, together with the selected pinned inputs and build settings.
Request planValidated operations, dependency relationships, capabilities and permitted preparation effects.
Prepared buildCaptured inputs and the exact provider-native recipe with its build identity, ready for execution.
Build resultPrepared build identity, output locations and execution evidence established by the provider.
ReportA rendering of typed inspection or execution evidence, with a defined input and compatibility boundary.

Identities, digests and locations§

TermComparison domain
content_identityPinned input content, compared together with its provider. Opaque to consumers outside that provider’s contract.
build_identityA fully prepared executable build, compared together with its provider. Includes the provider’s selected inputs and recipe semantics. A changed build identity means the request changed, not that output bytes differ.
File digestExact original file bytes under a named hashing scheme; an archive’s hash includes compression and archive metadata.
Tree digestDirectory content under a named tree-hashing scheme. A Nix NAR hash and an archive SHA-256 are different measurements.
Output digestMeasured content of a produced artifact under a named scheme.
pathA location of content; it is not automatically a content checksum.

Equal content identities do not imply equal builds: commands, selected files, tools and options also matter. Equal build identities do not prove deterministic execution. A checked rebuild provides evidence about repeated execution; it does not prove determinism for every execution. Consumers do not interpret opaque provider identities or compare them across providers.

Stages§

StageInputResponsibility
EvaluateBlueprintProduce and validate the Spec without effects.
ResolveSpec, previous Lock and source responsesExplicitly select dependency pins and record verification evidence.
FetchLockObtain and verify the pinned bytes without changing authority.
RealisePinned inputs and declared environmentMaterialize tools and activation data.
PlanSpec, Lock, request and execution systemValidate relationships and capability requirements before effects.
PrepareValidated build request and selected project filesCapture inputs and obtain the exact native build recipe and identity.
ExecutePrepared build or task planRun through the selected host or provider and validate results.
ActivateRealized environmentDescribe environment operations as data.
PresentTyped dataRender human output, JSON or shell syntax for a consumer.
InspectCommitted authority, and evidence explicitly suppliedDerive a read-only explanation without discovering hidden dependencies.

Preparation may fetch pinned content and write caches. It does not resolve new pins or start the requested build or dependency builds. A provider refuses preparation that would require unsupported evaluation effects. Execution uses the captured inputs and native recipe; it does not silently reevaluate a changed working tree.

Pure planning and effect execution§

The core library and provider adapters return data and constrained steps. They perform no I/O. A host performs the effects: the CLI is one host, and another application may import the same core types and execute authorized operations itself.

Executable steps are distinct from inspectable evidence. Parsing a saved record never authorizes executing it. Human output and JSON are renderings of the same typed result, never independently reconstructed models or raw provider output.

Authority, execution and release evidence§

The Lock is dependency authority, not a complete build description. A build also consumes its command, selected project files, tool options and declared dependency builds. Captured inputs can include untracked or task-generated files; the Lock alone cannot reconstruct them.

Every download the Lock records carries its trust record, so a reviewer of the lock diff sees where bytes came from and who vouched for their digest. A host the lock did not name before, whether declared or reached by redirect, is reported before the lock is written.

Successful-build evidence records what was prepared and obtained. It is disposable operational state, not a replacement lock. A failed build, planning or explanation never replaces the successful baseline. Missing or incompatible evidence means unavailable, never unchanged.

An SBOM describes selected artifact composition. Neither a lock projection nor an SBOM is a complete executable build graph. Release admission is repository policy: obtaining a cached result does not authorize adopting newly published bytes, and a producer keeps its own final build identity out of its recipe inputs so that identity cannot depend on itself.

Environment flow§

The diagram shows the environment path. Builds additionally consume captured project inputs and preparation evidence, as described above. Read-only reports inspect committed data and any execution evidence explicitly supplied to them.

Data flow through the environment layers
Figure 1. Data flow through the environment layers

Build and workflow execution§

A request validates structure and capabilities before effects. A workflow then executes in order and stops on failure. Each build captures its inputs when it is reached, after earlier tasks may have changed files. A repeated build step prepares again; the provider may reuse identical results through its cache. Blueprint never reuses a result by build name across intervening tasks.

Selected files and dependency identities let changes flow through the declared graph. Explanations distinguish changed declarations, changed build identities and measured output changes. A script that reads undeclared ambient inputs receives no guarantee beyond the executor’s enforced contract.

Commands use the same model§

Tasks use the common runner. Builds, preparation and explanations use the same request and prepared-build objects. JSON is presentation, not the architecture’s integration mechanism. Explanation compares a request with recorded evidence: the last successful local build, or any record explicitly supplied for comparison.

Invariants§

Invariant 1: The core is provider neutral§

A shared capability has one meaning. The Spec, the Lock and the core carry no provider concept outside namespaced hints and opaque provider-validated text: a reference, a package name and an executor’s settings are the owning provider’s to read. Explicit source ownership and executor selection determine routing; nothing ambient selects a provider.

Invariant 2: Every stage after Resolve is a pure function of named upstream facts§

Only Resolve chooses pins. Every later stage is a function of the Spec, the Lock, the execution system, the declared host facts and the captured project inputs, and of nothing else: no environment variable, installed tool or file that is not one of those. Two machines with the same upstream facts plan the same steps, prepare the same build and produce the same activation.

Invariant 3: Authority and evidence are separate§

Pins and their verification decisions belong in the reviewed Lock. Captured build inputs, results and measured outputs are execution evidence. Neither silently expands or rewrites the other.

Invariant 4: Pinned content is verified before every use§

Fetched bytes are checked against the Lock, and a tree unpacked from them is checked against its recorded digest, on every use. A damaged tree is rebuilt from its verified archive without a network request. Nothing in the store is exposed through a hard link, so no consumer can write into it. Native build caches use the provider’s own integrity contract.

Invariant 5: Materialization is disposable§

A cache may be deleted without losing committed authority. The Lock, the configuration and the captured project inputs together rebuild everything.

Invariant 6: Host dependence is explicit§

Expected tools are checked, not pinned. Tasks and configuration evaluation are not sandboxed. An isolation or reproducibility claim names the capability an executor enforces.

Invariant 7: Planning is pure and effects are constrained§

Providers return typed plans. Hosts execute only granted operations. Unsupported capabilities and invalid selected relationships fail before effects.

Invariant 8: Activation is data, and rendering happens at the edge§

An entered environment is an Activation value: search-path directories and variables, each naming what supplies it. The core produces it for what it realises, a provider for what it realises, and only a presenter turns it into shell syntax, CI files or JSON. Presenters own escaping. Machine and human presentations share one typed result; native process output is decoded first.

Invariant 9: Inspection declares what it reads§

Lock inspection reads committed authority without a Store or project evaluation. Build explanation reads committed authority and the execution evidence it is given. Missing coverage is explicit; an inspector never invents a complete graph from reports.

Invariant 10: One authoritative codec; JSON is interchange§

The Spec, the Lock, build records and every other authoritative or locally kept record are S-expressions with their own major and minor versions. JSON is for interchange and presentation only: reports a program reads, the output of a native tool the host decodes, and files written for another tool to consume. Nothing authoritative is read from JSON. A package version, a wire format and a compiler version are distinct. A format a consumer does not read is refused by name, never converted at runtime.

The coupling test§

An ecosystem implementing an existing capability needs an adapter, not a new shared meaning. A consumer uses typed plans, results and their renderings, not dependencies reconstructed from unrelated reports. A new capability may require versioned semantics or a constrained host effect; one provider’s syntax alone is not a reason for either.

Review a change by asking whether repository logic remains in scripts, source ownership is explicit, execution guarantees are accurate, identity comparisons are well-defined, and a provider could implement the capability without another provider’s native data.

What ships today§