Skip to main content
Doppels manifests use {{ ... }} template expressions to wire inputs into step environments and pass step outputs into your Capability’s declared returns. Expressions let you write manifests that are fully self-contained and deterministic — the same inputs always flow through the same paths to the same outputs, with no side channels or implicit state.

Syntax

There are exactly two expression forms: Expressions appear inside double-curly-brace delimiters and must be placed within quoted YAML strings. For example:

Where expressions are allowed

Expressions are valid in exactly three locations within a shell Recipe:

1. env values in steps

Use expressions to inject inputs (or prior step results) into a step’s environment before the script runs.

2. Declarative produces.file paths

Use expressions to construct artifact file paths that incorporate input values or step results.

3. returns values

Use expressions to map step results to the outputs declared in the Capability contract.

Where expressions are NOT allowed

Inside run.script

You must never place {{ }} expressions directly inside a step’s run.script block. Instead, inject the value through env: and reference it as a normal shell variable. Wrong — do not do this:
Correct:
This restriction exists to prevent shell injection: if a user provides a malicious input value, an expression embedded directly in the script would execute arbitrary code. Routing values through environment variables eliminates that risk.

Anywhere outside the three permitted fields

Expressions are not evaluated in metadata fields, requires, defaults, procedure, evidence, or any other part of a manifest. Use them only in env values, declarative produces.file paths, and returns values.

Complete wiring example

The example below shows all three permitted uses in a single step, along with the corresponding returns section.

Type coercion in returns

When a step’s produces.env captures an exported shell variable, the value arrives as plain text. The returns block converts that text to the type declared in the Capability’s outputs. The rules are strict — there is no lenient coercion and no whitespace trimming: If a captured value does not satisfy the target type’s rule, the run fails with a type conversion error. Export your shell variables in the exact format the Capability expects.