RFC 0003: Template Variable System
Comments on this RFC: start a discussion — or browse all RFC discussions.
- Status: Implemented
- Author(s): AltairaLabs Team
- Created: 2025-10-10
- Updated: 2025-10-31
- Implemented: 2025-10-31
- Related Issues: N/A
Summary
Define a robust template variable system for PromptPack that supports variable substitution, type validation, default values, and nested data structures using a {{variable}} syntax.
Motivation
Prompts need dynamic content that varies per execution:
- User-provided values (names, IDs, context)
- Environment-specific configuration (company name, region)
- Runtime-computed values (timestamps, session data)
Without a standard variable system:
- No portability - Each runtime implements variables differently
- No validation - Type errors discovered at runtime
- No documentation - Variables lack clear definitions
- No reusability - Hard to share prompts with clear interfaces
Goals
- Define a clear, unambiguous variable syntax
- Support type validation (string, number, boolean, object, array)
- Enable default values and required/optional variables
- Allow nested object access with dot notation
- Provide array indexing support
- Include validation rules (regex, min/max, enum)
Non-Goals
- Implement conditionals or loops in templates (future RFC)
- Create a full programming language
- Support arbitrary code execution
Detailed Design
Variable Syntax
Variables use double curly braces:
{{variable_name}}Variable Definitions
Each variable is defined with metadata:
{ "variables": [ { "name": "customer_name", "type": "string", "required": true, "description": "Customer's full name", "example": "John Doe" }, { "name": "priority", "type": "string", "required": false, "default": "medium", "validation": { "enum": ["low", "medium", "high", "urgent"] } } ]}Supported Types
- string - Text data
- number - Numeric values (integers and floats)
- boolean - True/false values
- object - Key-value maps
- array - Ordered lists
Dot Notation
Access nested object properties:
{{user.profile.name}}{{settings.theme.primaryColor}}{{account.billing.address.city}}Schema:
{ "name": "user", "type": "object", "description": "User object with nested properties"}Array Access
Access array elements by index:
{{items[0].title}}{{users[1].email}}{{tags[2]}}Validation Rules
Variables can have validation constraints:
{ "name": "email", "type": "string", "required": true, "validation": { "pattern": "^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$", "min_length": 5, "max_length": 100 }}Supported validations:
- pattern - Regular expression (string)
- min_length / max_length - String length (string)
- minimum / maximum - Numeric range (number)
- enum - Allowed values (any type)
Template Engine Configuration
Shared across all prompts in a pack:
{ "template_engine": { "version": "v1", "syntax": "{{variable}}", "features": ["basic_substitution", "fragments"] }}Key Design Decisions
Mustache-Style Syntax
Use {{variable}} instead of ${variable} or {variable}.
Rationale:
- Clear visual distinction from code
- Widely recognized in template systems (Mustache, Handlebars)
- Less collision with programming languages
Explicit Variable Definitions
All variables must be declared in the schema.
Rationale:
- Enables validation before execution
- Provides clear documentation
- Catches typos and missing variables early
Type System
Support common data types with validation.
Rationale:
- Prevents type errors at runtime
- Enables better IDE support
- Documents expected input format
Examples
Basic Substitution
Template:
You are a {{role}} assistant for {{company}}.Variables:
{ "variables": [ {"name": "role", "type": "string", "required": true}, {"name": "company", "type": "string", "required": true} ]}Input:
{ "role": "customer support", "company": "TechCorp"}Result:
You are a customer support assistant for TechCorp.Nested Objects
Template:
Customer: {{customer.name}}Email: {{customer.contact.email}}Priority: {{ticket.priority}}Variables:
{ "variables": [ { "name": "customer", "type": "object", "required": true, "description": "Customer information with nested fields" }, { "name": "ticket", "type": "object", "required": true } ]}Arrays
Template:
First item: {{items[0].title}}Second item: {{items[1].title}}Variables:
{ "variables": [ { "name": "items", "type": "array", "required": true, "description": "List of items" } ]}Default Values
Template:
Priority: {{priority}}Theme: {{theme}}Variables:
{ "variables": [ { "name": "priority", "type": "string", "required": false, "default": "medium" }, { "name": "theme", "type": "string", "required": false, "default": "light" } ]}If no input provided, uses defaults:
Priority: mediumTheme: lightDrawbacks
- Limited logic - No conditionals or loops (by design)
- Runtime errors - Nested access can fail if paths don’t exist
- Learning curve - Developers need to understand validation rules
Alternatives
Alternative 1: Jinja2-Style Syntax
Use {{ variable }} (with spaces) and support full Jinja2 features.
Rejected: Too complex, introduces programming logic into templates.
Alternative 2: String Interpolation
Use programming language string interpolation (e.g., Python f-strings).
Rejected: Not portable across languages and runtimes.
Alternative 3: No Validation
Allow variables without type definitions.
Rejected: Loses documentation and validation benefits.
Adoption Strategy
Backward Compatibility
N/A - Part of initial v1 specification.
Migration Path
N/A - No previous variable system.
Unresolved Questions
None - All design decisions finalized.
Revision History
- 2025-10-10: Initial draft
- 2025-10-20: Added validation rules
- 2025-10-31: Finalized and implemented