Step-by-step migration guide from legacy Pinocchio config keys to the unified app/profile/profiles document model.
This guide explains how to rewrite older Pinocchio config files to the current unified document model.
Use it when your config still contains legacy keys such as:
repositories at the top levelprofile-settings.*ai-chatopenai-chatclaude-chat.pinocchio-profile.ymlThe new model is intentionally stricter. Pinocchio now expects one unified config document with three semantic blocks:
appprofileprofilesThat means old top-level runtime sections are not read anymore. If you leave them in place, Pinocchio will fail loudly instead of silently guessing.
The old model mixed several concerns together in one flat app config file:
The new model separates those concerns explicitly:
app contains Pinocchio-owned application settingsprofile contains profile selection plus imported registry sourcesprofiles contains inline engine-profile definitions stored directly in the config documentA minimal unified document looks like this:
app:
repositories:
- ~/code/prompts
profile:
active: default
profiles:
default:
inference_settings:
chat:
api_type: openai
engine: gpt-5-mini
Use this table as the quick translation reference.
| Legacy shape | New shape | Notes |
|---|---|---|
top-level repositories: | app.repositories: | Pinocchio-owned application config |
profile-settings.profile | profile.active | Selected/default profile |
profile-settings.profile-registries | profile.registries | Imported engine-only registries |
.pinocchio-profile.yml | .pinocchio.yml | Local project override filename |
top-level ai-chat, openai-chat, claude-chat, similar runtime sections | profiles.<slug>.inference_settings or external profiles.yaml | There is no new top-level runtime block |
The most important migration rule is this:
There is no direct top-level replacement for old runtime sections.
If you previously kept model/provider defaults in top-level ai-chat or provider sections, move them into:
profiles.<slug>.inference_settings, orprofiles.yaml referenced from profile.registriesIf you have a repository-local or working-directory-local override file named:
.pinocchio-profile.yml
rename it to:
.pinocchio.yml
Pinocchio now rejects the old filename.
The supported local discovery order is:
.pinocchio.yml.pinocchio.yml--config-fileapp.repositoriesOlder config often used:
repositories:
- ~/code/prompts
- ~/.pinocchio/repository
Rewrite that to:
app:
repositories:
- ~/code/prompts
- ~/.pinocchio/repository
This is the easiest part of the migration.
profile-settings.* into profile.*Older config often looked like this:
profile-settings:
profile: assistant
profile-registries:
- ~/.config/pinocchio/profiles.yaml
Rewrite it to:
profile:
active: assistant
registries:
- ~/.config/pinocchio/profiles.yaml
Use:
profile.active for the selected/default profile slugprofile.registries for imported engine-only registry sourcesAt this point, you need to decide where the actual engine settings live.
This is the simplest migration when you previously had one personal config file with one default model.
Use inline profiles:
app:
repositories:
- ~/.pinocchio/repository
profile:
active: assistant
profiles:
assistant:
display_name: Assistant
inference_settings:
chat:
api_type: openai
engine: gpt-5-mini
This is the best target when:
profiles.yamlThis is the best target when you already have an external engine-profile registry file.
Unified app config:
app:
repositories:
- ~/.pinocchio/repository
profile:
active: assistant
registries:
- ~/.config/pinocchio/profiles.yaml
External engine-only registry:
slug: workspace
profiles:
assistant:
slug: assistant
inference_settings:
chat:
api_type: openai
engine: gpt-5-mini
This is the best target when:
profiles.yaml across multiple commands or machinesprofiles.<slug>.inference_settingsThis is the part that usually causes confusion.
Older config often kept engine settings in top-level runtime sections such as:
ai-chat:
ai-api-type: openai
ai-engine: gpt-5-mini
openai-chat:
openai-api-key: ...
claude-chat:
claude-api-key: ...
Do not try to keep these at the top level. The unified document does not support that shape.
Instead, decide what role those settings were playing.
Create an inline profile and make it active:
profile:
active: default
profiles:
default:
inference_settings:
chat:
api_type: openai
engine: gpt-5-mini
Move them into the engine-only profiles.yaml registry format and reference that file from profile.registries.
Prefer environment variables rather than copying secrets into every profile.
For example:
export OPENAI_API_KEY=...
export ANTHROPIC_API_KEY=...
This is usually cleaner than repeating credentials inside multiple inline profiles.
If you truly need profile-specific credentials, keep them under that profile's inference_settings. But avoid committing secrets to repository-local .pinocchio.yml files.
repositories:
- ~/.pinocchio/repository
profile-settings:
profile: assistant
profile-registries:
- ~/.config/pinocchio/profiles.yaml
ai-chat:
ai-api-type: openai
ai-engine: gpt-5-mini
openai-chat:
openai-api-key: <secret>
app:
repositories:
- ~/.pinocchio/repository
profile:
active: assistant
profiles:
assistant:
inference_settings:
chat:
api_type: openai
engine: gpt-5-mini
Then keep credentials in the environment:
export OPENAI_API_KEY=<secret>
~/.config/pinocchio/config.yaml:
app:
repositories:
- ~/.pinocchio/repository
profile:
active: assistant
registries:
- ~/.config/pinocchio/profiles.yaml
~/.config/pinocchio/profiles.yaml:
slug: workspace
profiles:
assistant:
slug: assistant
inference_settings:
chat:
api_type: openai
engine: gpt-5-mini
After rewriting the config, validate it with an ordinary Pinocchio command.
Recommended checks:
--print-inference-settings shows the expected final model/provider.Example commands:
pinocchio examples test --print-inference-settings
pinocchio js --script examples/js/runner-profile-smoke.js --print-inference-settings
If you rely on a specific config file during the migration, use:
pinocchio --config-file ~/.config/pinocchio/config.yaml examples test --print-inference-settings
profile-settings at the top levelThis now fails. Rewrite it to profile.active and profile.registries.
Changing .pinocchio-profile.yml to .pinocchio.yml is necessary, but not sufficient. The document contents must also be rewritten.
ai-chat as a top-level blockThere is no supported new top-level runtime block. Put model/provider settings under an inline profile or an imported engine-only registry.
profiles.yaml as an app-runtime documentprofiles.yaml is now engine-only. Keep prompts, tool choices, middleware choices, and repository settings out of it.
| Problem | Cause | Solution |
|---|---|---|
field profile-settings not found in type configdoc.Document | The config file still uses the old profile-settings block | Rewrite it to profile.active and profile.registries |
field ai-chat not found in type configdoc.Document | The config file still uses old top-level runtime sections | Move those settings into profiles.<slug>.inference_settings or profiles.yaml |
legacy local config filename ".pinocchio-profile.yml" is no longer supported | The local override file still uses the old filename | Rename it to .pinocchio.yml |
| A profile resolves but credentials are missing | Shared provider credentials were removed from old top-level provider blocks during migration | Set them via environment variables or add them intentionally to the target profile |
| Prompt repositories disappeared | repositories stayed at the top level instead of moving under app | Rewrite to app.repositories |