The answer to the capability question was conditional: keep both fields if
they carry the required/observed distinction, fix the terminology if they do
not. They did not.
Section 9 opened with "records known requirements or observations", mixing
both in one field — `models` was observational ("known to be compatible or
evaluated") while `capabilities` was prescriptive ("expected from the
execution environment"). Section 10 then described dependencies as what a
prompt "expects". Both fields said expected, so the overlap was real
ambiguity rather than redundancy, and the fix is terminology.
`dependencies` now means **required**; `compatibility` means **observed**. A
consumer must not refuse to run a package because its environment is absent
from a compatibility list. The same capability name may legitimately appear in
both: required to run at all, and separately observed to work well on
particular models. `compatibility.aliases` records the same capability under
other names, so a consumer can recognize a requirement its environment labels
differently.
Dependencies now have three kinds, separated by what the format can do about
them: `prompts` it resolves by id and version; `context` names what it does
not package at all; `capabilities` are what the environment must be able to
do. Context entries use `name` rather than `id`, because nothing can look them
up, and `description` is required because nothing else can explain an
unpackaged dependency. A capability takes no version and no
`requirement: generate` — it is not an artifact and cannot be fetched, pinned
or generated. Capability names are free-form kebab-case, validated for shape
and not membership, exactly as tags are.
Section 10.1 also draws the line the format had never stated: an input is
content the caller passes for one use; a context dependency is a standing fact
about the environment.
Spec: 9 rewritten, 9.1 and 10.1 and 10.2 new, 10 reframed, 18 (rules 19-20),
4 updated. Former 10.1/10.2 renumbered to 10.3/10.4 with cross-references.
Reference CLI: validate_capabilities, validate_context_dependencies, and a
`resolve` section listing required capabilities and context under "this tool
cannot verify these" rather than implying it checked. Tests 51 -> 65.
Also drops an invented `session-review` capability from the example package in
favour of an honest `long-context` observation.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 388925@bnt-lap001
Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
|
||
|---|---|---|
| examples | ||
| reference | ||
| workplans | ||
| .custodian-brief.md | ||
| .gitignore | ||
| .repo-classification.yaml | ||
| AGENTS.md | ||
| CannedPromptFormat-v0.1.md | ||
| INTENT.md | ||
| README.md | ||
| SCOPE.md | ||
| WORK-RECORDS.md | ||
canned-prompts seed
Collect, reuse and share prompts and prompt templates.
This bundle contains a first project seed for canned-prompts:
INTENT.md— project mission, boundaries, principles, and success criteria.CannedPromptFormat-v0.1.md— experimental package-format specification.reference/— deliberately small Python CLI implementing the basic lifecycle.examples/pqrst-estimate/— a real package that can be used to exercise the implementation.examples/house-style/— atype: fragmentpackage thatpqrst-estimatecomposes.
Try the reference implementation
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:
house:practice/pqrst-estimate@0.1.0 PQRST Estimate
local:practice/pqrst-estimate@0.1.0 PQRST Estimate
By default the reference tool uses:
~/.canned-prompts/catalog
~/.canned-prompts/registry
Override them with:
CANNED_PROMPTS_HOME=/some/path
or command-level --catalog / --registry options.
Resolution vs rendering
The format separates the two steps (CannedPromptFormat-v0.1.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:
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.
python canned_prompts.py eval practice/pqrst-estimate
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:
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-v0.1.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:
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.
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.