Skip to main content
Capabilities and Recipes are plain YAML files that live in your repository alongside your application code. There is no separate registry, no opaque binary format, and no external service required to store or share them. You commit them to Git, review them in pull requests, and share them with teammates the same way you share any other source file. When a teammate checks out your branch, they have everything they need to run the same Capability on their own machine.

What to commit

Commit these: Do not commit these: Run history is machine-specific runtime data. It doesn’t belong in version control and can grow large quickly. Add .doppels/ to your .gitignore:

Versioning Capabilities

Every Capability has a metadata.version field. Use semantic versioning — 1.0.0, 1.1.0, 2.0.0 — and treat each published version as immutable.
Once a Capability version has been referenced in a Run, re-publishing a different manifest with the same version number is an error. The capabilityRevision digest would change, making the new manifest incompatible with any existing run records. Always increment metadata.version when you change a Capability’s inputs, outputs, or display name.
The same immutability rule applies to Recipes that are referenced by a Share. If a Recipe version has been pinned in a capabilityRevision, changing it without bumping the version breaks the digest check. Increment metadata.version in the Recipe as well whenever you change its steps.
1

Freeze the session

After working through a problem in your agent, say the freeze phrase to trigger the doppel-freeze skill. The skill writes capabilities/<name>.yaml and recipes/<name>.yaml in your project.See Freeze with Agent for the full walkthrough.
2

Review the YAML diff

Open the new files in your editor. Check that:
  • Inputs match what you actually need to provide
  • Steps reflect the commands and operations from the session
  • Outputs capture the values you care about
  • Approval settings are appropriate for the operation’s risk level
Treat this review the same way you’d review a new script or migration — the YAML is code.
3

Validate

Run doppels validate to confirm the manifests are clean before committing.
Fix any errors reported. Common issues: a returns key that doesn’t match a declared output, an expression referencing a step result that isn’t yet produced, or a missing approval on a step.
4

Commit the YAML files

Stage and commit the Capability and Recipe files.
The commit is the repeatable asset. The YAML is all a teammate needs to run the same Capability.
5

Share with teammates

Push the branch or merge to main. Teammates pull the changes and run the Capability locally with their own credentials:
No special setup required beyond having doppels on their PATH. The freeze skill is only needed if they want to freeze new sessions of their own — running an existing Capability needs only the CLI.

Forking and modifying Recipes

Because Recipes are plain YAML in your repository, anyone on the team can fork them, adjust steps, and run a modified version. To create a variant:
  1. Copy recipes/<name>.yaml to recipes/<name>-variant.yaml
  2. Adjust the steps, add new requires, or change the shell commands
  3. Keep provides: [<name>] pointing at the same Capability — the contract doesn’t change, just the implementation
  4. Run doppels validate to confirm the modified Recipe still satisfies the Capability’s outputs
  5. Run it: doppels run capability/<name>
The CLI will discover both Recipes providing the same Capability. If there are multiple, it will ask which one to use.

Code review guidelines

Treat Capability and Recipe YAML changes like any other source change. When reviewing a pull request that modifies these files, check:
  • Inputs: Are required inputs clearly named and typed? Are optional inputs given reasonable defaults?
  • Steps: Do the shell commands do what the step name says? Is anything destructive or irreversible?
  • Approval settings: Steps that write to databases, call external APIs, or modify infrastructure should have approval: local or approval: always unless the context clearly warrants never.
  • Returns: Does returns cover all the outputs declared in the Capability? Are the expressions correct?
  • Version bump: If an existing Capability is changing, did the author increment metadata.version?
Adding a Capability is a low-risk change — it’s purely additive. Changing an existing Capability’s inputs or outputs is a breaking change for anyone who depends on that version. Always increment the version and consider whether existing callers need to be updated.