Prompt Template Contract
Status: strict Liquid-compatible rendering.
Shea Symphony renders workflow lane prompts, selected backend fragments, and
configured runtime templates before launching agents or writing evidence. Rendering uses the Rust
liquid engine with the standard Liquid tag and filter library, plus Shea's
strict external-context validation.
Supported Context
Prompt templates receive:
issue.*: fields from the normalizedTrackerIssuemodel.attempt: optional numeric attempt count.
Workpad templates receive the named values supplied by the caller for that
workpad surface, such as issue_ref, issue_title, run_id, target_state,
or evidence_summary.
Backend fragments are repository Markdown. Static fragments receive no dynamic
context; Merge repair receives only typed conflict facts such as pr_ref,
head_ref_name, expected_base, and sanitized mechanical_stderr. JSON Schema
construction, output classification, claim identity, and Project mutation
remain code-owned enforcement.
Examples:
Work on {{ issue.identifier }}: {{ issue.title }}
This is attempt {{ attempt }}.
### Labels
{% for label in issue.labels %}
- {{ forloop.index }}. {{ label }}
{% endfor %}
Liquid Tags And Filters
Templates may use Liquid-compatible syntax supported by the selected engine, including conditionals, loops, assignment/capture locals, and standard filters. Representative supported filters include:
defaultjoinsize- string filters such as
strip,upcase, andtruncate - array filters such as
first,last,sort, anduniq
Template-local variables introduced by Liquid tags, such as for label in ...,
assign, and capture, are allowed. External variables must come from the
prompt or workpad context described above.
Strict Failures
Rendering fails before agent launch or workpad evidence write when a template contains:
- an unknown external variable, such as
{{ issue.missing_field }}or{{ user.name }}; - an unknown workpad placeholder, such as
{{ missing_handoff_value }}; - an unknown filter, such as
{{ issue.title | no_such_filter }}; - malformed Liquid syntax, such as an unclosed
{% if %}or{% for %}block.
This strictness is intentional. Liquid compatibility must not silently drop missing data, tolerate misspelled filters, or write partial workpad evidence.
Validation Readback
cargo run -- validate .shea/workflows/shea-symphony.md reports:
prompt_renderer=strict-liquid-compatible;prompt_template_smoke.<lane>=passfor each configured lane prompt;backend_prompt_source.<id>=...with the exact selected Markdown path;workpad_template.<id>=... smoke=passfor every configured or centralized workpad/evidence template;resource_manifest=... groups=...and each exactresource_markdown_source=...from the enabled closure.
Any parse error, unknown filter, or unknown external variable in a configured prompt or workpad template makes validation fail.