Skip to main content
All Doppels manifests share a single apiVersion: doppels.so/v1alpha1 and are validated against JSON Schema Draft 2020-12. The YAML you write is a deterministic subset of the full YAML specification: no tags, timestamps, anchors, aliases, or merge keys are permitted. Numbers follow JSON numeric grammar. This constraint ensures that manifests parse identically across every runtime and toolchain that implements the schema, and that diffs stay readable in code review.

Capability schema

A Capability defines the public contract of an automation — what inputs it accepts and what outputs it guarantees. It says nothing about how the work gets done; that responsibility belongs to a Recipe. A Capability can exist without a Recipe, in which case a person fulfills the contract manually.

Input and output types

All declared outputs are part of the required result. A run that does not produce every declared output is an error.

Recipe schema — shell runtime

A Recipe defines how a Capability runs. It declares provides to bind itself to one or more Capabilities, and it lists the ordered steps that produce the required outputs. The shell runtime runs each step’s script in an isolated sh or bash process.
Steps execute in the order they are declared. stdout and stderr are logged but are not results — only values captured via produces become outputs. returns must cover every output declared in every Capability named in provides.

produces capture methods

defaults.approval values

Approval is never inferred. Every step resolves its approval policy from defaults.approval or its own approval field.

Recipe schema — manual runtime

The manual runtime records a human fulfillment of a Capability. Instead of steps and scripts, it points to a runbook document and collects evidence from the person completing the work.
The procedure explains the expected work. Outputs are collected directly according to the Capability contract, and evidence captures any proof-of-completion that the procedure requires beyond the standard outputs.

Space schema

A Space is the configuration boundary for a project. It groups the Capabilities and Recipes discovered by convention within its directory and associates them with an Organization context. Capabilities and Recipes are discovered from the filesystem — they are not enumerated inside the Space manifest itself.
Note that Space has no metadata.version field. Unlike Capabilities and Recipes, a Space represents mutable desired state rather than a published, immutable definition.

YAML rules

These rules apply to all Doppels manifests. The doppels validate command enforces them.
  • Paths must be POSIX-style and relative to the workspace. No absolute paths (starting with /), no drive prefixes (C:), no backslash separators (\), and no parent-directory segments (..). This keeps manifests portable across macOS, Linux, and Windows.
  • Never use {{ }} expressions inside run.script. Inject values through the env: block and reference them as normal shell variables ($NAME). This prevents shell injection vulnerabilities.
  • Quote ambiguous tokens. YAML plain scalars like yes, no, on, off, ~, and date-like strings are interpreted differently by YAML 1.1 and 1.2 parsers. When you intend them as strings, always quote them: "yes", "on", "~".
  • Comments and block scalars are allowed. Use # for comments and | or > for multiline strings (scripts, runbook paths, etc.).
  • Prohibited YAML features: tags (e.g. !!str), timestamps, anchors (&anchor), aliases (*alias), and merge keys (<<:). None of these are permitted in any Doppels manifest.