# Author a Blueprint

Package an application, validate its contract, test the exact candidate, and release it to a chosen audience.

Canonical: https://docs.deliberate.space/blueprints/authoring/

A Blueprint turns a tested application topology into one versioned deployment
for other Teams—or only your own Team—to reuse. Start private, expose only the
settings and connections deployers need, and release a version only after its
exact candidate works in a preview Environment.

## 1. Define the contract and resources

A bundle contains one `blueprint-manifest` followed by ordinary deliberate.
resources. This minimal example exposes one setting and one HTTP entry point:

```yaml
resource: blueprint-manifest
name: hello
namespace: acme
version: 0.1.0
category: Developer
title: Hello
license: MIT
licenseUrl: https://example.com/license
description: A small example web application.
arguments:
  - key: GREETING
    prompt: Greeting shown on the home page
    type: string
    default: Hello

---
resource: component
name: app
image: ghcr.io/acme/hello:1.0.0
cpu: 0.5
memory: 512Mi
env:
  GREETING: "${args.GREETING}"
ports:
  - port: 8080
healthcheck:
  path: /health
  port: 8080

---
resource: exposure
name: app
protocol: http
visibility: public
rules:
  - path: /
    to: app
open:
  - label: Open Hello
    path: /
```

An exposure asks the deployer to choose the outward hostname and public/private
visibility. It does not silently publish a Component. Keep the first-run path
public when a new user must reach it before they can enrol a Private Net device.

## 2. Keep the deployer-facing surface small

Use:

- `arguments` for values a deployer must choose;
- secret arguments for customer-supplied credentials;
- `generate` for credentials that can be minted once per instance;
- `provides` for values another Blueprint or Component may consume;
- `exports` for internal resources consumers may connect to; and
- `dependencies` for pinned Blueprints that are part of your implementation.

Resources are sealed unless exported. A parent Blueprint can configure a pinned
dependency and expose a smaller contract, so its customer still deploys one
coherent application rather than wiring every database, cache, and search
service individually.

Avoid arguments that merely expose implementation detail. Good defaults reduce
deployment friction and give the maintainer room to improve the internal
topology in later releases.

## 3. Validate and expand locally

Put the bundle in one multi-document YAML file or a directory of YAML files:

```sh
deliberate blueprint validate ./hello
deliberate blueprint expand ./hello --args '{"GREETING":"Hello, Team"}'
```

`validate` checks the bundle against the current schema. `expand` resolves its
contract and shows the resources a deployer would receive without publishing.

## 4. Publish a candidate and test it

Publishing creates an immutable candidate; it does not immediately make the
version discoverable to consumers:

```sh
deliberate blueprint publish ./hello --notes "Initial candidate"
```

Open **Blueprints → Manage**, select that exact candidate, and deploy it into a
disposable `preview-*` Environment. Choose its exposure, supply representative
arguments, and test first-run onboarding, health, persistence, backups, alerts,
and restart behavior. Fixes require a new semantic version and a new candidate;
published versions are immutable.

## 5. Release and choose the audience

Release the tested candidate:

```sh
deliberate blueprint release acme/hello@0.1.0
```

Audience is independent of release state:

```sh
deliberate blueprint visibility acme/hello --visibility private
deliberate blueprint visibility acme/hello --visibility unlisted
deliberate blueprint visibility acme/hello --visibility public
```

- **Private** keeps it within the publishing Team.
- **Unlisted** allows deployment by exact reference without catalogue discovery.
- **Public** adds it to the public catalogue.

Team-internal and public Blueprints use the same candidate validation, preview,
release, deployment, and upgrade path.

## Publish an upgrade

Bump the semantic version, pin any upgraded dependency versions, validate,
expand, and publish a new candidate. Test that candidate against a copy of the
production Environment before releasing it. Existing instances remain pinned;
deployers see an available update and approve it explicitly.

Do not fork an upstream Blueprint merely to republish it under a different name.
A fork is an independently maintained escape hatch, receives no upstream
updates, and retains its provenance. Prefer composition when you want to add
behavior while continuing to consume the maintainer's releases.

## Next steps

- [Manage a deployed Blueprint](/blueprints/lifecycle/)
- [Test a candidate in a preview Environment](/deploy/environments/)
- [Review the complete YAML vocabulary](/reference/yaml/)
