# canned-prompts seed > **Collect, reuse and share prompts and prompt templates.** This bundle contains a first project seed for `canned-prompts`: - [`INTENT.md`](INTENT.md) — project mission, boundaries, principles, and success criteria. - [`CannedPromptFormat.md`](CannedPromptFormat.md) — the package-format specification, currently revision v0.2. - [`reference/`](reference/) — deliberately small Python CLI implementing the basic lifecycle. - [`examples/pqrst-estimate/`](examples/pqrst-estimate/) — a real package that can be used to exercise the implementation. - [`examples/house-style/`](examples/house-style/) — a `type: fragment` package that `pqrst-estimate` composes. ## Try the reference implementation ```bash cd reference python -m venv .venv . .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txt # add the included examples to your local catalog python canned_prompts.py add ../examples/house-style python canned_prompts.py add ../examples/pqrst-estimate # find and inspect it python canned_prompts.py search pqrst python canned_prompts.py show practice/pqrst-estimate # see how each input and parameter resolves, and where the value came from python canned_prompts.py resolve practice/pqrst-estimate \ --set session_summary="Implemented feature X, read unfamiliar code, added tests." # render it python canned_prompts.py render practice/pqrst-estimate \ --set session_summary="Implemented feature X, read unfamiliar code, added tests." # publish it to the local filesystem registry python canned_prompts.py publish ../examples/pqrst-estimate # remove the local catalog if you want to simulate another machine, then install python canned_prompts.py install practice/pqrst-estimate --version 0.1.0 ``` Packages added from a path are filed under the registry name `local`; packages installed from a registry are filed under that registry's name. `search` prints qualified references: ```text house:practice/pqrst-estimate@0.1.0 PQRST Estimate local:practice/pqrst-estimate@0.1.0 PQRST Estimate ``` By default the reference tool uses: ```text ~/.canned-prompts/catalog ~/.canned-prompts/default # the default registry ``` Override them with: ```text CANNED_PROMPTS_HOME=/some/path ``` or command-level `--catalog` / `--registry` options. ## Resolution vs rendering The format separates the two steps (`CannedPromptFormat.md` § 5.1). Resolution decides a value for every input and parameter and may be non-deterministic; rendering substitutes those values and always is. An input may declare a default that is either a static value or a *derived* one — a prompt that a capable consumer may run to produce the value, declared without naming any resolver or model. This reference tool never calls a model, so it resolves supplied values and static defaults only, and reports anything it cannot derive instead of rendering a prompt with a silent hole in it. ## Composition A package composes another by declaring it as a dependency and binding it to an input default. There are two kinds: - **`include`** — inline the other package's *rendered template* as text. Deterministic, needs no model, and the reference CLI performs it. - **`derive`** — use the other package's *result*, obtained by running it. Only a consumer able to run it can supply one. `examples/pqrst-estimate` includes `examples/house-style`, so a shared style block is a versioned package rather than copied text: ```yaml dependencies: prompts: - id: practice/house-style version: ">= 0.1.0" requirement: required inputs: - name: house_style required: false default: include: practice/house-style ``` A dependency pins an exact version by default; `any`, `newest` and a `>= X.Y.Z` lower bound are explicit opt-ins. These are per-dependency selectors, not version ranges — there is no solver, and constraint resolution across a dependency graph remains a non-goal. There is no template inheritance. A package never extends another or overrides its parts; composition is by reference only, so a package's content stays readable without chasing ancestors. ## Evals An eval file declares what to assess. `evals/` used to hold whatever an author put there; it now has one schema the tooling understands, split along the same line as composition: - **render checks** — deterministic assertions about the *rendered prompt* (`contains`, `not_contains`, `resolves_all`). No model needed, so the reference CLI runs them. - **output criteria** — statements about a good *result*. Declared, not run. ```bash python canned_prompts.py eval practice/pqrst-estimate ``` ```text local:practice/pqrst-estimate@0.2.0 evals/quality.yaml (pqrst-estimate-quality) render PASS contains "must sum to exactly 100%" render PASS resolves_all output -- 4 criteria declared (not run: judging output needs a model) ``` An eval declares assessment, never results. Results are run evidence and live outside the immutable package. ## Required versus compatible Two fields used to say overlapping things about capabilities. They now differ in one word each: | Field | Meaning | Absence means | |-------|---------|---------------| | `dependencies` | **required** — does not work without it | a consumer should warn or refuse | | `compatibility` | **observed** — known to work with it | nothing; it is information | Dependencies come in three kinds, separated by what the format can do about them: `prompts` are packages it resolves by id and version, `context` names things it does not package at all (an information space, an API, a corpus the caller supplies), and `capabilities` are what the environment must be able to do. `resolve` lists the last two, since the reference tool cannot verify either: ```text requires (this tool cannot verify these): capability web-search context repository-tree — A listing of the repository under review. ``` ## Registries and identity An id names a package *within a registry* (`CannedPromptFormat.md` § 3.2). The same id obtained from two registries may be two different packages, so the catalog keeps them apart and a bare id that matches more than one is reported as ambiguous rather than guessed. Qualify it when you need to: ```bash python canned_prompts.py render house:practice/pqrst-estimate --set ... ``` A registry may describe itself with an optional `registry.yaml` naming it and recording which namespaces are claimed and under what policy. Those claims are descriptive: a filesystem registry cannot authenticate a publisher, and signing and trust scoring are explicit non-goals. Ownership lives with the registry rather than in the package, so no package carries an unverifiable assertion of authority. ## Registries over HTTP `--registry` takes a URL as readily as a path: ```bash export CANNED_PROMPTS_PUBLISH_TOKEN=... python canned_prompts.py publish ../examples/pqrst-estimate \ --registry https://registry.example --as helix python canned_prompts.py install helix:practice/pqrst-estimate \ --registry https://registry.example ``` Publishing needs `--as`, because a URL addresses a service that hosts several registries and so does not name one the way a directory does (§ 20.4). That is the *only* place the transport is visible: identity and ambiguity, immutability of a published version, strict packaging, validation and the index all behave the same over HTTP as on a filesystem. ## The index Every store keeps an `index.yaml` recording which package versions entered it, from where, and when: ```bash python canned_prompts.py index ``` ```text local:helix/repo-orient@0.1.0 2026-09-06T13:31:02Z add from /home/worsch/helix-forge/prompts/repo-orient declares source personal prompt collection, contributed 2026-09-06 ``` This is store metadata, not package data. `provenance` records who wrote a prompt; the index records how a copy arrived *here* — which differs for every consumer, and which must never rewrite the package it describes. `included_at` is first arrival and is never overwritten; a re-run updates `last_seen_at`. ## Dependencies are reported, not fetched Installing a package that composes another warns when the dependency is absent, including when it is present but no version matches: ```text declared dependencies not in this catalog: practice/house-style@>= 0.1.0 — install them, or composition referencing them will not resolve ``` Nothing is fetched automatically. Dependency resolution is left to the consumer, but a package that installs cleanly and then cannot render is worse than one that says what it is waiting for. ## Packaging and versions `add`, `publish` and `install` copy the reserved paths (`prompt.yaml`, `prompt.md`, `README.md`, `LICENSE`, `examples/`, `evals/`, `assets/`) plus anything a manifest field references — and nothing else, as § 2 requires. What was left behind is reported rather than silently dropped: ```text not packaged (not a reserved path, not referenced by the manifest): .git/, .venv/, notes.txt ``` Version precedence follows SemVer, so `1.0.0` outranks `1.0.0-rc1`, and `any`, `newest` and `>= X.Y.Z` skip prereleases entirely. Publishing a release candidate never changes what existing consumers resolve to; name it exactly to use it. ## Deliberate limitations This seed has no hosted registry, model execution, authentication, network access, dependency resolver, or social features. `publish` and `install` operate on a filesystem registry so that the package semantics can be tested before infrastructure is built around them.