RFC 0003: Template Variable System
- 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: medium
Theme: light
Drawbacks
- 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