Package Repository Contract
This contract describes the repository shape that Demiurge can inspect, trust, preview, install, sync, and uninstall.
The implementation source of truth is demiurge/packages.py. The built-in
repository is package-repository/.
Repository Root
Required:
repository.yaml
packages/
Optional component roots:
bootstrap/
input/
output/
tool/
skill/
lib/
core/
mcp/
schedule/
repository.yaml
schema_version: 1
id: community
name: Community Packages
summary: Shared Demiurge package recipes.
id must be stable. Local users may assign a different alias when adding the
repository.
Package Recipes
Each recipe lives at:
packages/<package_id>.yaml
Rules:
schema_versionmust be1.- Package ids are unique within a repository.
- Component ids are unique within a recipe.
- Component
kindmust be one ofbootstrap,input,output,tool,skill,lib,core,mcp, orschedule. - Component sources must stay inside the repository.
- Component sources cannot be symlinks.
- Removed v1 fields such as
slots,tools,files,config_defaults, andmetadataare rejected. manual_dependenciesare warnings only.- Recipes do not install Python dependencies or edit host dependency files.
Pipeline Rules
Pipeline edits are valid only for bootstrap, input, and output
components.
Rules:
bootstrapsupports onlygroup: serial.inputandoutputsupportgroup: serialandgroup: parallel.- A pipeline entry must declare exactly one of
append,before, orafter. - Install fails if a
beforeoraftertarget is missing. - Install fails if the target pipeline already contains the package slot id.
- Uninstall removes package-owned pipeline entries.
Component Targets
Directory components install into runtime-core-relative targets:
| Kind | Default target root |
|---|---|
bootstrap | agent/bootstrap/ |
input | agent/input/ |
output | agent/output/ |
tool | agent/tools/ |
skill | agent/skills/ |
lib | agent/lib/ |
core components create or update a package-owned runtime core named by
target_core_id.
Install fails when an unmanaged target already exists. Shared targets are allowed only when another installed package owns the same repository alias, source, target, and effective config hash.
Manifest File Components
mcp and schedule components install one YAML declaration file each.
Defaults:
mcpuses the target core'sslots.mcproot, oragent/mcpwhen unset.scheduleuses the target core'sslots.schedulesroot, oragent/scheduleswhen unset.
Rules:
- Source files live under
mcp/orschedule/. - Targets must be YAML files.
- Targets must be directly inside the declaration root.
- Component
configis rendered with package options and applied as a manifest overlay before validation. - Installed files are normalized with schema defaults.
MCP and schedule packages install declarations, not running servers or claimed jobs. The host owns MCP transport, server lifecycle, schedule claims, approvals, and execution.
Example:
schema_version: 1
id: docs_and_daily
components:
- id: docs
kind: mcp
source: docs.yaml
config:
url: ${options.url}
- id: daily
kind: schedule
source: daily.yaml
config:
schedule: "0 9 * * *"
prompt: "Write a daily summary."
Options and Secrets
Supported option types are string, bool, choice, path, and secret.
Use type: secret for secret values. Secret values may be written into
installed component config, but packages.yaml records only <redacted>.
Unknown script-supplied option ids are rejected. Required options must resolve to a non-empty value.
Trust Rule
External repositories must be trusted before installation:
uv run demiurge package repo add ./local-packages --alias local --trust
The interactive manager asks for trust confirmation. Non-interactive external
adds require --trust.
Trust is host-local. A package cannot make itself trusted.
Path repositories are read from their configured path. Git repositories sync into:
~/.demiurge/package-repositories/<alias>/
Install and Uninstall Contract
Install writes package-owned runtime core targets and pipeline entries for slot components under the core repository lock. It runs host-owned gates, commits the live agents tree, and writes a provenance record in:
~/.demiurge/agents/<core-id>/packages.yaml
Uninstall removes package-owned targets and pipeline entries unless another
installed package still references the same shared component. It refuses drifted
package-owned files unless the operator supplies an explicit destructive
strategy such as --force-drift. It then updates packages.yaml and commits
the live agents tree.
Data outside package-owned targets is outside the uninstall contract.
Verification
Validate a repository:
uv run demiurge package repo list
uv run demiurge package list --repo <alias>
Preview a package:
uv run demiurge package install <alias>/<package_id> --core assistant --preview
Check the runtime after installation:
uv run demiurge core check