A Recipe source supplies files to discovery. It does not grant those files permission to run a server, forward a credential or change a system. This guide targets Sonny 0.12.7 and users who can inspect the files they install. The local-directory and Git-tag workflows below were exercised with disposable sources; they require no access to Sonny’s private repositories.

Choose how to load the files

ChoiceEffect
sonny run --file ./brief.yamlLoads that one Recipe. Related prompt fragments can still be read relative to it; a separate parent Recipe is not automatically discovered.
sonny run --dir ./review-recipes --recipe evidence-briefUses that directory selection instead of normal discovery and selects its named Recipe.
sonny recipe add ./review-recipes --name review-localRegisters a dedicated local directory as a source and copies a snapshot into Sonny’s cache. Reloading reads the original again.
A tracked Git sourceClones approved content into the cache; branch policy or a release-tag pin controls updates.

For inspection, use sonny recipe resolve evidence-brief --file ./brief.yaml --format json or --dir ./review-recipes instead of starting a task. Here, evidence-brief is the ID of the complete research Recipe . The resolve directory flag replaces default discovery. Do not infer a different command’s flags from its name; inspect --dir, for example, is described by that command as an additional directory.

Register a dedicated local directory

After downloading and reviewing the research example, work from its parent directory. Keep only the intended Recipe, fragments and public inputs in review-recipes; a directory snapshot can copy more than one YAML file.

sonny recipe add ./review-recipes --name review-local --update-policy manual --no-model-catalog
sonny recipe list
sonny recipe resolve evidence-brief --format json

recipe list lists sources by default. Use sonny recipe list --recipes to list discovered Recipes. The source’s name and the Recipe’s pack.id are different identifiers.

The executed local-source case copied version one, left it active after editing the original under manual policy, and loaded version two after:

sonny recipe reload review-local

The original directory was unchanged by add, reload and remove. file:// source URLs were refused; use the supported local path form for a directory you own. An unreviewed directory is not made trustworthy by snapshotting it.

Understand which definition wins

Without explicit file/directory selection, discovery merges embedded Recipes, the effective system directory, the user’s data-directory Recipes, registered sources in configuration order, and the owned project ancestor chain. Later definitions win a duplicate ID, with deeper project definitions overriding shallower ones. Byte-identical copies can be deduplicated. Protected embedded IDs have additional signature/override requirements.

The installed test confirmed a source overriding a user copy, a project copy overriding the source, and explicit file/directory loading selecting its own copy instead. Inspect the resolved subject and provenance before running an ID that occurs in several locations. Project Recipe discovery and permission to contribute project model endpoints have separate trust rules; see model catalog trust .

On Linux, user Recipe files normally live under $XDG_DATA_HOME/sonny/packs, not the configuration directory. Source settings live in $XDG_CONFIG_HOME/sonny/pack-sources.yaml; source caches live under $XDG_CACHE_HOME/sonny/pack-repos/<name>. Platform paths and overrides are covered by configuration . Treat cache content as replaceable.

Pin a reviewed Git release

For an already reviewed Git repository, the syntax is:

sonny recipe add <approved-repository-url> --name <source-name> --pin <semver-tag> --no-model-catalog

Angle-bracket values are replacements, not a runnable repository recommendation. Use an acquisition URL your account is authorized to access. Existing Git credentials govern access; do not embed tokens in the URL or Recipe.

In the local Git qualification, --pin v1.0.0 selected that tag despite newer commits and tags. An unnamed recipe update left it pinned. A missing requested tag failed instead of selecting a branch. These are dated fixture tag names, not Sonny release requirements.

--pin latest selected the highest available semantic-version tag and recorded it as resolved_pin. A later tag did not change the selected files on ordinary load; explicit reload selected the new tag and updated that record. Thus latest is a moving selection on refresh, not a permanent content identity. Record the resolved tag, repository commit and file hashes with your evidence. A tag name alone is not proof that a remote repository’s history cannot change.

Review updates and rollback

An unpinned on_startup source can be refreshed during discovery. A manual source changes on explicit update/reload. Git refreshes can reset and clean the cache; do not keep your work there. Edit the original directory or an authorized working repository, review it, then reload. A failed refresh can leave cached content active: inspect the warning and actual resolved version before relying on a change.

To roll back, select the previously reviewed release/files, reload deliberately and repeat the acceptance checks. Model-variant pins are a separate mechanism; they do not pin a source repository or grant access to its content.

sonny recipe remove review-local

Removal unregisters that source and removes its cache. Another user/project copy of the same ID can remain discoverable. It does not retract prompts or results already sent to a provider or saved in session/export state.

Keep approvals separate

The example uses --no-model-catalog and grants neither routing nor MCP approval. A source can also ship model catalogs, MCP definitions and environment-variable references. Review those independently before using approval commands. A source pin, signature or natural-language instruction does not replace endpoint admission, tool policy, execution isolation or an operator’s consent.

Continue with Recipe authoring , model setup and MCP trust boundaries .