Recipes, profiles, and components¶
This guide explains how a data engineer creates a pipeline from a platform-owned recipe and how a platform engineer publishes that recipe safely. The beginner path stays declarative: no Airflow Python, Vault path, pack, or Kubernetes object is required.
Built-in recipes remain the shortest First DAG path. Use an external recipe when the platform team needs reusable defaults, locked policy, or a reusable process subgraph.
Start from your route (source → sink). Built-in recipes map to common routes:
| Recipe ref | Route (source → sink) | Strategy |
|---|---|---|
mssql-to-clickhouse-incremental |
MSSQL → ClickHouse | incremental merge (incremental_merge) |
postgres-to-clickhouse-incremental |
PostgreSQL → ClickHouse | incremental merge (incremental_merge) |
postgres-to-clickhouse-full-refresh |
PostgreSQL → ClickHouse | full refresh (full_refresh) |
See First Airflow DAG and the source → sink matrix.
Data engineer: create a pipeline¶
1. Discover recipes¶
dpone recipe list \
--source mssql \
--sink clickhouse \
--strategy incremental_merge
dpone recipe show mssql-to-clickhouse-incremental
These commands work with the built-in catalog in a fresh project. list is
optional when the First DAG guide already gives you the exact built-in name.
External recipes require a platform-configured catalog and always use
id@MAJOR.MINOR.PATCH; latest, ranges, and unpinned Git references are
rejected.
The show command returns safe metadata, available parameters, and allowed
profiles. Discovery also returns route support, certification evidence,
required install extras, limitations, and a structured next-command argv.
It does not print Vault paths, secret values, or environment bindings.
Abridged list --format json output:
{
"recipes": [
{
"ref": "mssql-to-clickhouse-incremental",
"route_id": "mssql:clickhouse:incremental_merge",
"support_status": "supported",
"evidence_status": "UNVERIFIED",
"scaffoldable": true
}
]
}
Abridged show --format json output includes the exact next command:
{
"ref": "mssql-to-clickhouse-incremental",
"source": "mssql",
"sink": "clickhouse",
"strategy": "incremental_merge",
"scaffold_argv": [
"dpone", "init", "pipeline", "<pipeline_id>",
"--recipe", "mssql-to-clickhouse-incremental"
]
}
Install extras describe drivers needed for live checks or runtime execution.
They are not required for offline recipe discovery, scaffolding, static
check, or Airflow preview.
2. Create the authoring source¶
For the built-in beginner route:
The equivalent route-first form resolves the one declared default recipe before writing any files:
--route and --recipe are mutually exclusive. Both forms resolve through the
same capability snapshot before any file is written. A runtime-supported route
without a beginner recipe reports DPONE_ROUTE_NOT_SCAFFOLDABLE; an explicit
external recipe whose declared route is absent or unsupported reports
DPONE_ROUTE_NOT_SUPPORTED. Both failures leave the project unchanged.
For a configured platform catalog:
dpone init pipeline orders_daily \
--recipe governed-mssql-clickhouse@1.2.0 \
--profile incremental-defaults@1.0.0
The command writes one editable dpone.flow.v1 primary source, its domain
catalog entry, and a test skeleton. Repeating the same command is a deterministic
no-op. Recipe, profile, and component files remain platform-owned inputs; dpone
does not copy or expand them into another editable manifest.
For allowed per-pipeline values, use a project-confined answers file:
source_connection_ref: mssql_sales_prod
sink_connection_ref: clickhouse_analytics_prod
source_table: orders
dpone init pipeline orders_daily \
--recipe governed-mssql-clickhouse@1.2.0 \
--profile incremental-defaults@1.0.0 \
--answers answers/orders_daily.yaml
Answers are bounded scalar values. Credential-like keys and values are rejected.
Use logical connection_ref values; credentials continue to resolve through the
environment binding and credential resolver at workload start.
3. Check and preview¶
All three commands resolve only the exact artifact paths and SHA-256 digests pinned in
the primary source. They perform no network, Vault, Airflow Connection, Variable,
or metadata database calls. The JSON output includes recipe_resolution with
the catalog id, recipe/profile/component refs, ordered closure digests, owner,
status, and domain.
Optional: Run the platform-gated safe sample¶
The sample path independently verifies the primary source and complete recipe closure against the pinned workload pack before credentials or data access. A changed artifact blocks the run and asks for a new build/deployment.
What dpone generates¶
The primary source contains an exact, replayable recipe lock:
kind: dpone.flow.v1
authoring:
mode: flow
source: pipelines/orders_daily/pipeline.yaml
metadata:
id: orders_daily
domain: sales
tags:
- dpone
- airflow
recipe:
catalog_id: data-platform
ref: governed-mssql-clickhouse@1.2.0
artifact_ref: platform/recipes/recipes/governed-mssql-clickhouse-1.2.0.yaml
sha256: sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
profile_ref: incremental-defaults@1.0.0
parameters:
source_connection_ref: mssql_sales_prod
sink_connection_ref: clickhouse_analytics_prod
source_table: orders
The compiler resolves the pinned data-only closure and then delegates to the existing canonical batch compiler:
flowchart LR
SRC["One dpone.flow.v1 source"] --> RES["Bounded recipe resolver"]
RES --> PROC["Expanded process mappings"]
PROC --> COMP["Canonical authoring compiler"]
COMP --> IR["Generated dpone.batch.v1 IR"]
IR --> PACK["Immutable workload pack"]
PACK --> AF["Static Airflow provider"]
PACK --> RUN["Runtime executes canonical IR"]
Recipe parsing and expansion happen only on the build plane. Airflow DAG parsing reads the static deployment index/spec/pack. Runtime may verify source digests, but it executes the materialized canonical IR and never imports or executes a recipe plugin.
Platform engineer: publish a catalog¶
Project trust configuration¶
Configure one local materialized catalog and an explicit allowlist:
schema: dpone.project.v1
authoring:
primary_source_policy: one_per_pipeline
recipe_catalog:
path: platform/recipes/catalog.yaml
trusted_catalog_ids:
- data-platform
The catalog itself contains exact pins:
schema: dpone.recipe-catalog.v1
catalog_id: data-platform
artifacts:
- kind: recipe
ref: governed-mssql-clickhouse@1.2.0
artifact_ref: platform/recipes/recipes/governed-mssql-clickhouse-1.2.0.yaml
sha256: sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
The recipe owns its allowed profile pins and ordered component pins. A profile
provides defaults and locked parameter names. A component contains declarative
process mappings with whole-value $param or $context placeholders.
Pin and validate¶
pin prints the logical kind/ref/path/SHA-256 entry to review before adding it to
the parent artifact or catalog. validate reads the complete catalog closure,
checks identities, schemas, bounds, digest pins, parameter references, and
declarative-only constraints. Neither command modifies source files.
Artifact versions are immutable. Never replace bytes behind an existing kind/ref/digest. Publish a new version, update the parent pin, validate, and let ordinary source review select that exact version.
For environment promotion, package the validated closure as an externally signed, content-addressed directory. The data engineer command does not change; this is a platform CI control. See signed catalog bundles.
Lifecycle¶
Supported publication-time states are experimental, stable, and
deprecated. A pinned deprecated artifact still compiles deterministically and
emits DPONE_RECIPE_ARTIFACT_DEPRECATED:<kind>:<ref>. The old immutable file is
not edited to add a replacement. Migration guidance belongs in platform docs and
catalog discovery.
Parameter rules¶
Precedence is deterministic:
- At most 64 scalar parameters are accepted.
- A profile can lock parameters; locked names cannot appear in the override allowlist.
- Identifier and
connection_refformats are validated before expansion. - Placeholders replace a complete YAML value only. String interpolation is not supported.
- Python, module, callable, shell, command, Jinja/template syntax, credential fields, and dynamic secret lookups are rejected.
Bounds and trust¶
| Contract | Limit |
|---|---|
| Catalog entries | 1,000 |
| Catalog or artifact | 1 MiB |
| Complete recipe closure | 8 MiB |
| Components per recipe | 32 |
| Expanded processes | 100 |
| Expansion nodes | 10,000 |
All paths are project-relative POSIX paths. Traversal, backslashes, symlinks, non-regular files, YAML aliases/anchors, duplicate keys, and digest mismatches fail closed.
Diagnose and recover¶
Machine-readable failures use dpone.error.v1. Stable exit codes are:
| Exit | Meaning |
|---|---|
1 |
validation or catalog contract failed |
2 |
bad CLI/ref/authoring-mode usage |
4 |
security or safety policy violation |
Common recovery commands:
dpone recipe list
dpone recipe show governed-mssql-clickhouse@1.2.0
dpone recipe validate
dpone airflow explain orders_daily
Filtered recipe list output contains both routes[] and recipes[]. A
runtime-supported route therefore remains visible with
beginner.recipe_available: false when no scaffold recipe exists. Invalid
capability evidence configuration returns passed: false, includes
issues[], exits 1, and writes JSON to stderr; successful discovery writes
to stdout.
On a digest mismatch, restore the exact immutable bytes or publish a new version;
do not rewrite the digest to bless unreviewed content. On
DPONE_RECIPE_SOURCE_CHANGED_DURING_BUILD, rerun check/preview only after the
source tree is stable. A failed scaffold writes no partial pipeline bundle, and a
failed preview does not publish a current release/deployment.
See the exact CLI reference, compatibility policy, and per-code pages under the error catalog.