0005. Templating with double brackets and typed whole-expression evaluation
- Status: Accepted
- Date: 2026-10-07
- Related: ADR-0004
Context
Blueprints are collector configurations with parameters. The collector has its own substitution syntax: ${env:NAME}, ${file:path}, ${VAR} and the escape $$. The server must not interpret or damage it, because secrets are referenced that way and resolved on the host (security model).
Parameters have types: numbers, booleans, durations, lists and maps. A rendered configuration where limit_percentage becomes the string "75" or a list becomes a joined text would be wrong or invalid.
Decision
Templates use the delimiters [[ and ]] (Go text/template, with an error on missing keys) and are evaluated per string value, after the YAML has been parsed.
- A string that consists of exactly one
[[ expression ]]is evaluated as a typed whole expression: the result keeps its type (number, boolean, list, map). - Any other string is interpolated and stays a string. Lists and maps are never converted to text implicitly; the author uses an explicit function such as
joinortoJson. - The collector syntax
${...}and$$is left untouched. - Templates have no access to the environment, files or the network, and are bounded in output size, nesting and run time (security model).
Consequences
Positive
- No collision with the collector’s substitution syntax.
- Types survive rendering, so numeric and list-valued settings are valid YAML values in the result.
- Because templates act on parsed values, a parameter value cannot change the structure of the document.
Negative
- A YAML value that starts with
[[must be quoted, otherwise YAML reads a flow sequence. The validator reports a typical symptom as a distinct issue code. - Authors must know the difference between whole-expression and interpolated strings.
- Templating is a restricted subset of
text/template; some constructs (define,template,block) are not available.
Alternatives considered
- Text templating before the YAML parse: exposes the configuration to YAML injection and indentation mistakes.