The serving ecosystem manages prompts as immutable versions of a templated
prompt with mutable aliases (dev / staging / production) resolved by a
prompts:/<name>@<alias> URI. The shape is right, but the store is mutable —
"which prompt did the agent actually run under" is a row someone with write
access can edit after the fact.
jcp-prompt keeps the shape and adds the family's trust layer:
- PromptVersion: immutable, content-addressed (the id IS the name+version+
template, so swapping the text changes the id); render() substitutes
{{ variable }} placeholders and reports missing ones; variables() lists them.
- PromptRegistry: register (auto-incrementing versions) + set_alias (promote)
+ resolve(prompts:/name@alias | prompts:/name/version). Each register and
each promotion seals a hash-chained prompt/1 JCR-1 receipt, so the exact
instructions and which version was live when are tamper-evident artifacts.
- parse_ref / verify round out the URI scheme and receipt verification.
Completes the MLflow methodology trio alongside jcp-trace's content-addressed
gate + judge alignment. Reuses jcp-schema + jcp-receipt jcr1 — no new crypto.
7 tests + example green, clippy clean; workspace test + clippy --all-targets
still clean.
Co-Authored-By: Claude Opus 4.8 <[email protected]>