> Documentation version: main. [HTML page](https://lukewilliamboswell.github.io/roc-blueprint/commands.html)

<a id="run-blueprint"></a>

# Run blueprint

Run project commands in the directory containing ` Blueprint.roc `, or set
` BLUEPRINT_ROOT `. ` compiler-version ` and ` store verify ` work in any directory.
` lock show ` needs only a committed lock, and works even when ` Blueprint.roc ` is
absent or invalid.

| Command | Meaning |
| --- | --- |
| ` blueprint ` / ` blueprint gen ` | Generate the Nix files under ` .blueprint/ ` from the lock. A project with no Nix package source has none, and nothing is generated |
| ` blueprint shell [NAME] ` | Enter the environment of the shell alias ` NAME ` (default ` default `): through ` nix develop ` when it has a tool from a Nix source, and otherwise in the caller’s own shell |
| ` blueprint run TASK [-- ARGS...] ` | Run the task’s argv in its environment, with the extra arguments appended |
| ` blueprint env NAME `, with ` --json `, ` --github-path ` or ` --github-env ` | Print what entering the shell ` NAME ` exports, as shell lines to ` eval `, a JSON report, or the lines a GitHub Actions step appends; nothing is entered |
| ` blueprint build NAME ` | Prepare and obtain an artifact plus declared dependencies through its selected executor; print its output path |
| ` blueprint plan build NAME [--prepare] [--json] ` | Inspect the build request; optionally prepare its exact provider build identity without executing builds |
| ` blueprint explain build NAME [--prepare] [--json] ` | Explain changes against the last successful local build; optionally compare exact prepared build identities |
| ` blueprint workflow NAME ` | Execute an ordered task/build workflow, stopping on failure |
| ` blueprint tasks ` | List tasks and their environments |
| ` blueprint update ` | Write ` Blueprint.lock `: the digest of every fetched program on every declared system, and the pins of package sources, inputs and build sources. See [What update needs and records](#what-update-needs-and-records) |
| ` blueprint update NAME... ` | Update only the named package sources, inputs, build sources and fetched programs, keeping everything else of a lock that is current for ` Blueprint.roc `. Local ` path: ` inputs are read again either way. A named program is resolved again whether or not its URLs changed |
| ` blueprint requirements [--json] [TASK...] ` | Say what the named tasks need, or every task: a provider, fetched programs, tools of the machine. See [What tasks need](#what-tasks-need) |
| ` blueprint lock show [--json] [NAME...] ` | Read committed pins and per-entry content identities without evaluating the project. See [Inspect committed pins](#inspect-committed-pins) |
| ` blueprint store verify [--repair] [--json] ` | Unpack every archive in the store of downloads again and compare each tree and its record with it, without a project or a download; exit 1 when anything differs. ` --repair ` makes what differs again. See [Verify the store](#verify-the-store) |
| ` blueprint check ` | Run the compiler check and validate all shell/task/build environments and executor declarations without requiring a lock |
| ` blueprint spec ` / ` blueprint flake ` | Print the Spec or the generated flake |
| ` blueprint compiler-version ` | Print the exact Roc release tag bundled with this Blueprint binary, for automation |
| ` blueprint --help ` | Project help; subcommand help lists tasks, aliases and builds |

<a id="align-an-automation-compiler"></a>

## Align an automation compiler

` blueprint compiler-version ` prints one release tag and a newline, with no
labels or colour. It reports this binary’s pinned compiler even when ` ROC `
or ` PATH ` selects another executable. It works offline without a project,
configuration evaluation, compiler installation or cache writes. Native smoke
tests run the actual bundled ` roc version ` and require it to match this tag
on every released system.

A CI check or commit hook can compare an installed automation compiler:

``` sh
test "$(roc-stable version)" = \
  "Roc compiler version $(blueprint compiler-version)"
```

A project can also compare its committed compiler pin with the reported tag
before installing tools. Keep upgrades explicit: align that pin when the
project’s automation is ready for the new compiler.

When a project fetches the same nightly with ` Recipes.roc_nightly `, it can
reuse the compiler archive Blueprint installed in its store. Matching tags
does not make an independently installed ` roc-stable `, such as a Nix package,
reuse Blueprint’s cached executable.

<a id="use-an-environment-from-another-program"></a>

## Use an environment from another program

` blueprint env NAME ` describes the shell ` NAME ` as data instead of entering
it: the directory of fetched programs the core puts first on ` PATH `, and what
the provider’s shell would export, obtained by asking the provider for its
shell as data (Nix answers with ` nix print-dev-env `). Nothing runs in the
environment. The directory of programs is kept at
` .blueprint/env/NAME/bin `, rebuilt on every call, so what was printed stays
valid until the next ` blueprint update `.

``` sh
eval "$(blueprint env dev)"              # this shell
blueprint env dev --github-path >> "$GITHUB_PATH"
blueprint env dev --github-env >> "$GITHUB_ENV"
blueprint env dev --json                 # for an editor or agent
```

The shell rendering single-quotes every value and prepends to the caller’s
own ` PATH `. The JSON report has ` format ` ` 1 `, ` path ` entries ` { directory, origin } ` first on the search path first, and ` variables ` ` { name, value, origin } `; ` origin ` names what supplies each, such as ` blueprint ` for fetched
programs or ` nix `. A provider’s shell variables that describe its own process,
such as ` HOME ` and ` PWD `, are not exported.

<a id="what-a-run-does-in-order"></a>

## What a run does, in order

` blueprint run `, ` shell `, ` workflow ` and ` build ` share the following
validation and execution boundary:

1. Read ` Blueprint.roc ` with the Roc compiler, and refuse what the
   configuration alone rules out, such as a task that does not exist or a
   program its recipe says is unavailable on this system.

2. Read ` Blueprint.lock ` and require that it matches ` Blueprint.roc `.


3. Plan every step of the request. All problems are reported together: a
   program the lock does not hold, one whose URLs changed, a build this
   machine cannot run.

4. Look on ` PATH ` for every program the steps need of the machine: the tools
   their environments ` Expect `, and ` nix ` when a step has a tool from a Nix
   source or is a build. Everything missing is named in one message.

5. Make every fetched program ready in the store, downloading what is not
   there and checking each against the lock.

6. Run the steps. Each gets its Roc packages published and its fetched
   programs first on ` PATH `.

Nothing is downloaded, generated or run for a request that fails an earlier
check. [Work without a provider](no-provider.md#the-store-of-downloads)
describes the store and the ` PATH ` of a step.

<a id="what-each-command-validates"></a>

## What each command validates

Provider capability checks follow the requested environment closure; unrelated
valid provider declarations do not block selected operations. Whole-project
structural validation and required-feature checks still apply. Full rendering
(` gen `, ` update `, ` check `, ` flake `) checks every shell, task and build
environment that Nix builds; one with no tool from a Nix source is entered
without Nix and is left out of the flake.

<a id="the-lock-and-generated-files"></a>

## The lock and generated files

- **Commit** ` Blueprint.roc ` and the authority (default ` Blueprint.lock `, a
  versioned S-expression listing each fetched program with its digest and
  each pinned source with its revision and digest);
  generated state (default ` .blueprint/ `) is not committed: ` blueprint `
  writes a ` .gitignore ` there that ignores everything in it.

- Normal ` gen `, ` shell `, ` run `, ` build ` and ` workflow ` require a lock that
  matches ` Blueprint.roc ` and never rewrite it. A lock that does not match
  says what changed, and one in a format this ` blueprint ` does not read is
  refused; both name ` blueprint update `.

- A fetched program is stale by itself. When its URLs in ` Blueprint.roc ` are
  not those in the lock, only requests that use it fail, and
  ` blueprint update <name> ` resolves it alone.

- ` nix develop ` takes the bash it runs a shell or task with from a flake input
  named ` nixpkgs `, so the generated flake gives that name to the first Nix
  package source declared and that bash is pinned by ` Blueprint.lock ` like
  every tool, unless the project declares an input named ` nixpkgs ` itself.

<a id="what-tasks-need"></a>

## What tasks need

` blueprint requirements ` reads ` Blueprint.roc ` and nothing else: not ` PATH `,
not the store and not ` Blueprint.lock `. It answers before anything is
installed or resolved, and gives the same answer on every machine. The system
is ` BLUEPRINT_TARGET `, or the one it runs on.

```
$ blueprint requirements
system x86_64-linux
providers: nix
task check [dev]: programs roc-stable; expects gh, git; roc packages 2
task host [zig]: provider nix (nix#zigpkgs."0.16.0"); programs roc-stable; expects gh, git; roc packages 2
```

With ` --json ` the report is one JSON object for a program to read:

``` json
{"format":1,"system":"x86_64-linux","providers":["nix"],"expects":["gh","git"],"tasks":[
 {"name":"check","environment":"dev","providers":[],"tools":[],"programs":["roc-stable"],"unavailable":[],"expects":["gh","git"],"roc_packages":2},
 {"name":"host","environment":"zig","providers":["nix"],"tools":["nix#zigpkgs.\"0.16.0\""],"programs":["roc-stable"],"unavailable":[],"expects":["gh","git"],"roc_packages":2}]}
```

| Field | Meaning |
| --- | --- |
| ` format ` | The number of this shape, ` 1 `. Every field below is always present. A change a reader of format 1 could misread gets another number. |
| ` system ` | The system the report is for. |
| ` providers ` | The providers that must be on the machine to run the reported tasks on that system, each once. ` "nix" ` is there exactly when one of those tasks has, in its environment on that system, a tool from a Nix package source. A Nix source that is declared and that no reported task uses does not put it there. Neither does a shell, a build or ` blueprint update `: they are not tasks. Build execution requirements follow the selected executor, and an update needs Nix only for declarations it owns. |
| ` expects ` | The programs those tasks expect the machine to have already, each once. |
| ` tasks ` | One object for each task, in the order asked, or in the order of ` Blueprint.roc ` when none is named. |
| ` tasks[].providers `, ` tasks[].tools ` | The providers that task needs, by the same rule, and the tools they supply, as ` Blueprint.roc ` writes them. |
| ` tasks[].programs `, ` tasks[].unavailable ` | The programs its environment fetches on that system, and those it lists that do not exist there. A task with an unavailable program cannot run on that system. |
| ` tasks[].expects `, ` tasks[].roc_packages ` | The programs the task expects of the machine, and how many Roc packages its environment has. |

A task that is not declared is an error, and nothing is printed for the
others. To install Nix only where it is needed, test whether ` providers `
holds ` "nix" ` for the tasks a job runs:

``` sh
blueprint requirements --json check | jq -e '.providers | index("nix")'
```

<a id="inspect-committed-pins"></a>

## Inspect committed pins

` blueprint lock show ` reads only ` Blueprint.lock `. It does not evaluate
` Blueprint.roc `, check freshness against declarations, invoke Roc or Nix,
access the network, or write generated files or caches. ` BLUEPRINT_ROOT ` and
` BLUEPRINT_LOCK ` select the project directory and lock path as usual; other
workspace, target and compiler settings have no effect. It reports committed
authority even when a working configuration has changed. Run ` blueprint gen `
when you need the ordinary freshness checks.

The stable S-expression lock remains the authority and is directly readable
through ` core.Lock `. The optional JSON projection gives Python, ` jq `, Nix and
other consumers public provider-qualified identities, digest kinds and native
metadata without decoding private provider hints. See
[Choose the authority or its public projection](lock-snapshot.md#choose-the-authority-or-its-public-projection)
for when to use each interface and the projection’s compatibility boundary.

Names select package sources, inputs, overlays, build sources, or fetched
programs. With no names, every entry is included. A program name selects all
its systems. Unknown names, unreadable locks, unsupported lock major versions
and inconsistent provider pins fail with nonzero status and no report on
stdout. Diagnostics go to stderr. Output order follows the lock; use the
per-entry identity when fingerprinting a dependency, rather than the output
bytes or whole lock.

` --json ` emits one JSON object followed by a newline. Its ` format ` is ` 2 `,
independent of the lock’s own format. Every field listed here is present; a
change a reader of format 2 could misread gets another number. Readers should
check ` format `, accept extra fields and treat ordering as insignificant.

``` json
{
  "format": 2,
  "sources": {
    "nix": {
      "name": "nix",
      "provider": "nix",
      "ref": "github:NixOS/nixpkgs/nixos-unstable",
      "rev": "4975466d324710c576dc11ad614684e6bd8cad8e",
      "digest": "sha256:c49f97e2106d39c00518139ee6700cc8c51e17d7e82419883aedcd8c1a81c9c5",
      "digestKind": "tree",
      "flatSha256": null,
      "content_identity": "sha256:c49f97e2106d39c00518139ee6700cc8c51e17d7e82419883aedcd8c1a81c9c5",
      "metadata": {
        "nix": {
          "fetchTree": {
            "type": "github",
            "owner": "NixOS",
            "repo": "nixpkgs",
            "rev": "4975466d324710c576dc11ad614684e6bd8cad8e",
            "narHash": "sha256-xJ+X4hBtOcAFGBOe5nAMyMUeF9foJBmIOu3NjBqBycU=",
            "lastModified": 1790185690
          }
        }
      }
    }
  },
  "fetched": []
}
```

| Field | Meaning |
| --- | --- |
| ` sources ` | Object keyed by the declared source name, covering package sources, inputs, overlays and build sources. |
| ` sources.NAME.name `, ` provider `, ` ref `, ` rev `, ` digest ` | The source fields recorded in the lock. ` rev ` is empty when absent. ` digest ` is the existing provider content digest; prefer ` content_identity ` for fingerprinting because aliases may have an empty recorded digest. |
| ` sources.NAME.content_identity ` | Per-entry pinned content identity, opaque outside the named provider. Compare identities together with ` provider `; unknown providers retain their recorded digest. For Nix and core file sources the identity is ` sha256:<hex> `. Nix remote entries use the decoded NAR hash, local entries the recorded Blueprint tree digest, and follows entries their resolved target’s identity. It is independent of names, mutable reference spelling, tasks, other entries, provider graph node names, and lock format minor versions. Unrelated updates and adding/removing tasks cannot change it. For trees it identifies the full source tree, including when a flake selects a subdirectory within that tree. For ` SourceFile `, it identifies the unchanged original file bytes. |
| ` sources.NAME.digestKind `, ` flatSha256 ` | ` digestKind ` is ` "file" `, ` "tree" `, or ` "unknown" `. Providers establish the kind; an unrecognized provider is never assumed to describe a tree. ` flatSha256 ` is the original file hash as 64 lowercase hexadecimal characters for core ` SourceFile ` entries, and ` null ` for all other sources. Core file sources have ` provider: "file" `, their URL in ` ref `, an empty ` rev `, and empty ` metadata `; their content identity is the original-file digest. |
| ` sources.NAME.metadata ` | All adapter-supplied typed metadata, namespaced by provider name. Consumers may use only fields whose provider-specific contract they understand. Unknown provider entries retain their recorded identity and have empty metadata. Duplicate metadata keys are refused, including nested keys. |
| ` sources.NAME.metadata.nix.fetchTree ` | For a remote Nix tree source, the exact locked fetch attributes, with string ` type `, ` owner `/` repo ` or ` url `, optional ` rev ` and numeric ` lastModified `, ` narHash `, and any applicable locked fetch flags or host metadata. No registry resolution or defaults are inserted. The flake-only ` dir ` selection is omitted because it is not a ` builtins.fetchTree ` argument. It is omitted for local paths; other providers define their own metadata. Local paths require a project location and Blueprint’s tree verification. |
| ` fetched ` | Array of program entries. Each has string ` name `, ` system `, ` sha256 `, ` content_identity `, array of string ` urls `, integer ` size ` (download bytes), string ` obtained ` (` computed `, ` published `, ` both `, or ` unstated `), array of string ` served ` and string ` witness `. ` served ` lists the hosts that served the bytes ` blueprint update ` hashed, after any redirect, sorted; it is empty when nothing was downloaded, as for a digest that was only published. ` witness ` is the address a published digest was read from, such as the GitHub releases API address of the release, and is empty when the digest was only computed. ` content_identity ` is ` sha256: ` followed by the download hash. URL or provenance changes do not change byte identity. |

An external producer can save a named pin without parsing Blueprint’s lock:

``` sh
blueprint lock show --json nix > locked-input.json
```

A Nix expression can consume that JSON directly:

``` nix
let
  locked = builtins.fromJSON (builtins.readFile ./locked-input.json);
  pin = assert locked.format == 2; locked.sources.nix;
  nixpkgs = builtins.fetchTree pin.metadata.nix.fetchTree;
in import nixpkgs.outPath { }
```

The inspector itself is offline; evaluating ` builtins.fetchTree ` may fetch the
source if Nix does not already have it. Use ` sources.nix.content_identity ` as the
producer’s input fingerprint so an unrelated ` roc-stable ` update does not
invalidate the producer’s artifacts.

<a id="verify-the-store"></a>

## Verify the store

Every use of a fetched program checks the store of downloads first: its
archive is hashed again and compared with the SHA-256 it is named by, and its
tree is hashed again and compared with the record written beside it when it
was unpacked. An archive that differs is downloaded again, and a tree that
differs is made again from its archive. That check guarantees a tree is what
its record says. It cannot see a tree and its record changed together, so
that they agree: nothing in it compares the tree with what its archive
unpacks to.

` blueprint store verify ` makes that comparison, at the cost of unpacking every
archive again. It hashes each archive in the store; for each tree with a
record, it unpacks the archive afresh into a scratch directory beside the
trees, never inside one, compares the tree and its record with that
extraction, and removes the scratch directory. It reads the store and nothing
else: not ` Blueprint.roc `, the lock, a compiler or the network. It changes
nothing.

```
$ blueprint store verify
intact /home/me/.cache/blueprint/v1/artifacts/sha256/<a>
tree differs /home/me/.cache/blueprint/v1/trees/sha256/<a>.tar.gz: it and its record agree, but it holds sha256:<x>, and its archive unpacks to sha256:<y>
intact /home/me/.cache/blueprint/v1/artifacts/sha256/<b>
intact /home/me/.cache/blueprint/v1/trees/sha256/<b>.file
store /home/me/.cache/blueprint: 4 checked, 3 intact, 1 tree differs
blueprint: the store is not intact; `blueprint store verify --repair` makes what differs again from its archive
```

Each archive is followed by its trees, in the order of their digests. A
finding is ` intact `; ` archive damaged `, when an archive is not its SHA-256;
` tree differs ` or ` record differs `, from the fresh extraction; ` no record `,
for a tree with none; or ` no archive `, for a tree whose archive is missing or
damaged, which nothing can verify without a download. The status is 0 when
every finding is ` intact `, and 1 otherwise.

` --repair ` then makes the store what it should be, and prints a ` repaired `
line for each change. A tree that differs, or has no record, is replaced by
its fresh extraction, with a record; a record that differs is written again.
A damaged archive is removed, and so is a tree with no archive, for the next
use to download the archive and make the tree from it. Nothing is downloaded,
and the status still says what was found: run ` verify ` again to see a clean
store.

` --json ` prints one JSON object for a program to read: ` format ` ` 1 `, ` store `,
` findings ` as ` { item, verdict, detail } ` with ` verdict ` one of ` intact `,
` archive_damaged `, ` tree_differs `, ` record_differs `, ` no_record ` and
` no_archive `, ` counts ` of each verdict, and ` repaired ` as ` { item, action } `.
The JSON is presentation: the records in the store remain S-expressions.

<a id="what-update-needs-and-records"></a>

## What update needs and records

` blueprint update ` is the command that explicitly selects dependency pins. It
writes the whole lock or nothing.

Pure Roc consumers can import the official ` core.LockSnapshot ` module from
this release’s existing core bundle. See
[Consume lock inspection in pure Roc](lock-snapshot.md#consume-lock-inspection-in-roc)
for typed parsing, lookups, metadata and the offline schema/profile.

<a id="without-nix-and-with-it"></a>

### Without Nix, and with it

` blueprint update ` starts Nix only when ` Blueprint.roc ` declares something Nix
resolves: a Nix package source, an input or overlay, or a build source,
including the bundle of a Roc package that a build uses. It looks for ` nix `
before doing anything else and says why it needs it:

```
blueprint: this machine lacks what blueprint update needs, and blueprint installs none of it:
  nix: Blueprint.roc declares the Nix source nix, which Nix resolves
```

A project that declares none of these is updated with no Nix on the machine.
In a project that does, the pins Nix resolves and the digests of fetched
programs share the one lock, and ` blueprint update PROGRAM... `, naming
fetched programs alone, asks Nix for nothing: it needs a lock that is already
current for everything else. A name that is neither an input nor a program is
an error that lists both kinds.

<a id="the-digests-of-fetched-programs"></a>

### The digests of fetched programs

For each fetched program and each declared system, the lock holds the URLs the
program is declared with, the SHA-256 and the length of the download, and how
the digest was obtained:

| ` obtained ` | Meaning |
| --- | --- |
| ` Computed ` | ` blueprint update ` downloaded the bytes and hashed them. Nothing else was to be had. |
| ` Published ` | The release that serves the download reports this digest, and the bytes were not downloaded. A run on that system checks its download against it. |
| ` Both ` | It hashed the bytes, and the release reports the same digest and length. |

A reviewer of a lock change reads these: ` Computed ` alone rests on the one
download ` blueprint update ` made, and ` Published ` on what the publisher’s
release says.

An entry whose URLs are unchanged is kept, and nothing is asked or downloaded
for it; a program named on the command line is resolved again regardless.
Otherwise the download for the system the update runs on is fetched and
hashed, and is kept in the store for the run that follows. A program that is
the very download ` blueprint ` fetched as its own compiler, as a
` Recipes.roc_nightly ` of that nightly is, is hashed from the store and not
fetched a second time.

When the first URL is a GitHub release asset,
` https://github.com/<owner>/<repo>/releases/download/<tag>/<asset> `, the
release is asked once what it publishes. A digest computed here that differs
from the published one stops the update, and nothing is written. For another
system the published digest is recorded and nothing is downloaded; an asset
with no published digest, or a URL that is not a release asset, is downloaded
and hashed instead.

<a id="when-the-release-cannot-be-asked"></a>

### When the release cannot be asked

The question to GitHub carries no token, and GitHub answers 60 such requests
an hour from one address. A question that is refused, that cannot be put, or
whose answer does not describe a release does not stop the update:
` blueprint update ` says so once for the release, downloads and hashes that
release’s assets for every system, and records each as ` Computed `. A digest
that is published and differs from the computed one always stops it. A run
never asks GitHub anything.

```
blueprint: could not ask for the digests roc-lang/nightlies publishes for its release nightly-2026-10-28-bad769b: HTTP 403 from https://api.github.com/repos/roc-lang/nightlies/releases/tags/nightly-2026-10-28-bad769b (1 attempt). GitHub answers 60 such requests an hour from one address when no token is sent, and blueprint sends none. The digests of its downloads are computed by downloading each of them instead, and Blueprint.lock records them as computed
```

Such an update downloads the program for every declared system, where one
that is answered downloads it for this machine alone.

<a id="new-download-hosts"></a>

### New download hosts

For each download it hashed, the lock records the hosts that served the
bytes, after any redirect, beside the URLs ` Blueprint.roc ` declares. Before
it writes the lock, ` blueprint update ` prints every download host the new
lock names and the lock before it did not, one to a line, and says whether a
URL in ` Blueprint.roc ` declares it or a redirect led there:

```
Blueprint.lock will name download hosts it did not name before:
  github.com, declared in Blueprint.roc
  release-assets.githubusercontent.com, reached by a redirect
```

It prints nothing when there is none. A new host in a lock update is worth a
reviewer’s look, and one reached by a redirect is named by no line of
` Blueprint.roc `. The list comes before the lock is written, so an update that
then fails to write it has still said what it would have named.

<a id="environment-variables"></a>

## Environment variables

- **` BLUEPRINT_ROOT `** names the directory containing ` Blueprint.roc `
  (default: the current directory).

- **` BLUEPRINT_WORKSPACE `**, **` BLUEPRINT_GENERATED_ROOT `**, **` BLUEPRINT_LOCK `**
  choose caller paths; relative values resolve against the selected project
  root, not the invocation directory. Out-of-tree generated roots are supported.

- **` BLUEPRINT_TARGET `** selects the declared execution system (default: this
  machine’s System), not a separate artifact target.

- **` ROC `** selects the compiler that reads ` Blueprint.roc `, which must be the
  nightly ` blueprint ` was built for; unset, a matching ` roc ` on ` PATH ` is
  used, or the nightly is downloaded into the store.

- **` XDG_CACHE_HOME `** names the directory that holds the store of downloads,
  ` blueprint/ `, and Roc’s package cache, ` roc/packages ` (default: ` .cache ` in
  ` HOME `).

- **` SHELL `** names the program ` blueprint shell ` starts for an environment
  with no tool from a Nix source (default: ` /bin/sh `).

- **` PATH `** is where expected tools, ` nix `, ` tar `, ` ln ` and ` chmod ` are found.


No variable selects a provider or turns Nix on or off: ` Blueprint.roc ` alone
decides what a request needs. No request ` blueprint ` makes carries a token or
any other credential, and it reads none from the environment.

