Skip to content
Prompting Press v0.2

Rust API reference

pub struct Prompt

An immutable, fully-validated prompt. Wraps a [PromptDefinition]; all invariants (shape-valid, template-parseable, agreement-sound, reserved-name clean) are enforced at construction time. There are no setters; the sole mutator is [Prompt::derive].

pub fn body(&self) -> &str

The root body template source (the default arm’s unrendered template).

pub fn check(&self) -> CheckReport

Pure advisory lint: returns a [CheckReport] containing only the trust/guard finding class. Construction already enforces agreement, parse, and reserved-name invariants, so those arms are structurally unreachable for a constructed Prompt. The only LIVE finding check can surface is [FindingKind::UntrustedWithoutGuard] — a prompt declaring trusted: false vars but carrying no "guard" key in metadata. Pure: takes &self, never renders, never mutates.

pub fn definition(&self) -> &PromptDefinition

Borrow the underlying [PromptDefinition] for use by binding crates (e.g. prompting-press-node, prompting-press-py) that need to call the kernel directly for render/get_source (their validation is owned in the binding layer, not in Rust garde, so the consumer’s generic render<V> is not usable there). Bindings call prompting_press_core::render(prompt.definition,...) directly after doing their own validation — the same zero-engine-logic pattern as the Prompt::render path. Also used by Composition::resolve within this crate.

pub fn derive(&self, overlay: PromptOverlay) -> Result<Self, ConsumerError>

The sole mutator: shallow-replace top-level fields from overlay onto a clone of this prompt’s definition, then route the merged definition through [Prompt::new] (full re-validation). The original Prompt is untouched. Each Some(field) in overlay replaces the corresponding field; None fields are left as-is. name IS overlayable (the overlay can rename a prompt). After the merge, every construction invariant is re-checked over the whole merged definition — so an overlay that introduces an agreement violation or a reserved variant name is rejected. In Rust the validator is the generic V named at the render call site (garde covers all fields at compile time); derive takes &self and carries no runtime validator. PromptOverlay therefore contains only data fields. # Errors Same error classes as [Prompt::new]: a merged definition that fails any construction invariant returns the structured error.

pub fn from_json(text: &str) -> Result<Self, ConsumerError>

Deserialize a Prompt from already-read JSON text, then validate. Equivalent to serde_json::from_str(..) + [Prompt::new]. Error semantics mirror from_yaml. # Errors [ConsumerError::Load] if text is not valid JSON or does not match the PromptDefinition shape, or any error from [Prompt::new].

pub fn from_toml(text: &str) -> Result<Self, ConsumerError>

Deserialize a Prompt from already-read TOML text, then validate. Uses toml::from_str (the serde-native TOML crate — research R3 / toml@1.1.2). Error semantics mirror from_yaml. # Errors [ConsumerError::Load] if text is not valid TOML or does not match the PromptDefinition shape, or any error from [Prompt::new].

pub fn from_yaml(text: &str) -> Result<Self, ConsumerError>

Deserialize a Prompt from already-read YAML text, then validate. Equivalent to serde_yaml_ng::from_str(..) + [Prompt::new]. A parse/shape error returns [ConsumerError::Load]; a validation error returns the same errors as new. The crate reads no files — the caller supplies already-read text. # Errors [ConsumerError::Load] if text is not valid YAML or does not match the PromptDefinition shape, or any error from [Prompt::new].

pub fn get_source(&self, variant: Option<&str>) -> Result<&str, ConsumerError>

Return a variant’s unrendered template source (the exact string the kernel hashes into template_hash). Delegates to the kernel; no vars, no validation. variant = None returns the root body source. # Errors [ConsumerError::Kernel] — the kernel rejected the lookup (unknown variant name).

pub fn metadata(&self) -> &Map<String, Value>

The metadata opaque map (library-defined top-level annotations, if any).

pub fn name(&self) -> &str

The prompt’s name (the name field of the underlying definition).

pub fn new(def: PromptDefinition) -> Result<Self, ConsumerError>

The primary validating constructor. Runs the construction invariants on def: 1. For each variant arm (root body + every named variant), asks the kernel for the arm’s [required_roots]. A kernel Err (parse failure or excluded feature) is a construction failure — the Prompt is not built. 2. Each analyzable arm’s referenced roots must be a subset of the declared variables. Any root not declared is an agreement violation. 3. A variant named literally "default" is rejected — the kernel reserves that name for the root body; the declared arm would be unreachable. On success the Prompt is returned. On any violation a structured [ConsumerError] is returned — never a panic. # Errors - [ConsumerError::Kernel] — a variant template could not be parsed or uses an excluded feature (&#123;% include %&#125; / macros / inheritance). - [ConsumerError::Kernel] — a variant template references a variable not declared in variables (agreement failure; code::UNDEFINED_VARIABLE). - [ConsumerError::Kernel] — a variant is literally named "default" (reserved; code::UNDEFINED_VARIABLE with field "variant").

pub fn output_model(&self) -> Option<&str>

The output model reference, if declared (output_model field). Carried as metadata only — never parsed or resolved by this library.

pub fn render<V>(&self, vars: &V, variant: Option<&str>, guard: &GuardConfig, reveal_render_detail: bool) -> Result<RenderResult, ConsumerError>
where
V: Serialize + Validate,
<V as Validate>::Context: Default

Validate-then-render this prompt. 1. Validates vars once via garde, BEFORE any templating. On failure returns [ConsumerError::Validation] — the kernel is never reached. 2. Bridges the validated struct to the kernel’s value type via [minijinja::Value::from_serialize]. 3. Delegates to [prompting_press_core::render], normalizing any [KernelError] to [ConsumerError::Kernel]. variant = None selects the default (root body) arm. guard is plumbed straight through to the kernel; RenderResult::guard is surfaced unchanged (guard expansion is the kernel’s contract). V::Context: Default so the whole-struct [Validate::validate] convenience applies (one validation pass over the entire input set). Context-carrying validation is intentionally out of v1 scope (one concrete path per concern). ## Byte-identical output The RenderResult hashes are byte-identical across Rust, Python, and TypeScript for the same template and inputs, because all three bindings share this kernel render path. ## reveal_render_detail — unsafe, off-by-default render-error detail opt-in Pass false in all production call sites (the default). When true, the full underlying render-error detail is surfaced in the returned [ConsumerError::Kernel] message instead of the fixed scrubbed string. Risk: enabling this may place bound-value content — untrusted input, PII, secrets — into the returned error message and into any log line or stack trace derived from it. Use only in a controlled debug context where you own the log destination and deliberately accept that exposure. Never set true by default or in ambient/global configuration. # Errors - [ConsumerError::Validation] — garde rejected vars. - [ConsumerError::Kernel] — the kernel rejected the render (unknown variant, strict-undefined reference, parse/render failure). Render detail scrubbed unless reveal_render_detail = true. Parse detail always preserved.

pub fn role(&self) -> &PromptDefinitionRole

The conversational role (system / user / assistant).

pub fn variables(&self) -> &HashMap<String, PromptVariable>

The declared variables map (name → PromptVariable).

pub fn variants(&self) -> &HashMap<String, PromptVariant>

The named variants map (name → PromptVariant). Empty when the prompt has no named variants (only the implicit default arm).

pub struct PromptOverlay

A shallow-replacement overlay for [Prompt::derive]. Each field is Option<T>. A Some(value) replaces the corresponding field on the cloned definition; a None leaves it unchanged. All fields are optional — pass only what should change. name is overlayable: a prompt can be renamed (useful for template-derived variants). After merging, the full construction invariants (agreement, parse, reserved name) are re-checked over the merged whole. In Rust the validator is the generic V named at the call site; PromptOverlay carries only data fields — no runtime validator object (the Rust compile-time asymmetry documented in R6).

pub body: Option<String>

Replace the root body template source.

pub metadata: Option<Map<String, Value>>

Replace the metadata opaque map.

pub name: Option<PromptDefinitionName>

Replace the prompt’s name.

pub output_model: Option<Option<String>>

Replace (or clear) the output_model reference.

pub role: Option<PromptDefinitionRole>

Replace the prompt’s role.

pub variables: Option<HashMap<String, PromptVariable>>

Replace the full variables map.

pub variants: Option<HashMap<String, PromptVariant>>

Replace the full variants map.

pub fn core_version() -> &'static str

Returns the version string of the underlying rendering kernel.

pub struct RenderResult

Render result + content-addressed provenance. Plain data returned to the caller — no telemetry sink, no tracing coupling. There is deliberately no vars_hash field.

pub guard: Option<String>

The guard instruction text, present only when guard expansion was opted in; None when the guard is disabled. Never concatenated into text.

pub name: String

The prompt name (def.name).

pub render_hash: String

Lowercase-hex SHA256(rendered text).

pub template_hash: String

Lowercase-hex SHA256(resolved variant source).

pub text: String

The rendered body text. The guard text is NEVER concatenated here.

pub variant: String

The resolved variant name (the reserved default, or the named arm).

pub struct GuardConfig

Per-render guard option. Opt-in, per render. When enabled is false: - The rendered body is byte-identical to a plain render (the pre-pass is not applied, no values are inspected, no entity-escaping occurs). - [build_guard_text] returns None. When enabled is true AND the definition declares at least one untrusted field (trusted: false): - The source pre-pass runs before rendering, rewriting each &#123;&#123; EXPR &#125;&#125; whose root identifier is untrusted into &#123;&#123; (EXPR) \| pp_guard_wrap &#125;&#125;. The pp_guard_wrap filter entity-escapes &, <, > (in that order) and wraps the result in <untrusted>…</untrusted>. Values of trusted roots are never touched. - [build_guard_text] returns a fixed advisory string referencing the markers. This is NOT a sanitizer. Enabling the guard makes untrusted values visually locatable in the output; it is not a guarantee that a downstream model will honour the markers. The advisory is a suggestion, not enforcement.

pub advisory: Option<String>

Optional override for the advisory sentence returned in [crate::RenderResult::guard]. None ⇒ [DEFAULT_GUARD_ADVISORY] (the fixed default that references the <untrusted>…</untrusted> markers). The <untrusted> MARKERS themselves are fixed and NOT configurable — they are the security-relevant contract. Only the human-readable advisory that explains them is overridable, for model-tuning or localization. A caller that overrides this owns its correctness (e.g. it should still describe the real markers). The override is plain text: it is never substituted, never parsed for placeholders, and never re-enters the template engine.

pub enabled: bool

When false, no delimiting and no guard advisory are produced.

pub struct CheckReport

The output of Prompt::check: an ordered list of [Finding]s. Empty ⇒ pass. Carries only findings — no rendered text, no mutated state.

pub fn is_empty(&self) -> bool

Alias for passed: true iff there are no findings.

pub fn passed(&self) -> bool

true iff there are no findings (the lint passed). Equivalent to self.findings.is_empty; reads more clearly at a CI gate call site.

pub findings: Vec<Finding>

Every advisory finding, in deterministic order. Empty ⇒ pass.

pub struct Finding

One actionable lint finding: it names the prompt, the variant where applicable, the failure kind, and a human-readable detail.

pub detail: String

A human-readable, actionable description. Carries no bound-value content.

pub kind: FindingKind

The kind of failure (the discriminant a consumer matches on).

pub prompt: String

The prompt’s name.

pub variant: Option<String>

The variant the finding pertains to (Some("default") / Some("<name>") for an agreement or analysis finding); None for a prompt-level trust/guard finding.

pub enum FindingKind

The closed set of lint-failure classes. UntrustedWithoutGuard is the only advisory class that Prompt::check can surface. All other hard invariants (undeclared variables, analysis errors, reserved variant names) are enforced at construction and are structurally unreachable from a live Prompt.

UntrustedWithoutGuard { field: String }

The prompt declares field as trusted: false but configures no guard for it (see the metadata.guard convention in module docs). The only advisory class surfaced by Prompt::check.

pub struct Composition

An explicit, ordered sequence of (Prompt, vars, variant) entries that resolves to a Vec<Message> in append order. Built with new + append; there is no fluent .chain. No Registry needed.

pub fn append<V>(&mut self, prompt: &Prompt, vars: &V, variant: Option<&str>) -> Result<(), ConsumerError>
where
V: Serialize + Validate,
<V as Validate>::Context: Default

Append one (prompt, vars, variant) entry, validating + serializing vars eagerly (see module docs). vars is validated once via garde now; on success it is serialized to the kernel’s value type ([minijinja::Value::from_serialize]) and the entry is stored (alongside a clone of prompt). On failure the garde report is normalized to [ConsumerError::Validation] and nothing is stored — the composition is unchanged, so a later resolve never sees a half-validated entry. Takes &mut self and returns Result<, ConsumerError> (not Self): the builder is intentionally not fluent/chainable. V::Context: Default so the whole-struct [Validate::validate] convenience applies (one validation pass over the entry’s entire input set). Context-carrying validation is intentionally out of v1 scope (one concrete path per concern). # Errors [ConsumerError::Validation] — garde rejected vars. The entry is not appended.

pub fn is_empty(&self) -> bool

true iff no entries have been appended.

pub fn len(&self) -> usize

The number of appended entries (== the resolved-message count on success).

pub fn new() -> Self

Create an empty composition. An empty composition resolves to Ok(vec![]).

pub fn resolve(&self) -> Result<Vec<Message>, ConsumerError>

Resolve the composition to an ordered Vec<Message>, rendering each entry — in append order — through the kernel. For each entry, in order: call [prompting_press_core::render] on the entry’s Prompt’s definition with the entry’s pre-validated value (vars were validated at append). The render result becomes Message &#123; role: <def.role stringified>, text: result.text &#125;. Composition uses no guard expansion — a default [GuardConfig] is passed (guard text is never concatenated into text). One entry’s render failure (unknown variant, strict-undefined reference, parse/render error) propagates as the normalized [ConsumerError]; the partial result built so far is discarded, never returned as success. An empty composition returns Ok(vec![]). resolve does not mutate self (it takes &self); it reuses the kernel’s render path rather than duplicating any rendering logic. # Errors [ConsumerError::Kernel] — the kernel rejected an entry’s render (unknown variant, strict-undefined reference, parse/render failure). Parse/Render detail is scrubbed.

pub struct Message

One resolved message in a composition’s output: a role-tagged rendered string. role is the prompt definition’s role stringified ("system" / "user" / "assistant"); text is that prompt rendered with the entry’s own validated vars.

pub role: String

The conversational role, taken from the prompt definition’s role.

pub text: String

The rendered body text for this entry.

pub struct FieldError

One normalized failure row — the common structured shape shared across every binding ([&#123;field, code, message&#125;]). - field: the offending field / path (a garde dot-path, a variable name, "variant", or "template"), or "" when no single field applies. - code: a stable string from the [code] vocabulary. - message: a human-readable, scrubbed description safe to log.

pub code: String

A stable code from the [code] vocabulary.

pub field: String

The offending field or path; "" when no single field applies.

pub message: String

A human-readable, scrubbed message safe to log.

pub enum ConsumerError

The single public error type for the consumer crate. Native error types ([garde::Report], [prompting_press_core::KernelError]) are mapped into this shape by the [From] impls in this module and never appear on a public signature. The enum is closed (no #[non_exhaustive]): the variant set is part of the compatibility surface.

Kernel(Vec<FieldError>)

The kernel rejected the render/source/analysis call. One [FieldError] per kernel failure, carrying the mapped code from the [code] vocabulary. Render detail is scrubbed; Parse detail is preserved (pre-binding template syntax).

Load(String)

Malformed input to the dual-input loader (bad YAML/JSON, or a deserialize error). Holds a short, loader-level description. Nothing is partially loaded.

Validation(Vec<FieldError>)

Typed-Vars validation failed (garde). One [FieldError] per reported path, each carrying [code::VALIDATION].

pub const EXCLUDED_FEATURE: &str = "excluded_feature";

The template used an excluded feature ([prompting_press_core::KernelError::ExcludedFeature]).

pub const LOAD: &str = "load";

Malformed YAML/JSON input, or a deserialize failure, in the dual-input loader.

pub const PARSE: &str = "parse";

The template failed to parse ([prompting_press_core::KernelError::Parse]). The underlying detail is scrubbed.

pub const RENDER: &str = "render";

A render-time failure other than an undefined variable ([prompting_press_core::KernelError::Render]). The underlying detail is scrubbed.

pub const UNDEFINED_VARIABLE: &str = "undefined_variable";

A strict-undefined variable was hit at render time ([prompting_press_core::KernelError::UndefinedVariable]).

pub const UNKNOWN_VARIANT: &str = "unknown_variant";

The kernel was asked for a variant the definition does not declare ([prompting_press_core::KernelError::UnknownVariant]).

pub const VALIDATION: &str = "validation";

A garde validation failure (the consumer synthesizes this; garde exposes no machine code). One row per reported path.

docs current as of 0.2.0